Compare commits

...

10 Commits

Author SHA1 Message Date
fhysy 34675100bb fast(dev): 调整config配置 2025-06-06 10:22:35 +08:00
fhysy e8d25e0eda fast(dev): 开发环境添加vite-plugin-vue-devtools 查看插件 2025-06-06 10:09:48 +08:00
fhysy 7f7702d37a fast(ui): 更新图标库和菜单图标 2025-03-27 15:23:25 +08:00
fhysy 1a2b068b4f fast(扫码录入): 添加扫码枪串口录入 2025-03-27 15:15:17 +08:00
fhysy 5ebb6625dc refactor(layout): 添加扫码录入页面和菜单 2025-03-25 10:34:24 +08:00
fhysy 9934f65ab6 refactor(layout): 注释掉部分菜单项并更新默认 MQTT 服务器地址
- 注释掉了视频监控、北向任务配置和采集数据监视等菜单项
- 将断路器调试页面的 MQTT 服务器地址修改为 digital.drgyen.com
2025-03-11 10:03:08 +08:00
fhysy 663c70bb9b fix(网关调试):调整设备基础参数字段,升级1.0.8 2024-12-06 15:33:42 +08:00
fhysy 8479aa3203 fix(网关调试):对接采集数据监视接口、调整南北向页面显示 2024-11-26 10:40:00 +08:00
fhysy 9b16a3bd58 fix(网关调试): 调整南向北向逻辑 2024-11-22 17:26:51 +08:00
fhysy 8e832298ec fix(网关调试): 初始化刷新table宽度,解决导出表格错误 2024-11-20 14:23:29 +08:00
21 changed files with 2849 additions and 2503 deletions

1
.gitignore vendored
View File

@ -4,3 +4,4 @@ out
*.log*
/dist/
/dist.zip
.idea

View File

@ -5,7 +5,9 @@
<excludeFolder url="file://$MODULE_DIR$/temp" />
<excludeFolder url="file://$MODULE_DIR$/.tmp" />
<excludeFolder url="file://$MODULE_DIR$/tmp" />
<excludeFolder url="file://$MODULE_DIR$/node_modules" />
</content>
<content url="file://$MODULE_DIR$/node_modules" />
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>

View File

@ -1,6 +1,7 @@
import { resolve } from 'path'
import { defineConfig, externalizeDepsPlugin } from 'electron-vite'
import vue from '@vitejs/plugin-vue'
import VueDevTools from 'vite-plugin-vue-devtools';
export default defineConfig({
main: {
@ -15,6 +16,9 @@ export default defineConfig({
'@renderer': resolve('src/renderer/src')
}
},
plugins: [vue()]
plugins: [
vue(),
VueDevTools()
]
}
})

View File

@ -1,6 +1,6 @@
{
"name": "gateway-app",
"version": "1.0.7",
"version": "1.0.9",
"description": "An Electron application with Vue",
"main": "./out/main/index.js",
"author": "example.com",
@ -21,10 +21,11 @@
"@electron-toolkit/preload": "^3.0.1",
"@electron-toolkit/utils": "^3.0.0",
"axios": "^1.7.2",
"dayjs": "^1.11.11",
"dayjs": "^1.11.13",
"electron-updater": "^6.1.7",
"element-plus": "^2.7.6",
"file-saver": "^2.0.5",
"gateway-app": "file:",
"pinia": "^2.1.7",
"vue-router": "^4.4.0",
"xlsx": "^0.18.5"
@ -43,6 +44,7 @@
"prettier": "^3.3.2",
"sass": "^1.77.6",
"vite": "^5.3.1",
"vite-plugin-vue-devtools": "^7.7.6",
"vue": "^3.4.30"
}
}

Binary file not shown.

View File

@ -9,7 +9,7 @@
<!-- http-equiv="Content-Security-Policy"-->
<!-- content="default-src 'self'; connect-src 'self' *; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:"-->
<!-- />-->
<script type="text/javascript" src="./videoplayer/EasyPlayer-element.min.js"></script>
<script type="text/javascript" src="/videoplayer/EasyPlayer-element.min.js"></script>
</head>
<body>

View File

@ -1,8 +1,8 @@
@font-face {
font-family: "iconfont"; /* Project id 4622943 */
src: url('iconfont.woff2?t=1729646274723') format('woff2'),
url('iconfont.woff?t=1729646274723') format('woff'),
url('iconfont.ttf?t=1729646274723') format('truetype');
src: url('iconfont.woff2?t=1743060096253') format('woff2'),
url('iconfont.woff?t=1743060096253') format('woff'),
url('iconfont.ttf?t=1743060096253') format('truetype');
}
.iconfont {
@ -13,6 +13,18 @@
-moz-osx-font-smoothing: grayscale;
}
.icon--_saomaqiang:before {
content: "\e640";
}
.icon-qianzhaoyiqibiaoding:before {
content: "\e633";
}
.icon-zuobiaobiaoding:before {
content: "\e602";
}
.icon-com001:before {
content: "\e62c";
}

View File

@ -10,12 +10,13 @@ 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="/gateway/southdirection"><span class="iconfont icon-icon_chajian"></span> 南向采集配置</el-menu-item>
<el-menu-item index="/gateway/northboundtask"><span class="iconfont icon-icon_chajian"></span> 北向任务配置</el-menu-item>
<el-menu-item index="/gateway/collectdatamonitor"><span class="iconfont icon-icon_chajian"></span> 采集数据监视</el-menu-item>
<el-menu-item index="/system/devicestandard"><span class="iconfont icon-qianzhaoyiqibiaoding"></span> 断路器标定</el-menu-item>
<el-menu-item index="/system/scancodewrite"><span class="iconfont icon--_saomaqiang"></span> 扫码录入</el-menu-item>
<!-- <el-menu-item index="/gateway/southdirection"><span class="iconfont icon-icon_chajian"></span> 南向采集配置</el-menu-item>-->
<!-- <el-menu-item index="/gateway/northboundtask"><span class="iconfont icon-icon_chajian"></span> 北向任务配置</el-menu-item>-->
<!-- <el-menu-item index="/gateway/collectdatamonitor"><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>

