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* *.log*
/dist/ /dist/
/dist.zip /dist.zip
.idea

View File

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

View File

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

View File

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

Binary file not shown.

View File

@ -9,7 +9,7 @@
<!-- http-equiv="Content-Security-Policy"--> <!-- http-equiv="Content-Security-Policy"-->
<!-- content="default-src 'self'; connect-src 'self' *; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:"--> <!-- 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> </head>
<body> <body>

View File

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

View File

@ -10,12 +10,13 @@ const settings = defineProps({
<el-scrollbar> <el-scrollbar>
<el-menu default-active="/system/switch" :collapse="settings.collapse" :router="true"> <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/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/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/devicestandard"><span class="iconfont icon-qianzhaoyiqibiaoding"></span> 断路器标定</el-menu-item>
<el-menu-item index="/gateway/southdirection"><span class="iconfont icon-icon_chajian"></span> 南向采集配置</el-menu-item> <el-menu-item index="/system/scancodewrite"><span class="iconfont icon--_saomaqiang"></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/southdirection"><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="/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-item index="/system/test"><el-icon> <Menu /> </el-icon></el-menu-item>-->
</el-menu> </el-menu>
</el-scrollbar> </el-scrollbar>

View File

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

View File

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

View File

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

View File

@ -3,233 +3,201 @@
<div class="device-config"> <div class="device-config">
<h2>设备状态</h2> <h2>设备状态</h2>
<div class="btn-list"> <div class="btn-list">
<div class="btn-list-left"> <div class="btn-list-left"></div>
</div>
<div class="btn-list-right"> <div class="btn-list-right">
<el-button type="primary" @click="getDeviceConfig">刷新</el-button> <el-button type="primary" @click="getDeviceList">刷新</el-button>
</div> </div>
</div> </div>
<div class="table-box"> <div class="table-box">
<el-table <el-table
ref="deviceConfigTableRef" ref="deviceConfigTableRef"
highlight-current-row highlight-current-row
:data="deviceConfigList" :data="deviceList"
border border
height="187" height="187"
@row-click="deviceConfigClick"
:style="{ width: tabelBox + 'px', background: '#f2f2f2' }" :style="{ width: tabelBox + 'px', background: '#f2f2f2' }"
empty-text="配置为空" empty-text="配置为空"
@row-click="deviceConfigClick"
> >
<el-table-column type="index" label="序号" align="center" width="60" /> <el-table-column type="index" label="序号" align="center" width="60" />
<el-table-column prop="equipId" label="设备ID" align="center" /> <el-table-column prop="equipId" label="设备ID" align="center" />
<el-table-column prop="communicationQuality" label="通讯质量" align="center"/> <el-table-column prop="quality" label="通讯质量" align="center" />
<el-table-column prop="state" label="运行状态" align="center"/> <el-table-column prop="status" label="运行状态" align="center" />
<el-table-column prop="equipName" label="临时停止" align="center"> <el-table-column prop="status" label="开启状态" align="center">
<template #default="scope"> <template #default="scope">
<el-switch v-model="scope.row.isStart" /> <el-switch v-model="scope.row.status" :before-change="handleBeforeChange.bind(this, scope.$index)" />
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
</div> </div>
</div> </div>
<div class="data-config"> <div class="data-config">
<h2>数据源配置</h2> <h2>数据源配置 {{ activeDeviceConfig.equipId || '' }}</h2>
<div class="btn-list"> <div class="btn-list">
<div class="btn-list-left"> <div class="btn-list-left"></div>
</div>
<div class="btn-list-right"> <div class="btn-list-right">
<el-button type="primary" @click="getDeviceConfig">刷新</el-button> <el-button type="primary" @click="getDeviceConfig">刷新</el-button>
</div> </div>
</div> </div>
<div class="table-box"> <div class="table-box">
<el-table <el-table ref="deviceDataTableRef" :data="activeDeviceConfig.result" border size="small" height="100%" :style="{ width: tabelBox + 'px' }" empty-text="配置为空">
: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 type="index" label="序号" align="center" width="60" fixed />
<el-table-column prop="dataId" label="设备ID_数据ID" align="center" /> <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="dataName" label="数据名" align="center" />
<el-table-column prop="dataDesc" label="描述" align="center" /> <el-table-column prop="dataValue" label="当前值" align="center" />
<el-table-column prop="value" label="当前值" align="center" /> <el-table-column prop="dataUnit" label="单位" align="center" />
<el-table-column prop="timeStamp" label="时间" align="center" /> <el-table-column prop="time" label="时间" align="center" />
<el-table-column label="操作" width="55" fixed="right" align="center"> <!-- <el-table-column label="操作" width="55" fixed="right" align="center">-->
<!-- <template #default="scope">--> <!-- <template #default="scope">-->
<!-- <el-button link type="danger" size="small" @click.stop="delDeviceDataConfig(scope.$index)">删除</el-button>--> <!-- <el-button link type="danger" size="small" @click.stop="delDeviceDataConfig(scope.$index)">删除</el-button>-->
<!-- </template>--> <!-- </template>-->
</el-table-column> <!-- </el-table-column>-->
</el-table> </el-table>
</div> </div>
</div> </div>
</div> </div>
</template> </template>
<script setup> <script setup>
import { reactive, ref, onMounted, onUnmounted, computed, watch } from "vue" import { ref, onMounted, onUnmounted } from 'vue';
import { ElMessage, ElMessageBox } from "element-plus" import { ElMessage } from 'element-plus';
import axios from "axios" import axios from 'axios';
import config from '@renderer/util/config.js'; import config from '@renderer/util/config.js';
const deviceConfigTableRef = ref(); const deviceConfigTableRef = ref();
const deviceDataTableRef = ref(); const deviceDataTableRef = ref();
const tabelBox = ref(884) const tabelBox = ref(884);
const deviceConfigList = ref([ const deviceList = 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 ActiveRowIndex = ref(0); 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( const getDeviceList = () => {
// () => ({ ...activeDeviceConfig.value }), // console.log('')
// (newVal) => { axios
// // console.log("",newVal) .get(config.url + '/data/equip/list', {})
// deviceConfigList.value[ActiveRowIndex.value] = newVal; .then(response => {
// }, //
// { deep: true } 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) => { const deviceConfigClick = e => {
console.log(`current page:`,e) getDeviceDataList(e.equipId);
activeDeviceConfig.value = e.dataList;
deviceConfigTableRef.value.toggleRowSelection(e); deviceConfigTableRef.value.toggleRowSelection(e);
ActiveRowIndex.value = deviceConfigList.value.indexOf(e); ActiveRowIndex.value = deviceList.value.indexOf(e);
// e.isDoubleClicked = !e.isDoubleClicked; };
}
// //
const handleResize = () => { const handleResize = () => {
deviceDataTableRef.value.doLayout(); deviceDataTableRef.value.doLayout();
tabelBox.value = window.innerWidth - 180 - 10; tabelBox.value = window.innerWidth - 180 - 10;
} };
onMounted(() => { onMounted(() => {
window.addEventListener('resize', handleResize); window.addEventListener('resize', handleResize);
if(deviceConfigList.value[0]){ getDeviceList();
activeDeviceConfig.value = deviceConfigList.value[0].dataList; handleResize();
ActiveRowIndex.value = 0;
}
}); });
onUnmounted(() => { onUnmounted(() => {
window.removeEventListener('resize', handleResize); window.removeEventListener('resize', handleResize);
@ -269,5 +237,4 @@ onUnmounted(() => {
//width: 100%; //width: 100%;
} }
} }
</style> </style>

View File

@ -68,7 +68,7 @@
<el-switch v-model="scope.row.pushConf.isUseResumeBrokenTransfer" /> <el-switch v-model="scope.row.pushConf.isUseResumeBrokenTransfer" />
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="protocol.params.linkPar" label="设备地址" > <el-table-column prop="tasks" label="任务ID" >
<template #default="scope"> <template #default="scope">
{{scope.row.tasks?scope.row.tasks.join():''}} {{scope.row.tasks?scope.row.tasks.join():''}}
</template> </template>
@ -97,9 +97,10 @@
empty-text="配置为空" empty-text="配置为空"
> >
<el-table-column type="index" label="序号" align="center" width="60" /> <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"> <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> </template>
</el-table-column> </el-table-column>
<el-table-column prop="uploadMode" label="上报策略" > <el-table-column prop="uploadMode" label="上报策略" >
@ -120,7 +121,7 @@
<h2>上报测点 {{activeDeviceConfig.taskId}}</h2> <h2>上报测点 {{activeDeviceConfig.taskId}}</h2>
<div class="table-box"> <div class="table-box">
<el-table <el-table
:data="activeDeviceConfig.dataId_entire" :data="activeDeviceConfig.dataIdEntire"
border border
size="small" size="small"
height="100%" height="100%"
@ -130,8 +131,8 @@
> >
<el-table-column type="index" label="序号" align="center" width="60" fixed /> <el-table-column type="index" label="序号" align="center" width="60" fixed />
<el-table-column prop="equipId" label="设备ID" align="center"/> <el-table-column prop="equipId" label="设备ID" align="center"/>
<el-table-column prop="idInfo.id" label="数据ID" align="center"/> <el-table-column prop="idInfo[0].id" label="数据ID" align="center"/>
<el-table-column prop="idInfo.uploadMode" label="上报策略" align="center"/> <el-table-column prop="idInfo[0].uploadMode" label="上报策略" align="center"/>
</el-table> </el-table>
</div> </div>
</div> </div>
@ -288,209 +289,11 @@ const createFilter = (queryString) => {
} }
// //
const taskList = ref([ 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 platConfigTableRef = ref();
const deviceDataTableRef = ref(); const deviceDataTableRef = ref();
const tabelBox = ref(884) const tabelBox = ref(884)
const platConfigList = ref([]) 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([ const uploadType = ref([
{ label: 'DT-MQTT-DEFAULT', value: 'DT-MQTT-DEFAULT'}, { label: 'DT-MQTT-DEFAULT', value: 'DT-MQTT-DEFAULT'},
@ -591,18 +394,34 @@ const getDeviceConfig = () => {
if (response.data.code == 0) { if (response.data.code == 0) {
// //
platConfigList.value = response.data.data.PlatformPar || []; 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){ if(!platConfigList.value.length){
addDeviceConfig() addDeviceConfig()
} }
// if(platConfigList.value.length){ if(platConfigList.value.length){
// if(platConfigList.value.length>ActiveRowIndex.value){ if(platConfigList.value.length>ActiveRowIndex.value){
// activeDeviceConfig.value = platConfigList.value[ActiveRowIndex.value]; activeDeviceConfig.value = platConfigList.value[ActiveRowIndex.value];
// }else{ }else{
// activeDeviceConfig.value = platConfigList.value[0]; activeDeviceConfig.value = platConfigList.value[0];
// } }
// }else{ }
// addDeviceConfig()
// }
} else { } else {
ElMessage.error(response.data.message); ElMessage.error(response.data.message);
@ -617,7 +436,7 @@ const getDeviceConfig = () => {
const setDeviceConfig = () => { const setDeviceConfig = () => {
console.log('提交配置',platConfigList.value) console.log('提交配置',platConfigList.value)
axios axios
.post(config.url + '/config/platform/add', {PlatformPar: platConfigList.value}) .post(config.url + '/config/platform/add', {PlatformPar: platConfigList.value,tasks:taskList.value})
.then(response => { .then(response => {
// //
console.log(response); // console.log(response); //
@ -744,7 +563,7 @@ const activeDeviceConfig = ref({
watch( watch(
() => ({ ...activeDeviceConfig.value }), () => ({ ...activeDeviceConfig.value }),
(newVal) => { (newVal) => {
// console.log("",newVal) console.log("数据变化",newVal)
platConfigList.value[ActiveRowIndex.value] = newVal; platConfigList.value[ActiveRowIndex.value] = newVal;
}, },
{ deep: true } { deep: true }
@ -782,6 +601,7 @@ const handleResize = () => {
onMounted(() => { onMounted(() => {
window.addEventListener('resize', handleResize); window.addEventListener('resize', handleResize);
getDeviceConfig() getDeviceConfig()
handleResize()
// if(platConfigList.value[0]){ // if(platConfigList.value[0]){
// activeDeviceConfig.value = platConfigList.value[0]; // activeDeviceConfig.value = platConfigList.value[0];
// platConfigTableRef.value.toggleRowSelection(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, id: 3,
name: '产品主型号', name: '产品主型号',
startValue: 12, startValue: 12,
lengthValue: 3, lengthValue: 4,
inputValue: '', inputValue: '',
inputLoadingStatus: false, inputLoadingStatus: false,
outputValue: '', outputValue: '',
@ -341,8 +341,8 @@ const deviceAttrList = ref([
{ {
id: 4, id: 4,
name: '产品次型号', name: '产品次型号',
startValue: 15, startValue: 16,
lengthValue: 5, lengthValue: 4,
inputValue: '', inputValue: '',
inputLoadingStatus: false, inputLoadingStatus: false,
outputValue: '', outputValue: '',
@ -440,6 +440,7 @@ const analysisData = (hexData, data) => {
} }
}; };
const sendDeviceAttr = (data, type, index) => { const sendDeviceAttr = (data, type, index) => {
if (!serialportForm.port) { if (!serialportForm.port) {
ElMessage.error('请先打开串口'); ElMessage.error('请先打开串口');
@ -553,6 +554,7 @@ const allReadDeviceAttr = () => {
// //
console.log('串口请求', response); // console.log('串口请求', response); //
if (response.data.code === 0) { if (response.data.code === 0) {
if (response.data.data.hex !== '') {
ElMessage.success('操作成功'); ElMessage.success('操作成功');
let hexValue = response.data.data.hex.substring(24, 392); let hexValue = response.data.data.hex.substring(24, 392);
let startValue = 0; let startValue = 0;
@ -574,6 +576,10 @@ const allReadDeviceAttr = () => {
deviceAttrList.value[index].inputValue = value; deviceAttrList.value[index].inputValue = value;
} }
}); });
} else {
ElMessage.error('获取数据为空');
}
// deviceAttrList.value[index].outputValue = analysisData(response.data.data.hex || '', data); // deviceAttrList.value[index].outputValue = analysisData(response.data.data.hex || '', data);
} else { } else {
ElMessage.error(response.data.message); ElMessage.error(response.data.message);

View File

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

1559
yarn.lock

File diff suppressed because it is too large Load Diff