feat: 增加示波器探测参数显示,增加旋转编码器按下的功能
This commit is contained in:
parent
7d3ef598de
commit
6302489f3a
|
@ -268,10 +268,10 @@ public class OscilloscopeApiController : ControllerBase
|
|||
|
||||
var response = new OscilloscopeDataResponse
|
||||
{
|
||||
ADFrequency = freqResult.Value,
|
||||
ADVpp = vppResult.Value,
|
||||
ADMax = maxResult.Value,
|
||||
ADMin = minResult.Value,
|
||||
AdFrequency = freqResult.Value,
|
||||
AdVpp = vppResult.Value,
|
||||
AdMax = maxResult.Value,
|
||||
AdMin = minResult.Value,
|
||||
WaveformData = Convert.ToBase64String(waveformResult.Value)
|
||||
};
|
||||
|
||||
|
|
|
@ -34,10 +34,10 @@ public interface IOscilloscopeReceiver
|
|||
[TranspilationSource]
|
||||
public class OscilloscopeDataResponse
|
||||
{
|
||||
public uint ADFrequency { get; set; }
|
||||
public byte ADVpp { get; set; }
|
||||
public byte ADMax { get; set; }
|
||||
public byte ADMin { get; set; }
|
||||
public uint AdFrequency { get; set; }
|
||||
public byte AdVpp { get; set; }
|
||||
public byte AdMax { get; set; }
|
||||
public byte AdMin { get; set; }
|
||||
public string WaveformData { get; set; } = "";
|
||||
}
|
||||
|
||||
|
@ -275,19 +275,19 @@ public class OscilloscopeHub : Hub<IOscilloscopeReceiver>, IOscilloscopeHub
|
|||
|
||||
var response = new OscilloscopeDataResponse
|
||||
{
|
||||
ADFrequency = freqResult.Value,
|
||||
ADVpp = vppResult.Value,
|
||||
ADMax = maxResult.Value,
|
||||
ADMin = minResult.Value,
|
||||
AdFrequency = freqResult.Value,
|
||||
AdVpp = vppResult.Value,
|
||||
AdMax = maxResult.Value,
|
||||
AdMin = minResult.Value,
|
||||
WaveformData = Convert.ToBase64String(waveformResult.Value)
|
||||
};
|
||||
|
||||
return new OscilloscopeDataResponse
|
||||
{
|
||||
ADFrequency = freqResult.Value,
|
||||
ADVpp = vppResult.Value,
|
||||
ADMax = maxResult.Value,
|
||||
ADMin = minResult.Value,
|
||||
AdFrequency = freqResult.Value,
|
||||
AdVpp = vppResult.Value,
|
||||
AdMax = maxResult.Value,
|
||||
AdMin = minResult.Value,
|
||||
WaveformData = Convert.ToBase64String(waveformResult.Value)
|
||||
};
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@ public interface IRotaryEncoderHub
|
|||
{
|
||||
Task<bool> SetEnable(bool enable);
|
||||
Task<bool> RotateEncoderOnce(int num, RotaryEncoderDirection direction);
|
||||
Task<bool> PressEncoderOnce(int num, RotaryEncoderPressStatus press);
|
||||
Task<bool> EnableCycleRotateEncoder(int num, RotaryEncoderDirection direction, int freq);
|
||||
Task<bool> DisableCycleRotateEncoder();
|
||||
}
|
||||
|
@ -133,6 +134,30 @@ public class RotaryEncoderHub : Hub<IRotaryEncoderReceiver>, IRotaryEncoderHub
|
|||
}
|
||||
}
|
||||
|
||||
public async Task<bool> PressEncoderOnce(int num, RotaryEncoderPressStatus press)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (num <= 0 || num > 4)
|
||||
throw new ArgumentException($"RotaryEncoder num should be 1~3, instead of {num}");
|
||||
|
||||
var board = TryGetBoard().OrThrow(() => new Exception("Board not found"));
|
||||
var encoderCtrl = new RotaryEncoderCtrl(board.IpAddr, board.Port, 0);
|
||||
var result = await encoderCtrl.PressEncoderOnce(num, press);
|
||||
if (!result.IsSuccessful)
|
||||
{
|
||||
logger.Error(result.Error, $"RotateEncoderOnce({num}, {press}) failed");
|
||||
return false;
|
||||
}
|
||||
return result.Value;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
logger.Error(ex, "Failed to rotate encoder once");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<bool> EnableCycleRotateEncoder(int num, RotaryEncoderDirection direction, int freq)
|
||||
{
|
||||
try
|
||||
|
|
|
@ -7,8 +7,10 @@ namespace Peripherals.RotaryEncoderClient;
|
|||
class RotaryEncoderCtrlAddr
|
||||
{
|
||||
public const UInt32 BASE = 0xB0_00_00_30;
|
||||
public const UInt32 PRESS_BASE = 0xB0_00_00_40;
|
||||
|
||||
public const UInt32 ENABLE = BASE;
|
||||
public const UInt32 PRESS_ENABLE = PRESS_BASE;
|
||||
}
|
||||
|
||||
[TranspilationSource]
|
||||
|
@ -18,6 +20,13 @@ public enum RotaryEncoderDirection : uint
|
|||
Clockwise = 1,
|
||||
}
|
||||
|
||||
[TranspilationSource]
|
||||
public enum RotaryEncoderPressStatus : uint
|
||||
{
|
||||
Press = 0,
|
||||
Release = 1,
|
||||
}
|
||||
|
||||
public class RotaryEncoderCtrl
|
||||
{
|
||||
private static readonly NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();
|
||||
|
@ -45,10 +54,22 @@ public class RotaryEncoderCtrl
|
|||
MsgBus.UDPServer.ClearUDPData(this.address, this.taskID);
|
||||
else return new(new Exception("Message Bus not work!"));
|
||||
|
||||
var ret = await UDPClientPool.WriteAddr(
|
||||
this.ep, this.taskID, RotaryEncoderCtrlAddr.ENABLE, enable ? 0x1U : 0x0U, this.timeout);
|
||||
if (!ret.IsSuccessful) return new(ret.Error);
|
||||
return ret.Value;
|
||||
{
|
||||
var ret = await UDPClientPool.WriteAddr(
|
||||
this.ep, this.taskID, RotaryEncoderCtrlAddr.ENABLE, enable ? 0x1U : 0x0U, this.timeout);
|
||||
if (!ret.IsSuccessful) return new(ret.Error);
|
||||
if (!ret.Value)
|
||||
{
|
||||
logger.Error($"Set Rotary Encoder Enable failed: {ret.Error}");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
{
|
||||
var ret = await UDPClientPool.WriteAddr(
|
||||
this.ep, this.taskID, RotaryEncoderCtrlAddr.PRESS_ENABLE, enable ? 0x1U : 0x0U, this.timeout);
|
||||
if (!ret.IsSuccessful) return new(ret.Error);
|
||||
return ret.Value;
|
||||
}
|
||||
}
|
||||
|
||||
public async ValueTask<Result<bool>> RotateEncoderOnce(int num, RotaryEncoderDirection direction)
|
||||
|
@ -61,7 +82,23 @@ public class RotaryEncoderCtrl
|
|||
this.ep, this.taskID, RotaryEncoderCtrlAddr.BASE + (UInt32)num, (UInt32)direction, this.timeout);
|
||||
if (!ret.IsSuccessful)
|
||||
{
|
||||
logger.Error($"Set Rotary Encoder {num} {direction.ToString()} failed: {ret.Error}");
|
||||
logger.Error($"Set Rotary Encoder Rotate {num} {direction.ToString()} failed: {ret.Error}");
|
||||
return new(ret.Error);
|
||||
}
|
||||
return ret.Value;
|
||||
}
|
||||
|
||||
public async ValueTask<Result<bool>> PressEncoderOnce(int num, RotaryEncoderPressStatus press)
|
||||
{
|
||||
if (MsgBus.IsRunning)
|
||||
MsgBus.UDPServer.ClearUDPData(this.address, this.taskID);
|
||||
else return new(new Exception("Message Bus not work!"));
|
||||
|
||||
var ret = await UDPClientPool.WriteAddr(
|
||||
this.ep, this.taskID, RotaryEncoderCtrlAddr.PRESS_BASE + (UInt32)num, (UInt32)press, this.timeout);
|
||||
if (!ret.IsSuccessful)
|
||||
{
|
||||
logger.Error($"Set Rotary Encoder Set {num} {press.ToString()} failed: {ret.Error}");
|
||||
return new(ret.Error);
|
||||
}
|
||||
return ret.Value;
|
||||
|
|
|
@ -199,10 +199,16 @@ const [useProvideOscilloscope, useOscilloscopeState] = createInjectionState(
|
|||
}
|
||||
sampleCount.value = bytes.length;
|
||||
|
||||
const aDFrequency = resp.adFrequency;
|
||||
|
||||
// 计算采样周期(ns)
|
||||
const samplePeriodNs =
|
||||
aDFrequency > 0 ? 1_000_000_000 / aDFrequency : 200;
|
||||
|
||||
// 构建时间轴
|
||||
const x = Array.from(
|
||||
{ length: bytes.length },
|
||||
(_, i) => (i * samplePeriodNs.value) / 1000, // us
|
||||
(_, i) => (i * samplePeriodNs) / 1000, // us
|
||||
);
|
||||
const y = Array.from(bytes);
|
||||
|
||||
|
@ -211,11 +217,13 @@ const [useProvideOscilloscope, useOscilloscopeState] = createInjectionState(
|
|||
y,
|
||||
xUnit: "us",
|
||||
yUnit: "V",
|
||||
adFrequency: resp.aDFrequency,
|
||||
adVpp: resp.aDVpp,
|
||||
adMax: resp.aDMax,
|
||||
adMin: resp.aDMin,
|
||||
adFrequency: aDFrequency,
|
||||
adVpp: resp.adVpp,
|
||||
adMax: resp.adMax,
|
||||
adMin: resp.adMin,
|
||||
};
|
||||
|
||||
console.log("解析后的参数:", resp, oscData.value); // 添加调试日志
|
||||
};
|
||||
|
||||
// 获取数据
|
||||
|
|
|
@ -88,6 +88,67 @@
|
|||
<div class="w-2 h-2 bg-white rounded-full animate-pulse"></div>
|
||||
采集中
|
||||
</div>
|
||||
|
||||
<!-- 测量数据展示面板 -->
|
||||
<div
|
||||
v-if="hasData"
|
||||
class="absolute top-4 left-4 bg-white/95 dark:bg-slate-800/95 backdrop-blur-sm rounded-lg shadow-lg border border-slate-200/50 dark:border-slate-700/50 p-3 min-w-[200px]"
|
||||
>
|
||||
<h4 class="text-sm font-semibold text-slate-700 dark:text-slate-300 mb-3 flex items-center gap-2">
|
||||
<Activity class="w-4 h-4 text-blue-500" />
|
||||
测量参数
|
||||
</h4>
|
||||
|
||||
<div class="space-y-2 text-xs">
|
||||
<!-- 采样频率 -->
|
||||
<div class="flex justify-between items-center">
|
||||
<span class="text-slate-600 dark:text-slate-400">采样频率:</span>
|
||||
<span class="font-mono font-semibold text-blue-600 dark:text-blue-400">
|
||||
{{ formatFrequency(oscData?.adFrequency || 0) }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<!-- 电压范围 -->
|
||||
<div class="flex justify-between items-center">
|
||||
<span class="text-slate-600 dark:text-slate-400">Vpp:</span>
|
||||
<span class="font-mono font-semibold text-emerald-600 dark:text-emerald-400">
|
||||
{{ (oscData?.adVpp || 0).toFixed(2) }}V
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<!-- 最大值 -->
|
||||
<div class="flex justify-between items-center">
|
||||
<span class="text-slate-600 dark:text-slate-400">最大值:</span>
|
||||
<span class="font-mono font-semibold text-orange-600 dark:text-orange-400">
|
||||
{{ formatAdcValue(oscData?.adMax || 0) }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<!-- 最小值 -->
|
||||
<div class="flex justify-between items-center">
|
||||
<span class="text-slate-600 dark:text-slate-400">最小值:</span>
|
||||
<span class="font-mono font-semibold text-purple-600 dark:text-purple-400">
|
||||
{{ formatAdcValue(oscData?.adMin || 0) }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<!-- 采样点数 -->
|
||||
<div class="flex justify-between items-center pt-1 border-t border-slate-200 dark:border-slate-700">
|
||||
<span class="text-slate-600 dark:text-slate-400">采样点:</span>
|
||||
<span class="font-mono font-semibold text-slate-700 dark:text-slate-300">
|
||||
{{ formatSampleCount(oscManager.sampleCount.value) }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<!-- 采样周期 -->
|
||||
<div class="flex justify-between items-center">
|
||||
<span class="text-slate-600 dark:text-slate-400">周期:</span>
|
||||
<span class="font-mono font-semibold text-slate-700 dark:text-slate-300">
|
||||
{{ formatPeriod(oscManager.samplePeriodNs.value) }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
@ -156,6 +217,44 @@ const hasData = computed(() => {
|
|||
);
|
||||
});
|
||||
|
||||
// 格式化频率显示
|
||||
const formatFrequency = (frequency: number): string => {
|
||||
if (frequency >= 1_000_000) {
|
||||
return `${(frequency / 1_000_000).toFixed(1)}MHz`;
|
||||
} else if (frequency >= 1_000) {
|
||||
return `${(frequency / 1_000).toFixed(1)}kHz`;
|
||||
} else {
|
||||
return `${frequency}Hz`;
|
||||
}
|
||||
};
|
||||
|
||||
// 格式化ADC值显示
|
||||
const formatAdcValue = (value: number): string => {
|
||||
return `${value} (${((value / 255) * 3.3).toFixed(2)}V)`;
|
||||
};
|
||||
|
||||
// 格式化采样点数显示
|
||||
const formatSampleCount = (count: number): string => {
|
||||
if (count >= 1_000_000) {
|
||||
return `${(count / 1_000_000).toFixed(1)}M`;
|
||||
} else if (count >= 1_000) {
|
||||
return `${(count / 1_000).toFixed(1)}k`;
|
||||
} else {
|
||||
return `${count}`;
|
||||
}
|
||||
};
|
||||
|
||||
// 格式化周期显示
|
||||
const formatPeriod = (periodNs: number): string => {
|
||||
if (periodNs >= 1_000_000) {
|
||||
return `${(periodNs / 1_000_000).toFixed(2)}ms`;
|
||||
} else if (periodNs >= 1_000) {
|
||||
return `${(periodNs / 1_000).toFixed(2)}μs`;
|
||||
} else {
|
||||
return `${periodNs.toFixed(2)}ns`;
|
||||
}
|
||||
};
|
||||
|
||||
const option = computed((): EChartsOption => {
|
||||
if (!oscData.value || !oscData.value.x || !oscData.value.y) {
|
||||
return {};
|
||||
|
@ -235,7 +334,9 @@ const option = computed((): EChartsOption => {
|
|||
if (!oscData.value) return "";
|
||||
let result = `<div style="font-weight: 600; margin-bottom: 4px;">时间: ${params[0].data[0].toFixed(2)} ${oscData.value.xUnit}</div>`;
|
||||
params.forEach((param: any) => {
|
||||
result += `<div style="color: ${param.color};">● ${param.seriesName}: ${param.data[1].toFixed(3)} ${oscData.value?.yUnit ?? ""}</div>`;
|
||||
const adcValue = param.data[1];
|
||||
const voltage = ((adcValue / 255) * 3.3).toFixed(3);
|
||||
result += `<div style="color: ${param.color};">● ${param.seriesName}: ${adcValue} (${voltage}V)</div>`;
|
||||
});
|
||||
return result;
|
||||
},
|
||||
|
@ -333,7 +434,7 @@ const option = computed((): EChartsOption => {
|
|||
},
|
||||
yAxis: {
|
||||
type: "value",
|
||||
name: oscData.value ? `电压 (${oscData.value.yUnit})` : "电压",
|
||||
name: oscData.value ? `ADC值 (0-255)` : "ADC值",
|
||||
nameLocation: "middle",
|
||||
nameGap: 50,
|
||||
nameTextStyle: {
|
||||
|
@ -357,6 +458,9 @@ const option = computed((): EChartsOption => {
|
|||
axisLabel: {
|
||||
color: "#64748B",
|
||||
fontSize: 11,
|
||||
formatter: (value: number) => {
|
||||
return `${value} (${((value / 255) * 3.3).toFixed(1)}V)`;
|
||||
},
|
||||
},
|
||||
splitLine: {
|
||||
show: true,
|
||||
|
@ -536,6 +640,14 @@ button:active::after {
|
|||
font-size: 12px;
|
||||
padding: 4px 8px;
|
||||
}
|
||||
|
||||
/* 移动端测量面板调整 */
|
||||
.absolute.top-4.left-4 {
|
||||
top: 8px;
|
||||
left: 8px;
|
||||
min-width: 180px;
|
||||
font-size: 11px;
|
||||
}
|
||||
}
|
||||
|
||||
/* 平滑过渡效果 */
|
||||
|
@ -548,4 +660,17 @@ button:focus-visible {
|
|||
outline: 2px solid rgba(59, 130, 246, 0.5);
|
||||
outline-offset: 2px;
|
||||
}
|
||||
</style>
|
||||
|
||||
/* 测量面板样式增强 */
|
||||
.absolute.top-4.left-4 {
|
||||
backdrop-filter: blur(8px);
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
|
||||
transition: all 0.3s ease-in-out;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.absolute.top-4.left-4:hover {
|
||||
transform: translateY(-1px);
|
||||
box-shadow: 0 6px 16px rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
</style>
|
|
@ -176,7 +176,10 @@
|
|||
|
||||
<script lang="ts" setup>
|
||||
import { useRotaryEncoder } from "@/stores/Peripherals/RotaryEncoder";
|
||||
import { RotaryEncoderDirection } from "@/utils/signalR/Peripherals.RotaryEncoderClient";
|
||||
import {
|
||||
RotaryEncoderDirection,
|
||||
RotaryEncoderPressStatus,
|
||||
} from "@/utils/signalR/Peripherals.RotaryEncoderClient";
|
||||
import { watch } from "vue";
|
||||
import { watchEffect } from "vue";
|
||||
import { ref, computed } from "vue";
|
||||
|
@ -185,6 +188,7 @@ const rotataryEncoderStore = useRotaryEncoder();
|
|||
|
||||
interface Props {
|
||||
size?: number;
|
||||
componentId?: string;
|
||||
enableDigitalTwin?: boolean;
|
||||
encoderNumber?: number;
|
||||
}
|
||||
|
@ -236,8 +240,16 @@ function handleMouseUp() {
|
|||
// 仅在未发生旋转时才触发按压
|
||||
if (!drag.value.hasRotated) {
|
||||
isPressed.value = true;
|
||||
rotataryEncoderStore.pressOnce(
|
||||
props.encoderNumber,
|
||||
RotaryEncoderPressStatus.Press,
|
||||
);
|
||||
setTimeout(() => {
|
||||
isPressed.value = false;
|
||||
rotataryEncoderStore.pressOnce(
|
||||
props.encoderNumber,
|
||||
RotaryEncoderPressStatus.Release,
|
||||
);
|
||||
}, 100);
|
||||
}
|
||||
}
|
||||
|
@ -252,7 +264,10 @@ function handlePress(pressed: boolean) {
|
|||
}
|
||||
|
||||
watchEffect(() => {
|
||||
rotataryEncoderStore.setEnable(props.enableDigitalTwin);
|
||||
if (!props.enableDigitalTwin) return;
|
||||
|
||||
if (props.componentId)
|
||||
rotataryEncoderStore.setEnable(props.enableDigitalTwin);
|
||||
});
|
||||
|
||||
watch(
|
||||
|
|
|
@ -108,6 +108,7 @@ import { ref, computed, watch, onMounted } from "vue";
|
|||
|
||||
interface Props {
|
||||
size?: number;
|
||||
componentId?: string;
|
||||
enableDigitalTwin?: boolean;
|
||||
switchCount?: number;
|
||||
initialValues?: string;
|
||||
|
@ -191,13 +192,10 @@ function setBtnStatus(idx: number, isOn: boolean) {
|
|||
}
|
||||
|
||||
// 监听 props 变化只同步一次
|
||||
const isFirstEnableDigitalTwin = ref(true);
|
||||
watch(
|
||||
() => props.enableDigitalTwin,
|
||||
(newVal) => {
|
||||
if (isFirstEnableDigitalTwin.value) {
|
||||
isFirstEnableDigitalTwin.value = false;
|
||||
} else {
|
||||
if (props.componentId) {
|
||||
const client = getClient();
|
||||
client.setEnable(newVal);
|
||||
}
|
||||
|
@ -205,16 +203,11 @@ watch(
|
|||
{ immediate: true },
|
||||
);
|
||||
|
||||
const isFirstUpdateStatus = ref(true);
|
||||
watch(
|
||||
() => [switchCount.value, props.initialValues],
|
||||
() => {
|
||||
btnStatus.value = parseInitialValues();
|
||||
if (isFirstUpdateStatus.value) {
|
||||
isFirstUpdateStatus.value = false;
|
||||
} else {
|
||||
updateStatus(btnStatus.value);
|
||||
}
|
||||
if (props.componentId) updateStatus(btnStatus.value);
|
||||
},
|
||||
);
|
||||
</script>
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
import { AuthManager } from "@/utils/AuthManager";
|
||||
import type { RotaryEncoderDirection } from "@/utils/signalR/Peripherals.RotaryEncoderClient";
|
||||
import type {
|
||||
RotaryEncoderDirection,
|
||||
RotaryEncoderPressStatus,
|
||||
} from "@/utils/signalR/Peripherals.RotaryEncoderClient";
|
||||
import {
|
||||
getHubProxyFactory,
|
||||
getReceiverRegister,
|
||||
|
@ -72,6 +75,11 @@ export const useRotaryEncoder = defineStore("RotaryEncoder", () => {
|
|||
return await proxy.rotateEncoderOnce(num, direction);
|
||||
}
|
||||
|
||||
async function pressOnce(num: number, pressStatus: RotaryEncoderPressStatus) {
|
||||
const proxy = getHubProxy();
|
||||
return await proxy.pressEncoderOnce(num, pressStatus);
|
||||
}
|
||||
|
||||
async function enableCycleRotate(
|
||||
num: number,
|
||||
direction: RotaryEncoderDirection,
|
||||
|
@ -89,6 +97,7 @@ export const useRotaryEncoder = defineStore("RotaryEncoder", () => {
|
|||
return {
|
||||
setEnable,
|
||||
rotateOnce,
|
||||
pressOnce,
|
||||
enableCycleRotate,
|
||||
disableCycleRotate,
|
||||
};
|
||||
|
|
|
@ -8,3 +8,9 @@ export enum RotaryEncoderDirection {
|
|||
Clockwise = 1,
|
||||
}
|
||||
|
||||
/** Transpiled from Peripherals.RotaryEncoderClient.RotaryEncoderPressStatus */
|
||||
export enum RotaryEncoderPressStatus {
|
||||
Press = 0,
|
||||
Release = 1,
|
||||
}
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
import type { HubConnection, IStreamResult, Subject } from '@microsoft/signalr';
|
||||
import type { IDigitalTubesHub, IJtagHub, IOscilloscopeHub, IProgressHub, IRotaryEncoderHub, IWS2812Hub, IDigitalTubesReceiver, IJtagReceiver, IOscilloscopeReceiver, IProgressReceiver, IRotaryEncoderReceiver, IWS2812Receiver } from './server.Hubs';
|
||||
import type { DigitalTubeTaskStatus, OscilloscopeFullConfig, OscilloscopeDataResponse, ProgressInfo } from '../server.Hubs';
|
||||
import type { RotaryEncoderDirection } from '../Peripherals.RotaryEncoderClient';
|
||||
import type { RotaryEncoderDirection, RotaryEncoderPressStatus } from '../Peripherals.RotaryEncoderClient';
|
||||
import type { RGBColor } from '../Peripherals.WS2812Client';
|
||||
|
||||
|
||||
|
@ -270,6 +270,10 @@ class IRotaryEncoderHub_HubProxy implements IRotaryEncoderHub {
|
|||
return await this.connection.invoke("RotateEncoderOnce", num, direction);
|
||||
}
|
||||
|
||||
public readonly pressEncoderOnce = async (num: number, press: RotaryEncoderPressStatus): Promise<boolean> => {
|
||||
return await this.connection.invoke("PressEncoderOnce", num, press);
|
||||
}
|
||||
|
||||
public readonly enableCycleRotateEncoder = async (num: number, direction: RotaryEncoderDirection, freq: number): Promise<boolean> => {
|
||||
return await this.connection.invoke("EnableCycleRotateEncoder", num, direction, freq);
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
// @ts-nocheck
|
||||
import type { IStreamResult, Subject } from '@microsoft/signalr';
|
||||
import type { DigitalTubeTaskStatus, OscilloscopeFullConfig, OscilloscopeDataResponse, ProgressInfo } from '../server.Hubs';
|
||||
import type { RotaryEncoderDirection } from '../Peripherals.RotaryEncoderClient';
|
||||
import type { RotaryEncoderDirection, RotaryEncoderPressStatus } from '../Peripherals.RotaryEncoderClient';
|
||||
import type { RGBColor } from '../Peripherals.WS2812Client';
|
||||
|
||||
export type IDigitalTubesHub = {
|
||||
|
@ -116,6 +116,12 @@ export type IRotaryEncoderHub = {
|
|||
rotateEncoderOnce(num: number, direction: RotaryEncoderDirection): Promise<boolean>;
|
||||
/**
|
||||
* @param num Transpiled from int
|
||||
* @param press Transpiled from Peripherals.RotaryEncoderClient.RotaryEncoderPressStatus
|
||||
* @returns Transpiled from System.Threading.Tasks.Task<bool>
|
||||
*/
|
||||
pressEncoderOnce(num: number, press: RotaryEncoderPressStatus): Promise<boolean>;
|
||||
/**
|
||||
* @param num Transpiled from int
|
||||
* @param direction Transpiled from Peripherals.RotaryEncoderClient.RotaryEncoderDirection
|
||||
* @param freq Transpiled from int
|
||||
* @returns Transpiled from System.Threading.Tasks.Task<bool>
|
||||
|
|
|
@ -13,13 +13,13 @@ export type DigitalTubeTaskStatus = {
|
|||
/** Transpiled from server.Hubs.OscilloscopeDataResponse */
|
||||
export type OscilloscopeDataResponse = {
|
||||
/** Transpiled from uint */
|
||||
aDFrequency: number;
|
||||
adFrequency: number;
|
||||
/** Transpiled from byte */
|
||||
aDVpp: number;
|
||||
adVpp: number;
|
||||
/** Transpiled from byte */
|
||||
aDMax: number;
|
||||
adMax: number;
|
||||
/** Transpiled from byte */
|
||||
aDMin: number;
|
||||
adMin: number;
|
||||
/** Transpiled from string */
|
||||
waveformData: string;
|
||||
}
|
||||
|
|
|
@ -182,7 +182,7 @@
|
|||
<!-- MD文档 -->
|
||||
<div class="space-y-2">
|
||||
<label class="text-sm font-medium text-base-content"
|
||||
>MD文档 (必需)</label
|
||||
>MD文档 (可选)</label
|
||||
>
|
||||
<div
|
||||
class="border-2 border-dashed border-base-300 rounded-lg p-6 text-center cursor-pointer hover:border-primary hover:bg-primary/5 transition-colors aspect-square flex items-center justify-center"
|
||||
|
@ -468,7 +468,7 @@ const canCreateExam = computed(() => {
|
|||
editExamInfo.value.id.trim() !== "" &&
|
||||
editExamInfo.value.name.trim() !== "" &&
|
||||
editExamInfo.value.description.trim() !== "" &&
|
||||
(uploadFiles.value.mdFile !== null || mode.value === "edit")
|
||||
(mode.value === "edit")
|
||||
);
|
||||
});
|
||||
|
||||
|
@ -605,11 +605,6 @@ const submitCreateExam = async () => {
|
|||
return;
|
||||
}
|
||||
|
||||
if (!uploadFiles.value.mdFile) {
|
||||
alert.error("请上传MD文档");
|
||||
return;
|
||||
}
|
||||
|
||||
isUpdating.value = true;
|
||||
|
||||
try {
|
||||
|
|
Loading…
Reference in New Issue