View File

@ -2,6 +2,7 @@ import '@renderer/assets/main.css'
import { createPinia } from 'pinia'
import { createApp } from 'vue'
import dayjs from 'dayjs'
import * as ElementPlusIconsVue from '@element-plus/icons-vue'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
@ -10,6 +11,7 @@ import App from '@renderer/App.vue'
import router from '@renderer/router'
const app = createApp(App)
app.config.globalProperties.$dayjs = dayjs
for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
app.component(key, component)

View File

@ -44,6 +44,15 @@ const router = createRouter({
keepAlive: true
}
},
{
path: 'scancodewrite',
name: 'scancodewrite',
component: () => import('@renderer/views/system/scancodewrite/index.vue'),
meta: {
menu: 'scancodewrite',
keepAlive: true
}
},
{
path: 'devicestandard',
name: 'devicestandard',

View File

@ -16,22 +16,27 @@
// wsUrl: 'ws://127.0.0.1:8000'
// }
// export default {
// 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',
// }
export default {
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',
// url: 'http://192.168.1.17:8000',
// wsUrl: 'ws://192.168.1.17:8000',
// swichWsUrl: 'ws://192.168.1.17:8001',
// serialPortUrl: 'http://192.168.1.17:8000',
// 远程连接串口使用
// serialPortUrl: 'http://120.77.172.42:7202',
// serialPortUrl: 'http://192.168.1.17:8888',
}
// 手动配置的地址
export default {
url: 'http://192.168.1.17:8000',
wsUrl: 'ws://192.168.1.17:8000',
swichWsUrl: 'ws://192.168.1.17:8001',
serialPortUrl: 'http://127.0.0.1:8888',
}
// export default {
// url: 'http://192.168.1.17:8000',
// wsUrl: 'ws://192.168.1.17:8000',
// swichWsUrl: 'ws://192.168.1.17:8001',
// serialPortUrl: 'http://192.168.1.17:8000',
// }

View File

@ -1,273 +1,240 @@
<template>
<div id="southdirection-box">
<div class="device-config">
<h2>设备状态</h2>
<div class="btn-list">
<div class="btn-list-left">
</div>
<div class="btn-list-right">
<el-button type="primary" @click="getDeviceConfig">刷新</el-button>
</div>
</div>
<div class="table-box">
<el-table
ref="deviceConfigTableRef"
highlight-current-row
:data="deviceConfigList"
border
height="187"
@row-click="deviceConfigClick"
:style="{ width: tabelBox + 'px',background:'#f2f2f2' }"
empty-text="配置为空"
>
<el-table-column type="index" label="序号" align="center" width="60" />
<el-table-column prop="equipId" label="设备ID" align="center"/>
<el-table-column prop="communicationQuality" label="通讯质量" align="center"/>
<el-table-column prop="state" label="运行状态" align="center"/>
<el-table-column prop="equipName" label="临时停止" align="center">
<template #default="scope">
<el-switch v-model="scope.row.isStart" />
</template>
</el-table-column>
</el-table>
</div>
</div>
<div class="data-config">
<h2>数据源配置</h2>
<div class="btn-list">
<div class="btn-list-left">
</div>
<div class="btn-list-right">
<el-button type="primary" @click="getDeviceConfig">刷新</el-button>
</div>
</div>
<div class="table-box">
<el-table
:data="activeDeviceConfig"
border
size="small"
height="100%"
ref="deviceDataTableRef"
:style="{ width: tabelBox + 'px' }"
empty-text="配置为空"
>
<el-table-column type="index" label="序号" align="center" width="60" fixed />
<el-table-column prop="dataId" label="设备ID_数据ID" align="center" />
<el-table-column prop="dataName" label="数据名" align="center" />
<el-table-column prop="dataDesc" label="描述" align="center" />
<el-table-column prop="value" label="当前值" align="center" />
<el-table-column prop="timeStamp" label="时间" align="center" />
<el-table-column label="操作" width="55" fixed="right" align="center">
<div id="southdirection-box">
<div class="device-config">
<h2>设备状态</h2>
<div class="btn-list">
<div class="btn-list-left"></div>
<div class="btn-list-right">
<el-button type="primary" @click="getDeviceList">刷新</el-button>
</div>
</div>
<div class="table-box">
<el-table
ref="deviceConfigTableRef"
highlight-current-row
:data="deviceList"
border
height="187"
:style="{ width: tabelBox + 'px', background: '#f2f2f2' }"
empty-text="配置为空"
@row-click="deviceConfigClick"
>
<el-table-column type="index" label="序号" align="center" width="60" />
<el-table-column prop="equipId" label="设备ID" align="center" />
<el-table-column prop="quality" label="通讯质量" align="center" />
<el-table-column prop="status" label="运行状态" align="center" />
<el-table-column prop="status" label="开启状态" align="center">
<template #default="scope">
<el-switch v-model="scope.row.status" :before-change="handleBeforeChange.bind(this, scope.$index)" />
</template>
</el-table-column>
</el-table>
</div>
</div>
<div class="data-config">
<h2>数据源配置 {{ activeDeviceConfig.equipId || '' }}</h2>
<div class="btn-list">
<div class="btn-list-left"></div>
<div class="btn-list-right">
<el-button type="primary" @click="getDeviceConfig">刷新</el-button>
</div>
</div>
<div class="table-box">
<el-table ref="deviceDataTableRef" :data="activeDeviceConfig.result" border size="small" height="100%" :style="{ width: tabelBox + 'px' }" empty-text="配置为空">
<el-table-column type="index" label="序号" align="center" width="60" fixed />
<el-table-column prop="id" label="设备ID_数据ID" align="center">
<template #default="scope">
{{ activeDeviceConfig.equipId + '_' + scope.row.id }}
</template>
</el-table-column>
<el-table-column prop="dataName" label="数据名" align="center" />
<el-table-column prop="dataValue" label="当前值" align="center" />
<el-table-column prop="dataUnit" label="单位" align="center" />
<el-table-column prop="time" label="时间" align="center" />
<!-- <el-table-column label="操作" width="55" fixed="right" align="center">-->
<!-- <template #default="scope">-->
<!-- <el-button link type="danger" size="small" @click.stop="delDeviceDataConfig(scope.$index)">删除</el-button>-->
<!-- </template>-->
</el-table-column>
</el-table>
</div>
</div>
</div>
<!-- </el-table-column>-->
</el-table>
</div>
</div>
</div>
</template>
<script setup>
import { reactive, ref, onMounted, onUnmounted, computed, watch } from "vue"
import { ElMessage, ElMessageBox } from "element-plus"
import axios from "axios"
import { ref, onMounted, onUnmounted } from 'vue';
import { ElMessage } from 'element-plus';
import axios from 'axios';
import config from '@renderer/util/config.js';
const deviceConfigTableRef = ref();
const deviceDataTableRef = ref();
const tabelBox = ref(884)
const deviceConfigList = ref([
{
"equipId": "dev102", // ID
"communicationQuality": "good",
"state":true,
"isStart":false,
"dataList":[
{
"dataId":'WUHaNG-ELOT A01',
"dataName":'A01',
"dataDesc":'炉体进水流量',
"value":'-1.17549',
"timeStamp":'2024-09-11 11:44:52.721',
},
{
"dataId":'WUHaNG-ELOT A02',
"dataName":'A02',
"dataDesc":'炉体出水流量',
"value":'-1.71603',
"timeStamp":'2024-09-11 11:44:52.721',
},
{
"dataId":'WUHaNG-ELOT A03',
"dataName":'A03',
"dataDesc":'炉盖进水流量',
"value":'-0.447121',
"timeStamp":'2024-09-11 11:44:52.721',
}
]
},
{
"equipId": "dev103", // ID
"communicationQuality": "good",
"state":true,
"isStart":false,
"dataList":[
{
"dataId":'WUHaNG-ELOT A01',
"dataName":'A01',
"dataDesc":'炉体进水流量',
"value":'-1.17549',
"timeStamp":'2024-09-11 11:44:52.721',
}
]
},
{
"equipId": "dev104", // ID
"communicationQuality": "good",
"state":true,
"isStart":false,
"dataList":[
{
"dataId":'WUHaNG-ELOT A01',
"dataName":'A01',
"dataDesc":'炉体进水流量',
"value":'-1.17549',
"timeStamp":'2024-09-11 11:44:52.721',
},
{
"dataId":'WUHaNG-ELOT A02',
"dataName":'A02',
"dataDesc":'炉体出水流量',
"value":'-1.71603',
"timeStamp":'2024-09-11 11:44:52.721',
},
{
"dataId":'WUHaNG-ELOT A03',
"dataName":'A03',
"dataDesc":'炉盖进水流量',
"value":'-0.447121',
"timeStamp":'2024-09-11 11:44:52.721',
},
{
"dataId":'WUHaNG-ELOT A02',
"dataName":'A02',
"dataDesc":'炉体出水流量',
"value":'-1.71603',
"timeStamp":'2024-09-11 11:44:52.721',
},
{
"dataId":'WUHaNG-ELOT A03',
"dataName":'A03',
"dataDesc":'炉盖进水流量',
"value":'-0.447121',
"timeStamp":'2024-09-11 11:44:52.721',
},
{
"dataId":'WUHaNG-ELOT A02',
"dataName":'A02',
"dataDesc":'炉体出水流量',
"value":'-1.71603',
"timeStamp":'2024-09-11 11:44:52.721',
},
{
"dataId":'WUHaNG-ELOT A03',
"dataName":'A03',
"dataDesc":'炉盖进水流量',
"value":'-0.447121',
"timeStamp":'2024-09-11 11:44:52.721',
}
]
}
]);
const getDeviceConfig = () => {
console.log('获取配置')
}
const tabelBox = ref(884);
const deviceList = ref([]);
//
const ActiveRowIndex = ref(0);
const activeDeviceConfig = ref([])
const activeDeviceConfig = ref({
equipId: '',
status: false,
result: []
});
const getDeviceDataList = id => {
// console.log('')
axios
.get(config.url + '/data/collect?equipId=' + id, {})
.then(response => {
//
if (response.data.code == 0) {
//
activeDeviceConfig.value = {
equipId: response.data.data.equipId || '',
status: response.data.data.status || false,
result: response.data.data.result || []
};
// activeDeviceResult.value = response.data.data.result || []
} else {
ElMessage.error(response.data.message);
}
})
.catch(error => {
//
console.error(error); //
ElMessage.error(error);
});
};
// watch(
// () => ({ ...activeDeviceConfig.value }),
// (newVal) => {
// // console.log("",newVal)
// deviceConfigList.value[ActiveRowIndex.value] = newVal;
// },
// { deep: true }
// );
const getDeviceList = () => {
// console.log('')
axios
.get(config.url + '/data/equip/list', {})
.then(response => {
//
if (response.data.code == 0) {
//
deviceList.value = response.data.data.equips || [];
if (deviceList.value.length > ActiveRowIndex.value) {
getDeviceDataList(deviceList.value[ActiveRowIndex.value].equipId);
} else if (deviceList.value.length > 0) {
getDeviceDataList(deviceList.value[0].equipId);
} else {
activeDeviceConfig.value = {
equipId: '',
starus: false,
result: []
};
// activeDeviceResult.value = []
}
} else {
ElMessage.error(response.data.message);
}
})
.catch(error => {
//
console.error(error); //
ElMessage.error(error);
});
};
const getDeviceConfig = () => {
getDeviceDataList(deviceList.value[ActiveRowIndex.value].equipId);
};
const handleBeforeChange = index => {
console.log('e', index);
return new Promise((resolve, reject) => {
let deviceObj = deviceList.value[index];
console.log('deviceObj', deviceObj.status);
let url = config.url + '/data/collect/start?equipId=' + deviceObj.equipId;
if (deviceObj.status) {
url = config.url + '/data/collect/end?taskId=' + deviceObj.equipId;
}
// axios.get
axios
.get(url)
.then(response => {
console.log('response', response);
if (response.data.code === 0) {
// ok
if (deviceObj.status) {
ElMessage.success('关闭成功');
} else {
ElMessage.success('开启成功');
}
deviceList.value[index].status = !deviceList.value[index].status;
getDeviceList();
resolve();
} else {
// ok
ElMessage.error(response.data.message);
reject();
}
})
.catch(error => {
//
ElMessage.error(error.data.message);
reject();
});
});
};
//
const deviceConfigClick = (e) => {
console.log(`current page:`,e)
activeDeviceConfig.value = e.dataList;
deviceConfigTableRef.value.toggleRowSelection(e);
ActiveRowIndex.value = deviceConfigList.value.indexOf(e);
// e.isDoubleClicked = !e.isDoubleClicked;
}
const deviceConfigClick = e => {
getDeviceDataList(e.equipId);
deviceConfigTableRef.value.toggleRowSelection(e);
ActiveRowIndex.value = deviceList.value.indexOf(e);
};
//
const handleResize = () => {
deviceDataTableRef.value.doLayout();
tabelBox.value = window.innerWidth - 180 - 10 ;
}
deviceDataTableRef.value.doLayout();
tabelBox.value = window.innerWidth - 180 - 10;
};
onMounted(() => {
window.addEventListener('resize', handleResize);
if(deviceConfigList.value[0]){
activeDeviceConfig.value = deviceConfigList.value[0].dataList;
ActiveRowIndex.value = 0;
}
window.addEventListener('resize', handleResize);
getDeviceList();
handleResize();
});
onUnmounted(() => {
window.removeEventListener('resize', handleResize);
window.removeEventListener('resize', handleResize);
});
</script>
<style scoped lang="scss">
.el-table .double-clicked-row {
background-color: #f0f9eb;
background-color: #f0f9eb;
}
:deep(.el-table .el-scrollbar) {
background: #fff;
background: #fff;
}
#southdirection-box{
height: 100%;
.btn-list{
display: flex;
align-items: center;
justify-content: space-between;
padding: 10px 0;
}
.device-config{
position: relative;
overflow-y: auto;
}
.data-config{
position: relative;
height: calc(100% - 278px);
.table-box{
position: absolute;
width: 100%;
height: calc(100% - 162px);
}
}
.table-box{
//position: absolute;
//width: 100%;
}
#southdirection-box {
height: 100%;
.btn-list {
display: flex;
align-items: center;
justify-content: space-between;
padding: 10px 0;
}
.device-config {
position: relative;
overflow-y: auto;
}
.data-config {
position: relative;
height: calc(100% - 278px);
.table-box {
position: absolute;
width: 100%;
height: calc(100% - 162px);
}
}
.table-box {
//position: absolute;
//width: 100%;
}
}
</style>

