Compare commits
8 Commits
pyg
...
a5fca01ee9
| Author | SHA1 | Date | |
|---|---|---|---|
| a5fca01ee9 | |||
| c47aeb33ca | |||
| eb3a166079 | |||
| f9178784c3 | |||
| 1ce12120a0 | |||
| 5804863af7 | |||
| 17b89aa575 | |||
|
|
8106f54ae7 |
@@ -59,7 +59,7 @@ try
|
||||
IssuerSigningKey = new SymmetricSecurityKey(
|
||||
Encoding.UTF8.GetBytes("my secret key 1234567890my secret key 1234567890")),
|
||||
};
|
||||
options.Authority = "http://localhost:5000";
|
||||
options.Authority = $"http://{Global.localhost}:5000";
|
||||
options.RequireHttpsMetadata = false;
|
||||
});
|
||||
// Add JWT Token Authorization Policy
|
||||
@@ -175,7 +175,14 @@ try
|
||||
app.UseAuthorization();
|
||||
|
||||
// Swagger
|
||||
app.UseOpenApi();
|
||||
app.UseOpenApi(settings =>
|
||||
{
|
||||
settings.PostProcess = (document, httpRequest) =>
|
||||
{
|
||||
document.Servers.Clear();
|
||||
document.Servers.Add(new NSwag.OpenApiServer { Url = $"http://{Global.localhost}:5000" });
|
||||
};
|
||||
});
|
||||
app.UseSwaggerUi();
|
||||
|
||||
// Router
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
"commandName": "Project",
|
||||
"dotnetRunMessages": true,
|
||||
"launchBrowser": true,
|
||||
"applicationUrl": "http://localhost:5000",
|
||||
"applicationUrl": "http://0.0.0.0:5000",
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development",
|
||||
"ASPNETCORE_HOSTINGSTARTUPASSEMBLIES": "Microsoft.AspNetCore.SpaProxy"
|
||||
@@ -15,7 +15,7 @@
|
||||
"commandName": "Project",
|
||||
"dotnetRunMessages": true,
|
||||
"launchBrowser": true,
|
||||
"applicationUrl": "https://localhost:7278;http://localhost:5000",
|
||||
"applicationUrl": "https://0.0.0.0:7278;http://0.0.0.0:5000",
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development",
|
||||
"ASPNETCORE_HOSTINGSTARTUPASSEMBLIES": "Microsoft.AspNetCore.SpaProxy"
|
||||
|
||||
20
server/src/Common/Global.cs
Normal file
20
server/src/Common/Global.cs
Normal file
@@ -0,0 +1,20 @@
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
|
||||
public static class Global {
|
||||
|
||||
public static readonly string localhost = "192.168.137.1";
|
||||
|
||||
public static string GetLocalIPAddress()
|
||||
{
|
||||
var host = Dns.GetHostEntry(Dns.GetHostName());
|
||||
foreach (var ip in host.AddressList)
|
||||
{
|
||||
if (ip.AddressFamily == AddressFamily.InterNetwork)
|
||||
{
|
||||
return ip.ToString();
|
||||
}
|
||||
}
|
||||
throw new Exception("No network adapters with an IPv4 address in the system!");
|
||||
}
|
||||
}
|
||||
@@ -148,10 +148,10 @@ public class VideoStreamController : ControllerBase
|
||||
FrameWidth = _videoStreamService.FrameWidth,
|
||||
FrameHeight = _videoStreamService.FrameHeight,
|
||||
Format = "MJPEG",
|
||||
HtmlUrl = $"http://localhost:{_videoStreamService.ServerPort}/video-feed.html",
|
||||
MjpegUrl = $"http://localhost:{_videoStreamService.ServerPort}/video-stream",
|
||||
SnapshotUrl = $"http://localhost:{_videoStreamService.ServerPort}/snapshot",
|
||||
UsbCameraUrl = $"http://localhost:{_videoStreamService.ServerPort}/usb-camera"
|
||||
HtmlUrl = $"http://{Global.localhost}:{_videoStreamService.ServerPort}/video-feed.html",
|
||||
MjpegUrl = $"http://{Global.localhost}:{_videoStreamService.ServerPort}/video-stream",
|
||||
SnapshotUrl = $"http://{Global.localhost}:{_videoStreamService.ServerPort}/snapshot",
|
||||
UsbCameraUrl = $"http://{Global.localhost}:{_videoStreamService.ServerPort}/usb-camera"
|
||||
};
|
||||
return TypedResults.Ok(result);
|
||||
}
|
||||
@@ -267,7 +267,7 @@ public class VideoStreamController : ControllerBase
|
||||
using (var httpClient = new HttpClient())
|
||||
{
|
||||
httpClient.Timeout = TimeSpan.FromSeconds(2); // 设置较短的超时时间
|
||||
var response = await httpClient.GetAsync($"http://localhost:{_videoStreamService.ServerPort}/");
|
||||
var response = await httpClient.GetAsync($"http://{Global.localhost}:{_videoStreamService.ServerPort}/");
|
||||
|
||||
// 只要能连接上就认为成功,不管返回状态
|
||||
isConnected = response.IsSuccessStatusCode;
|
||||
|
||||
@@ -86,7 +86,7 @@ public class HttpVideoStreamService : BackgroundService
|
||||
{
|
||||
private static readonly NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();
|
||||
private HttpListener? _httpListener;
|
||||
private readonly int _serverPort = 8080;
|
||||
private readonly int _serverPort = 4321;
|
||||
private readonly int _frameRate = 30; // 30 FPS
|
||||
|
||||
// 动态分辨率配置
|
||||
@@ -311,7 +311,7 @@ public class HttpVideoStreamService : BackgroundService
|
||||
|
||||
// 创建 HTTP 监听器
|
||||
_httpListener = new HttpListener();
|
||||
_httpListener.Prefixes.Add($"http://localhost:{_serverPort}/");
|
||||
_httpListener.Prefixes.Add($"http://{Global.localhost}:{_serverPort}/");
|
||||
_httpListener.Start();
|
||||
|
||||
logger.Info("HTTP 视频流服务已启动,监听端口: {Port}", _serverPort);
|
||||
@@ -412,7 +412,7 @@ public class HttpVideoStreamService : BackgroundService
|
||||
{
|
||||
if (_usbCamera == null)
|
||||
{
|
||||
_usbCamera = new VideoCapture(0);
|
||||
_usbCamera = new VideoCapture(1);
|
||||
_usbCamera.Fps = _frameRate;
|
||||
_usbCamera.FrameWidth = _frameWidth;
|
||||
_usbCamera.FrameHeight = _frameHeight;
|
||||
|
||||
@@ -15,7 +15,7 @@ export class VideoStreamClient {
|
||||
|
||||
constructor(baseUrl?: string, http?: { fetch(url: RequestInfo, init?: RequestInit): Promise<Response> }) {
|
||||
this.http = http ? http : window as any;
|
||||
this.baseUrl = baseUrl ?? "http://localhost:5000";
|
||||
this.baseUrl = baseUrl ?? "http://192.168.137.1:5000";
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -638,7 +638,7 @@ export class BsdlParserClient {
|
||||
|
||||
constructor(baseUrl?: string, http?: { fetch(url: RequestInfo, init?: RequestInit): Promise<Response> }) {
|
||||
this.http = http ? http : window as any;
|
||||
this.baseUrl = baseUrl ?? "http://localhost:5000";
|
||||
this.baseUrl = baseUrl ?? "http://192.168.137.1:5000";
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -691,7 +691,7 @@ export class DataClient {
|
||||
|
||||
constructor(baseUrl?: string, http?: { fetch(url: RequestInfo, init?: RequestInit): Promise<Response> }) {
|
||||
this.http = http ? http : window as any;
|
||||
this.baseUrl = baseUrl ?? "http://localhost:5000";
|
||||
this.baseUrl = baseUrl ?? "http://192.168.137.1:5000";
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1404,7 +1404,7 @@ export class DDSClient {
|
||||
|
||||
constructor(baseUrl?: string, http?: { fetch(url: RequestInfo, init?: RequestInit): Promise<Response> }) {
|
||||
this.http = http ? http : window as any;
|
||||
this.baseUrl = baseUrl ?? "http://localhost:5000";
|
||||
this.baseUrl = baseUrl ?? "http://192.168.137.1:5000";
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1644,7 +1644,7 @@ export class JtagClient {
|
||||
|
||||
constructor(baseUrl?: string, http?: { fetch(url: RequestInfo, init?: RequestInit): Promise<Response> }) {
|
||||
this.http = http ? http : window as any;
|
||||
this.baseUrl = baseUrl ?? "http://localhost:5000";
|
||||
this.baseUrl = baseUrl ?? "http://192.168.137.1:5000";
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2164,7 +2164,7 @@ export class LogicAnalyzerClient {
|
||||
|
||||
constructor(baseUrl?: string, http?: { fetch(url: RequestInfo, init?: RequestInit): Promise<Response> }) {
|
||||
this.http = http ? http : window as any;
|
||||
this.baseUrl = baseUrl ?? "http://localhost:5000";
|
||||
this.baseUrl = baseUrl ?? "http://192.168.137.1:5000";
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2609,7 +2609,7 @@ export class MatrixKeyClient {
|
||||
|
||||
constructor(baseUrl?: string, http?: { fetch(url: RequestInfo, init?: RequestInit): Promise<Response> }) {
|
||||
this.http = http ? http : window as any;
|
||||
this.baseUrl = baseUrl ?? "http://localhost:5000";
|
||||
this.baseUrl = baseUrl ?? "http://192.168.137.1:5000";
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2793,7 +2793,7 @@ export class NetConfigClient {
|
||||
|
||||
constructor(baseUrl?: string, http?: { fetch(url: RequestInfo, init?: RequestInit): Promise<Response> }) {
|
||||
this.http = http ? http : window as any;
|
||||
this.baseUrl = baseUrl ?? "http://localhost:5000";
|
||||
this.baseUrl = baseUrl ?? "http://192.168.137.1:5000";
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -3419,7 +3419,7 @@ export class OscilloscopeApiClient {
|
||||
|
||||
constructor(baseUrl?: string, http?: { fetch(url: RequestInfo, init?: RequestInit): Promise<Response> }) {
|
||||
this.http = http ? http : window as any;
|
||||
this.baseUrl = baseUrl ?? "http://localhost:5000";
|
||||
this.baseUrl = baseUrl ?? "http://192.168.137.1:5000";
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -3853,7 +3853,7 @@ export class PowerClient {
|
||||
|
||||
constructor(baseUrl?: string, http?: { fetch(url: RequestInfo, init?: RequestInit): Promise<Response> }) {
|
||||
this.http = http ? http : window as any;
|
||||
this.baseUrl = baseUrl ?? "http://localhost:5000";
|
||||
this.baseUrl = baseUrl ?? "http://192.168.137.1:5000";
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -3925,7 +3925,7 @@ export class RemoteUpdateClient {
|
||||
|
||||
constructor(baseUrl?: string, http?: { fetch(url: RequestInfo, init?: RequestInit): Promise<Response> }) {
|
||||
this.http = http ? http : window as any;
|
||||
this.baseUrl = baseUrl ?? "http://localhost:5000";
|
||||
this.baseUrl = baseUrl ?? "http://192.168.137.1:5000";
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -4266,7 +4266,7 @@ export class TutorialClient {
|
||||
|
||||
constructor(baseUrl?: string, http?: { fetch(url: RequestInfo, init?: RequestInit): Promise<Response> }) {
|
||||
this.http = http ? http : window as any;
|
||||
this.baseUrl = baseUrl ?? "http://localhost:5000";
|
||||
this.baseUrl = baseUrl ?? "http://192.168.137.1:5000";
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -4315,7 +4315,7 @@ export class UDPClient {
|
||||
|
||||
constructor(baseUrl?: string, http?: { fetch(url: RequestInfo, init?: RequestInit): Promise<Response> }) {
|
||||
this.http = http ? http : window as any;
|
||||
this.baseUrl = baseUrl ?? "http://localhost:5000";
|
||||
this.baseUrl = baseUrl ?? "http://192.168.137.1:5000";
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { createInjectionState } from "@vueuse/core";
|
||||
import { autoResetRef, createInjectionState } from "@vueuse/core";
|
||||
import { shallowRef, reactive, ref, computed } from "vue";
|
||||
import { Mutex } from "async-mutex";
|
||||
import {
|
||||
@@ -26,7 +26,7 @@ const DEFAULT_CONFIG: OscilloscopeFullConfig = new OscilloscopeFullConfig({
|
||||
triggerLevel: 128,
|
||||
triggerRisingEdge: true,
|
||||
horizontalShift: 0,
|
||||
decimationRate: 0,
|
||||
decimationRate: 50,
|
||||
autoRefreshRAM: false,
|
||||
});
|
||||
|
||||
@@ -83,6 +83,10 @@ const [useProvideOscilloscope, useOscilloscopeState] = createInjectionState(() =
|
||||
alert.info("配置已重置", 2000);
|
||||
};
|
||||
|
||||
const clearOscilloscopeData = () => {
|
||||
oscData.value = undefined;
|
||||
}
|
||||
|
||||
// 获取数据
|
||||
const getOscilloscopeData = async () => {
|
||||
try {
|
||||
@@ -119,6 +123,28 @@ const [useProvideOscilloscope, useOscilloscopeState] = createInjectionState(() =
|
||||
}
|
||||
};
|
||||
|
||||
// 定时器引用
|
||||
let refreshIntervalId: number | undefined;
|
||||
// 刷新间隔(毫秒),可根据需要调整
|
||||
const refreshIntervalMs = ref(1000);
|
||||
|
||||
// 定时刷新函数
|
||||
const startAutoRefresh = () => {
|
||||
if (refreshIntervalId !== undefined) return;
|
||||
refreshIntervalId = window.setInterval(async () => {
|
||||
await refreshRAM();
|
||||
await getOscilloscopeData();
|
||||
}, refreshIntervalMs.value);
|
||||
};
|
||||
|
||||
const stopAutoRefresh = () => {
|
||||
if (refreshIntervalId !== undefined) {
|
||||
clearInterval(refreshIntervalId);
|
||||
refreshIntervalId = undefined;
|
||||
isCapturing.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
// 启动捕获
|
||||
const startCapture = async () => {
|
||||
if (operationMutex.isLocked()) {
|
||||
@@ -133,14 +159,13 @@ const [useProvideOscilloscope, useOscilloscopeState] = createInjectionState(() =
|
||||
if (!started) throw new Error("无法启动捕获");
|
||||
alert.info("开始捕获...", 2000);
|
||||
|
||||
// 简单轮询,直到捕获完成(可根据后端实际情况优化)
|
||||
await new Promise((resolve) => setTimeout(resolve, 1000));
|
||||
await getOscilloscopeData();
|
||||
alert.success("捕获完成", 2000);
|
||||
// 启动定时刷新
|
||||
startAutoRefresh();
|
||||
} catch (error) {
|
||||
alert.error("捕获失败", 3000);
|
||||
} finally {
|
||||
isCapturing.value = false;
|
||||
stopAutoRefresh();
|
||||
} finally {
|
||||
release();
|
||||
}
|
||||
};
|
||||
@@ -152,6 +177,7 @@ const [useProvideOscilloscope, useOscilloscopeState] = createInjectionState(() =
|
||||
return;
|
||||
}
|
||||
isCapturing.value = false;
|
||||
stopAutoRefresh();
|
||||
const release = await operationMutex.acquire();
|
||||
try {
|
||||
const client = AuthManager.createAuthenticatedOscilloscopeApiClient();
|
||||
@@ -205,7 +231,7 @@ const [useProvideOscilloscope, useOscilloscopeState] = createInjectionState(() =
|
||||
try {
|
||||
const ok = await client.refreshRAM();
|
||||
if (ok) {
|
||||
alert.success("RAM已刷新", 2000);
|
||||
// alert.success("RAM已刷新", 2000);
|
||||
} else {
|
||||
throw new Error();
|
||||
}
|
||||
@@ -236,21 +262,18 @@ const [useProvideOscilloscope, useOscilloscopeState] = createInjectionState(() =
|
||||
alert.success("测试数据生成成功", 2000);
|
||||
};
|
||||
|
||||
const isOperationInProgress = computed(
|
||||
() => isApplying.value || isCapturing.value || operationMutex.isLocked()
|
||||
);
|
||||
|
||||
return {
|
||||
oscData,
|
||||
config,
|
||||
isApplying,
|
||||
isCapturing,
|
||||
isOperationInProgress,
|
||||
sampleCount,
|
||||
samplePeriodNs,
|
||||
refreshIntervalMs,
|
||||
|
||||
applyConfiguration,
|
||||
resetConfiguration,
|
||||
clearOscilloscopeData,
|
||||
getOscilloscopeData,
|
||||
startCapture,
|
||||
stopCapture,
|
||||
|
||||
@@ -2,10 +2,7 @@
|
||||
<div class="w-full h-100 flex flex-col">
|
||||
<!-- 原有内容 -->
|
||||
<v-chart v-if="hasData" class="w-full h-full" :option="option" autoresize />
|
||||
<div
|
||||
v-else
|
||||
class="w-full h-full flex flex-col gap-4 items-center justify-center text-gray-500"
|
||||
>
|
||||
<div v-else class="w-full h-full flex flex-col gap-4 items-center justify-center text-gray-500">
|
||||
<span> 暂无数据 </span>
|
||||
<!-- 采集控制按钮 -->
|
||||
<div class="flex justify-center items-center mb-2">
|
||||
@@ -16,13 +13,11 @@
|
||||
!oscManager.isCapturing.value,
|
||||
'from-red-500 to-red-600 hover:from-red-600 hover:to-red-700 focus:ring-red-300':
|
||||
oscManager.isCapturing.value,
|
||||
}"
|
||||
@click="
|
||||
}" @click="
|
||||
oscManager.isCapturing.value
|
||||
? oscManager.stopCapture()
|
||||
: oscManager.startCapture()
|
||||
"
|
||||
>
|
||||
">
|
||||
<span class="flex items-center gap-2">
|
||||
<template v-if="oscManager.isCapturing.value">
|
||||
<Square class="w-5 h-5" />
|
||||
@@ -109,9 +104,11 @@ const option = computed((): EChartsOption => {
|
||||
return {};
|
||||
}
|
||||
|
||||
const isCapturing = oscManager.isCapturing.value;
|
||||
|
||||
const series: LineSeriesOption[] = [];
|
||||
|
||||
// 兼容单通道和多通道,确保 yChannels 为 number[][]
|
||||
// 兼容单通道和多通道,确保 yChannels 为 number[]
|
||||
const yChannels: number[][] = Array.isArray(oscData.value.y[0])
|
||||
? (oscData.value.y as number[][])
|
||||
: [oscData.value.y as number[]];
|
||||
@@ -131,6 +128,10 @@ const option = computed((): EChartsOption => {
|
||||
lineStyle: {
|
||||
width: 2,
|
||||
},
|
||||
// 关闭系列动画
|
||||
animation: !isCapturing,
|
||||
animationDuration: isCapturing ? 0 : 1000,
|
||||
animationEasing: isCapturing ? "linear" : "cubicOut",
|
||||
});
|
||||
});
|
||||
|
||||
@@ -203,6 +204,10 @@ const option = computed((): EChartsOption => {
|
||||
show: false,
|
||||
},
|
||||
},
|
||||
// 全局动画开关
|
||||
animation: !isCapturing,
|
||||
animationDuration: isCapturing ? 0 : 1000,
|
||||
animationEasing: isCapturing ? "linear" : "cubicOut",
|
||||
series: series,
|
||||
};
|
||||
});
|
||||
|
||||
@@ -180,15 +180,12 @@ const option = computed((): EChartsOption => {
|
||||
// 构造带过渡的点序列
|
||||
function buildVcdLine(valArr: number[], high: number, low: number) {
|
||||
const points: {x: number, y: number}[] = [];
|
||||
for (let i = 0; i < valArr.length; i++) {
|
||||
const v = valArr[i] > 0 ? high : low;
|
||||
let lastValue = high;
|
||||
points.push({x: xArr[0], y: lastValue});
|
||||
for (let i = 1; i < valArr.length; i++) {
|
||||
const v = valArr[i] !== valArr[i-1] ? (lastValue === high ? low : high) : lastValue;
|
||||
points.push({x: xArr[i], y: v});
|
||||
// 检查下一个点是否变化,若变化则插入过渡点
|
||||
if (i < valArr.length - 1 && valArr[i] !== valArr[i+1]) {
|
||||
// 过渡点,x略微偏移(如+0.3),y为下一个值
|
||||
const nextV = valArr[i+1] > 0 ? high : low;
|
||||
points.push({x: xArr[i]+0.3, y: nextV});
|
||||
}
|
||||
lastValue = v;
|
||||
}
|
||||
// 返回y数组,x由category轴控制
|
||||
return points.map(p => p.y);
|
||||
|
||||
@@ -3,9 +3,21 @@
|
||||
<!-- 波形展示 -->
|
||||
<div class="card bg-base-200 shadow-xl mx-5">
|
||||
<div class="card-body">
|
||||
<h2 class="card-title">
|
||||
<h2 class="card-title flex flex-row justify-between">
|
||||
<div class="flex items-center gap-2">
|
||||
<Activity class="w-5 h-5" />
|
||||
波形显示
|
||||
</div>
|
||||
<div class="flex items-center gap-2">
|
||||
<button class="btn btn-sm btn-warning" @click="osc.stopCapture" :disabled="!osc.isCapturing.value">
|
||||
停止捕获
|
||||
</button>
|
||||
<div class="flex items-center gap-2">
|
||||
<button class="btn btn-sm btn-error" @click="osc.clearOscilloscopeData">
|
||||
清空
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</h2>
|
||||
<OscilloscopeWaveformDisplay />
|
||||
</div>
|
||||
@@ -16,120 +28,71 @@
|
||||
<div class="card-body">
|
||||
<h2 class="card-title">示波器配置</h2>
|
||||
<form class="flex flex-col gap-2" @submit.prevent="applyConfiguration">
|
||||
<div class="flex gap-4">
|
||||
<div class="flex flex-row items-center justify-between gap-4">
|
||||
<label>
|
||||
触发电平:
|
||||
<input
|
||||
type="number"
|
||||
v-model="osc.config.triggerLevel"
|
||||
min="0"
|
||||
max="255"
|
||||
class="input input-bordered w-24"
|
||||
/>
|
||||
</label>
|
||||
<label>
|
||||
边沿:
|
||||
<select
|
||||
v-model="osc.config.triggerRisingEdge"
|
||||
class="select select-bordered w-24"
|
||||
>
|
||||
边沿触发:
|
||||
<select v-model="osc.config.triggerRisingEdge" class="select select-bordered w-24">
|
||||
<option :value="true">上升沿</option>
|
||||
<option :value="false">下降沿</option>
|
||||
</select>
|
||||
</label>
|
||||
<label>
|
||||
触发电平:
|
||||
<div class="flex items-center gap-2">
|
||||
<input type="range" min="0" max="255" step="1" v-model="osc.config.triggerLevel"
|
||||
class="range range-sm w-50" />
|
||||
<input type="number" v-model="osc.config.triggerLevel" min="0" max="255"
|
||||
class="input input-bordered w-24" />
|
||||
</div>
|
||||
</label>
|
||||
<label>
|
||||
水平偏移:
|
||||
<input
|
||||
type="number"
|
||||
v-model="osc.config.horizontalShift"
|
||||
class="input input-bordered w-24"
|
||||
/>
|
||||
<div class="flex items-center gap-2">
|
||||
<input type="range" min="0" max="1000" step="1" v-model="osc.config.horizontalShift"
|
||||
class="range range-sm w-50" />
|
||||
<input type="number" v-model="osc.config.horizontalShift" min="0" max="1000"
|
||||
class="input input-bordered w-24" />
|
||||
</div>
|
||||
</label>
|
||||
<label>
|
||||
抽取率:
|
||||
<input
|
||||
type="number"
|
||||
v-model="osc.config.decimationRate"
|
||||
min="0"
|
||||
class="input input-bordered w-24"
|
||||
/>
|
||||
</label>
|
||||
<label>
|
||||
自动刷新RAM:
|
||||
<input
|
||||
type="checkbox"
|
||||
v-model="osc.config.autoRefreshRAM"
|
||||
class="checkbox"
|
||||
/>
|
||||
<div class="flex items-center gap-2">
|
||||
<input type="range" min="0" max="100" step="1" v-model="osc.config.decimationRate"
|
||||
class="range range-sm w-50" />
|
||||
<input type="number" v-model="osc.config.decimationRate" min="0" max="100"
|
||||
class="input input-bordered w-24" />
|
||||
</div>
|
||||
</label>
|
||||
</div>
|
||||
<div class="flex gap-2 mt-2">
|
||||
<button
|
||||
class="btn btn-primary"
|
||||
type="submit"
|
||||
:disabled="osc.isOperationInProgress.value"
|
||||
>
|
||||
<div class="flex gap-4">
|
||||
</div>
|
||||
<div class="flex items-center justify-between gap-2 mt-2">
|
||||
<label>
|
||||
刷新间隔(ms):
|
||||
<div class="flex items-center gap-2">
|
||||
<input type="range" min="100" max="3000" step="100" v-model="osc.refreshIntervalMs.value"
|
||||
class="range range-sm w-50" />
|
||||
<input type="number" min="100" max="3000" step="100" v-model="osc.refreshIntervalMs.value"
|
||||
class="input input-bordered w-24" />
|
||||
</div>
|
||||
</label>
|
||||
<div class="flex items-center gap-2">
|
||||
<button class="btn btn-primary" type="submit" :disabled="osc.isApplying.value || osc.isCapturing.value">
|
||||
应用配置
|
||||
</button>
|
||||
<button
|
||||
class="btn btn-secondary"
|
||||
type="button"
|
||||
@click="osc.resetConfiguration"
|
||||
:disabled="osc.isOperationInProgress.value"
|
||||
>
|
||||
<button class="btn btn-secondary" type="button" @click="osc.resetConfiguration"
|
||||
:disabled="osc.isApplying.value || osc.isCapturing.value">
|
||||
重置
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 捕获控制 -->
|
||||
<div class="card bg-base-200 shadow-xl mx-5">
|
||||
<div class="card-body flex gap-2">
|
||||
<h2 class="card-title">捕获控制</h2>
|
||||
<button
|
||||
class="btn btn-success"
|
||||
@click="osc.startCapture"
|
||||
:disabled="osc.isOperationInProgress.value"
|
||||
>
|
||||
开始捕获
|
||||
</button>
|
||||
<button
|
||||
class="btn btn-warning"
|
||||
@click="osc.stopCapture"
|
||||
:disabled="!osc.isCapturing.value"
|
||||
>
|
||||
停止捕获
|
||||
</button>
|
||||
<button
|
||||
class="btn btn-info"
|
||||
@click="osc.getOscilloscopeData"
|
||||
:disabled="osc.isOperationInProgress.value"
|
||||
>
|
||||
获取数据
|
||||
</button>
|
||||
<button
|
||||
class="btn btn-accent"
|
||||
@click="osc.generateTestData"
|
||||
:disabled="osc.isOperationInProgress.value"
|
||||
>
|
||||
生成测试数据
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- RAM刷新 -->
|
||||
<div class="card bg-base-200 shadow-xl mx-5">
|
||||
<div class="card-body flex gap-2">
|
||||
<h2 class="card-title">RAM 操作</h2>
|
||||
<button
|
||||
class="btn btn-outline"
|
||||
@click="osc.refreshRAM"
|
||||
:disabled="osc.isOperationInProgress.value"
|
||||
>
|
||||
<button class="btn btn-outline" @click="osc.refreshRAM" :disabled="osc.isApplying.value || osc.isCapturing.value">
|
||||
刷新RAM
|
||||
</button>
|
||||
<!-- <button class="btn btn-accent" @click="osc.generateTestData" :disabled="osc.isOperationInProgress.value">
|
||||
生成测试数据
|
||||
</button> -->
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user