fast(串口调试): 增加串口连接功能、设备参数获取写入、断路器标定功能、解决相关bug、打包1.0.6
This commit is contained in:
parent
d12381feb3
commit
1c024beeb8
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "gateway-app",
|
||||
"version": "1.0.3",
|
||||
"version": "1.0.6",
|
||||
"description": "An Electron application with Vue",
|
||||
"main": "./out/main/index.js",
|
||||
"author": "example.com",
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
[{"name":"属性1","addr":"60000","len":"2","data":"15"},{"name":"属性2","addr":"50000","len":"1","data":"1"}]
|
|
@ -1,5 +1,5 @@
|
|||
server:
|
||||
address: ":8000"
|
||||
address: ":8888"
|
||||
openapiPath: "/api.json"
|
||||
swaggerPath: "/swagger"
|
||||
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
server:
|
||||
address: ":8888"
|
||||
staticRoot: "./resource/template"
|
||||
apiPrefix: "/api/v1"
|
||||
pluginPrefix: "/plugins"
|
||||
file:
|
||||
upload_path: "./resource/upload"
|
||||
dir_mode: "byDate"
|
||||
|
||||
|
||||
|
||||
|
||||
logger:
|
||||
level: debug
|
||||
path: "./resource/logs/server.log"
|
||||
max_size: 10
|
||||
max_age: 30
|
||||
|
||||
|
||||
database:
|
||||
default:
|
||||
kind: "mysql"
|
||||
dsn: "root:mysql_YiniNx@tcp(123.60.30.87:3306)/goside?charset=utf8mb4&parseTime=True&loc=Local"
|
||||
max_idle_conns: 10
|
||||
max_open_conns: 100
|
||||
# kind: "SQLite"
|
||||
# dsn: "./resource/db/db.db"
|
||||
# max_idle_conns: 10
|
Binary file not shown.
|
@ -2,6 +2,7 @@ import { app, shell, BrowserWindow, ipcMain, globalShortcut, dialog } from 'elec
|
|||
import { join } from 'path';
|
||||
import { electronApp, optimizer, is } from '@electron-toolkit/utils';
|
||||
import icon from '../../resources/icon.png?asset';
|
||||
// const fs = require('fs');
|
||||
|
||||
//关闭exe命令
|
||||
function killProcessByName(processName) {
|
||||
|
@ -164,6 +165,44 @@ if (!gotTheLock) {
|
|||
});
|
||||
});
|
||||
|
||||
// 处理来自渲染进程的请求
|
||||
// ipcMain.handle('readFile', async (event, path) => {
|
||||
// return new Promise((resolve, reject) => {
|
||||
// fs.readFile(join(__dirname, path), 'utf8', (err, data) => {
|
||||
// if (err) {
|
||||
// reject(err);
|
||||
// } else {
|
||||
// resolve(data);
|
||||
// }
|
||||
// });
|
||||
// });
|
||||
// });
|
||||
//
|
||||
// ipcMain.handle('writeFile', async (event, path, content) => {
|
||||
// return new Promise((resolve, reject) => {
|
||||
// fs.writeFile(join(__dirname, path), content, 'utf8', (err) => {
|
||||
// if (err) {
|
||||
// reject(err);
|
||||
// } else {
|
||||
// resolve();
|
||||
// }
|
||||
// });
|
||||
// });
|
||||
// });
|
||||
//
|
||||
// // 处理来自渲染进程的请求
|
||||
// ipcMain.handle('readDirectory', async (event, directoryPath) => {
|
||||
// return new Promise((resolve, reject) => {
|
||||
// fs.readdir(join(__dirname, directoryPath), (err, files) => {
|
||||
// if (err) {
|
||||
// reject(err);
|
||||
// } else {
|
||||
// resolve(files);
|
||||
// }
|
||||
// });
|
||||
// });
|
||||
// });
|
||||
|
||||
// Quit when all windows are closed, except on macOS. There, it's common
|
||||
// for applications and their menu bar to stay active until the user quits
|
||||
// explicitly with Cmd + Q.
|
||||
|
|
|
@ -1,9 +1,21 @@
|
|||
import { contextBridge } from 'electron'
|
||||
import { contextBridge, ipcRenderer } from 'electron'
|
||||
import { electronAPI } from '@electron-toolkit/preload'
|
||||
|
||||
// Custom APIs for renderer
|
||||
// 自定义的主进程方法API
|
||||
const api = {}
|
||||
// const api = {
|
||||
// readFile: async (path) => {
|
||||
// const result = await ipcRenderer.invoke('readFile', path);
|
||||
// return result;
|
||||
// },
|
||||
// writeFile: async (path, content) => {
|
||||
// await ipcRenderer.invoke('writeFile', path, content);
|
||||
// },
|
||||
// readDirectory: async (directoryPath) => {
|
||||
// const result = await ipcRenderer.invoke('readDirectory', directoryPath);
|
||||
// return result;
|
||||
// }
|
||||
// }
|
||||
|
||||
// Use `contextBridge` APIs to expose Electron APIs to
|
||||
// renderer only if context isolation is enabled, otherwise
|
||||
|
@ -12,11 +24,11 @@ const api = {}
|
|||
if (process.contextIsolated) {
|
||||
try {
|
||||
contextBridge.exposeInMainWorld('electron', electronAPI)
|
||||
contextBridge.exposeInMainWorld('api', api)
|
||||
// contextBridge.exposeInMainWorld('api', api)
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
}
|
||||
} else {
|
||||
window.electron = electronAPI
|
||||
window.api = api
|
||||
// window.api = api
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
@font-face {
|
||||
font-family: "iconfont"; /* Project id 4622943 */
|
||||
src: url('iconfont.woff2?t=1721353754291') format('woff2'),
|
||||
url('iconfont.woff?t=1721353754291') format('woff'),
|
||||
url('iconfont.ttf?t=1721353754291') format('truetype');
|
||||
src: url('iconfont.woff2?t=1729646274723') format('woff2'),
|
||||
url('iconfont.woff?t=1729646274723') format('woff'),
|
||||
url('iconfont.ttf?t=1729646274723') format('truetype');
|
||||
}
|
||||
|
||||
.iconfont {
|
||||
|
@ -13,6 +13,26 @@
|
|||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
.icon-com001:before {
|
||||
content: "\e62c";
|
||||
}
|
||||
|
||||
.icon-chuankou:before {
|
||||
content: "\e6be";
|
||||
}
|
||||
|
||||
.icon-chuankou1:before {
|
||||
content: "\e60a";
|
||||
}
|
||||
|
||||
.icon-chuankoushezhi:before {
|
||||
content: "\e600";
|
||||
}
|
||||
|
||||
.icon-chuankou2:before {
|
||||
content: "\e6fc";
|
||||
}
|
||||
|
||||
.icon-shousuoshangjiantou:before {
|
||||
content: "\e9b6";
|
||||
}
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -10,7 +10,9 @@ const settings = defineProps({
|
|||
<el-scrollbar>
|
||||
<el-menu default-active="/system/switch" :collapse="settings.collapse" :router="true">
|
||||
<el-menu-item index="/system/switch"> <span class="iconfont icon-icon_duanluqi"></span> 断路器调试</el-menu-item>
|
||||
<el-menu-item index="/system/videoplayer"><span class="iconfont icon-icon_jiankong"></span> 视频监控</el-menu-item>
|
||||
<el-menu-item index="/system/videoplayer"><span class="iconfont icon-icon_jiankong"></span> 视频监控</el-menu-item>
|
||||
<el-menu-item index="/system/serialport"><span class="iconfont icon-chuankou2"></span> 设备参数读写</el-menu-item>
|
||||
<el-menu-item index="/system/devicestandard"><span class="iconfont icon-icon_chajian"></span> 空开标定</el-menu-item>
|
||||
<!-- <el-menu-item index="/system/test"><el-icon> <Menu /> </el-icon>测试</el-menu-item>-->
|
||||
</el-menu>
|
||||
</el-scrollbar>
|
||||
|
@ -36,7 +38,7 @@ const settings = defineProps({
|
|||
color: #333;
|
||||
font-size: 16px;
|
||||
.iconfont {
|
||||
margin-right: 10px;
|
||||
margin-right: 6px;
|
||||
color: #999;
|
||||
font-size: 22px;
|
||||
}
|
||||
|
|
|
@ -26,12 +26,30 @@ const router = createRouter({
|
|||
keepAlive: true
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'videoplayer',
|
||||
name: 'videoplayer',
|
||||
component: () => import('@renderer/views/system/videoplayer/index.vue'),
|
||||
meta: {
|
||||
menu: 'videoplayer',
|
||||
keepAlive: true
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'serialport',
|
||||
name: 'serialport',
|
||||
component: () => import('@renderer/views/system/serialport/index.vue'),
|
||||
meta: {
|
||||
menu: 'serialport',
|
||||
keepAlive: true
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'videoplayer',
|
||||
name: 'videoplayer',
|
||||
component: () => import('@renderer/views/system/videoplayer/index.vue'),
|
||||
path: 'devicestandard',
|
||||
name: 'devicestandard',
|
||||
component: () => import('@renderer/views/system/serialport/devicestandard.vue'),
|
||||
meta: {
|
||||
menu: 'videoplayer',
|
||||
menu: 'devicestandard',
|
||||
keepAlive: true
|
||||
}
|
||||
},
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
import { defineStore } from 'pinia';
|
||||
|
||||
export const useSerialPortStore = defineStore('seralPort', {
|
||||
state: () => ({
|
||||
serialport: {
|
||||
port: '',
|
||||
baudrate: 115200,
|
||||
databits: 8,
|
||||
parity: 0,
|
||||
stopbits: 0
|
||||
}
|
||||
}),
|
||||
actions: {
|
||||
setSerialport(data) {
|
||||
this.serialport = data;
|
||||
}
|
||||
}
|
||||
});
|
|
@ -17,9 +17,14 @@
|
|||
// }
|
||||
|
||||
export default {
|
||||
url: 'http://127.0.0.1:8000',
|
||||
wsUrl: 'ws://127.0.0.1:8000',
|
||||
url: 'http://127.0.0.1:8888',
|
||||
wsUrl: 'ws://127.0.0.1:8888',
|
||||
swichWsUrl: 'ws://127.0.0.1:8001',
|
||||
serialPortUrl: 'http://127.0.0.1:8888',
|
||||
|
||||
// 远程连接串口使用
|
||||
// serialPortUrl: 'http://120.77.172.42:7202',
|
||||
// serialPortUrl: 'http://192.168.1.17:8888',
|
||||
}
|
||||
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,760 @@
|
|||
<template>
|
||||
<div id="serialport-box">
|
||||
<div id="serialport-main" class="serialport-main">
|
||||
<el-collapse v-model="activeFold" @change="foldChange">
|
||||
<el-collapse-item name="1" title="串口设置">
|
||||
<el-form ref="serialportFormRef" :model="serialportForm" :rules="serialportRules" class="demo-serialportForm" label-width="auto" status-icon>
|
||||
<el-form-item label="端口" prop="port" required >
|
||||
<el-select v-model="serialportForm.port" :disabled="connectionState" placeholder="选择端口" style="flex: 1">
|
||||
<el-option v-for="(item, index) in serialportList" :key="index" :label="item" :value="item" />
|
||||
</el-select>
|
||||
<el-button style="margin-left: 10px" type="primary" @click="getSerialPortList">获取端口列表</el-button>
|
||||
</el-form-item>
|
||||
<el-form-item label="波特率" prop="baudrate" required>
|
||||
<el-select v-model="serialportForm.baudrate" :disabled="connectionState" placeholder="选择波特率">
|
||||
<el-option label="4800" :value="4800" />
|
||||
<el-option label="9600" :value="9600" />
|
||||
<el-option label="19200" :value="19200" />
|
||||
<el-option label="43000" :value="43000" />
|
||||
<el-option label="56000" :value="56000" />
|
||||
<el-option label="115200" :value="115200" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="数据位" prop="databits" required>
|
||||
<el-select v-model="serialportForm.databits" :disabled="connectionState" placeholder="选择数据位">
|
||||
<el-option label="5" :value="5" />
|
||||
<el-option label="6" :value="6" />
|
||||
<el-option label="7" :value="7" />
|
||||
<el-option label="8" :value="8" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="校验位" prop="parity" required>
|
||||
<el-select v-model="serialportForm.parity" :disabled="connectionState" placeholder="选择校验位">
|
||||
<el-option label="None" :value="0" />
|
||||
<el-option label="Odd" :value="1" />
|
||||
<el-option label="Even" :value="2" />
|
||||
<el-option label="Mark" :value="3" />
|
||||
<el-option label="Space" :value="4" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="停止位" prop="stopbits" required>
|
||||
<el-select v-model="serialportForm.stopbits" :disabled="connectionState" placeholder="选择停止位">
|
||||
<el-option label="1" :value="0" />
|
||||
<el-option label="1.5" :value="1" />
|
||||
<el-option label="2" :value="2" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item class="btn-box">
|
||||
<el-button type="danger" @click="disconnSerialPort">关闭 </el-button>
|
||||
<el-button type="primary" @click="connectSerialPort(serialportFormRef)">{{ connectionState ? '已打开' : '打开' }}</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-collapse-item>
|
||||
<!-- <el-collapse-item name="2" title="通用调试">-->
|
||||
<!-- <el-form ref="commonDebuggerFormRef" :model="commonDebuggerForm" :rules="commonDebuggerRules" class="demo-serialportForm" label-width="auto" status-icon>-->
|
||||
<!-- <el-form-item label="数据类型" prop="dataType">-->
|
||||
<!-- <el-input-->
|
||||
<!-- </el-form-item>-->
|
||||
<!-- <el-form-item label="端口" prop="port" required >-->
|
||||
<!-- <el-select v-model="commonDebuggerForm.port" :disabled="connectionState" placeholder="选择端口" style="flex: 1">-->
|
||||
<!-- <el-option v-for="(item, index) in serialportList" :key="index" :label="item" :value="item" />-->
|
||||
<!-- </el-select>-->
|
||||
<!-- <el-button style="margin-left: 10px" type="primary" @click="getSerialPortList">获取端口列表</el-button>-->
|
||||
<!-- </el-form-item>-->
|
||||
<!-- <el-form-item label="波特率" prop="baudrate" required>-->
|
||||
<!-- <el-select v-model="commonDebuggerForm.baudrate" :disabled="connectionState" placeholder="选择波特率">-->
|
||||
<!-- <el-option label="4800" :value="4800" />-->
|
||||
<!-- <el-option label="9600" :value="9600" />-->
|
||||
<!-- <el-option label="19200" :value="19200" />-->
|
||||
<!-- <el-option label="43000" :value="43000" />-->
|
||||
<!-- <el-option label="56000" :value="56000" />-->
|
||||
<!-- <el-option label="115200" :value="115200" />-->
|
||||
<!-- </el-select>-->
|
||||
<!-- </el-form-item>-->
|
||||
<!-- <el-form-item label="数据位" prop="databits" required>-->
|
||||
<!-- <el-select v-model="commonDebuggerForm.databits" :disabled="connectionState" placeholder="选择数据位">-->
|
||||
<!-- <el-option label="5" :value="5" />-->
|
||||
<!-- <el-option label="6" :value="6" />-->
|
||||
<!-- <el-option label="7" :value="7" />-->
|
||||
<!-- <el-option label="8" :value="8" />-->
|
||||
<!-- </el-select>-->
|
||||
<!-- </el-form-item>-->
|
||||
<!-- <el-form-item label="校验位" prop="parity" required>-->
|
||||
<!-- <el-select v-model="commonDebuggerForm.parity" :disabled="connectionState" placeholder="选择校验位">-->
|
||||
<!-- <el-option label="None" :value="0" />-->
|
||||
<!-- <el-option label="Odd" :value="1" />-->
|
||||
<!-- <el-option label="Even" :value="2" />-->
|
||||
<!-- <el-option label="Mark" :value="3" />-->
|
||||
<!-- <el-option label="Space" :value="4" />-->
|
||||
<!-- </el-select>-->
|
||||
<!-- </el-form-item>-->
|
||||
<!-- <el-form-item label="停止位" prop="stopbits" required>-->
|
||||
<!-- <el-select v-model="commonDebuggerForm.stopbits" :disabled="connectionState" placeholder="选择停止位">-->
|
||||
<!-- <el-option label="1" :value="0" />-->
|
||||
<!-- <el-option label="1.5" :value="1" />-->
|
||||
<!-- <el-option label="2" :value="2" />-->
|
||||
<!-- </el-select>-->
|
||||
<!-- </el-form-item>-->
|
||||
<!-- <el-form-item class="btn-box">-->
|
||||
<!-- <el-button type="danger" @click="disconnSerialPort">关闭 </el-button>-->
|
||||
<!-- <el-button type="primary" @click="connectSerialPort(serialportFormRef)">{{ connectionState ? '已打开' : '打开' }}</el-button>-->
|
||||
<!-- </el-form-item>-->
|
||||
<!-- </el-form>-->
|
||||
<!-- </el-collapse-item>-->
|
||||
<el-collapse-item name="3" title="设备基础参数">
|
||||
<div class="device-attr-list">
|
||||
<div v-for="(item, index) in deviceAttrList" :key="item.id" class="device-attr-item">
|
||||
<div class="device-attr-item-name">{{ item.name }}</div>
|
||||
<div class="device-attr-item-value">
|
||||
<el-input v-model="item.outputValue" class="device-attr-input" disabled />
|
||||
<el-button type="primary" :loading="item.outputLoadingStatus" @click="sendDeviceAttr(item, 'output', index)">读取</el-button>
|
||||
</div>
|
||||
<div class="device-attr-item-value">
|
||||
<el-input v-model="item.inputValue" :disabled="item.inputDisable" class="device-attr-input" />
|
||||
<el-button type="primary" :disabled="item.inputDisable" :loading="item.inputLoadingStatus" @click="sendDeviceAttr(item, 'input', index)">写入</el-button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="btn-box">
|
||||
<el-button type="primary" @click="allReadDeviceAttr">一键读取</el-button>
|
||||
<el-button type="primary" @click="allWriteDeviceAttr">一键写入</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</el-collapse-item>
|
||||
</el-collapse>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import axios from 'axios'; // 引入axios
|
||||
import config from '@renderer/util/config.js';
|
||||
|
||||
import { reactive, ref, onMounted, onUnmounted,watch } from 'vue';
|
||||
import { ElMessage } from 'element-plus';
|
||||
import { buildHead, hexToString, hexToVersion, rearrangeHexStr, versionToHex } from "./js/fun"
|
||||
import { useSerialPortStore } from '@renderer/stores/seralPort.js';
|
||||
|
||||
|
||||
const useseralPortStore = useSerialPortStore();
|
||||
const activeFold = ref(['1', '2', '3']);
|
||||
|
||||
//连接状态
|
||||
const connectionState = ref(false);
|
||||
|
||||
const serialportFormRef = ref();
|
||||
|
||||
const serialportList = ref([]);
|
||||
|
||||
const serialportForm = reactive({
|
||||
port: '',
|
||||
baudrate: 115200,
|
||||
databits: 8,
|
||||
parity: 0,
|
||||
stopbits: 0
|
||||
});
|
||||
|
||||
// 监听 serialportForm 的变化
|
||||
watch(() => ({ ...serialportForm }), (newVal) => {
|
||||
// 将新的值存储到 localStorage 中
|
||||
newVal.port = newVal.port.toLowerCase();
|
||||
useseralPortStore.setSerialport(newVal);
|
||||
// localStorage.setItem('serialportForm', newVal);
|
||||
}, { deep: true });
|
||||
|
||||
|
||||
|
||||
const serialportRules = reactive({
|
||||
port: [{ required: true, message: '请选择端口', trigger: 'change' }],
|
||||
baudrate: [{ required: true, message: '请选择波特率', trigger: 'change' }],
|
||||
databits: [{ required: true, message: '请选择port', trigger: 'change' }],
|
||||
parity: [{ required: true, message: '请选择userName', trigger: 'change' }],
|
||||
stopbits: [{ required: true, message: '请选择passWord', trigger: 'change' }]
|
||||
});
|
||||
|
||||
//获取端口列表
|
||||
const getSerialPortList = (msgShow = true) => {
|
||||
axios
|
||||
.get(config.serialPortUrl + '/serial/list', {})
|
||||
.then(response => {
|
||||
// 成功响应后的处理
|
||||
if (response.data.code === 0) {
|
||||
serialportList.value = response.data.data.List || [];
|
||||
if(msgShow){
|
||||
ElMessage.success('获取端口列表成功');
|
||||
}
|
||||
} else {
|
||||
ElMessage.error(response.data.message);
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
// 错误处理
|
||||
ElMessage.error(error);
|
||||
});
|
||||
};
|
||||
|
||||
//打开
|
||||
const connectSerialPort = formEl => {
|
||||
if (!formEl) return;
|
||||
formEl.validate(valid => {
|
||||
if (valid) {
|
||||
serialportForm.port = serialportForm.port.toLowerCase();
|
||||
axios
|
||||
.post(config.serialPortUrl + '/serial/open', serialportForm)
|
||||
.then(response => {
|
||||
// 成功响应后的处理
|
||||
console.log(response); // 打印响应数据
|
||||
if (response.data.code === 0) {
|
||||
ElMessage.success('打开成功');
|
||||
connectionState.value = true;
|
||||
} else {
|
||||
if (response.data.code === 60) {
|
||||
connectionState.value = false;
|
||||
}
|
||||
ElMessage.error(response.data.message);
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
// 错误处理
|
||||
if (error.response.data.message) {
|
||||
ElMessage.error(error.response.data.message);
|
||||
} else {
|
||||
ElMessage.error(error);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
//关闭串口
|
||||
const disconnSerialPort = () => {
|
||||
serialportForm.port = serialportForm.port.toLowerCase();
|
||||
axios
|
||||
.get(config.serialPortUrl + '/serial/close', {
|
||||
params: {
|
||||
port: serialportForm.port
|
||||
}
|
||||
})
|
||||
.then(response => {
|
||||
// 成功响应后的处理
|
||||
if (response.data.code === 0) {
|
||||
connectionState.value = false;
|
||||
ElMessage.success('关闭成功');
|
||||
} else {
|
||||
ElMessage.error(response.data.message);
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
// 错误处理
|
||||
ElMessage.error(error);
|
||||
});
|
||||
};
|
||||
const deviceAttrCommonList = ref({
|
||||
input: {
|
||||
//数据长度类型
|
||||
datalentype: '00',
|
||||
//目标ID
|
||||
remote_id: '0',
|
||||
//本地ID
|
||||
local_id: '0',
|
||||
//指令码
|
||||
cmd: '0100',
|
||||
//设备类型
|
||||
devtype: '00',
|
||||
//数据类型
|
||||
datatype: '00'
|
||||
},
|
||||
output: {
|
||||
//数据长度类型
|
||||
datalentype: '00',
|
||||
//目标ID
|
||||
remote_id: '0',
|
||||
//本地ID
|
||||
local_id: '0',
|
||||
//指令码
|
||||
cmd: '0011',
|
||||
//设备类型
|
||||
devtype: '00',
|
||||
//数据类型
|
||||
datatype: '00'
|
||||
}
|
||||
});
|
||||
|
||||
const deviceAttrList = ref([
|
||||
{
|
||||
id: 1,
|
||||
name: '芯片ID',
|
||||
startValue: 0,
|
||||
lengthValue: 4,
|
||||
inputValue: '',
|
||||
inputLoadingStatus: false,
|
||||
outputValue: '',
|
||||
outputLoadingStatus: false,
|
||||
dataType: 'hex',
|
||||
inputDisable: false
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
name: '设备序列号(SN)',
|
||||
startValue: 4,
|
||||
lengthValue: 8,
|
||||
inputValue: '',
|
||||
inputLoadingStatus: false,
|
||||
outputValue: '',
|
||||
outputLoadingStatus: false,
|
||||
dataType: 'str',
|
||||
inputDisable: false
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
name: '产品主型号',
|
||||
startValue: 12,
|
||||
lengthValue: 3,
|
||||
inputValue: '',
|
||||
inputLoadingStatus: false,
|
||||
outputValue: '',
|
||||
outputLoadingStatus: false,
|
||||
dataType: 'str',
|
||||
inputDisable: false
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
name: '产品次型号',
|
||||
startValue: 15,
|
||||
lengthValue: 5,
|
||||
inputValue: '',
|
||||
inputLoadingStatus: false,
|
||||
outputValue: '',
|
||||
outputLoadingStatus: false,
|
||||
dataType: 'str',
|
||||
inputDisable: false
|
||||
},
|
||||
{
|
||||
id: 5,
|
||||
name: '产品密钥',
|
||||
startValue: 20,
|
||||
lengthValue: 8,
|
||||
inputValue: '',
|
||||
inputLoadingStatus: false,
|
||||
outputValue: '',
|
||||
outputLoadingStatus: false,
|
||||
dataType: 'str',
|
||||
inputDisable: false
|
||||
},
|
||||
{
|
||||
id: 6,
|
||||
name: '主板序列号',
|
||||
startValue: 28,
|
||||
lengthValue: 8,
|
||||
inputValue: '',
|
||||
inputLoadingStatus: false,
|
||||
outputValue: '',
|
||||
outputLoadingStatus: false,
|
||||
dataType: 'str',
|
||||
inputDisable: false
|
||||
},
|
||||
{
|
||||
id: 7,
|
||||
name: '69序列号',
|
||||
startValue: 36,
|
||||
lengthValue: 8,
|
||||
inputValue: '',
|
||||
inputLoadingStatus: false,
|
||||
outputValue: '',
|
||||
outputLoadingStatus: false,
|
||||
dataType: 'str',
|
||||
inputDisable: false
|
||||
},
|
||||
{
|
||||
id: 8,
|
||||
name: '通信版本号',
|
||||
startValue: 44,
|
||||
lengthValue: 1,
|
||||
inputValue: '',
|
||||
inputLoadingStatus: false,
|
||||
outputValue: '',
|
||||
outputLoadingStatus: false,
|
||||
dataType: 'firmware',
|
||||
inputDisable: true
|
||||
},
|
||||
{
|
||||
id: 9,
|
||||
name: '软件固件号',
|
||||
startValue: 45,
|
||||
lengthValue: 1,
|
||||
inputValue: '',
|
||||
inputLoadingStatus: false,
|
||||
outputValue: '',
|
||||
outputLoadingStatus: false,
|
||||
dataType: 'firmware',
|
||||
inputDisable: true
|
||||
}
|
||||
]);
|
||||
|
||||
//解码
|
||||
const analysisData = (hexData, data) => {
|
||||
if (hexData.length < 28) {
|
||||
console.log('返回hex小于28个字符串', hexData);
|
||||
return '';
|
||||
} else {
|
||||
// let head = hexData.substring(0,8);
|
||||
// let startAddr = hexData.substring(8,16);
|
||||
// let len = hexData.substring(16,24);
|
||||
let hexValue = hexData.substring(24, data.lengthValue * 4 * 2 + 24);
|
||||
// let crc = hexData.substring(hexData.length - 4);
|
||||
if (data.dataType === 'str') {
|
||||
let str = hexToString(hexValue).trim();
|
||||
return str;
|
||||
}
|
||||
else if(data.dataType === 'hex'){
|
||||
let str = rearrangeHexStr(hexValue);
|
||||
return str;
|
||||
}
|
||||
// else if(data.dataType === 'firmware'){
|
||||
// let str = hexToVersion(hexValue);
|
||||
// return str;
|
||||
// }
|
||||
else {
|
||||
return hexValue;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const sendDeviceAttr = (data, type, index) => {
|
||||
if (!serialportForm.port) {
|
||||
ElMessage.error('请先打开串口');
|
||||
return '';
|
||||
}
|
||||
console.log('readDeviceAttr', data);
|
||||
|
||||
let head = buildHead(
|
||||
deviceAttrCommonList.value[type].datalentype,
|
||||
deviceAttrCommonList.value[type].remote_id,
|
||||
deviceAttrCommonList.value[type].local_id,
|
||||
deviceAttrCommonList.value[type].cmd,
|
||||
deviceAttrCommonList.value[type].devtype,
|
||||
deviceAttrCommonList.value[type].datatype,
|
||||
data.startValue,
|
||||
data.lengthValue,
|
||||
data.inputValue,
|
||||
data
|
||||
);
|
||||
|
||||
if (type === 'input') {
|
||||
deviceAttrList.value[index].inputLoadingStatus = true;
|
||||
// head = head + 'd240';
|
||||
} else {
|
||||
deviceAttrList.value[index].outputLoadingStatus = true;
|
||||
}
|
||||
axios
|
||||
.post(
|
||||
config.serialPortUrl + '/serial/response',
|
||||
{
|
||||
port: serialportForm.port,
|
||||
data: head,
|
||||
hex: 1,
|
||||
crc: 1,
|
||||
flush:1
|
||||
},
|
||||
{
|
||||
headers: {
|
||||
'Content-Type': 'application/x-www-form-urlencoded'
|
||||
}
|
||||
}
|
||||
)
|
||||
.then(response => {
|
||||
// 成功响应后的处理
|
||||
console.log('串口请求', response); // 打印响应数据
|
||||
if (response.data.code === 0) {
|
||||
ElMessage.success('操作成功');
|
||||
if (type === 'output') {
|
||||
deviceAttrList.value[index].outputValue = analysisData(response.data.data.hex || '', data);
|
||||
}
|
||||
} else {
|
||||
ElMessage.error(response.data.message);
|
||||
}
|
||||
if (type === 'input') {
|
||||
deviceAttrList.value[index].inputLoadingStatus = false;
|
||||
} else {
|
||||
deviceAttrList.value[index].outputLoadingStatus = false;
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.log('error', error);
|
||||
if (type === 'input') {
|
||||
deviceAttrList.value[index].inputLoadingStatus = false;
|
||||
} else {
|
||||
deviceAttrList.value[index].outputLoadingStatus = false;
|
||||
}
|
||||
// 错误处理
|
||||
if (error.response.data.message) {
|
||||
ElMessage.error(error.response.data.message);
|
||||
} else {
|
||||
ElMessage.error(error);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const allReadDeviceAttr = () => {
|
||||
if (!serialportForm.port) {
|
||||
ElMessage.error('请先打开串口');
|
||||
return '';
|
||||
}
|
||||
|
||||
let head = buildHead(
|
||||
deviceAttrCommonList.value['output'].datalentype,
|
||||
deviceAttrCommonList.value['output'].remote_id,
|
||||
deviceAttrCommonList.value['output'].local_id,
|
||||
deviceAttrCommonList.value['output'].cmd,
|
||||
deviceAttrCommonList.value['output'].devtype,
|
||||
deviceAttrCommonList.value['output'].datatype,
|
||||
0,
|
||||
46,
|
||||
''
|
||||
);
|
||||
|
||||
axios
|
||||
.post(
|
||||
config.serialPortUrl + '/serial/response',
|
||||
{
|
||||
port: serialportForm.port,
|
||||
data: head,
|
||||
hex: 1,
|
||||
crc: 1,
|
||||
flush:1
|
||||
},
|
||||
{
|
||||
headers: {
|
||||
'Content-Type': 'application/x-www-form-urlencoded'
|
||||
}
|
||||
}
|
||||
)
|
||||
.then(response => {
|
||||
// 成功响应后的处理
|
||||
console.log('串口请求', response); // 打印响应数据
|
||||
if (response.data.code === 0) {
|
||||
ElMessage.success('操作成功');
|
||||
let hexValue = response.data.data.hex.substring(24, 392);
|
||||
let startValue = 0;
|
||||
deviceAttrList.value.forEach((item, index) => {
|
||||
if(startValue === 0){
|
||||
startValue = item.startValue;
|
||||
}
|
||||
let value = hexValue.substring(startValue, item.lengthValue * 4 * 2 + startValue);
|
||||
startValue = startValue + item.lengthValue * 4 * 2;
|
||||
console.log("value",value)
|
||||
if (item.dataType === 'str') {
|
||||
deviceAttrList.value[index].outputValue = hexToString(value).trim();
|
||||
deviceAttrList.value[index].inputValue = hexToString(value).trim();
|
||||
}else if (item.dataType === 'hex') {
|
||||
deviceAttrList.value[index].outputValue = rearrangeHexStr(value);
|
||||
deviceAttrList.value[index].inputValue = rearrangeHexStr(value);
|
||||
}else{
|
||||
deviceAttrList.value[index].outputValue = value;
|
||||
deviceAttrList.value[index].inputValue = value;
|
||||
}
|
||||
})
|
||||
// deviceAttrList.value[index].outputValue = analysisData(response.data.data.hex || '', data);
|
||||
} else {
|
||||
ElMessage.error(response.data.message);
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.log('error', error);
|
||||
// 错误处理
|
||||
if (error.response.data.message) {
|
||||
ElMessage.error(error.response.data.message);
|
||||
} else {
|
||||
ElMessage.error(error);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
const allWriteDeviceAttr = () => {
|
||||
if (!serialportForm.port) {
|
||||
ElMessage.error('请先打开串口');
|
||||
return '';
|
||||
}
|
||||
deviceAttrList.value.forEach((item, index)=>{
|
||||
setTimeout(()=>{
|
||||
sendDeviceAttr(item, 'input', index)
|
||||
},50)
|
||||
})
|
||||
|
||||
// let head = buildHead(
|
||||
// deviceAttrCommonList.value['input'].datalentype,
|
||||
// deviceAttrCommonList.value['input'].remote_id,
|
||||
// deviceAttrCommonList.value['input'].local_id,
|
||||
// deviceAttrCommonList.value['input'].cmd,
|
||||
// deviceAttrCommonList.value['input'].devtype,
|
||||
// deviceAttrCommonList.value['input'].datatype,
|
||||
// 0,
|
||||
// 46,
|
||||
// ''
|
||||
// );
|
||||
//
|
||||
// axios
|
||||
// .post(
|
||||
// config.serialPortUrl + '/serial/response',
|
||||
// {
|
||||
// port: serialportForm.port,
|
||||
// data: head,
|
||||
// hex: 1,
|
||||
// crc: 1
|
||||
// },
|
||||
// {
|
||||
// headers: {
|
||||
// 'Content-Type': 'application/x-www-form-urlencoded'
|
||||
// }
|
||||
// }
|
||||
// )
|
||||
// .then(response => {
|
||||
// // 成功响应后的处理
|
||||
// console.log('串口请求', response); // 打印响应数据
|
||||
// if (response.data.code === 0) {
|
||||
// ElMessage.success('操作成功');
|
||||
// let hexValue = response.data.data.hex.substring(24, 392);
|
||||
// let startValue = 0;
|
||||
// deviceAttrList.value.forEach((item, index) => {
|
||||
// if(startValue === 0){
|
||||
// startValue = item.startValue;
|
||||
// }
|
||||
// let value = hexValue.substring(startValue, item.lengthValue * 4 * 2 + startValue);
|
||||
// startValue = startValue + item.lengthValue * 4 * 2;
|
||||
// console.log("value",value)
|
||||
// if (item.dataType === 'str') {
|
||||
// deviceAttrList.value[index].outputValue = hexToString(value).trim();
|
||||
// deviceAttrList.value[index].inputValue = hexToString(value).trim();
|
||||
// }else{
|
||||
// deviceAttrList.value[index].outputValue = value;
|
||||
// deviceAttrList.value[index].inputValue = value;
|
||||
// }
|
||||
// })
|
||||
// // deviceAttrList.value[index].outputValue = analysisData(response.data.data.hex || '', data);
|
||||
// } else {
|
||||
// ElMessage.error(response.data.message);
|
||||
// }
|
||||
// })
|
||||
// .catch(error => {
|
||||
// console.log('error', error);
|
||||
// // 错误处理
|
||||
// if (error.response.data.message) {
|
||||
// ElMessage.error(error.response.data.message);
|
||||
// } else {
|
||||
// ElMessage.error(error);
|
||||
// }
|
||||
// });
|
||||
}
|
||||
|
||||
|
||||
// const commonDebuggerFormRef = ref();
|
||||
//
|
||||
// const commonDebuggerList = ref([]);
|
||||
//
|
||||
// const commonDebuggerForm = reactive({
|
||||
// localId:'',
|
||||
// port: '',
|
||||
// baudrate: 115200,
|
||||
// databits: 8,
|
||||
// parity: 0,
|
||||
// stopbits: 0
|
||||
// });
|
||||
//
|
||||
// const commonDebuggerRules = reactive({
|
||||
// port: [{ required: true, message: '请选择端口', trigger: 'change' }],
|
||||
// baudrate: [{ required: true, message: '请选择波特率', trigger: 'change' }],
|
||||
// databits: [{ required: true, message: '请选择port', trigger: 'change' }],
|
||||
// parity: [{ required: true, message: '请选择userName', trigger: 'change' }],
|
||||
// stopbits: [{ required: true, message: '请选择passWord', trigger: 'change' }]
|
||||
// });
|
||||
|
||||
// 生命周期钩子
|
||||
onMounted(() => {
|
||||
getSerialPortList(false);
|
||||
});
|
||||
|
||||
onUnmounted(() => {});
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
/* 样式可以在这里定义 */
|
||||
#serialport-box {
|
||||
height: 100%;
|
||||
position: relative;
|
||||
padding-bottom: 5px;
|
||||
.serialport-main {
|
||||
height: calc(100% - 60px);
|
||||
overflow-y: auto;
|
||||
border-radius: 10px;
|
||||
background: #f2f2f2;
|
||||
&.open-log {
|
||||
height: calc(50% - 42px);
|
||||
}
|
||||
}
|
||||
.device-attr-list {
|
||||
padding: 20px 10px;
|
||||
.device-attr-item {
|
||||
display: flex;
|
||||
.device-attr-item-name {
|
||||
width: 120px;
|
||||
}
|
||||
.device-attr-item-value {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 5px;
|
||||
.device-attr-input {
|
||||
margin-right: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.btn-box{
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
padding: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.el-form) {
|
||||
padding: 20px 20px 0;
|
||||
}
|
||||
|
||||
:deep(.el-tabs--border-card > .el-tabs__content) {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
:deep(.el-collapse-item__header) {
|
||||
//height: 42px;
|
||||
//line-height: 42px;
|
||||
}
|
||||
|
||||
:deep(.el-collapse-item__content) {
|
||||
padding-bottom: 0;
|
||||
}
|
||||
:deep(.el-tabs__content) {
|
||||
background: #f2f2f2;
|
||||
}
|
||||
:deep(.el-tabs__item) {
|
||||
background: #e6e6e6;
|
||||
&.is-active {
|
||||
background: #f2f2f2;
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.log-box-search .el-input__wrapper) {
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
:deep(.log-box-search .el-select__wrapper) {
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.btn-box {
|
||||
:deep(.el-form-item__content) {
|
||||
justify-content: end;
|
||||
width: 100%;
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,296 @@
|
|||
/*
|
||||
* @Descripttion:
|
||||
* @version:
|
||||
* @Author: lfzxs@qq.com
|
||||
* @Date: 2024-10-16 13:52:11
|
||||
* @LastEditors: lfzxs@qq.com
|
||||
* @LastEditTime: 2024-10-18 16:33:31
|
||||
*/
|
||||
|
||||
export function buildHead(d_length,d_remote_id,d_local_id,d_cmd,d_dev_type,d_data_type,dataStart,dataLength,dataValue,activeData) {
|
||||
// 初始化data为一个32位2进制数
|
||||
|
||||
let data = "0000" + d_data_type + d_dev_type + d_cmd + toBinaryString(d_local_id,9) + toBinaryString(d_remote_id,9) + d_length;
|
||||
|
||||
console.log("获取头部",data);
|
||||
|
||||
let hex_data = binaryToHex(data);
|
||||
let dataBuffer = '';
|
||||
let buffer = hexToBuffer(hex_data);
|
||||
//根据d_cmd的值拼接命令格式
|
||||
switch (d_cmd) {
|
||||
case "0000"://特殊指令
|
||||
break;
|
||||
case "0011"://地址读
|
||||
buffer = concatenateBuffers(htonl(buffer),htonl(toFixedSizeBuffer(parseInt(dataStart),4)),htonl(toFixedSizeBuffer(parseInt(dataLength),4)));
|
||||
break;
|
||||
case "0100"://地址写
|
||||
|
||||
if(activeData.dataType === 'hex'){
|
||||
dataValue = rearrangeHexStr(dataValue);
|
||||
dataBuffer = hexToBuffer(dataValue);
|
||||
}else if(activeData.dataType === 'hexString'){
|
||||
dataBuffer = hexToBuffer(dataValue);
|
||||
}else{
|
||||
dataBuffer = stringToHexBuffer(dataValue,dataLength*4*2);
|
||||
}
|
||||
console.log("dataBuffer",dataBuffer)
|
||||
buffer = concatenateBuffers(htonl(buffer),htonl(toFixedSizeBuffer(parseInt(dataStart),4)),htonl(toFixedSizeBuffer(parseInt(dataLength),4)),dataBuffer)
|
||||
break;
|
||||
}
|
||||
console.log("dataValue-buffer",dataValue,buffer)
|
||||
|
||||
let result = bufferToHex(buffer);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
export function allBuildHead(d_length,d_remote_id,d_local_id,d_cmd,d_dev_type,d_data_type,dataStart,dataLength,dataValue,allList) {
|
||||
// 初始化data为一个32位2进制数
|
||||
|
||||
let data = "0000" + d_data_type + d_dev_type + d_cmd + toBinaryString(d_local_id,9) + toBinaryString(d_remote_id,9) + d_length;
|
||||
|
||||
console.log("获取头部",data);
|
||||
|
||||
let hex_data = binaryToHex(data);
|
||||
|
||||
let buffer = hexToBuffer(hex_data);
|
||||
let allBufferList = [];
|
||||
//根据d_cmd的值拼接命令格式
|
||||
switch (d_cmd) {
|
||||
case "0000"://特殊指令
|
||||
break;
|
||||
case "0011"://地址读
|
||||
buffer = concatenateBuffers(htonl(buffer),htonl(toFixedSizeBuffer(parseInt(dataStart),4)),htonl(toFixedSizeBuffer(parseInt(dataLength),4)));
|
||||
break;
|
||||
case "0100"://地址写
|
||||
allBufferList = allList.map(item=>{
|
||||
return stringToHexBuffer(item.inputValue,item.lengthValue*4*2);
|
||||
})
|
||||
buffer = concatenateBuffers(htonl(buffer),htonl(toFixedSizeBuffer(parseInt(dataStart),4)),htonl(toFixedSizeBuffer(parseInt(dataLength),4)),...allBufferList)
|
||||
break;
|
||||
}
|
||||
|
||||
let result = bufferToHex(buffer);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
export function bufferToHex(buffer) {
|
||||
let hexString = '';
|
||||
const view = new Uint8Array(buffer);
|
||||
for (let i = 0; i < view.length; i++) {
|
||||
const hex = view[i].toString(16).padStart(2, '0');
|
||||
hexString += hex;
|
||||
}
|
||||
return hexString;
|
||||
}
|
||||
|
||||
export function toBinaryString(number, length) {
|
||||
let binaryString = number.toString(2);
|
||||
return binaryString.padStart(length, '0');
|
||||
}
|
||||
|
||||
export function binaryToHex(binaryStr) {
|
||||
// 确保二进制字符串长度是4的倍数
|
||||
if (binaryStr.length % 4 !== 0) {
|
||||
binaryStr = binaryStr.padStart(binaryStr.length + 4 - (binaryStr.length % 4), '0');
|
||||
}
|
||||
|
||||
let hexStr = '';
|
||||
for (let i = 0; i < binaryStr.length; i += 4) {
|
||||
// 取出每4位二进制字符串
|
||||
const binaryChunk = binaryStr.slice(i, i + 4);
|
||||
// 转换成十六进制字符并追加到结果字符串中
|
||||
hexStr += parseInt(binaryChunk, 2).toString(16);
|
||||
}
|
||||
|
||||
return hexStr;
|
||||
}
|
||||
|
||||
|
||||
export function hexToBuffer(hexStr) {
|
||||
if (hexStr.length % 2 !== 0) {
|
||||
throw new Error('Invalid hex string');
|
||||
}
|
||||
|
||||
let buffer = new ArrayBuffer(hexStr.length / 2);
|
||||
let view = new Uint8Array(buffer);
|
||||
|
||||
for (let i = 0; i < hexStr.length; i += 2) {
|
||||
view[i / 2] = parseInt(hexStr.substr(i, 2), 16);
|
||||
}
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
export function swapEndian(buffer) {
|
||||
const swappedBuffer = new ArrayBuffer(buffer.byteLength);
|
||||
const view = new DataView(buffer);
|
||||
const swappedView = new DataView(swappedBuffer);
|
||||
|
||||
for (let i = 0; i < buffer.byteLength; i++) {
|
||||
swappedView.setUint8(i, view.getUint8(buffer.byteLength - 1 - i));
|
||||
}
|
||||
|
||||
return swappedBuffer;
|
||||
}
|
||||
|
||||
|
||||
export function htonl(buffer) {
|
||||
if (buffer.byteLength !== 4) {
|
||||
throw new Error('Buffer must be exactly 4 bytes.');
|
||||
}
|
||||
|
||||
let view = new DataView(buffer);
|
||||
let number = view.getUint32(0);
|
||||
|
||||
let swappedNumber = ((number & 0xFF) << 24) |
|
||||
((number & 0xFF00) << 8) |
|
||||
((number & 0xFF0000) >> 8) |
|
||||
((number >> 24) & 0xFF);
|
||||
|
||||
let swappedBuffer = new ArrayBuffer(4);
|
||||
let swappedView = new DataView(swappedBuffer);
|
||||
swappedView.setUint32(0, swappedNumber);
|
||||
|
||||
return swappedBuffer;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//将数字转换成指定字节大小的buffer
|
||||
export function toFixedSizeBuffer(number, byteSize) {
|
||||
if (byteSize <= 0) {
|
||||
throw new Error('Byte size must be greater than zero.');
|
||||
}
|
||||
|
||||
let buffer = new ArrayBuffer(byteSize);
|
||||
let view = new DataView(buffer);
|
||||
|
||||
// 根据指定字节数设置数值到缓冲区中
|
||||
for (let i = 0; i < byteSize; i++) {
|
||||
view.setUint8(byteSize - 1 - i, number & 0xFF);
|
||||
number = number >> 8;
|
||||
}
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
|
||||
export function concatenateBuffers(...buffers) {
|
||||
|
||||
// 确保所有元素均为 ArrayBuffer
|
||||
buffers.forEach(buffer => {
|
||||
if (!(buffer instanceof ArrayBuffer)) {
|
||||
throw new TypeError('All arguments must be ArrayBuffers');
|
||||
}
|
||||
});
|
||||
// 计算总长度
|
||||
let totalLength = buffers.reduce((sum, buffer) => sum + buffer.byteLength, 0);
|
||||
|
||||
// 创建一个新的 ArrayBuffer 并使用 Uint8Array 进行操作
|
||||
let concatenatedBuffer = new Uint8Array(totalLength);
|
||||
let offset = 0;
|
||||
|
||||
// 逐个复制每个缓冲区的内容
|
||||
buffers.forEach(buffer => {
|
||||
concatenatedBuffer.set(new Uint8Array(buffer), offset);
|
||||
offset += buffer.byteLength;
|
||||
});
|
||||
|
||||
return concatenatedBuffer.buffer;
|
||||
}
|
||||
|
||||
export function stringToHexBuffer(str,length) {
|
||||
// return new TextEncoder().encode(str).buffer;
|
||||
const bufferView = new TextEncoder().encode(str);
|
||||
|
||||
// 计算需要补充的00的数量
|
||||
const targetLength = length / 2; // 目标长度(字节数)
|
||||
const paddingLength = targetLength - bufferView.length;
|
||||
|
||||
// 创建一个新的Uint8Array,长度为目标长度
|
||||
const paddedBufferView = new Uint8Array(targetLength);
|
||||
|
||||
// 将原始Uint8Array的内容复制到新的Uint8Array中
|
||||
paddedBufferView.set(bufferView);
|
||||
|
||||
// 填充00
|
||||
if (paddingLength > 0) {
|
||||
paddedBufferView.fill(0, bufferView.length, targetLength);
|
||||
}
|
||||
|
||||
// 返回格式化后的Uint8Array
|
||||
return paddedBufferView.buffer;
|
||||
}
|
||||
|
||||
export function hexToString(hexStr) {
|
||||
let str = '';
|
||||
for (let i = 0; i < hexStr.length; i += 2) {
|
||||
if(hexStr.substr(i, 2)!=='00'){
|
||||
str += String.fromCharCode(parseInt(hexStr.substr(i, 2), 16));
|
||||
}
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
export function rearrangeHexStr(hexStr) {
|
||||
// 将输入的十六进制字符串解析为字节数组
|
||||
// 将输入的十六进制字符串按每8位分组
|
||||
const groups = [];
|
||||
for (let i = 0; i < hexStr.length; i += 8) {
|
||||
groups.push(hexStr.slice(i, i + 8));
|
||||
}
|
||||
|
||||
// 对每个组内的每两位进行倒序拼接
|
||||
const rearrangedGroups = groups.map(group => {
|
||||
let rearrangedGroup = '';
|
||||
for (let i = 0; i < group.length; i += 2) {
|
||||
rearrangedGroup = group.substr(i, 2) + rearrangedGroup;
|
||||
}
|
||||
return rearrangedGroup;
|
||||
});
|
||||
|
||||
// 将所有组重新拼接成一个字符串
|
||||
const rearrangedHexStr = rearrangedGroups.join('');
|
||||
|
||||
return rearrangedHexStr;
|
||||
}
|
||||
|
||||
//高低位交换
|
||||
export function rearrangeHexStr4(hexStr) {
|
||||
let rearrangedGroup = '';
|
||||
for (let i = 0; i < hexStr.length; i += 2) {
|
||||
rearrangedGroup = hexStr.substr(i, 2) + rearrangedGroup;
|
||||
}
|
||||
return rearrangedGroup;
|
||||
}
|
||||
|
||||
export function hexToVersion(hexStr) {
|
||||
let str = rearrangeHexStr(hexStr);
|
||||
str = hexToDec(str);
|
||||
return str;
|
||||
}
|
||||
|
||||
export function versionToHex(hexStr) {
|
||||
let str = decToHex(hexStr);
|
||||
str = rearrangeHexStr(str);
|
||||
return str;
|
||||
}
|
||||
|
||||
// 十六进制转十进制
|
||||
export function hexToDec(hexStr) {
|
||||
// 去除前缀 "0x"(如果存在)
|
||||
hexStr = hexStr.replace(/^0x/, '');
|
||||
// 将十六进制字符串转换为十进制数字
|
||||
return parseInt(hexStr, 16);
|
||||
}
|
||||
|
||||
// 十进制转十六进制
|
||||
export function decToHex(decNum) {
|
||||
// 将十进制数字转换为十六进制字符串
|
||||
let hexStr = decNum.toString(16);
|
||||
// 可选:添加前缀 "0x"
|
||||
return `0x${hexStr}`;
|
||||
}
|
Loading…
Reference in New Issue