View File

@ -68,7 +68,7 @@
<el-switch v-model="scope.row.pushConf.isUseResumeBrokenTransfer" />
</template>
</el-table-column>
<el-table-column prop="protocol.params.linkPar" label="设备地址" >
<el-table-column prop="tasks" label="任务ID" >
<template #default="scope">
{{scope.row.tasks?scope.row.tasks.join():''}}
</template>
@ -97,9 +97,10 @@
empty-text="配置为空"
>
<el-table-column type="index" label="序号" align="center" width="60" />
<el-table-column prop="taskId" label="任务ID" >
<el-table-column prop="taskId" label="任务ID" align="center">
<template #default="scope">
<el-input v-model="scope.row.taskId" placeholder="请输入任务ID" />
{{scope.row.taskId}}
<!-- <el-input v-model="scope.row.taskId" placeholder="请输入任务ID" />-->
</template>
</el-table-column>
<el-table-column prop="uploadMode" label="上报策略" >
@ -117,10 +118,10 @@
</div>
</div>
<div class="data-config">
<h2>上报测点{{activeDeviceConfig.taskId}}</h2>
<h2>上报测点 {{activeDeviceConfig.taskId}}</h2>
<div class="table-box">
<el-table
:data="activeDeviceConfig.dataId_entire"
:data="activeDeviceConfig.dataIdEntire"
border
size="small"
height="100%"
@ -130,8 +131,8 @@
>
<el-table-column type="index" label="序号" align="center" width="60" fixed />
<el-table-column prop="equipId" label="设备ID" align="center"/>
<el-table-column prop="idInfo.id" label="数据ID" align="center"/>
<el-table-column prop="idInfo.uploadMode" label="上报策略" align="center"/>
<el-table-column prop="idInfo[0].id" label="数据ID" align="center"/>
<el-table-column prop="idInfo[0].uploadMode" label="上报策略" align="center"/>
</el-table>
</div>
</div>
@ -288,209 +289,11 @@ const createFilter = (queryString) => {
}
//
const taskList = ref([
{
"dataId_entire": [
{
"equipId": "dev102",
"idInfo": [{ "id": "", "uploadMode": "timer 10 || change 10" }]
},
{
"equipId": "dev103",
"idInfo": [{ "id": "as", "uploadMode": "timer 10 || change 10" }]
},
{
"equipId": "dev103",
"idInfo": [{ "id": "as", "uploadMode": "timer 10 || change 10" }]
},
{
"equipId": "dev103",
"idInfo": [{ "id": "as", "uploadMode": "timer 10 || change 10" }]
},
{
"equipId": "dev103",
"idInfo": [{ "id": "as", "uploadMode": "timer 10 || change 10" }]
},
{
"equipId": "dev103",
"idInfo": [{ "id": "as", "uploadMode": "timer 10 || change 10" }]
},
{
"equipId": "dev103",
"idInfo": [{ "id": "as", "uploadMode": "timer 10 || change 10" }]
},
{
"equipId": "dev103",
"idInfo": [{ "id": "as", "uploadMode": "timer 10 || change 10" }]
},
{
"equipId": "dev103",
"idInfo": [{ "id": "as", "uploadMode": "timer 10 || change 10" }]
},
{
"equipId": "dev103",
"idInfo": [{ "id": "as", "uploadMode": "timer 10 || change 10" }]
},
{
"equipId": "dev103",
"idInfo": [{ "id": "as", "uploadMode": "timer 10 || change 10" }]
},
{
"equipId": "dev103",
"idInfo": [{ "id": "as", "uploadMode": "timer 10 || change 10" }]
},
{
"equipId": "dev103",
"idInfo": [{ "id": "as", "uploadMode": "timer 10 || change 10" }]
},
{
"equipId": "dev103",
"idInfo": [{ "id": "as", "uploadMode": "timer 10 || change 10" }]
},
{
"equipId": "dev103",
"idInfo": [{ "id": "as", "uploadMode": "timer 10 || change 10" }]
},
{
"equipId": "dev103",
"idInfo": [{ "id": "as", "uploadMode": "timer 10 || change 10" }]
},
{
"equipId": "dev103",
"idInfo": [{ "id": "as", "uploadMode": "timer 10 || change 10" }]
}
],
"taskId": "T1",
"taskType": "",
"uploadMode": "timer 1 || change 0.1"
},
{
"dataId_entire": [
{
"equipId": "dev103",
"idInfo": [{ "id": "xc", "uploadMode": "" }]
}
],
"taskId": "T2",
"taskType": "",
"uploadMode": "timer 10 || change 1"
},
{
"dataId_entire": [],
"taskId": "T3",
"taskType": "",
"uploadMode": "timer 120 || change 0.1"
},
{
"dataId_entire": [],
"taskId": "T4",
"taskType": "",
"uploadMode": "timer 120 || change 1"
},
{
"dataId_entire": [],
"taskId": "T5",
"taskType": "",
"uploadMode": "timer 120 || change 3"
}
]);
const platConfigTableRef = ref();
const deviceDataTableRef = ref();
const tabelBox = ref(884)
const platConfigList = ref([])
// const platConfigList = ref([
// {
// // IP
// "PlatformIp": "",
// //
// "tasks": [
// "T1",
// "T2",
// "T3",
// "T4",
// "T5"
// ],
// //
// "type": "",
// // MQTT
// "mqtt": {
// // MQTT
// "user": "",
// // MQTT
// "passwd": "",
// // 使SSL
// "isUseSsl": false,
// // 使SSL
// "isUseSslConf": false,
// // SSL
// "sslConf": {
// //
// "localCertificate_file": "/etc/custom/sslConf/pupu_core_3501000001.pem",
// //
// "privateKey_file": "/etc/custom/sslConf/pupu_core_3501000001.prv"
// }
// },
// //
// "pushConf": {
// //
// "isRun": true,
// // 使
// "isUseResumeBrokenTransfer": false,
// //
// "broken": {
// //
// "resume": {
// "intervalTime_ms": 1000
// },
// //
// "filter": {
// //
// "filter_s": 600,
// // ID
// "relevanceTaskId": [
// "T1",
// "T2",
// "T3",
// "T4",
// "T5"
// ]
// }
// }
// },
// //
// "encrypt_decrypt": {
// //
// "encrypt_1": {
// //
// "algorithm": "AES",
// //
// "param": {
// "mode": "CBC",
// "key": "0123456789abcdef",
// "ivec": "0123456789abcdef",
// "bits": 128
// },
// //
// "enable": false
// },
// //
// "decrypt_1": {
// //
// "algorithm": "AES",
// //
// "param": {
// "mode": "CBC",
// "key": "0123456789abcdef",
// "ivec": "0123456789abcdef",
// "bits": 128
// },
// //
// "enable": false
// }
// }
// }
// ]);
const activeTaskIndex = ref(0);
const uploadType = ref([
{ label: 'DT-MQTT-DEFAULT', value: 'DT-MQTT-DEFAULT'},
@ -591,18 +394,34 @@ const getDeviceConfig = () => {
if (response.data.code == 0) {
//
platConfigList.value = response.data.data.PlatformPar || [];
taskList.value = response.data.data.tasks.map(item=>{
if(item.dataIdEntire!=[]){
let dataIdEntireList = [];
item.dataIdEntire.forEach(val=>{
val.idInfo.forEach(info=>{
dataIdEntireList.push({
equipId: val.equipId,
idInfo:[info]
})
})
})
item.dataIdEntire = dataIdEntireList;
}
return item;
}) || [];
// taskList.value = taskDataList;
console.log("格式化后数据",taskList.value)
if(!platConfigList.value.length){
addDeviceConfig()
}
// if(platConfigList.value.length){
// if(platConfigList.value.length>ActiveRowIndex.value){
// activeDeviceConfig.value = platConfigList.value[ActiveRowIndex.value];
// }else{
// activeDeviceConfig.value = platConfigList.value[0];
// }
// }else{
// addDeviceConfig()
// }
if(platConfigList.value.length){
if(platConfigList.value.length>ActiveRowIndex.value){
activeDeviceConfig.value = platConfigList.value[ActiveRowIndex.value];
}else{
activeDeviceConfig.value = platConfigList.value[0];
}
}
} else {
ElMessage.error(response.data.message);
@ -617,7 +436,7 @@ const getDeviceConfig = () => {
const setDeviceConfig = () => {
console.log('提交配置',platConfigList.value)
axios
.post(config.url + '/config/platform/add', {PlatformPar: platConfigList.value})
.post(config.url + '/config/platform/add', {PlatformPar: platConfigList.value,tasks:taskList.value})
.then(response => {
//
console.log(response); //
@ -744,7 +563,7 @@ const activeDeviceConfig = ref({
watch(
() => ({ ...activeDeviceConfig.value }),
(newVal) => {
// console.log("",newVal)
console.log("数据变化",newVal)
platConfigList.value[ActiveRowIndex.value] = newVal;
},
{ deep: true }
@ -782,6 +601,7 @@ const handleResize = () => {
onMounted(() => {
window.addEventListener('resize', handleResize);
getDeviceConfig()
handleResize()
// if(platConfigList.value[0]){
// activeDeviceConfig.value = platConfigList.value[0];
// platConfigTableRef.value.toggleRowSelection(platConfigList.value[0]);

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,796 @@
<template>
<div class="scanner-container">
<el-upload
v-model:file-list="fileList"
class="upload-demo"
:action="config.serialPortUrl + '/importDevice'"
multiple
ref="upload"
name="excelFile"
:before-remove="beforeRemove"
:limit="1"
:on-exceed="handleExceed"
:before-upload="beforeAvatarUpload"
>
<el-button type="primary"><el-icon><Upload /></el-icon></el-button>
<!-- <template #tip>-->
<!-- <div class="el-upload__tip">-->
<!-- xls 文件.-->
<!-- </div>-->
<!-- </template>-->
</el-upload>
<!-- Device Code Section -->
<div class="input-section">
<div class="label">设备序列号</div>
<el-input
ref="snInputRef"
v-model="deviceAttrList[1].inputValue"
placeholder="请输入或扫描设备序列号"
size="large"
clearable
class="device-code-input"
@focus="handleSnInputFocus"
@blur="handleSnInputBlur"
/>
</div>
<!-- Main and Sub Model Section -->
<div class="model-section">
<div class="model-inputs">
<div class="model-input-group">
<div class="label">主型号</div>
<el-input v-model="deviceAttrList[2].inputValue" :disabled="inputStatus" size="large" placeholder="请输入主型号" @input="saveCache($event,2)" />
</div>
<div class="model-input-group">
<div class="label">次型号</div>
<el-input v-model="deviceAttrList[3].inputValue" :disabled="inputStatus" size="large" placeholder="请输入次型号" @input="saveCache($event,3)" />
</div>
<el-button size="large" type="primary" @click="toggleInput">{{inputStatus?'解锁':'锁定'}}</el-button>
</div>
</div>
<!-- Information Display Section -->
<div class="info-section">
<span class="info-time">{{infoTime ? '时间:' + $dayjs(infoTime).format('YYYY-MM-DD HH:mm:ss') : ''}}</span>
<el-tag type="info" class="status-tag" v-if="deviceAttrList[1].outputValue==''">-</el-tag>
<el-tag type="success" class="status-tag" v-else-if="getContrastStatus()">比对成功</el-tag>
<el-tag type="danger" class="status-tag" v-else>比对失败</el-tag>
<div class="info-card">
<div class="info-title">设备序列号</div>
<div class="info-content">{{ deviceAttrList[1].outputValue || '-' }}</div>
</div>
<div class="info-card">
<div class="info-title"></div>
<div class="info-content"></div>
</div>
<div class="info-card">
<div class="info-title">主型号</div>
<div class="info-content">{{ deviceAttrList[2].outputValue || '-' }}</div>
</div>
<div class="info-card">
<div class="info-title">次型号</div>
<div class="info-content">{{ deviceAttrList[3].outputValue || '-' }}</div>
</div>
</div>
</div>
<!-- <div id="serialport-box">-->
<!-- <div id="serialport-main" class="serialport-main">-->
<!-- <el-collapse v-model="activeFold" @change="foldChange">-->
<!-- <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"-->
<!-- v-if="item.name === '设备序列号SN'"-->
<!-- ref="snInputRef"-->
<!-- class="device-attr-input"-->
<!-- :disabled="item.inputDisable"-->
<!-- @focus="handleSnInputFocus"-->
<!-- @blur="handleSnInputBlur"-->
<!-- @keyup.enter="handleSnEnter(item, index)"-->
<!-- placeholder="扫码输入"/>-->
<!-- <el-input v-model="item.inputValue" :disabled="item.inputDisable" class="device-attr-input" v-else/>-->
<!-- <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, computed, nextTick, onDeactivated, onActivated } from 'vue';
import { ElMessage,ElMessageBox,genFileId } from 'element-plus';
import { buildHead, hexToString, hexToVersion, rearrangeHexStr, versionToHex } from '../serialport/js/fun';
import { useSerialPortStore } from '@renderer/stores/seralPort.js';
const useseralPortStore = useSerialPortStore();
const upload = ref()
//
const connectionState = ref(false);
const inputStatus = ref(false);
const snInputRef = ref(null); // SN
const serialportForm = computed(() => {
return useseralPortStore.serialport;
});
const infoTime = ref('');
//
const isScannerInput = ref(false);
const lastScanTime = ref(0);
const scanTimeout = ref(null);
const toggleInput = () => {
inputStatus.value = !inputStatus.value;
ElMessage.success(inputStatus.value?'已锁定':'已解锁');
}
const fileList = ref([])
const handleExceed = () => {
ElMessage.error(
`只能上传一个设备表、请先删除设备表再上传`
);
}
const beforeAvatarUpload = (rawFile) => {
console.log("rawFile",rawFile)
if (rawFile.type !== 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' && rawFile.type !== 'application/vnd.ms-excel') {
ElMessage.error('请上传xls或者xlsx格式文件!')
fileList.value = [];
return false
}
return true
}
const beforeRemove = (uploadFile, uploadFiles) => {
return ElMessageBox.confirm(
`确认要删除 ${uploadFile.name} 吗?`, "告警", {
confirmButtonText: "确认",
cancelButtonText: "取消",
type: "warning"
}
).then(
() => {
fileList.value = [];
return true;
},
() => false
)
}
// SN
const handleSnInputFocus = () => {
isScannerInput.value = true;
};
// SN
const handleSnInputBlur = () => {
isScannerInput.value = false;
};
//
const generateDerivedSerialNumbers = serialNumber => {
if (!serialNumber || serialNumber.length === 0) return;
// Get the first digit and the rest of the string
const firstDigit = parseInt(serialNumber.charAt(0));
const restOfString = serialNumber.substring(1);
// Generate motherboard serial number (first digit + 1)
const motherboardFirstDigit = (firstDigit + 1) % 10; // Use modulo to handle 9 -> 0
const motherboardSN = motherboardFirstDigit + restOfString;
// Generate 69 serial number (first digit + 2)
const sn69FirstDigit = (firstDigit + 2) % 10; // Use modulo to handle 8 -> 0, 9 -> 1
const sn69 = sn69FirstDigit + restOfString;
// Find and update the motherboard serial number field
const motherboardIndex = deviceAttrList.value.findIndex(item => item.name === '主板序列号');
if (motherboardIndex !== -1) {
deviceAttrList.value[motherboardIndex].inputValue = motherboardSN;
}
// Find and update the 69 serial number field
const sn69Index = deviceAttrList.value.findIndex(item => item.name === '69序列号');
if (sn69Index !== -1) {
deviceAttrList.value[sn69Index].inputValue = sn69;
}
};
//
const handleSnEnter = (item, index) => {
console.log("item",item.inputValue)
if (item.inputValue && item.inputValue.trim() !== '') {
//
queryProductKey(item.inputValue);
// SN
// sendDeviceAttr(item, 'input', index);
}
};
const JudgeInput = () => {
if(deviceAttrList.value[2].inputValue === '' || deviceAttrList.value[3].inputValue === ''){
ElMessage.error('主型号和次型号不能为空');
}else if(deviceAttrList.value[1].inputValue === ''){
ElMessage.error('设备序列号不能为空');
}else if(deviceAttrList.value[4].inputValue === ''){
ElMessage.error('产品密钥不能为空');
}else if(deviceAttrList.value[5].inputValue === ''){
ElMessage.error('主板序列号不能为空');
}else if(deviceAttrList.value[6].inputValue === ''){
ElMessage.error('69序列号不能为空');
}else if (!serialportForm.value.port) {
ElMessage.error('请先打开串口');
}else{
allWriteDeviceAttr()
}
}
// API
const queryProductKey = async serialNumber => {
try {
//
const keyIndex = deviceAttrList.value.findIndex(item => item.name === '产品密钥');
if (keyIndex !== -1) {
deviceAttrList.value[keyIndex].inputLoadingStatus = true;
}
// API
const response = await axios.get(`${config.serialPortUrl}/importDeviceSearch`, {
params: { devKey: serialNumber }
});
if (response.data.code === 0 && response.data.data.Result) {
//
if (keyIndex !== -1) {
deviceAttrList.value[keyIndex].inputValue = response.data.data.Result.devSecret;
generateDerivedSerialNumbers(serialNumber);
JudgeInput()
// ElMessage.success('');
}
} else {
ElMessage.error('未找到对应密钥,请检查设备序列号和设备表内设备序列号是否正确');
}
} catch (error) {
console.error('查询密钥失败:', error);
ElMessage.error('查询密钥失败');
} finally {
//
const keyIndex = deviceAttrList.value.findIndex(item => item.name === '产品密钥');
if (keyIndex !== -1) {
deviceAttrList.value[keyIndex].inputLoadingStatus = false;
}
}
};
// SN
const focusSnInput = () => {
if (snInputRef.value) {
// SN
const snIndex = deviceAttrList.value.findIndex(item => item.name === '设备序列号SN');
if (snIndex !== -1) {
//
deviceAttrList.value[snIndex].inputValue = '';
//
nextTick(() => {
snInputRef.value.focus();
});
}
}
};
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: 4,
inputValue: '',
inputLoadingStatus: false,
outputValue: '',
outputLoadingStatus: false,
dataType: 'str',
inputDisable: false
},
{
id: 4,
name: '产品次型号',
startValue: 16,
lengthValue: 4,
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
}
]);
const saveCache = (e,index) => {
console.log("e,index",e,index)
if(index === 2){
localStorage.setItem('mainModel', e);
}else if(index === 3){
localStorage.setItem('secondaryModel', e);
}
}
//
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.value.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.value.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 = () => {
console.log('serialportForm', serialportForm.value);
if (!serialportForm.value.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.value.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) {
if(response.data.data.hex!==''){
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);
infoTime.value = new Date().getTime();
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;
}
});
}else{
ElMessage.error('获取数据为空');
}
// 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.value.port) {
ElMessage.error('请先打开串口');
return '';
}
deviceAttrList.value.forEach((item, index) => {
setTimeout(() => {
if(index === 1 || index === 2 || index === 3 || index === 4 || index === 5 || index === 6 ){
sendDeviceAttr(item, 'input', index);
}
}, 50);
});
setTimeout(() => {
allReadDeviceAttr();
},1000)
};
const getKeyboardWriter = e => {
// SN
if (isScannerInput.value) {
const now = Date.now();
//
if (now - lastScanTime.value > 3000) {
// 500ms
const snIndex = deviceAttrList.value.findIndex(item => item.name === '设备序列号SN');
if (snIndex !== -1) {
deviceAttrList.value[snIndex].inputValue = '';
}
}
lastScanTime.value = now;
//
if (scanTimeout.value) {
clearTimeout(scanTimeout.value);
}
// 50ms
scanTimeout.value = setTimeout(() => {
//
if (e.key === 'Enter') {
const snIndex = deviceAttrList.value.findIndex(item => item.name === '设备序列号SN');
if (snIndex !== -1 && deviceAttrList.value[snIndex].inputValue) {
handleSnEnter(deviceAttrList.value[snIndex], snIndex);
}
}
}, 50);
}
};
const getContrastStatus = () => {
let flag = true;
if(deviceAttrList.value[1].outputValue && deviceAttrList.value[1].outputValue !== deviceAttrList.value[1].inputValue){
flag = false;
}
if(deviceAttrList.value[2].outputValue && deviceAttrList.value[2].outputValue !== deviceAttrList.value[2].inputValue){
flag = false;
}
if(deviceAttrList.value[3].outputValue && deviceAttrList.value[3].outputValue !== deviceAttrList.value[3].inputValue){
flag = false;
}
return flag;
}
//
onMounted(() => {
// getSerialPortList(false);
deviceAttrList.value[2].inputValue = localStorage.getItem('mainModel');
deviceAttrList.value[3].inputValue = localStorage.getItem('secondaryModel');
});
onActivated(() => {
console.log('页面重新打开(从缓存恢复)');
console.log("serialportForm",serialportForm.value)
allReadDeviceAttr();
//
// SN
nextTick(() => {
focusSnInput();
});
//
window.addEventListener('keydown', getKeyboardWriter);
});
//
onDeactivated(() => {
console.log('页面离开(进入缓存)');
//
window.removeEventListener('keydown', getKeyboardWriter);
//
if (scanTimeout.value) {
clearTimeout(scanTimeout.value);
}
});
</script>
<style lang="less" scoped>
.scanner-container {
padding: 20px;
height: calc(100% - 80px);
background: #f2f2f2;
border-radius: 10px;
font-family: Arial, sans-serif;
}
.import-btn {
margin-bottom: 20px;
}
.device-code-input {
margin-bottom: 20px;
}
//.input-section,
.model-section,
.info-section {
margin-bottom: 20px;
}
.label {
font-size: 14px;
margin-bottom: 8px;
font-weight: 500;
}
.model-inputs {
display: flex;
gap: 10px;
align-items: flex-end;
}
.model-input-group {
flex: 1;
}
.info-section {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
gap: 15px;
background-color: #f8f8f8;
padding: 15px;
position: relative;
}
.info-card {
padding: 15px;
}
.info-title {
margin-bottom: 10px;
display: flex;
justify-content: space-between;
align-items: center;
color: #666;
}
.info-time{
position: absolute;
top: 5px;
left: 10px;
color: #999;
font-size: 12px;
}
.status-tag {
position: absolute;
top: 10px;
right: 10px;
font-size: 12px;
font-weight: normal;
}
.info-content {
}
</style>

View File

@ -330,7 +330,7 @@ const deviceAttrList = ref([
id: 3,
name: '产品主型号',
startValue: 12,
lengthValue: 3,
lengthValue: 4,
inputValue: '',
inputLoadingStatus: false,
outputValue: '',
@ -341,8 +341,8 @@ const deviceAttrList = ref([
{
id: 4,
name: '产品次型号',
startValue: 15,
lengthValue: 5,
startValue: 16,
lengthValue: 4,
inputValue: '',
inputLoadingStatus: false,
outputValue: '',
@ -440,6 +440,7 @@ const analysisData = (hexData, data) => {
}
};
const sendDeviceAttr = (data, type, index) => {
if (!serialportForm.port) {
ElMessage.error('请先打开串口');
@ -486,10 +487,10 @@ const sendDeviceAttr = (data, type, index) => {
//
console.log('串口请求', response); //
if (response.data.code === 0) {
ElMessage.success('操作成功');
if (type === 'output') {
deviceAttrList.value[index].outputValue = analysisData(response.data.data.hex || '', data);
}
ElMessage.success('操作成功');
if (type === 'output') {
deviceAttrList.value[index].outputValue = analysisData(response.data.data.hex || '', data);
}
} else {
ElMessage.error(response.data.message);
}
@ -553,27 +554,32 @@ const allReadDeviceAttr = () => {
//
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;
}
});
if (response.data.data.hex !== '') {
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;
}
});
} else {
ElMessage.error('获取数据为空');
}
// deviceAttrList.value[index].outputValue = analysisData(response.data.data.hex || '', data);
} else {
ElMessage.error(response.data.message);

View File

@ -395,7 +395,7 @@ const mqttFormRef = ref();
// })
const mqttForm = reactive({
clientId: getGuid(),
host: '123.60.30.87',
host: 'digital.drgyen.com',
port: '8017',
path: '',
userName: 'admin',

1559
yarn.lock

File diff suppressed because it is too large Load Diff