init commit
This commit is contained in:
26
src/render/components/SerialPort/ManagementView/data.ts
Normal file
26
src/render/components/SerialPort/ManagementView/data.ts
Normal file
@@ -0,0 +1,26 @@
|
||||
export const BAUDRATE_OPTIONS = [
|
||||
{ label: 9600 , value: 9600 },
|
||||
{ label: 38400 , value: 38400 },
|
||||
{ label: 115200, value: 115200 },
|
||||
]
|
||||
|
||||
export const DATA_BITS_OPTIONS = [
|
||||
{ label: 8 , value: 8 },
|
||||
{ label: 7 , value: 7 },
|
||||
]
|
||||
|
||||
export const STOPBITS_OPTIONS = [
|
||||
{ label: 1 , value: 1 },
|
||||
{ label: 2 , value: 2 },
|
||||
]
|
||||
|
||||
export const PARITY_OPTIONS = [
|
||||
{ label: '无' , value: 'none' },
|
||||
{ label: '奇' , value: 'odd' },
|
||||
{ label: '偶' , value: 'even' },
|
||||
]
|
||||
|
||||
export const FLOW_CONTROL_OPTIONS = [
|
||||
{ label: '无' , value: 'none' },
|
||||
{ label: '硬件', value: 'hardware' },
|
||||
]
|
||||
1
src/render/components/SerialPort/ManagementView/index.ts
Normal file
1
src/render/components/SerialPort/ManagementView/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
export { default as SerialPortManagementView } from './index.vue'
|
||||
74
src/render/components/SerialPort/ManagementView/index.vue
Normal file
74
src/render/components/SerialPort/ManagementView/index.vue
Normal file
@@ -0,0 +1,74 @@
|
||||
<template>
|
||||
<!-- TODO: 使用form grid替换 -->
|
||||
<n-descriptions :column="1">
|
||||
<n-descriptions-item>
|
||||
<n-button :disabled="serialPort.isOpen" type="primary" @click="onSelectBtnClick">选择串口</n-button>
|
||||
</n-descriptions-item>
|
||||
<n-descriptions-item label="波特率">
|
||||
<n-select :disabled="serialPort.instance === null || serialPort.isOpen" v-model:value="serialPortOptions.baudRate" :options="BAUDRATE_OPTIONS" />
|
||||
</n-descriptions-item>
|
||||
<n-descriptions-item label="数据位">
|
||||
<n-select :disabled="serialPort.instance === null || serialPort.isOpen" v-model:value="serialPortOptions.dataBits" :options="DATA_BITS_OPTIONS" />
|
||||
</n-descriptions-item>
|
||||
<n-descriptions-item label="停止位">
|
||||
<n-select :disabled="serialPort.instance === null || serialPort.isOpen" v-model:value="serialPortOptions.stopBits" :options="STOPBITS_OPTIONS" />
|
||||
</n-descriptions-item>
|
||||
<n-descriptions-item label="奇偶校验">
|
||||
<n-select :disabled="serialPort.instance === null || serialPort.isOpen" v-model:value="serialPortOptions.parity" :options="PARITY_OPTIONS" />
|
||||
</n-descriptions-item>
|
||||
<n-descriptions-item>
|
||||
<n-button :disabled="serialPort.instance === null" type="primary" @click="onTriggerBtnClick">{{ serialPort.isOpen ? '关闭串口' : '打开串口' }}</n-button>
|
||||
</n-descriptions-item>
|
||||
</n-descriptions>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import { NDescriptions, NDescriptionsItem, NSelect, NButton, useMessage } from 'naive-ui'
|
||||
import { BAUDRATE_OPTIONS, DATA_BITS_OPTIONS, STOPBITS_OPTIONS, PARITY_OPTIONS } from './data'
|
||||
|
||||
import { useSerialPortStore } from '@/stores/serialPort'
|
||||
|
||||
const message = useMessage()
|
||||
|
||||
const serialPort = useSerialPortStore()
|
||||
|
||||
const serialPortOptions = ref({
|
||||
baudRate: BAUDRATE_OPTIONS[BAUDRATE_OPTIONS.length - 1].value,
|
||||
dataBits: DATA_BITS_OPTIONS[0].value,
|
||||
stopBits: STOPBITS_OPTIONS[0].value,
|
||||
parity : PARITY_OPTIONS[0].value,
|
||||
})
|
||||
|
||||
let closedPromise
|
||||
const openSerialPort = () => {
|
||||
closedPromise = serialPort.open(serialPortOptions.value).catch((error) => {
|
||||
console.error(error)
|
||||
message.error('打开串口失败,' + error.message)
|
||||
})
|
||||
}
|
||||
const closeSerialPort = async () => {
|
||||
try {
|
||||
await serialPort.close()
|
||||
await closedPromise
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
message.error('关闭串口失败,' + error.message)
|
||||
}
|
||||
}
|
||||
|
||||
const onSelectBtnClick = serialPort.select
|
||||
const onTriggerBtnClick = async () => {
|
||||
if (serialPort.isOpen) {
|
||||
closeSerialPort()
|
||||
} else {
|
||||
openSerialPort()
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
.n-button {
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1 @@
|
||||
export { default as SerialPortReceivingMessageView } from './index.vue';
|
||||
@@ -0,0 +1,64 @@
|
||||
<template>
|
||||
<n-card embedded title="数据接收" class="h-full">
|
||||
<div
|
||||
ref="terminalRef"
|
||||
class="h-full">
|
||||
</div>
|
||||
|
||||
<template #header-extra>
|
||||
<n-space align="center" :wrap="false">
|
||||
<n-button
|
||||
type="primary"
|
||||
size="large"
|
||||
class="primary-button"
|
||||
@click="clearBtnClick">
|
||||
清 除
|
||||
</n-button>
|
||||
<n-switch size="large" v-model:value="appending">
|
||||
<template #checked>
|
||||
接 收
|
||||
</template>
|
||||
<template #unchecked>
|
||||
暂 停
|
||||
</template>
|
||||
</n-switch>
|
||||
</n-space>
|
||||
</template>
|
||||
</n-card>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, onMounted } from 'vue'
|
||||
import { Terminal } from 'xterm'
|
||||
import { FitAddon } from 'xterm-addon-fit'
|
||||
import 'xterm/css/xterm.css'
|
||||
import { NCard, NSpace, NButton, NSwitch } from 'naive-ui'
|
||||
import { useSerialPortStore, SerialPortEventType } from '@/stores/serialPort'
|
||||
|
||||
const terminalRef = ref()
|
||||
|
||||
let term: Terminal
|
||||
const clearBtnClick = () => term?.clear()
|
||||
onMounted(() => {
|
||||
term = new Terminal({
|
||||
rows: Math.floor(terminalRef.value.clientHeight / 17)
|
||||
})
|
||||
|
||||
const fitAddon = new FitAddon();
|
||||
term.loadAddon(fitAddon)
|
||||
if (terminalRef.value) {
|
||||
term.open(terminalRef.value)
|
||||
fitAddon.fit()
|
||||
}
|
||||
})
|
||||
|
||||
const appending = ref(true)
|
||||
const onSerialPortData = (data: Uint8Array) => {
|
||||
if (!data) return
|
||||
|
||||
if (appending.value) term?.write(data)
|
||||
}
|
||||
|
||||
const serialPort = useSerialPortStore()
|
||||
serialPort.addEventListener(SerialPortEventType.data, onSerialPortData)
|
||||
</script>
|
||||
@@ -0,0 +1 @@
|
||||
export { default as SerialPortSendingMessageView } from './index.vue'
|
||||
@@ -0,0 +1,51 @@
|
||||
<template>
|
||||
<n-card embedded title="数据发送" class="h-full">
|
||||
<n-input
|
||||
v-model:value="message"
|
||||
type="textarea"
|
||||
size="large"
|
||||
placeholder="输入要发送的信息"
|
||||
class="h-full"
|
||||
:autosize="{ maxRows: 8}"
|
||||
:clearable="true"
|
||||
/>
|
||||
|
||||
<template #header-extra>
|
||||
<n-space align="center" :wrap="false">
|
||||
<n-button type="primary"
|
||||
size="large"
|
||||
:disabled="!serialPort.isOpen || message.length === 0"
|
||||
@click="sendBtnClick">
|
||||
发 送
|
||||
</n-button>
|
||||
|
||||
<slot name="extra"></slot>
|
||||
</n-space>
|
||||
</template>
|
||||
</n-card>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import { NCard, NInput, NSpace, NButton } from 'naive-ui'
|
||||
import { useSerialPortStore } from '@/stores/serialPort'
|
||||
|
||||
const message = ref('')
|
||||
|
||||
const NEWLINE_REGEXP = /\n/g
|
||||
const serialPort = useSerialPortStore()
|
||||
const sendBtnClick = async () => {
|
||||
if (!message.value) return
|
||||
const text = message.value.replace(NEWLINE_REGEXP, '\r\n') + '\r\n'
|
||||
await serialPort.write(text)
|
||||
message.value = ''
|
||||
}
|
||||
|
||||
const update = (text: string) => {
|
||||
if ( text.length <= 0 ) return
|
||||
|
||||
message.value = text
|
||||
}
|
||||
|
||||
defineExpose({ update })
|
||||
</script>
|
||||
3
src/render/components/SerialPort/index.ts
Normal file
3
src/render/components/SerialPort/index.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
export * from './ManagementView'
|
||||
export * from './SendingMessageView'
|
||||
export * from './ReceivingMessageView'
|
||||
Reference in New Issue
Block a user