feat: 添加嵌入式逻辑分析仪
This commit is contained in:
		@@ -111,7 +111,7 @@ const [useProvideLogicAnalyzer, useLogicAnalyzerState] = createInjectionState(
 | 
			
		||||
          new SignalTriggerConfig({
 | 
			
		||||
            signalIndex: index,
 | 
			
		||||
            operator: SignalOperator.Equal,
 | 
			
		||||
            value: SignalValue.Logic1,
 | 
			
		||||
            value: SignalValue.NotCare,
 | 
			
		||||
          }),
 | 
			
		||||
      ),
 | 
			
		||||
    );
 | 
			
		||||
@@ -229,7 +229,7 @@ const [useProvideLogicAnalyzer, useLogicAnalyzerState] = createInjectionState(
 | 
			
		||||
 | 
			
		||||
      signalConfigs.forEach((signal) => {
 | 
			
		||||
        signal.operator = SignalOperator.Equal;
 | 
			
		||||
        signal.value = SignalValue.Logic1;
 | 
			
		||||
        signal.value = SignalValue.NotCare;
 | 
			
		||||
      });
 | 
			
		||||
 | 
			
		||||
      alert?.info("配置已重置", 2000);
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										238
									
								
								src/components/WaveformDisplay/WaveformDisplay.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										238
									
								
								src/components/WaveformDisplay/WaveformDisplay.vue
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,238 @@
 | 
			
		||||
<template>
 | 
			
		||||
  <div
 | 
			
		||||
    class="w-full"
 | 
			
		||||
    :class="{
 | 
			
		||||
      'h-48': !analyzer.logicData.value,
 | 
			
		||||
      'h-150': analyzer.logicData.value,
 | 
			
		||||
    }"
 | 
			
		||||
  >
 | 
			
		||||
    <v-chart
 | 
			
		||||
      v-if="analyzer.logicData.value"
 | 
			
		||||
      class="w-full h-full"
 | 
			
		||||
      :option="option"
 | 
			
		||||
      autoresize
 | 
			
		||||
      :update-options="updateOptions"
 | 
			
		||||
    />
 | 
			
		||||
    <div
 | 
			
		||||
      v-else
 | 
			
		||||
      class="w-full h-full flex flex-col gap-6 items-center justify-center"
 | 
			
		||||
    >
 | 
			
		||||
      <div class="text-center">
 | 
			
		||||
        <h3 class="text-xl font-semibold text-slate-600 mb-2">
 | 
			
		||||
          暂无逻辑分析数据
 | 
			
		||||
        </h3>
 | 
			
		||||
      </div>
 | 
			
		||||
    </div>
 | 
			
		||||
  </div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script setup lang="ts">
 | 
			
		||||
import { computed, shallowRef } from "vue";
 | 
			
		||||
import VChart from "vue-echarts";
 | 
			
		||||
 | 
			
		||||
// Echarts
 | 
			
		||||
import { use } from "echarts/core";
 | 
			
		||||
import { LineChart } from "echarts/charts";
 | 
			
		||||
import {
 | 
			
		||||
  TooltipComponent,
 | 
			
		||||
  GridComponent,
 | 
			
		||||
  DataZoomComponent,
 | 
			
		||||
  AxisPointerComponent,
 | 
			
		||||
  ToolboxComponent,
 | 
			
		||||
} from "echarts/components";
 | 
			
		||||
import { CanvasRenderer } from "echarts/renderers";
 | 
			
		||||
import type { ComposeOption } from "echarts/core";
 | 
			
		||||
import type { LineSeriesOption } from "echarts/charts";
 | 
			
		||||
import type {
 | 
			
		||||
  AxisPointerComponentOption,
 | 
			
		||||
  TooltipComponentOption,
 | 
			
		||||
  GridComponentOption,
 | 
			
		||||
  DataZoomComponentOption,
 | 
			
		||||
} from "echarts/components";
 | 
			
		||||
import type {
 | 
			
		||||
  ToolboxComponentOption,
 | 
			
		||||
  XAXisOption,
 | 
			
		||||
  YAXisOption,
 | 
			
		||||
} from "echarts/types/dist/shared";
 | 
			
		||||
import { useRequiredInjection } from "@/utils/Common";
 | 
			
		||||
