feat: 实现lazy load,加快加载速度;美化界面
This commit is contained in:
		@@ -1,11 +1,11 @@
 | 
				
			|||||||
import { createRouter, createWebHistory } from "vue-router";
 | 
					import { createRouter, createWebHistory } from "vue-router";
 | 
				
			||||||
import HomeView from "../views/HomeView.vue";
 | 
					const HomeView = () => import("../views/HomeView.vue");
 | 
				
			||||||
import AuthView from "../views/AuthView.vue";
 | 
					const AuthView = () => import("../views/AuthView.vue");
 | 
				
			||||||
import ProjectView from "../views/Project/Index.vue";
 | 
					const ProjectView = () => import("../views/Project/Index.vue");
 | 
				
			||||||
import TestView from "../views/TestView.vue";
 | 
					const TestView = () => import("../views/TestView.vue");
 | 
				
			||||||
import UserView from "@/views/User/Index.vue";
 | 
					const UserView = () => import("@/views/User/Index.vue");
 | 
				
			||||||
import ExamView from "@/views/Exam/Index.vue";
 | 
					const ExamView = () => import("@/views/Exam/Index.vue");
 | 
				
			||||||
import MarkdownEditor from "@/components/MarkdownEditor.vue";
 | 
					const MarkdownEditor = () => import("@/components/MarkdownEditor.vue");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const router = createRouter({
 | 
					const router = createRouter({
 | 
				
			||||||
  history: createWebHistory(import.meta.env.BASE_URL),
 | 
					  history: createWebHistory(import.meta.env.BASE_URL),
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,113 +1,153 @@
 | 
				
			|||||||
<template>
 | 
					<template>
 | 
				
			||||||
  <div class="h-full flex flex-col gap-7">
 | 
					  <div class="h-full flex flex-col gap-4">
 | 
				
			||||||
    <div class="tabs tabs-lift flex-shrink-0 mx-5">
 | 
					    <!-- 标签栏 -->
 | 
				
			||||||
      <label class="tab">
 | 
					    <div class="tabs-container mx-5">
 | 
				
			||||||
        <input
 | 
					      <div
 | 
				
			||||||
          type="radio"
 | 
					        class="tabs tabs-lift flex-shrink-0 bg-base-100 rounded-xl shadow-lg border border-base-300"
 | 
				
			||||||
          name="function-bar"
 | 
					 | 
				
			||||||
          id="1"
 | 
					 | 
				
			||||||
          :checked="checkID === 1"
 | 
					 | 
				
			||||||
          @change="handleTabChange"
 | 
					 | 
				
			||||||
        />
 | 
					 | 
				
			||||||
        <TerminalIcon class="icon" />
 | 
					 | 
				
			||||||
        日志终端
 | 
					 | 
				
			||||||
      </label>
 | 
					 | 
				
			||||||
      <label class="tab">
 | 
					 | 
				
			||||||
        <input
 | 
					 | 
				
			||||||
          type="radio"
 | 
					 | 
				
			||||||
          name="function-bar"
 | 
					 | 
				
			||||||
          id="2"
 | 
					 | 
				
			||||||
          :checked="checkID === 2"
 | 
					 | 
				
			||||||
          @change="handleTabChange"
 | 
					 | 
				
			||||||
        />
 | 
					 | 
				
			||||||
        <VideoIcon class="icon" />
 | 
					 | 
				
			||||||
        HTTP视频流
 | 
					 | 
				
			||||||
      </label>
 | 
					 | 
				
			||||||
      <label class="tab">
 | 
					 | 
				
			||||||
        <input
 | 
					 | 
				
			||||||
          type="radio"
 | 
					 | 
				
			||||||
          name="function-bar"
 | 
					 | 
				
			||||||
          id="3"
 | 
					 | 
				
			||||||
          :checked="checkID === 3"
 | 
					 | 
				
			||||||
          @change="handleTabChange"
 | 
					 | 
				
			||||||
        />
 | 
					 | 
				
			||||||
        <Monitor class="icon" />
 | 
					 | 
				
			||||||
        HDMI视频流
 | 
					 | 
				
			||||||
      </label>
 | 
					 | 
				
			||||||
      <label class="tab">
 | 
					 | 
				
			||||||
        <input
 | 
					 | 
				
			||||||
          type="radio"
 | 
					 | 
				
			||||||
          name="function-bar"
 | 
					 | 
				
			||||||
          id="4"
 | 
					 | 
				
			||||||
          :checked="checkID === 4"
 | 
					 | 
				
			||||||
          @change="handleTabChange"
 | 
					 | 
				
			||||||
        />
 | 
					 | 
				
			||||||
        <SquareActivityIcon class="icon" />
 | 
					 | 
				
			||||||
        示波器
 | 
					 | 
				
			||||||
      </label>
 | 
					 | 
				
			||||||
      <label class="tab">
 | 
					 | 
				
			||||||
        <input
 | 
					 | 
				
			||||||
          type="radio"
 | 
					 | 
				
			||||||
          name="function-bar"
 | 
					 | 
				
			||||||
          id="5"
 | 
					 | 
				
			||||||
          :checked="checkID === 5"
 | 
					 | 
				
			||||||
          @change="handleTabChange"
 | 
					 | 
				
			||||||
        />
 | 
					 | 
				
			||||||
        <Binary class="icon" />
 | 
					 | 
				
			||||||
        逻辑分析仪
 | 
					 | 
				
			||||||
      </label>
 | 
					 | 
				
			||||||
      <label class="tab">
 | 
					 | 
				
			||||||
        <input
 | 
					 | 
				
			||||||
          type="radio"
 | 
					 | 
				
			||||||
          name="function-bar"
 | 
					 | 
				
			||||||
          id="6"
 | 
					 | 
				
			||||||
          :checked="checkID === 6"
 | 
					 | 
				
			||||||
          @change="handleTabChange"
 | 
					 | 
				
			||||||
        />
 | 
					 | 
				
			||||||
        <Hand class="icon" />
 | 
					 | 
				
			||||||
        嵌入式逻辑分析仪
 | 
					 | 
				
			||||||
      </label>
 | 
					 | 
				
			||||||
      <label class="tab">
 | 
					 | 
				
			||||||
        <input
 | 
					 | 
				
			||||||
          type="radio"
 | 
					 | 
				
			||||||
          name="function-bar"
 | 
					 | 
				
			||||||
          id="7"
 | 
					 | 
				
			||||||
          :checked="checkID === 7"
 | 
					 | 
				
			||||||
          @change="handleTabChange"
 | 
					 | 
				
			||||||
        />
 | 
					 | 
				
			||||||
        <Signature class="icon" />
 | 
					 | 
				
			||||||
        信号发生器
 | 
					 | 
				
			||||||
      </label>
 | 
					 | 
				
			||||||
      <!-- 全屏按钮 -->
 | 
					 | 
				
			||||||
      <button
 | 
					 | 
				
			||||||
        class="fullscreen-btn ml-auto btn btn-ghost btn-sm"
 | 
					 | 
				
			||||||
        @click="toggleFullscreen"
 | 
					 | 
				
			||||||
        :title="isFullscreen ? '退出全屏' : '全屏'"
 | 
					 | 
				
			||||||
      >
 | 
					      >
 | 
				
			||||||
        <MaximizeIcon v-if="!isFullscreen" class="icon" />
 | 
					        <label
 | 
				
			||||||
        <MinimizeIcon v-else class="icon" />
 | 
					          v-for="tab in tabs"
 | 
				
			||||||
      </button>
 | 
					          :key="tab.id"
 | 
				
			||||||
 | 
					          class="tab-item"
 | 
				
			||||||
 | 
					          :class="{ 'tab-active': checkID === tab.id }"
 | 
				
			||||||
 | 
					        >
 | 
				
			||||||
 | 
					          <input
 | 
				
			||||||
 | 
					            type="radio"
 | 
				
			||||||
 | 
					            name="function-bar"
 | 
				
			||||||
 | 
					            :id="tab.id.toString()"
 | 
				
			||||||
 | 
					            :checked="checkID === tab.id"
 | 
				
			||||||
 | 
					            @change="handleTabChange"
 | 
				
			||||||
 | 
					            class="hidden"
 | 
				
			||||||
 | 
					          />
 | 
				
			||||||
 | 
					          <component :is="tab.icon" class="icon" />
 | 
				
			||||||
 | 
					          <span class="tab-label">{{ tab.label }}</span>
 | 
				
			||||||
 | 
					          <!-- 活跃指示器 -->
 | 
				
			||||||
 | 
					          <div class="active-indicator" v-if="checkID === tab.id"></div>
 | 
				
			||||||
 | 
					        </label>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        <!-- 全屏按钮 -->
 | 
				
			||||||
 | 
					        <div class="fullscreen-container ml-auto">
 | 
				
			||||||
 | 
					          <button
 | 
				
			||||||
 | 
					            class="fullscreen-btn"
 | 
				
			||||||
 | 
					            @click="toggleFullscreen"
 | 
				
			||||||
 | 
					            :title="isFullscreen ? '退出全屏' : '全屏'"
 | 
				
			||||||
 | 
					          >
 | 
				
			||||||
 | 
					            <MaximizeIcon v-if="!isFullscreen" class="icon" />
 | 
				
			||||||
 | 
					            <MinimizeIcon v-else class="icon" />
 | 
				
			||||||
 | 
					            <span class="btn-tooltip">{{
 | 
				
			||||||
 | 
					              isFullscreen ? "退出全屏" : "全屏"
 | 
				
			||||||
 | 
					            }}</span>
 | 
				
			||||||
 | 
					          </button>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					      </div>
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
    <!-- 主页面 -->
 | 
					
 | 
				
			||||||
    <div class="flex-1 overflow-hidden">
 | 
					    <!-- 主内容区域 -->
 | 
				
			||||||
      <div v-if="checkID === 1" class="h-full overflow-y-auto"></div>
 | 
					    <div class="content-area flex-1 overflow-hidden mx-5 mb-5">
 | 
				
			||||||
      <div v-else-if="checkID === 2" class="h-full overflow-y-auto">
 | 
					      <div
 | 
				
			||||||
        <VideoStreamView />
 | 
					        class="content-wrapper bg-base-100 rounded-xl shadow-lg border border-base-300 h-full overflow-hidden"
 | 
				
			||||||
      </div>
 | 
					      >
 | 
				
			||||||
      <div v-else-if="checkID === 3" class="h-full overflow-y-auto">
 | 
					        <!-- 加载状态 -->
 | 
				
			||||||
        <HdmiVideoStreamView />
 | 
					        <div v-if="isLoading" class="loading-container">
 | 
				
			||||||
      </div>
 | 
					          <span class="loading loading-spinner loading-xl"></span>
 | 
				
			||||||
      <div v-else-if="checkID === 4" class="h-full overflow-y-auto">
 | 
					          <p class="loading-text">正在加载 {{ getCurrentTabLabel }}...</p>
 | 
				
			||||||
        <OscilloscopeView />
 | 
					        </div>
 | 
				
			||||||
      </div>
 | 
					
 | 
				
			||||||
      <div v-else-if="checkID === 5" class="h-full overflow-y-auto">
 | 
					        <!-- 内容区域 -->
 | 
				
			||||||
        <LogicAnalyzerView />
 | 
					        <div v-else class="content-panel h-full overflow-hidden">
 | 
				
			||||||
      </div>
 | 
					          <Transition name="fade" mode="out-in">
 | 
				
			||||||
      <div v-else-if="checkID === 6" class="h-full overflow-y-auto">
 | 
					            <div :key="checkID" class="h-full overflow-y-auto">
 | 
				
			||||||
        <DebuggerView />
 | 
					              <!-- 日志终端 -->
 | 
				
			||||||
      </div>
 | 
					              <div v-if="checkID === 1" class="panel-content">
 | 
				
			||||||
      <div v-else-if="checkID === 7" class="h-full overflow-y-auto">
 | 
					                <div class="panel-header">
 | 
				
			||||||
        <DDSCtrlView />
 | 
					                  <TerminalIcon class="panel-icon" />
 | 
				
			||||||
 | 
					                  <h3 class="panel-title">日志终端</h3>
 | 
				
			||||||
 | 
					                </div>
 | 
				
			||||||
 | 
					                <div class="terminal-placeholder">
 | 
				
			||||||
 | 
					                  <p class="placeholder-text">日志终端功能正在开发中...</p>
 | 
				
			||||||
 | 
					                </div>
 | 
				
			||||||
 | 
					              </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					              <!-- HTTP视频流 -->
 | 
				
			||||||
 | 
					              <Suspense v-else-if="checkID === 2">
 | 
				
			||||||
 | 
					                <template #default>
 | 
				
			||||||
 | 
					                  <VideoStreamView />
 | 
				
			||||||
 | 
					                </template>
 | 
				
			||||||
 | 
					                <template #fallback>
 | 
				
			||||||
 | 
					                  <div class="loading-fallback">
 | 
				
			||||||
 | 
					                    <span class="loading loading-spinner loading-xl"></span>
 | 
				
			||||||
 | 
					                    <p class="loading-text">正在加载视频流组件...</p>
 | 
				
			||||||
 | 
					                  </div>
 | 
				
			||||||
 | 
					                </template>
 | 
				
			||||||
 | 
					              </Suspense>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					              <!-- HDMI视频流 -->
 | 
				
			||||||
 | 
					              <Suspense v-else-if="checkID === 3">
 | 
				
			||||||
 | 
					                <template #default>
 | 
				
			||||||
 | 
					                  <HdmiVideoStreamView />
 | 
				
			||||||
 | 
					                </template>
 | 
				
			||||||
 | 
					                <template #fallback>
 | 
				
			||||||
 | 
					                  <div class="loading-fallback">
 | 
				
			||||||
 | 
					                    <span class="loading loading-spinner loading-xl"></span>
 | 
				
			||||||
 | 
					                    <p class="loading-text">正在加载HDMI视频流组件...</p>
 | 
				
			||||||
 | 
					                  </div>
 | 
				
			||||||
 | 
					                </template>
 | 
				
			||||||
 | 
					              </Suspense>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					              <!-- 示波器 -->
 | 
				
			||||||
 | 
					              <Suspense v-else-if="checkID === 4">
 | 
				
			||||||
 | 
					                <template #default>
 | 
				
			||||||
 | 
					                  <OscilloscopeView />
 | 
				
			||||||
 | 
					                </template>
 | 
				
			||||||
 | 
					                <template #fallback>
 | 
				
			||||||
 | 
					                  <div class="loading-fallback">
 | 
				
			||||||
 | 
					                    <span class="loading loading-spinner loading-xl"></span>
 | 
				
			||||||
 | 
					                    <p class="loading-text">正在加载示波器组件...</p>
 | 
				
			||||||
 | 
					                  </div>
 | 
				
			||||||
 | 
					                </template>
 | 
				
			||||||
 | 
					              </Suspense>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					              <!-- 逻辑分析仪 -->
 | 
				
			||||||
 | 
					              <Suspense v-else-if="checkID === 5">
 | 
				
			||||||
 | 
					                <template #default>
 | 
				
			||||||
 | 
					                  <LogicAnalyzerView />
 | 
				
			||||||
 | 
					                </template>
 | 
				
			||||||
 | 
					                <template #fallback>
 | 
				
			||||||
 | 
					                  <div class="loading-fallback">
 | 
				
			||||||
 | 
					                    <span class="loading loading-spinner loading-xl"></span>
 | 
				
			||||||
 | 
					                    <p class="loading-text">正在加载逻辑分析仪组件...</p>
 | 
				
			||||||
 | 
					                  </div>
 | 
				
			||||||
 | 
					                </template>
 | 
				
			||||||
 | 
					              </Suspense>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					              <!-- 嵌入式逻辑分析仪 -->
 | 
				
			||||||
 | 
					              <Suspense v-else-if="checkID === 6">
 | 
				
			||||||
 | 
					                <template #default>
 | 
				
			||||||
 | 
					                  <DebuggerView />
 | 
				
			||||||
 | 
					                </template>
 | 
				
			||||||
 | 
					                <template #fallback>
 | 
				
			||||||
 | 
					                  <div class="loading-fallback">
 | 
				
			||||||
 | 
					                    <span class="loading loading-spinner loading-xl"></span>
 | 
				
			||||||
 | 
					                    <p class="loading-text">正在加载嵌入式逻辑分析仪组件...</p>
 | 
				
			||||||
 | 
					                  </div>
 | 
				
			||||||
 | 
					                </template>
 | 
				
			||||||
 | 
					              </Suspense>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					              <!-- 信号发生器 -->
 | 
				
			||||||
 | 
					              <Suspense v-else-if="checkID === 7">
 | 
				
			||||||
 | 
					                <template #default>
 | 
				
			||||||
 | 
					                  <DDSCtrlView />
 | 
				
			||||||
 | 
					                </template>
 | 
				
			||||||
 | 
					                <template #fallback>
 | 
				
			||||||
 | 
					                  <div class="loading-fallback">
 | 
				
			||||||
 | 
					                    <span class="loading loading-spinner loading-xl"></span>
 | 
				
			||||||
 | 
					                    <p class="loading-text">正在加载信号发生器组件...</p>
 | 
				
			||||||
 | 
					                  </div>
 | 
				
			||||||
 | 
					                </template>
 | 
				
			||||||
 | 
					              </Suspense>
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					          </Transition>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
      </div>
 | 
					      </div>
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
  </div>
 | 
					  </div>
 | 
				
			||||||
@@ -126,21 +166,43 @@ import {
 | 
				
			|||||||
  Signature,
 | 
					  Signature,
 | 
				
			||||||
} from "lucide-vue-next";
 | 
					} from "lucide-vue-next";
 | 
				
			||||||
import { useLocalStorage } from "@vueuse/core";
 | 
					import { useLocalStorage } from "@vueuse/core";
 | 
				
			||||||
import VideoStreamView from "@/views/Project/VideoStream.vue";
 | 
					 | 
				
			||||||
import HdmiVideoStreamView from "@/views/Project/HdmiVideoStream.vue";
 | 
					 | 
				
			||||||
import OscilloscopeView from "@/views/Project/Oscilloscope.vue";
 | 
					 | 
				
			||||||
import LogicAnalyzerView from "@/views/Project/LogicAnalyzer.vue";
 | 
					 | 
				
			||||||
import DebuggerView from "./Debugger.vue";
 | 
					 | 
				
			||||||
import DDSCtrlView from "./DDSCtrl.vue";
 | 
					 | 
				
			||||||
import { isNull, toNumber } from "lodash";
 | 
					import { isNull, toNumber } from "lodash";
 | 
				
			||||||
import { onMounted, ref, watch } from "vue";
 | 
					import { onMounted, ref, watch, defineAsyncComponent, computed } from "vue";
 | 
				
			||||||
import { useProvideLogicAnalyzer } from "@/components/LogicAnalyzer";
 | 
					import { useProvideLogicAnalyzer } from "@/components/LogicAnalyzer";
 | 
				
			||||||
import { useProvideOscilloscope } from "@/components/Oscilloscope/OscilloscopeManager";
 | 
					import { useProvideOscilloscope } from "@/components/Oscilloscope/OscilloscopeManager";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 懒加载组件
 | 
				
			||||||
 | 
					const VideoStreamView = defineAsyncComponent(
 | 
				
			||||||
 | 
					  () => import("@/views/Project/VideoStream.vue"),
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
					const HdmiVideoStreamView = defineAsyncComponent(
 | 
				
			||||||
 | 
					  () => import("@/views/Project/HdmiVideoStream.vue"),
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
					const OscilloscopeView = defineAsyncComponent(
 | 
				
			||||||
 | 
					  () => import("@/views/Project/Oscilloscope.vue"),
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
					const LogicAnalyzerView = defineAsyncComponent(
 | 
				
			||||||
 | 
					  () => import("@/views/Project/LogicAnalyzer.vue"),
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
					const DebuggerView = defineAsyncComponent(() => import("./Debugger.vue"));
 | 
				
			||||||
 | 
					const DDSCtrlView = defineAsyncComponent(() => import("./DDSCtrl.vue"));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const analyzer = useProvideLogicAnalyzer();
 | 
					const analyzer = useProvideLogicAnalyzer();
 | 
				
			||||||
const oscilloscopeManager = useProvideOscilloscope();
 | 
					const oscilloscopeManager = useProvideOscilloscope();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const checkID = useLocalStorage("checkID", 1);
 | 
					const checkID = useLocalStorage("checkID", 1);
 | 
				
			||||||
 | 
					const isLoading = ref(false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 标签页配置
 | 
				
			||||||
 | 
					const tabs = [
 | 
				
			||||||
 | 
					  { id: 1, label: "日志终端", icon: TerminalIcon },
 | 
				
			||||||
 | 
					  { id: 2, label: "HTTP视频流", icon: VideoIcon },
 | 
				
			||||||
 | 
					  { id: 3, label: "HDMI视频流", icon: Monitor },
 | 
				
			||||||
 | 
					  { id: 4, label: "示波器", icon: SquareActivityIcon },
 | 
				
			||||||
 | 
					  { id: 5, label: "逻辑分析仪", icon: Binary },
 | 
				
			||||||
 | 
					  { id: 6, label: "嵌入式逻辑分析仪", icon: Hand },
 | 
				
			||||||
 | 
					  { id: 7, label: "信号发生器", icon: Signature },
 | 
				
			||||||
 | 
					];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 定义事件
 | 
					// 定义事件
 | 
				
			||||||
const emit = defineEmits<{
 | 
					const emit = defineEmits<{
 | 
				
			||||||
@@ -162,11 +224,30 @@ watch(
 | 
				
			|||||||
  },
 | 
					  },
 | 
				
			||||||
);
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 获取当前标签页标签
 | 
				
			||||||
 | 
					const getCurrentTabLabel = computed(() => {
 | 
				
			||||||
 | 
					  const currentTab = tabs.find((tab) => tab.id === checkID.value);
 | 
				
			||||||
 | 
					  return currentTab?.label || "";
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function handleTabChange(event: Event) {
 | 
					function handleTabChange(event: Event) {
 | 
				
			||||||
  const target = event.currentTarget as HTMLInputElement;
 | 
					  const target = event.currentTarget as HTMLInputElement;
 | 
				
			||||||
  if (isNull(target)) return;
 | 
					  if (isNull(target)) return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  checkID.value = toNumber(target.id);
 | 
					  const newTabId = toNumber(target.id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // 如果不是日志终端(需要懒加载的组件),显示加载状态
 | 
				
			||||||
 | 
					  if (newTabId !== 1 && newTabId !== checkID.value) {
 | 
				
			||||||
 | 
					    isLoading.value = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // 模拟加载延迟,让用户看到加载状态
 | 
				
			||||||
 | 
					    setTimeout(() => {
 | 
				
			||||||
 | 
					      checkID.value = newTabId;
 | 
				
			||||||
 | 
					      isLoading.value = false;
 | 
				
			||||||
 | 
					    }, 300);
 | 
				
			||||||
 | 
					  } else {
 | 
				
			||||||
 | 
					    checkID.value = newTabId;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function toggleFullscreen() {
 | 
					function toggleFullscreen() {
 | 
				
			||||||
@@ -177,19 +258,286 @@ function toggleFullscreen() {
 | 
				
			|||||||
<style scoped lang="postcss">
 | 
					<style scoped lang="postcss">
 | 
				
			||||||
@import "@/assets/main.css";
 | 
					@import "@/assets/main.css";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.icon {
 | 
					/* 标签栏容器 */
 | 
				
			||||||
  @apply h-4 w-4 opacity-70 mr-1.5;
 | 
					.tabs-container {
 | 
				
			||||||
 | 
					  transition: all 0.3s ease;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.tabs {
 | 
					.tabs {
 | 
				
			||||||
  @apply relative flex items-center;
 | 
					  @apply relative flex items-center p-1 gap-1;
 | 
				
			||||||
 | 
					  background: linear-gradient(135deg, hsl(var(--b1)) 0%, hsl(var(--b2)) 100%);
 | 
				
			||||||
 | 
					  backdrop-filter: blur(10px);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* 标签项样式 */
 | 
				
			||||||
 | 
					.tab-item {
 | 
				
			||||||
 | 
					  @apply relative flex items-center px-4 py-3 cursor-pointer rounded-lg transition-all duration-300;
 | 
				
			||||||
 | 
					  @apply hover:bg-base-200;
 | 
				
			||||||
 | 
					  position: relative;
 | 
				
			||||||
 | 
					  min-width: 120px;
 | 
				
			||||||
 | 
					  justify-content: center;
 | 
				
			||||||
 | 
					  background: transparent;
 | 
				
			||||||
 | 
					  border: 1px solid transparent;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.tab-item:hover {
 | 
				
			||||||
 | 
					  background: linear-gradient(
 | 
				
			||||||
 | 
					    135deg,
 | 
				
			||||||
 | 
					    hsl(var(--primary) / 0.1) 0%,
 | 
				
			||||||
 | 
					    hsl(var(--secondary) / 0.1) 100%
 | 
				
			||||||
 | 
					  );
 | 
				
			||||||
 | 
					  border-color: hsl(var(--primary) / 0.2);
 | 
				
			||||||
 | 
					  transform: translateY(-1px);
 | 
				
			||||||
 | 
					  box-shadow: 0 4px 12px hsl(var(--primary) / 0.15);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.tab-item.tab-active {
 | 
				
			||||||
 | 
					  background: linear-gradient(
 | 
				
			||||||
 | 
					    135deg,
 | 
				
			||||||
 | 
					    hsl(var(--primary)) 0%,
 | 
				
			||||||
 | 
					    hsl(var(--secondary)) 100%
 | 
				
			||||||
 | 
					  );
 | 
				
			||||||
 | 
					  color: hsl(var(--primary-content));
 | 
				
			||||||
 | 
					  border-color: hsl(var(--primary));
 | 
				
			||||||
 | 
					  transform: translateY(-2px);
 | 
				
			||||||
 | 
					  box-shadow: 0 6px 20px hsl(var(--primary) / 0.3);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.tab-item.tab-active .icon {
 | 
				
			||||||
 | 
					  @apply opacity-100;
 | 
				
			||||||
 | 
					  filter: drop-shadow(0 0 4px rgba(255, 255, 255, 0.3));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* 图标样式 */
 | 
				
			||||||
 | 
					.icon {
 | 
				
			||||||
 | 
					  @apply h-4 w-4 opacity-70 mr-2 transition-all duration-300;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.tab-item:hover .icon {
 | 
				
			||||||
 | 
					  @apply opacity-100;
 | 
				
			||||||
 | 
					  transform: scale(1.1);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* 标签文字 */
 | 
				
			||||||
 | 
					.tab-label {
 | 
				
			||||||
 | 
					  @apply text-sm font-medium transition-all duration-300;
 | 
				
			||||||
 | 
					  white-space: nowrap;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.tab-item:hover .tab-label {
 | 
				
			||||||
 | 
					  font-weight: 600;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* 活跃指示器 */
 | 
				
			||||||
 | 
					.active-indicator {
 | 
				
			||||||
 | 
					  @apply absolute -bottom-1 left-1/2 transform -translate-x-1/2;
 | 
				
			||||||
 | 
					  width: 6px;
 | 
				
			||||||
 | 
					  height: 6px;
 | 
				
			||||||
 | 
					  background: hsl(var(--primary-content));
 | 
				
			||||||
 | 
					  border-radius: 50%;
 | 
				
			||||||
 | 
					  box-shadow: 0 0 8px hsl(var(--primary-content) / 0.8);
 | 
				
			||||||
 | 
					  animation: pulse 2s infinite;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@keyframes pulse {
 | 
				
			||||||
 | 
					  0%,
 | 
				
			||||||
 | 
					  100% {
 | 
				
			||||||
 | 
					    opacity: 1;
 | 
				
			||||||
 | 
					    transform: translate(-50%, 0) scale(1);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  50% {
 | 
				
			||||||
 | 
					    opacity: 0.7;
 | 
				
			||||||
 | 
					    transform: translate(-50%, 0) scale(1.2);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* 全屏按钮容器 */
 | 
				
			||||||
 | 
					.fullscreen-container {
 | 
				
			||||||
 | 
					  @apply flex items-center justify-center p-1;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.fullscreen-btn {
 | 
					.fullscreen-btn {
 | 
				
			||||||
  @apply flex items-center justify-center p-2 rounded-lg transition-colors;
 | 
					  @apply relative flex items-center justify-center p-3 rounded-lg transition-all duration-300;
 | 
				
			||||||
 | 
					  @apply bg-base-200 hover:bg-primary hover:text-primary-content;
 | 
				
			||||||
 | 
					  @apply border border-base-300 hover:border-primary;
 | 
				
			||||||
 | 
					  @apply shadow-md hover:shadow-lg;
 | 
				
			||||||
 | 
					  position: relative;
 | 
				
			||||||
 | 
					  overflow: hidden;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.fullscreen-btn:hover {
 | 
				
			||||||
 | 
					  transform: translateY(-1px) scale(1.05);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.fullscreen-btn .icon {
 | 
					.fullscreen-btn .icon {
 | 
				
			||||||
  @apply mr-0;
 | 
					  @apply mr-0 transition-transform duration-300;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.fullscreen-btn:hover .icon {
 | 
				
			||||||
 | 
					  transform: rotate(180deg);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* 工具提示 */
 | 
				
			||||||
 | 
					.btn-tooltip {
 | 
				
			||||||
 | 
					  @apply absolute -top-10 left-1/2 transform -translate-x-1/2;
 | 
				
			||||||
 | 
					  @apply bg-base-content text-base-100 text-xs px-2 py-1 rounded;
 | 
				
			||||||
 | 
					  @apply opacity-0 pointer-events-none transition-opacity duration-200;
 | 
				
			||||||
 | 
					  white-space: nowrap;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.fullscreen-btn:hover .btn-tooltip {
 | 
				
			||||||
 | 
					  @apply opacity-100;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* 内容区域 */
 | 
				
			||||||
 | 
					.content-area {
 | 
				
			||||||
 | 
					  transition: all 0.3s ease;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.content-wrapper {
 | 
				
			||||||
 | 
					  background: linear-gradient(135deg, hsl(var(--b1)) 0%, hsl(var(--b2)) 100%);
 | 
				
			||||||
 | 
					  backdrop-filter: blur(10px);
 | 
				
			||||||
 | 
					  border: 1px solid hsl(var(--border) / 0.2);
 | 
				
			||||||
 | 
					  position: relative;
 | 
				
			||||||
 | 
					  overflow: hidden;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.content-wrapper::before {
 | 
				
			||||||
 | 
					  content: "";
 | 
				
			||||||
 | 
					  position: absolute;
 | 
				
			||||||
 | 
					  top: 0;
 | 
				
			||||||
 | 
					  left: 0;
 | 
				
			||||||
 | 
					  right: 0;
 | 
				
			||||||
 | 
					  height: 1px;
 | 
				
			||||||
 | 
					  background: linear-gradient(
 | 
				
			||||||
 | 
					    90deg,
 | 
				
			||||||
 | 
					    transparent,
 | 
				
			||||||
 | 
					    hsl(var(--primary) / 0.3),
 | 
				
			||||||
 | 
					    transparent
 | 
				
			||||||
 | 
					  );
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* 面板内容 */
 | 
				
			||||||
 | 
					.content-panel {
 | 
				
			||||||
 | 
					  @apply h-full;
 | 
				
			||||||
 | 
					  animation: slideIn 0.3s ease-out;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@keyframes slideIn {
 | 
				
			||||||
 | 
					  from {
 | 
				
			||||||
 | 
					    opacity: 0;
 | 
				
			||||||
 | 
					    transform: translateY(10px);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  to {
 | 
				
			||||||
 | 
					    opacity: 1;
 | 
				
			||||||
 | 
					    transform: translateY(0);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* 面板头部 */
 | 
				
			||||||
 | 
					.panel-content {
 | 
				
			||||||
 | 
					  @apply h-full flex flex-col;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.panel-header {
 | 
				
			||||||
 | 
					  @apply flex items-center p-4 border-b border-base-300 bg-base-100;
 | 
				
			||||||
 | 
					  background: linear-gradient(135deg, hsl(var(--b1)) 0%, hsl(var(--b2)) 100%);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.panel-icon {
 | 
				
			||||||
 | 
					  @apply h-5 w-5 mr-3 text-primary;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.panel-title {
 | 
				
			||||||
 | 
					  @apply text-lg font-semibold text-base-content;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* 终端占位符 */
 | 
				
			||||||
 | 
					.terminal-placeholder {
 | 
				
			||||||
 | 
					  @apply flex-1 flex items-center justify-center;
 | 
				
			||||||
 | 
					  background: linear-gradient(135deg, hsl(var(--b1)) 0%, hsl(var(--b3)) 100%);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.placeholder-text {
 | 
				
			||||||
 | 
					  @apply text-base-content opacity-60 text-center;
 | 
				
			||||||
 | 
					  font-size: 1.1rem;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* 加载状态 */
 | 
				
			||||||
 | 
					.loading-container,
 | 
				
			||||||
 | 
					.loading-fallback {
 | 
				
			||||||
 | 
					  @apply h-full flex items-center justify-center gap-5;
 | 
				
			||||||
 | 
					  background: linear-gradient(135deg, hsl(var(--b1)) 0%, hsl(var(--b2)) 100%);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.loading-text {
 | 
				
			||||||
 | 
					  @apply text-base-content opacity-70 text-sm;
 | 
				
			||||||
 | 
					  animation: pulse 1.5s ease-in-out infinite;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* 过渡动画 */
 | 
				
			||||||
 | 
					.fade-enter-active,
 | 
				
			||||||
 | 
					.fade-leave-active {
 | 
				
			||||||
 | 
					  transition: all 0.3s ease;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.fade-enter-from {
 | 
				
			||||||
 | 
					  opacity: 0;
 | 
				
			||||||
 | 
					  transform: translateY(10px);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.fade-leave-to {
 | 
				
			||||||
 | 
					  opacity: 0;
 | 
				
			||||||
 | 
					  transform: translateY(-10px);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* 响应式设计 */
 | 
				
			||||||
 | 
					@media (max-width: 768px) {
 | 
				
			||||||
 | 
					  .tab-item {
 | 
				
			||||||
 | 
					    @apply px-2 py-2;
 | 
				
			||||||
 | 
					    min-width: 80px;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  .tab-label {
 | 
				
			||||||
 | 
					    @apply text-xs;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  .icon {
 | 
				
			||||||
 | 
					    @apply h-3 w-3 mr-1;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* 深色模式适配 */
 | 
				
			||||||
 | 
					@media (prefers-color-scheme: dark) {
 | 
				
			||||||
 | 
					  .content-wrapper::before {
 | 
				
			||||||
 | 
					    background: linear-gradient(
 | 
				
			||||||
 | 
					      90deg,
 | 
				
			||||||
 | 
					      transparent,
 | 
				
			||||||
 | 
					      hsl(var(--primary) / 0.5),
 | 
				
			||||||
 | 
					      transparent
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* 辅助功能 */
 | 
				
			||||||
 | 
					.tab-item:focus-visible {
 | 
				
			||||||
 | 
					  outline: 2px solid hsl(var(--primary));
 | 
				
			||||||
 | 
					  outline-offset: 2px;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.fullscreen-btn:focus-visible {
 | 
				
			||||||
 | 
					  outline: 2px solid hsl(var(--primary));
 | 
				
			||||||
 | 
					  outline-offset: 2px;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* 高对比度模式 */
 | 
				
			||||||
 | 
					@media (prefers-contrast: high) {
 | 
				
			||||||
 | 
					  .tab-item {
 | 
				
			||||||
 | 
					    border: 2px solid hsl(var(--base-content) / 0.2);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  .tab-item.tab-active {
 | 
				
			||||||
 | 
					    border: 2px solid hsl(var(--primary));
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
</style>
 | 
					</style>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,6 @@
 | 
				
			|||||||
<template>
 | 
					<template>
 | 
				
			||||||
  <div
 | 
					  <div
 | 
				
			||||||
    class="oscilloscope-container min-h-screen bg-gradient-to-br from-slate-50 to-blue-50 dark:from-slate-900 dark:to-slate-800 p-4"
 | 
					    class="min-h-screen bg-gradient-to-br from-slate-50 to-blue-50 dark:from-slate-900 dark:to-slate-800 p-4"
 | 
				
			||||||
  >
 | 
					  >
 | 
				
			||||||
    <!-- 顶部状态栏 -->
 | 
					    <!-- 顶部状态栏 -->
 | 
				
			||||||
    <div class="status-bar mb-6">
 | 
					    <div class="status-bar mb-6">
 | 
				
			||||||
@@ -80,13 +80,13 @@
 | 
				
			|||||||
                  <div
 | 
					                  <div
 | 
				
			||||||
                    class="w-2 h-2 bg-green-500 rounded-full animate-pulse"
 | 
					                    class="w-2 h-2 bg-green-500 rounded-full animate-pulse"
 | 
				
			||||||
                  ></div>
 | 
					                  ></div>
 | 
				
			||||||
                  {{ refreshCycle }}ms 刷新
 | 
					                  {{ osc.config.captureFrequency }}Hz 刷新频率
 | 
				
			||||||
                </div>
 | 
					                </div>
 | 
				
			||||||
              </div>
 | 
					              </div>
 | 
				
			||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            <div
 | 
					            <div
 | 
				
			||||||
              class="waveform-display h-96 lg:h-[500px] relative overflow-hidden rounded-lg border border-slate-200 dark:border-slate-700"
 | 
					              class="waveform-display h-full relative overflow-hidden rounded-lg border border-slate-200 dark:border-slate-700"
 | 
				
			||||||
            >
 | 
					            >
 | 
				
			||||||
              <OscilloscopeWaveformDisplay class="w-full h-full" />
 | 
					              <OscilloscopeWaveformDisplay class="w-full h-full" />
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -154,9 +154,9 @@
 | 
				
			|||||||
                    class="range range-primary [--range-bg:#2b7fff]"
 | 
					                    class="range range-primary [--range-bg:#2b7fff]"
 | 
				
			||||||
                  />
 | 
					                  />
 | 
				
			||||||
                  <div
 | 
					                  <div
 | 
				
			||||||
                    class="range-labels flex justify-between text-xs text-slate-500 mt-1"
 | 
					                    class="range-labels flex justify-between text-xs text-slate-500 mt-1 mx-2"
 | 
				
			||||||
                  >
 | 
					                  >
 | 
				
			||||||
                    <span>0</span>
 | 
					                    <span> 0 </span>
 | 
				
			||||||
                    <span>128</span>
 | 
					                    <span>128</span>
 | 
				
			||||||
                    <span>255</span>
 | 
					                    <span>255</span>
 | 
				
			||||||
                  </div>
 | 
					                  </div>
 | 
				
			||||||
@@ -214,15 +214,17 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
                <div class="form-control">
 | 
					                <div class="form-control">
 | 
				
			||||||
                  <label class="label">
 | 
					                  <label class="label">
 | 
				
			||||||
                    <span class="label-text font-medium">刷新间隔</span>
 | 
					                    <span class="label-text font-medium">刷新频率</span>
 | 
				
			||||||
                    <span class="label-text-alt">{{ refreshCycle }}ms</span>
 | 
					                    <span class="label-text-alt"
 | 
				
			||||||
 | 
					                      >{{ osc.config.captureFrequency }}Hz</span
 | 
				
			||||||
 | 
					                    >
 | 
				
			||||||
                  </label>
 | 
					                  </label>
 | 
				
			||||||
                  <input
 | 
					                  <input
 | 
				
			||||||
                    type="range"
 | 
					                    type="range"
 | 
				
			||||||
                    min="1"
 | 
					                    min="1"
 | 
				
			||||||
                    max="1000"
 | 
					                    max="1000"
 | 
				
			||||||
                    step="1"
 | 
					                    step="1"
 | 
				
			||||||
                    v-model="refreshCycle"
 | 
					                    v-model="osc.config.captureFrequency"
 | 
				
			||||||
                    class="range range-info [--range-bg:#51a2ff]"
 | 
					                    class="range range-info [--range-bg:#51a2ff]"
 | 
				
			||||||
                  />
 | 
					                  />
 | 
				
			||||||
                </div>
 | 
					                </div>
 | 
				
			||||||
@@ -331,6 +333,7 @@ import { useEquipments } from "@/stores/equipments";
 | 
				
			|||||||
import { useOscilloscopeState } from "@/components/Oscilloscope/OscilloscopeManager";
 | 
					import { useOscilloscopeState } from "@/components/Oscilloscope/OscilloscopeManager";
 | 
				
			||||||
import { useRequiredInjection } from "@/utils/Common";
 | 
					import { useRequiredInjection } from "@/utils/Common";
 | 
				
			||||||
import { ref, computed } from "vue";
 | 
					import { ref, computed } from "vue";
 | 
				
			||||||
 | 
					import { watchEffect } from "vue";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 使用全局设备配置
 | 
					// 使用全局设备配置
 | 
				
			||||||
const equipments = useEquipments();
 | 
					const equipments = useEquipments();
 | 
				
			||||||
@@ -338,8 +341,6 @@ const equipments = useEquipments();
 | 
				
			|||||||
// 获取示波器状态和操作
 | 
					// 获取示波器状态和操作
 | 
				
			||||||
const osc = useRequiredInjection(useOscilloscopeState);
 | 
					const osc = useRequiredInjection(useOscilloscopeState);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const refreshCycle = ref(10);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// 计算是否有波形数据
 | 
					// 计算是否有波形数据
 | 
				
			||||||
const hasWaveformData = computed(() => {
 | 
					const hasWaveformData = computed(() => {
 | 
				
			||||||
  const data = osc.oscData.value;
 | 
					  const data = osc.oscData.value;
 | 
				
			||||||
@@ -357,7 +358,6 @@ function toggleCapture() {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
function resetConfiguration() {
 | 
					function resetConfiguration() {
 | 
				
			||||||
  osc.resetConfiguration();
 | 
					  osc.resetConfiguration();
 | 
				
			||||||
  refreshCycle.value = 1000 / osc.config.captureFrequency;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
</script>
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -395,7 +395,7 @@ function resetConfiguration() {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
/* 滑块样式美化 */
 | 
					/* 滑块样式美化 */
 | 
				
			||||||
.range {
 | 
					.range {
 | 
				
			||||||
  @apply rounded-lg appearance-none cursor-pointer;
 | 
					  @apply rounded-lg appearance-none cursor-pointer w-full px-2;
 | 
				
			||||||
  --range-fill: 0;
 | 
					  --range-fill: 0;
 | 
				
			||||||
  --range-thumb: white;
 | 
					  --range-thumb: white;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user