feat: 实现参数设置与设备连接

This commit is contained in:
2025-12-24 15:03:28 +08:00
parent 03a56ec480
commit 614130e303
3 changed files with 189 additions and 0 deletions

View File

@ -0,0 +1,43 @@
<script lang="ts">
import {
Tabs,
TabsContent,
TabsList,
TabsTrigger,
} from '$lib/components/ui/tabs';
import SerialSetting from './components/SerialSetting.svelte';
let activeTab = 'serial';
</script>
<Tabs bind:value={activeTab} className="p-2">
<TabsList className="grid w-full grid-cols-2">
<TabsTrigger value="serial">
<svg
xmlns="http://www.w3.org/2000/svg"
width="32"
height="32"
viewBox="0 0 24 24"
><!-- Icon from Material Design Icons by Pictogrammers - https://github.com/Templarian/MaterialDesign/blob/master/LICENSE --><path
fill="currentColor"
d="M7 3h10v2h2v3h-3v6H8V8H5V5h2zm10 6h2v5h-2zm-6 6h2v7h-2zM5 9h2v5H5z"
/></svg
>
串口</TabsTrigger
>
<TabsTrigger value="ble">
<svg
xmlns="http://www.w3.org/2000/svg"
width="32"
height="32"
viewBox="0 0 24 24"
><!-- Icon from Material Design Icons by Pictogrammers - https://github.com/Templarian/MaterialDesign/blob/master/LICENSE --><path
fill="currentColor"
d="M14.88 16.29L13 18.17v-3.76m0-8.58l1.88 1.88L13 9.58m4.71-1.87L12 2h-1v7.58L6.41 5L5 6.41L10.59 12L5 17.58L6.41 19L11 14.41V22h1l5.71-5.71l-4.3-4.29z"
/></svg
>
蓝牙</TabsTrigger
>
</TabsList>
<TabsContent value="serial"><SerialSetting /></TabsContent>
<TabsContent value="ble">蓝牙设置</TabsContent>
</Tabs>

View File

@ -0,0 +1,35 @@
<script lang="ts">
import {
Select,
SelectContent,
SelectTrigger,
} from '$lib/components/ui/select';
type Props = {
id: string;
label: string;
items: { label: string; value: string }[];
value: string;
placeholder: string;
};
let { id, label, items, value = $bindable(), placeholder }: Props = $props();
</script>
<label
for={id}
class="text-md leading-none font-medium peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
>
{label}
</label>
<Select type="single" bind:value>
<SelectTrigger
{id}
class="w-full outline-none focus:border-base-content/20 focus-visible:border-primary focus-visible:ring-2 focus-visible:ring-primary focus-visible:ring-offset-2"
>
{items.find((i) => i.value === value)?.label ?? placeholder}
</SelectTrigger>
<SelectContent {items} />
</Select>

View File

@ -0,0 +1,111 @@
<script lang="ts">
import {
baudRateValue,
baudRateItems,
dataBitsValue,
parityValue,
stopBitsValue,
} from '$lib/stores/serial.ui';
import { serialOptions } from '$lib/stores/serial.options';
import SerialParamSelect from './SerialParamSelect.svelte';
import { Button } from '$lib/components/ui/button';
import { getSerialContext } from '$lib/serial/serial.store';
const serial = getSerialContext();
const serialState = serial.state;
const dataBitsItems = [
{ value: '7', label: '7' },
{ value: '8', label: '8' },
];
const parityItems = [
{ value: 'none', label: 'None' },
{ value: 'even', label: 'Even' },
{ value: 'odd', label: 'Odd' },
];
const stopBitsItems = [
{ value: '1', label: '1' },
{ value: '2', label: '2' },
];
async function connect() {
await serial.requestPort();
await serial.openPort($serialOptions);
}
</script>
<div class="flex flex-col p-4">
<div class="flex flex-col gap-y-1.5 pb-4">
<h3 class="leading-none font-semibold tracking-tight">串口设置</h3>
<p class="text-neutral/50">请选择串口连接相关参数</p>
</div>
<div class="flex flex-col space-y-3 pb-4">
<SerialParamSelect
id="baud-rate"
label="波特率"
items={$baudRateItems}
bind:value={$baudRateValue}
placeholder="选择波特率"
/>
<SerialParamSelect
id="data-bits"
label="数据位"
items={dataBitsItems}
bind:value={$dataBitsValue}
placeholder="选择数据位"
/>
<SerialParamSelect
id="parity"
label="校验位"
items={parityItems}
bind:value={$parityValue}
placeholder="选择校验位"
/>
<SerialParamSelect
id="stop-bits"
label="停止位"
items={stopBitsItems}
bind:value={$stopBitsValue}
placeholder="选择停止位"
/>
<div class="flex grid-cols-1 flex-col gap-4">
{#if $serialState.status === 'idle'}
{#if $serialState.port !== null}
<Button class="w-full" color="primary" onclick={connect}
>重新选择设备</Button
>
<Button
class="w-full"
color="primary"
onclick={() => {
serial.reopenPort($serialOptions);
}}>重新连接</Button
>
{:else}
<Button class="w-full" color="primary" onclick={connect}
>选择串口设备</Button
>
{/if}
{:else if $serialState.status === 'requesting' || $serialState.status === 'connecting'}
<Button class="w-full" disabled>连接中...</Button>
{:else if $serialState.status === 'connected'}
<Button class="w-full" color="error" onclick={serial.closePort}
>断开连接</Button
>
{:else}
<Button class="w-full" color="error" onclick={connect}
>连接失败,点击重试</Button
>
{/if}
</div>
</div>
</div>