import { isUndefined } from "lodash";
 | 
			
		||||
import { useWaveformManager } from "./WaveformManager";
 | 
			
		||||
 | 
			
		||||
use([
 | 
			
		||||
  TooltipComponent,
 | 
			
		||||
  ToolboxComponent,
 | 
			
		||||
  GridComponent,
 | 
			
		||||
  AxisPointerComponent,
 | 
			
		||||
  DataZoomComponent,
 | 
			
		||||
  LineChart,
 | 
			
		||||
  CanvasRenderer,
 | 
			
		||||
]);
 | 
			
		||||
 | 
			
		||||
type EChartsOption = ComposeOption<
 | 
			
		||||
  | AxisPointerComponentOption
 | 
			
		||||
  | TooltipComponentOption
 | 
			
		||||
  | ToolboxComponentOption
 | 
			
		||||
  | GridComponentOption
 | 
			
		||||
  | DataZoomComponentOption
 | 
			
		||||
  | LineSeriesOption
 | 
			
		||||
>;
 | 
			
		||||
 | 
			
		||||
const analyzer = useRequiredInjection(useWaveformManager);
 | 
			
		||||
 | 
			
		||||
// 添加更新选项来减少重绘
 | 
			
		||||
const updateOptions = shallowRef({
 | 
			
		||||
  notMerge: false,
 | 
			
		||||
  lazyUpdate: true,
 | 
			
		||||
  silent: false,
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
const option = computed((): EChartsOption => {
 | 
			
		||||
  if (isUndefined(analyzer.logicData.value)) return {};
 | 
			
		||||
 | 
			
		||||
  // 只获取启用的通道,使用y数据结构
 | 
			
		||||
  const enabledChannels = analyzer.logicData.value.y.filter(channel => channel.enabled);
 | 
			
		||||
  const enabledChannelIndices = analyzer.logicData.value.y
 | 
			
		||||
    .map((channel, index) => (channel.enabled ? index : -1))
 | 
			
		||||
    .filter((index) => index !== -1);
 | 
			
		||||
 | 
			
		||||
  const channelCount = enabledChannels.length;
 | 
			
		||||
  const channelSpacing = 2; // 每个通道之间的间距
 | 
			
		||||
 | 
			
		||||
  // 如果没有启用的通道,返回空配置
 | 
			
		||||
  if (channelCount === 0) {
 | 
			
		||||
    return {};
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // 使用单个网格
 | 
			
		||||
  const grids: GridComponentOption[] = [
 | 
			
		||||
    {
 | 
			
		||||
      left: "5%",
 | 
			
		||||
      right: "5%",
 | 
			
		||||
      top: "5%",
 | 
			
		||||
      bottom: "15%",
 | 
			
		||||
    },
 | 
			
		||||
  ];
 | 
			
		||||
 | 
			
		||||
  // 单个X轴
 | 
			
		||||
  const xAxis: XAXisOption[] = [
 | 
			
		||||
    {
 | 
			
		||||
      type: "category",
 | 
			
		||||
      boundaryGap: false,
 | 
			
		||||
      data: analyzer.logicData.value.x.map((x) => x.toFixed(3)),
 | 
			
		||||
      axisLabel: {
 | 
			
		||||
        formatter: (value: string) =>
 | 
			
		||||
          analyzer.logicData.value
 | 
			
		||||
            ? `${value}${analyzer.logicData.value.xUnit}`
 | 
			
		||||
            : `${value}`,
 | 
			
		||||
      },
 | 
			
		||||
    },
 | 
			
		||||
  ];
 | 
			
		||||
 | 
			
		||||
  // 单个Y轴,范围根据启用通道数量调整
 | 
			
		||||
  const yAxis: YAXisOption[] = [
 | 
			
		||||
    {
 | 
			
		||||
      type: "value",
 | 
			
		||||
      min: -0.5,
 | 
			
		||||
      max: channelCount * channelSpacing - 0.5,
 | 
			
		||||
      interval: channelSpacing,
 | 
			
		||||
      axisLabel: {
 | 
			
		||||
        formatter: (value: number) => {
 | 
			
		||||
          const channelIndex = Math.round(value / channelSpacing);
 | 
			
		||||
          return channelIndex < channelCount
 | 
			
		||||
            ? enabledChannels[channelIndex].name
 | 
			
		||||
            : "";
 | 
			
		||||
        },
 | 
			
		||||
      },
 | 
			
		||||
      splitLine: { show: false },
 | 
			
		||||
    },
 | 
			
		||||
  ];
 | 
			
		||||
 | 
			
		||||
  // 创建系列数据,只包含启用的通道
 | 
			
		||||
  const series: LineSeriesOption[] = enabledChannelIndices.map(
 | 
			
		||||
    (originalIndex: number, displayIndex: number) => ({
 | 
			
		||||
      name: enabledChannels[displayIndex].name,
 | 
			
		||||
      type: "line",
 | 
			
		||||
      data: analyzer.logicData.value!.y[originalIndex].value.map(
 | 
			
		||||
        (value: number) => value + displayIndex * channelSpacing + 0.2,
 | 
			
		||||
      ),
 | 
			
		||||
      step: "end",
 | 
			
		||||
      lineStyle: {
 | 
			
		||||
        width: 2,
 | 
			
		||||
        color: enabledChannels[displayIndex].color,
 | 
			
		||||
      },
 | 
			
		||||
      areaStyle: {
 | 
			
		||||
        opacity: 0.3,
 | 
			
		||||
        origin: displayIndex * channelSpacing,
 | 
			
		||||
        color: enabledChannels[displayIndex].color,
 | 
			
		||||
      },
 | 
			
		||||
      symbol: "none",
 | 
			
		||||
      // 优化性能配置
 | 
			
		||||
      sampling: "lttb",
 | 
			
		||||
      // 减少动画以避免闪烁
 | 
			
		||||
      animation: false,
 | 
			
		||||
    }),
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
  return {
 | 
			
		||||
    // 全局动画配置
 | 
			
		||||
    animation: false,
 | 
			
		||||
    tooltip: {
 | 
			
		||||
      trigger: "axis",
 | 
			
		||||
      axisPointer: {
 | 
			
		||||
        type: "line",
 | 
			
		||||
        label: {
 | 
			
		||||
          backgroundColor: "#6a7985",
 | 
			
		||||
        },
 | 
			
		||||
        // 减少axisPointer的动画
 | 
			
		||||
        animation: false,
 | 
			
		||||
      },
 | 
			
		||||
      formatter: (params: any) => {
 | 
			
		||||
        if (Array.isArray(params) && params.length > 0) {
 | 
			
		||||
          const timeValue = analyzer.logicData.value!.x[params[0].dataIndex];
 | 
			
		||||
          const dataIndex = params[0].dataIndex;
 | 
			
		||||
 | 
			
		||||
          let tooltip = `Time: ${timeValue.toFixed(3)}${analyzer.logicData.value!.xUnit}<br/>`;
 | 
			
		||||
 | 
			
		||||
          // 只显示启用通道在当前时间点的原始数值(0或1)
 | 
			
		||||
          enabledChannelIndices.forEach(
 | 
			
		||||
            (originalIndex: number, displayIndex: number) => {
 | 
			
		||||
              const channelName = enabledChannels[displayIndex].name;
 | 
			
		||||
              const originalValue =
 | 
			
		||||
                analyzer.logicData.value!.y[originalIndex].value[dataIndex];
 | 
			
		||||
              tooltip += `${channelName}: ${originalValue}<br/>`;
 | 
			
		||||
            },
 | 
			
		||||
          );
 | 
			
		||||
 | 
			
		||||
          return tooltip;
 | 
			
		||||
        }
 | 
			
		||||
        return "";
 | 
			
		||||
      },
 | 
			
		||||
      // 优化tooltip性能
 | 
			
		||||
      hideDelay: 100,
 | 
			
		||||
    },
 | 
			
		||||
    toolbox: {
 | 
			
		||||
      feature: {
 | 
			
		||||
        restore: {},
 | 
			
		||||
      },
 | 
			
		||||
    },
 | 
			
		||||
    grid: grids,
 | 
			
		||||
    xAxis: xAxis,
 | 
			
		||||
    yAxis: yAxis,
 | 
			
		||||
    dataZoom: [
 | 
			
		||||
      {
 | 
			
		||||
        show: true,
 | 
			
		||||
        realtime: true,
 | 
			
		||||
        start: 0,
 | 
			
		||||
        end: 100,
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        type: "inside",
 | 
			
		||||
        realtime: true,
 | 
			
		||||
        start: 0,
 | 
			
		||||
        end: 100,
 | 
			
		||||
      },
 | 
			
		||||
    ],
 | 
			
		||||
    series: series,
 | 
			
		||||
  };
 | 
			
		||||
});
 | 
			
		||||
</script>
 | 
			
		||||
							
								
								
									
										73
									
								
								src/components/WaveformDisplay/WaveformManager.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										73
									
								
								src/components/WaveformDisplay/WaveformManager.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,73 @@
 | 
			
		||||
import { createInjectionState } from "@vueuse/core";
 | 
			
		||||
import { shallowRef } from "vue";
 | 
			
		||||
 | 
			
		||||
export type LogicDataType = {
 | 
			
		||||
  x: number[];
 | 
			
		||||
  y: {
 | 
			
		||||
    enabled: boolean;
 | 
			
		||||
    type: "logic" | "number";
 | 
			
		||||
    name: string;
 | 
			
		||||
    color: string;
 | 
			
		||||
    value: number[];
 | 
			
		||||
    base: "bin" | "dec" | "hex";
 | 
			
		||||
  }[];
 | 
			
		||||
  xUnit: "s" | "ms" | "us" | "ns";
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// 生成4路测试数据的函数
 | 
			
		||||
export function generateTestData(): LogicDataType {
 | 
			
		||||
  // 生成时间轴数据 (0-100ns,每1ns一个采样点)
 | 
			
		||||
  const timePoints = Array.from({ length: 101 }, (_, i) => i);
 | 
			
		||||
 | 
			
		||||
  return {
 | 
			
		||||
    x: timePoints,
 | 
			
		||||
    y: [
 | 
			
		||||
      {
 | 
			
		||||
        enabled: true,
 | 
			
		||||
        type: "logic",
 | 
			
		||||
        name: "CLK",
 | 
			
		||||
        color: "#ff0000",
 | 
			
		||||
        value: timePoints.map((t) => t % 2), // 时钟信号,每1ns翻转
 | 
			
		||||
        base: "bin",
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        enabled: true,
 | 
			
		||||
        type: "logic",
 | 
			
		||||
        name: "RESET",
 | 
			
		||||
        color: "#00ff00",
 | 
			
		||||
        value: timePoints.map((t) => (t < 10 ? 1 : 0)), // 复位信号,前10ns为高电平
 | 
			
		||||
        base: "bin",
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        enabled: true,
 | 
			
		||||
        type: "number",
 | 
			
		||||
        name: "DATA",
 | 
			
		||||
        color: "#0000ff",
 | 
			
		||||
        value: timePoints.map((t) => Math.floor(t / 4) % 16), // 计数器,每4ns递增
 | 
			
		||||
        base: "hex",
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        enabled: true,
 | 
			
		||||
        type: "logic",
 | 
			
		||||
        name: "ENABLE",
 | 
			
		||||
        color: "#ff8800",
 | 
			
		||||
        value: timePoints.map((t) => (t >= 20 && t < 80 ? 1 : 0)), // 使能信号,20-80ns为高电平
 | 
			
		||||
        base: "bin",
 | 
			
		||||
      },
 | 
			
		||||
    ],
 | 
			
		||||
    xUnit: "ns",
 | 
			
		||||
  };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const [useProvideWaveformManager, useWaveformManager] = createInjectionState(
 | 
			
		||||
  () => {
 | 
			
		||||
    const logicData = shallowRef<LogicDataType>();
 | 
			
		||||
 | 
			
		||||
    return {
 | 
			
		||||
      logicData,
 | 
			
		||||
      generateTestData,
 | 
			
		||||
    };
 | 
			
		||||
  },
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
export { useProvideWaveformManager, useWaveformManager };
 | 
			
		||||
							
								
								
									
										5
									
								
								src/components/WaveformDisplay/index.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								src/components/WaveformDisplay/index.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,5 @@
 | 
			
		||||
import WaveformDisplay from "./WaveformDisplay.vue";
 | 
			
		||||
 | 
			
		||||
export {
 | 
			
		||||
  WaveformDisplay
 | 
			
		||||
};
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
<template>
 | 
			
		||||
  <div class="h-full flex flex-col gap-7">
 | 
			
		||||
    <div class="tabs tabs-box flex-shrink-0 shadow-xl">
 | 
			
		||||
    <div class="tabs tabs-box flex-shrink-0 shadow-xl mx-5">
 | 
			
		||||
      <label class="tab">
 | 
			
		||||
        <input
 | 
			
		||||
          type="radio"
 | 
			
		||||
@@ -42,9 +42,20 @@
 | 
			
		||||
          :checked="checkID === 4"
 | 
			
		||||
          @change="handleTabChange"
 | 
			
		||||
        />
 | 
			
		||||
        <Zap class="icon" />
 | 
			
		||||
        <Binary class="icon" />
 | 
			
		||||
        逻辑分析仪
 | 
			
		||||
      </label>
 | 
			
		||||
      <label class="tab">
 | 
			
		||||
        <input
 | 
			
		||||
          type="radio"
 | 
			
		||||
          name="function-bar"
 | 
			
		||||
          id="5"
 | 
			
		||||
          :checked="checkID === 5"
 | 
			
		||||
          @change="handleTabChange"
 | 
			
		||||
        />
 | 
			
		||||
        <Hand class="icon" />
 | 
			
		||||
        嵌入式逻辑分析仪
 | 
			
		||||
      </label>
 | 
			
		||||
      <!-- 全屏按钮 -->
 | 
			
		||||
      <button
 | 
			
		||||
        class="fullscreen-btn ml-auto btn btn-ghost btn-sm"
 | 
			
		||||
@@ -67,6 +78,9 @@
 | 
			
		||||
      <div v-else-if="checkID === 4" class="h-full overflow-y-auto">
 | 
			
		||||
        <LogicAnalyzerView />
 | 
			
		||||
      </div>
 | 
			
		||||
      <div v-else-if="checkID === 5" class="h-full overflow-y-auto">
 | 
			
		||||
        <Debugger />
 | 
			
		||||
      </div>
 | 
			
		||||
    </div>
 | 
			
		||||
  </div>
 | 
			
		||||
</template>
 | 
			
		||||
@@ -78,7 +92,8 @@ import {
 | 
			
		||||
  TerminalIcon,
 | 
			
		||||
  MaximizeIcon,
 | 
			
		||||
  MinimizeIcon,
 | 
			
		||||
  Zap,
 | 
			
		||||
  Binary,
 | 
			
		||||
  Hand,
 | 
			
		||||
} from "lucide-vue-next";
 | 
			
		||||
import { useLocalStorage } from "@vueuse/core";
 | 
			
		||||
import VideoStreamView from "@/views/Project/VideoStream.vue";
 | 
			
		||||
@@ -86,8 +101,13 @@ import OscilloscopeView from "@/views/Project/Oscilloscope.vue";
 | 
			
		||||
import LogicAnalyzerView from "@/views/Project/LogicAnalyzer.vue";
 | 
			
		||||
import { isNull, toNumber } from "lodash";
 | 
			
		||||
import { onMounted, ref, watch } from "vue";
 | 
			
		||||
import { im } from "mathjs";
 | 
			
		||||
import Debugger from "./Debugger.vue";
 | 
			
		||||
import { useProvideLogicAnalyzer } from "@/components/LogicAnalyzer";
 | 
			
		||||
import { useProvideWaveformManager } from "@/components/WaveformDisplay/WaveformManager";
 | 
			
		||||
 | 
			
		||||
const analyzer = useProvideLogicAnalyzer();
 | 
			
		||||
const waveformManager = useProvideWaveformManager();
 | 
			
		||||
waveformManager.logicData.value = waveformManager.generateTestData();
 | 
			
		||||
 | 
			
		||||
const checkID = useLocalStorage("checkID", 1);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										11
									
								
								src/views/Project/Debugger.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								src/views/Project/Debugger.vue
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,11 @@
 | 
			
		||||
<template>
 | 
			
		||||
  <div>
 | 
			
		||||
    <div class="card">
 | 
			
		||||
      <WaveformDisplay />
 | 
			
		||||
    </div>
 | 
			
		||||
  </div>
 | 
			
		||||
</template>
 | 
			
		||||
<script setup lang="ts">
 | 
			
		||||
import WaveformDisplay from '@/components/WaveformDisplay/WaveformDisplay.vue';
 | 
			
		||||
 | 
			
		||||
</script>
 | 
			
		||||
@@ -78,7 +78,7 @@
 | 
			
		||||
          id="splitter-group-v-panel-bar"
 | 
			
		||||
          :default-size="isBottomBarFullscreen ? 100 : (100 - verticalSplitterSize)"
 | 
			
		||||
          :min-size="isBottomBarFullscreen ? 100 : 15"
 | 
			
		||||
          class="w-full overflow-hidden px-5 pt-3"
 | 
			
		||||
          class="w-full overflow-hidden pt-3"
 | 
			
		||||
        >
 | 
			
		||||
          <BottomBar 
 | 
			
		||||
            :isFullscreen="isBottomBarFullscreen"
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,7 @@
 | 
			
		||||
<template>
 | 
			
		||||
  <div class="bg-base-100 flex flex-col gap-10 mb-5">
 | 
			
		||||
    <!-- 逻辑信号展示 -->
 | 
			
		||||
    <div class="card bg-base-200 shadow-xl">
 | 
			
		||||
    <div class="card bg-base-200 shadow-xl mx-5">
 | 
			
		||||
      <div class="card-body">
 | 
			
		||||
        <h2 class="card-title flex justify-between items-center">
 | 
			
		||||
          <div class="flex items-center gap-2">
 | 
			
		||||
@@ -19,7 +19,7 @@
 | 
			
		||||
    </div>
 | 
			
		||||
 | 
			
		||||
    <!-- 触发设置 -->
 | 
			
		||||
    <div class="card bg-base-200 shadow-xl">
 | 
			
		||||
    <div class="card bg-base-200 shadow-xl mx-5">
 | 
			
		||||
      <div class="card-body">
 | 
			
		||||
        <h2 class="card-title">
 | 
			
		||||
          <Settings class="w-5 h-5" />
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,7 @@
 | 
			
		||||
<template>
 | 
			
		||||
  <div class="bg-base-100 flex flex-col">
 | 
			
		||||
    <!-- 波形展示 -->
 | 
			
		||||
    <div class="card bg-base-200 shadow-xl">
 | 
			
		||||
    <div class="card bg-base-200 shadow-xl mx-5">
 | 
			
		||||
      <div class="card-body">
 | 
			
		||||
        <h2 class="card-title">
 | 
			
		||||
          <Activity class="w-5 h-5" />
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,7 @@
 | 
			
		||||
<template>
 | 
			
		||||
  <div class="bg-base-100 flex flex-col gap-7">
 | 
			
		||||
    <!-- 控制面板 -->
 | 
			
		||||
    <div class="card bg-base-200 shadow-xl">
 | 
			
		||||
    <div class="card bg-base-200 shadow-xl mx-5">
 | 
			
		||||
      <div class="card-body">
 | 
			
		||||
        <h2 class="card-title text-primary">
 | 
			
		||||
          <Settings class="w-6 h-6" />
 | 
			
		||||
@@ -153,7 +153,7 @@
 | 
			
		||||
    </div>
 | 
			
		||||
 | 
			
		||||
    <!-- 视频预览区域 -->
 | 
			
		||||
    <div class="card bg-base-200 shadow-xl">
 | 
			
		||||
    <div class="card bg-base-200 shadow-xl mx-5">
 | 
			
		||||
      <div class="card-body">
 | 
			
		||||
        <h2 class="card-title text-primary">
 | 
			
		||||
          <Video class="w-6 h-6" />
 | 
			
		||||
@@ -299,7 +299,7 @@
 | 
			
		||||
    </div>
 | 
			
		||||
 | 
			
		||||
    <!-- 日志区域 -->
 | 
			
		||||
    <div class="card bg-base-200 shadow-xl">
 | 
			
		||||
    <div class="card bg-base-200 shadow-xl mx-5"> 
 | 
			
		||||
      <div class="card-body">
 | 
			
		||||
        <h2 class="card-title text-primary">
 | 
			
		||||
          <FileText class="w-6 h-6" />
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user