feat(main): 添加获取应用版本功能并优化日志功能
- 在主进程中添加 get-app-version 的 IPC 处理程序,返回应用版本号 - 在预加载脚本中暴露 getAppVersion 方法给渲染进程 - 在 calibration 页面中添加版本信息显示 - 优化日志显示功能,增加日志转置和分页显示 - 添加清空日志功能 - 调整设备卡片样式,增加选中状态
This commit is contained in:
parent
9bc4e481e5
commit
8a7e53bc97
|
@ -8,7 +8,10 @@ directories:
|
||||||
# 定义要包含或排除在构建输出中的文件
|
# 定义要包含或排除在构建输出中的文件
|
||||||
files:
|
files:
|
||||||
- '!**/.vscode/*' # 排除VSCode配置文件
|
- '!**/.vscode/*' # 排除VSCode配置文件
|
||||||
|
- '!**/.cursor/*' # 排除cursor配置文件
|
||||||
|
- '!**/.idea/*' # 排除idea配置文件
|
||||||
- '!src/*' # 排除源代码目录
|
- '!src/*' # 排除源代码目录
|
||||||
|
- '!**/*.log' # 排除日志文件
|
||||||
- '!electron.vite.config.{js,ts,mjs,cjs}' # 排除Electron构建配置文件
|
- '!electron.vite.config.{js,ts,mjs,cjs}' # 排除Electron构建配置文件
|
||||||
- '!{.eslintignore,.eslintrc.cjs,.prettierignore,.prettierrc.yaml,dev-app-update.yml,CHANGELOG.md,README.md}' # 排除开发和文档文件
|
- '!{.eslintignore,.eslintrc.cjs,.prettierignore,.prettierrc.yaml,dev-app-update.yml,CHANGELOG.md,README.md}' # 排除开发和文档文件
|
||||||
- '!{.env,.env.*,.npmrc,pnpm-lock.yaml,*.zip,app.log}' # 排除环境和包管理配置文件
|
- '!{.env,.env.*,.npmrc,pnpm-lock.yaml,*.zip,app.log}' # 排除环境和包管理配置文件
|
||||||
|
|
|
@ -91,9 +91,9 @@ if (!gotTheLock) {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// This method will be called when Electron has finished
|
//当Electron完成时,将调用此方法
|
||||||
// initialization and is ready to create browser windows.
|
//初始化并准备创建浏览器窗口。
|
||||||
// Some APIs can only be used after this event occurs.
|
//某些API只能在此事件发生后使用。
|
||||||
const { spawn } = require('child_process');
|
const { spawn } = require('child_process');
|
||||||
let child = null;
|
let child = null;
|
||||||
let exePluginsExeList = [];
|
let exePluginsExeList = [];
|
||||||
|
@ -220,5 +220,10 @@ if (!gotTheLock) {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// In this file you can include the rest of your app"s specific main process
|
// In this file you can include the rest of your app"s specific main process
|
||||||
// code. You can also put them in separate files and require them here.
|
// code. You can also put them in separate files and require them here.
|
||||||
|
|
||||||
|
ipcMain.handle('get-app-version', () => {
|
||||||
|
return app.getVersion();
|
||||||
|
});
|
||||||
|
|
|
@ -16,6 +16,10 @@ import { electronAPI } from '@electron-toolkit/preload'
|
||||||
// return result;
|
// return result;
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
|
// // 暴露获取版本号的方法
|
||||||
|
// ipcMain.handle('get-app-version', () => {
|
||||||
|
// return app.getVersion(); // 返回当前应用版本(来自 package.json)
|
||||||
|
// });
|
||||||
|
|
||||||
// Use `contextBridge` APIs to expose Electron APIs to
|
// Use `contextBridge` APIs to expose Electron APIs to
|
||||||
// renderer only if context isolation is enabled, otherwise
|
// renderer only if context isolation is enabled, otherwise
|
||||||
|
@ -23,12 +27,22 @@ import { electronAPI } from '@electron-toolkit/preload'
|
||||||
// 使用contextBridge将Electron API和自定义的主进程方法API暴露给渲染进程页面。
|
// 使用contextBridge将Electron API和自定义的主进程方法API暴露给渲染进程页面。
|
||||||
if (process.contextIsolated) {
|
if (process.contextIsolated) {
|
||||||
try {
|
try {
|
||||||
contextBridge.exposeInMainWorld('electron', electronAPI)
|
contextBridge.exposeInMainWorld('electron', {
|
||||||
|
...electronAPI,
|
||||||
|
getAppVersion: async () => {
|
||||||
|
return await ipcRenderer.invoke('get-app-version');
|
||||||
|
}
|
||||||
|
})
|
||||||
// contextBridge.exposeInMainWorld('api', api)
|
// contextBridge.exposeInMainWorld('api', api)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error)
|
console.error(error)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
window.electron = electronAPI
|
window.electron = {
|
||||||
|
...electronAPI,
|
||||||
|
getAppVersion: async () => {
|
||||||
|
return await ipcRenderer.invoke('get-app-version');
|
||||||
|
}
|
||||||
|
}
|
||||||
// window.api = api
|
// window.api = api
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
<div class="calibration-page">
|
<div class="calibration-page">
|
||||||
<el-header class="calibration-header">
|
<el-header class="calibration-header">
|
||||||
<div class="header-left">
|
<div class="header-left">
|
||||||
<el-select v-model="selectedScheme" placeholder="选择方案" style="width: 200px; margin-right: 15px" @change="schemeChange">
|
<el-select v-model="selectedScheme" placeholder="选择方案" :disabled="playState" style="width: 200px; margin-right: 15px" @change="schemeChange">
|
||||||
<el-option v-for="(item, index) in schemeList" :key="index" :label="item.schemeName" :value="item.id"></el-option>
|
<el-option v-for="(item, index) in schemeList" :key="index" :label="item.schemeName" :value="item.id"></el-option>
|
||||||
</el-select>
|
</el-select>
|
||||||
<el-button icon="CaretRight" type="primary" :disabled="playState" @click="startExecution">开始执行</el-button>
|
<el-button icon="CaretRight" type="primary" :disabled="playState" @click="startExecution">开始执行</el-button>
|
||||||
|
@ -10,10 +10,10 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="header-right">
|
<div class="header-right">
|
||||||
<el-button icon="RefreshRight" type="primary" :disabled="playState" @click="generateDeviceList">刷新列表</el-button>
|
<el-button icon="RefreshRight" type="primary" :disabled="playState" @click="generateDeviceList">刷新列表</el-button>
|
||||||
<el-button icon="Setting" :disabled="playState" @click="openSettings">设置</el-button>
|
<el-button icon="Setting" :disabled="playState" @click="openSettings">配置方案</el-button>
|
||||||
</div>
|
</div>
|
||||||
</el-header>
|
</el-header>
|
||||||
<div class="scheme-list" v-if="activeScheme && activeScheme.series">
|
<div v-if="activeScheme && activeScheme.series" class="scheme-list list-one">
|
||||||
<span class="scheme-item"
|
<span class="scheme-item"
|
||||||
>系列: <span class="scheme-value">{{ activeScheme.series }}</span></span
|
>系列: <span class="scheme-value">{{ activeScheme.series }}</span></span
|
||||||
>
|
>
|
||||||
|
@ -21,8 +21,13 @@
|
||||||
>框架: <span class="scheme-value">{{ activeScheme.framework }}</span></span
|
>框架: <span class="scheme-value">{{ activeScheme.framework }}</span></span
|
||||||
>
|
>
|
||||||
<span class="scheme-item"
|
<span class="scheme-item"
|
||||||
>类型: <span class="scheme-value">{{ activeScheme.schemeType }}</span></span
|
>P位: <span class="scheme-value">{{ activeScheme.schemeType }}</span></span
|
||||||
>
|
>
|
||||||
|
<span class="scheme-item"
|
||||||
|
>额定电流(A): <span class="scheme-value">{{ activeScheme.configParam.format[2].value }}</span></span
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
<div v-if="activeScheme && activeScheme.series" class="scheme-list list-two">
|
||||||
<span v-for="(item, index) in activeScheme.configParam.format" :key="index" class="scheme-item"
|
<span v-for="(item, index) in activeScheme.configParam.format" :key="index" class="scheme-item"
|
||||||
>{{ item.unit ? item.name + '(' + item.unit + ')' : item.name }}: <span class="scheme-value">{{ item.value }}</span></span
|
>{{ item.unit ? item.name + '(' + item.unit + ')' : item.name }}: <span class="scheme-value">{{ item.value }}</span></span
|
||||||
>
|
>
|
||||||
|
@ -30,25 +35,25 @@
|
||||||
|
|
||||||
<el-main class="calibration-main">
|
<el-main class="calibration-main">
|
||||||
<div class="device-grid">
|
<div class="device-grid">
|
||||||
<el-card v-for="(device, index) in devices" :key="device.id" class="device-card">
|
<el-card v-for="(device, index) in devices" :key="device.id" class="device-card" :class="activeDeviceIndex === index ? 'active' : ''" @click="selectDevice(device, index)">
|
||||||
<template #header>
|
<template #header>
|
||||||
<div class="device-card-header">
|
<div class="device-card-header">
|
||||||
<!-- <span>{{ device.code }}</span>-->
|
<!-- <span>{{ device.code }}</span>-->
|
||||||
<span>设备{{ device.id }}</span>
|
<span>设备{{ device.id }}</span>
|
||||||
<el-tag :type="device.status === 1 ? 'success' : 'info'" size="small">
|
<el-tag :type="device.connectStatus === 1 ? 'success' : 'info'" size="small">
|
||||||
{{ device.status === 1 ? '已连接' : '未连接' }}
|
{{ device.connectStatus === 1 ? '已连接' : '未连接' }}
|
||||||
</el-tag>
|
</el-tag>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<div class="device-card-body">
|
<div class="device-card-body">
|
||||||
<div :class="['iconfont', 'icon-icon_duanluqi', 'circuit-breaker', device.result === '成功' ? 'color-green' : device.result === '失败' ? 'color-red' : '']"></div>
|
<div :class="['iconfont', 'icon-icon_duanluqi', 'circuit-breaker', device.result === '成功' ? 'color-green' : device.result === '失败' ? 'color-red' : '']"></div>
|
||||||
<p>设备码: {{ device.deviceSN || '无' }}</p>
|
<p>芯片ID: {{ device.deviceSN || '无' }}</p>
|
||||||
<p>设备端口: {{ device.devicePort || '无' }}</p>
|
<p>设备端口: {{ device.devicePort || '无' }}</p>
|
||||||
<p>
|
<p>
|
||||||
标定结果: <span :class="['device-result', device.result === '成功' ? 'color-green' : device.result === '失败' ? 'color-red' : '']">{{ device.result || '无' }}</span>
|
标定结果: <span :class="['device-result', device.result === '成功' ? 'color-green' : device.result === '失败' ? 'color-red' : '']">{{ device.result || '无' }}</span>
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
失败描述:
|
结果描述:
|
||||||
<span
|
<span
|
||||||
><el-tooltip class="box-item" effect="dark" :content="device.resultTxt" placement="top-start">
|
><el-tooltip class="box-item" effect="dark" :content="device.resultTxt" placement="top-start">
|
||||||
{{ device.resultTxt || '无' }}
|
{{ device.resultTxt || '无' }}
|
||||||
|
@ -104,6 +109,11 @@
|
||||||
<span class="iconfont icon-icon_suoding"></span>
|
<span class="iconfont icon-icon_suoding"></span>
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
</view>
|
</view>
|
||||||
|
<view class="log-box-operate-item" @click="clearLog">
|
||||||
|
<el-tooltip class="box-item" content="清空日志" effect="dark" placement="bottom">
|
||||||
|
<span class="iconfont icon-icon_shanchu"></span>
|
||||||
|
</el-tooltip>
|
||||||
|
</view>
|
||||||
<view class="log-box-operate-item" @click="toggleOpenLog">
|
<view class="log-box-operate-item" @click="toggleOpenLog">
|
||||||
<el-tooltip v-if="isOpenLog" class="box-item" content="收缩日志" effect="dark" placement="bottom">
|
<el-tooltip v-if="isOpenLog" class="box-item" content="收缩日志" effect="dark" placement="bottom">
|
||||||
<span class="iconfont icon-up-arrow"></span>
|
<span class="iconfont icon-up-arrow"></span>
|
||||||
|
@ -113,14 +123,13 @@
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
</view>
|
</view>
|
||||||
</div>
|
</div>
|
||||||
<div class="version-info">{{ version }}</div>
|
<div class="version-info">V{{ version }}</div>
|
||||||
</div>
|
</div>
|
||||||
</el-footer>
|
</el-footer>
|
||||||
|
|
||||||
<!-- 方案配置抽屉 -->
|
<!-- 方案配置抽屉 -->
|
||||||
<el-drawer v-model="schemeDrawerVisible" title="方案配置" size="80%" :destroy-on-close="true">
|
<el-drawer v-model="schemeDrawerVisible" title="方案配置" size="80%" :destroy-on-close="true">
|
||||||
<div class="scheme-drawer-content">
|
<div class="scheme-drawer-content">
|
||||||
<div class="scheme-list">
|
|
||||||
<div class="scheme-list-header">
|
<div class="scheme-list-header">
|
||||||
<el-button type="primary" @click="addScheme">新增方案</el-button>
|
<el-button type="primary" @click="addScheme">新增方案</el-button>
|
||||||
<el-button type="primary" @click="loadSchemes">刷新</el-button>
|
<el-button type="primary" @click="loadSchemes">刷新</el-button>
|
||||||
|
@ -137,6 +146,7 @@
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
</div>
|
</div>
|
||||||
|
</el-drawer>
|
||||||
|
|
||||||
<!-- 方案详情对话框 -->
|
<!-- 方案详情对话框 -->
|
||||||
<el-dialog v-model="schemeDetailVisible" :title="currentScheme.schemeName" width="95%" :destroy-on-close="true" align-center :close-on-click-modal="false">
|
<el-dialog v-model="schemeDetailVisible" :title="currentScheme.schemeName" width="95%" :destroy-on-close="true" align-center :close-on-click-modal="false">
|
||||||
|
@ -252,14 +262,53 @@
|
||||||
</span>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
|
|
||||||
|
<!-- 方案配置抽屉 -->
|
||||||
|
<el-drawer v-model="logVisible" title="设备日志" size="80%" :destroy-on-close="true">
|
||||||
|
<div class="scheme-drawer-content log-content">
|
||||||
|
<div class="device-info">
|
||||||
|
<div class="device-info-item">设备: {{ activeDeviceInfo.id || '-' }}</div>
|
||||||
|
<div class="device-info-item">芯片ID: {{ activeDeviceInfo.deviceSN || '-' }}</div>
|
||||||
|
<div class="device-info-item">设备端口: {{ activeDeviceInfo.devicePort || '-' }}</div>
|
||||||
|
<div class="device-info-item">标定结果: {{ activeDeviceInfo.result || '-' }}</div>
|
||||||
|
<div class="device-info-item">结果描述: {{ activeDeviceInfo.resultTxt || '-' }}</div>
|
||||||
|
</div>
|
||||||
|
<el-tabs v-model="logTabActive" class="demo-tabs" @tab-click="logTabChange">
|
||||||
|
<el-tab-pane label="标定日志" name="log">
|
||||||
|
<el-table :data="transposedLogList" style="width: 100%" size="small" scrollbar-always-on resizable empty-text="暂无日志">
|
||||||
|
<el-table-column prop="name" label="参数" fixed align="center" />
|
||||||
|
<el-table-column v-for="(item, index) in logList" :key="index" :label="item.name" align="center">
|
||||||
|
<el-table-column prop="name" label="结果" align="center" min-width="80">
|
||||||
|
<template #default="scope">
|
||||||
|
<span :style="{ color: scope.row.data[index].result != 1 ? 'red' : 'green' }">{{ scope.row.data[index].value || '-' }}</span>
|
||||||
|
<el-icon v-if="scope.row.data[index].result === 2" style="color: red"><Top /></el-icon>
|
||||||
|
<el-icon v-if="scope.row.data[index].result === 0" style="color: red"><Bottom /></el-icon>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="范围" align="errLog">
|
||||||
|
<template #default="scope">
|
||||||
|
<span style="margin-left: 8px; color: #888; font-size: 12px">{{
|
||||||
|
scope.row.data[index].minValue && scope.row.data[index].maxValue ? scope.row.data[index].minValue + ' ~ ' + scope.row.data[index].maxValue : '-'
|
||||||
|
}}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
</el-tab-pane>
|
||||||
|
<el-tab-pane label="错误日志" name="second">
|
||||||
|
错误日志
|
||||||
|
</el-tab-pane>
|
||||||
|
</el-tabs>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</el-drawer>
|
</el-drawer>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, onMounted, computed, onUnmounted } from 'vue';
|
import { ref, onMounted, onUnmounted, computed } from 'vue';
|
||||||
import { ElMessage, ElMessageBox } from 'element-plus';
|
import { ElMessage, ElMessageBox } from 'element-plus';
|
||||||
|
import { throttle } from 'lodash-es';
|
||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import config from '@renderer/util/config.js';
|
import config from '@renderer/util/config.js';
|
||||||
|
@ -273,6 +322,7 @@ const devices = ref([]);
|
||||||
const isScroll = ref(true);
|
const isScroll = ref(true);
|
||||||
const logs = ref([]);
|
const logs = ref([]);
|
||||||
const version = ref('V1.0.0');
|
const version = ref('V1.0.0');
|
||||||
|
const logTabActive = ref('log')
|
||||||
|
|
||||||
const loading = ref(true);
|
const loading = ref(true);
|
||||||
const isOpenLog = ref(false);
|
const isOpenLog = ref(false);
|
||||||
|
@ -307,6 +357,236 @@ const defaultConfList = ref({
|
||||||
format: []
|
format: []
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const logVisible = ref(false);
|
||||||
|
|
||||||
|
const logList = ref([
|
||||||
|
{
|
||||||
|
name: '标定1',
|
||||||
|
dataList: [
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
name: '电压',
|
||||||
|
value: 220,
|
||||||
|
unit: 'V',
|
||||||
|
accuracy: 1,
|
||||||
|
result: 0,
|
||||||
|
minValue: '210',
|
||||||
|
maxValue: '230'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 2,
|
||||||
|
name: '电流',
|
||||||
|
value: 5,
|
||||||
|
unit: 'A',
|
||||||
|
accuracy: 1,
|
||||||
|
result: 0,
|
||||||
|
minValue: '7.5',
|
||||||
|
maxValue: '12.5'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 3,
|
||||||
|
name: '漏电流',
|
||||||
|
value: 1,
|
||||||
|
unit: 'A',
|
||||||
|
accuracy: 1,
|
||||||
|
result: 2,
|
||||||
|
minValue: '0',
|
||||||
|
maxValue: '0'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '标定1重复1',
|
||||||
|
dataList: [
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
name: '电压',
|
||||||
|
value: 220,
|
||||||
|
unit: 'V',
|
||||||
|
accuracy: 1,
|
||||||
|
result: 1,
|
||||||
|
minValue: '210',
|
||||||
|
maxValue: '230'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 2,
|
||||||
|
name: '电流',
|
||||||
|
value: 10,
|
||||||
|
unit: 'A',
|
||||||
|
accuracy: 1,
|
||||||
|
result: 1,
|
||||||
|
minValue: '7.5',
|
||||||
|
maxValue: '12.5'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 3,
|
||||||
|
name: '漏电流',
|
||||||
|
value: 0,
|
||||||
|
unit: 'A',
|
||||||
|
accuracy: 1,
|
||||||
|
result: 1,
|
||||||
|
minValue: '0',
|
||||||
|
maxValue: '0'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '标定2',
|
||||||
|
dataList: [
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
name: '电压',
|
||||||
|
value: 220,
|
||||||
|
unit: 'V',
|
||||||
|
accuracy: 1,
|
||||||
|
result: 1,
|
||||||
|
minValue: '210',
|
||||||
|
maxValue: '230'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 2,
|
||||||
|
name: '电流',
|
||||||
|
value: 10,
|
||||||
|
unit: 'A',
|
||||||
|
accuracy: 1,
|
||||||
|
result: 1,
|
||||||
|
minValue: '7.5',
|
||||||
|
maxValue: '12.5'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 3,
|
||||||
|
name: '漏电流',
|
||||||
|
value: 0,
|
||||||
|
unit: 'A',
|
||||||
|
accuracy: 1,
|
||||||
|
result: 1,
|
||||||
|
minValue: '0',
|
||||||
|
maxValue: '0'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '标定3',
|
||||||
|
dataList: [
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
name: '电压',
|
||||||
|
value: 220,
|
||||||
|
unit: 'V',
|
||||||
|
accuracy: 1,
|
||||||
|
result: 1,
|
||||||
|
minValue: '210',
|
||||||
|
maxValue: '230'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 2,
|
||||||
|
name: '电流',
|
||||||
|
value: 10,
|
||||||
|
unit: 'A',
|
||||||
|
accuracy: 1,
|
||||||
|
result: 1,
|
||||||
|
minValue: '7.5',
|
||||||
|
maxValue: '12.5'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 3,
|
||||||
|
name: '漏电流',
|
||||||
|
value: 0,
|
||||||
|
unit: 'A',
|
||||||
|
accuracy: 1,
|
||||||
|
result: 1,
|
||||||
|
minValue: '0',
|
||||||
|
maxValue: '0'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '标定4',
|
||||||
|
dataList: [
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
name: '电压',
|
||||||
|
value: 220,
|
||||||
|
unit: 'V',
|
||||||
|
accuracy: 1,
|
||||||
|
result: 1,
|
||||||
|
minValue: '210',
|
||||||
|
maxValue: '230'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 2,
|
||||||
|
name: '电流',
|
||||||
|
value: 10,
|
||||||
|
unit: 'A',
|
||||||
|
accuracy: 1,
|
||||||
|
result: 1,
|
||||||
|
minValue: '7.5',
|
||||||
|
maxValue: '12.5'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 3,
|
||||||
|
name: '漏电流',
|
||||||
|
value: 0,
|
||||||
|
unit: 'A',
|
||||||
|
accuracy: 1,
|
||||||
|
result: 1,
|
||||||
|
minValue: '0',
|
||||||
|
maxValue: '0'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '标定5',
|
||||||
|
dataList: [
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
name: '电压',
|
||||||
|
value: 220,
|
||||||
|
unit: 'V',
|
||||||
|
accuracy: 1,
|
||||||
|
result: 1,
|
||||||
|
minValue: '210',
|
||||||
|
maxValue: '230'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 2,
|
||||||
|
name: '电流',
|
||||||
|
value: 10,
|
||||||
|
unit: 'A',
|
||||||
|
accuracy: 1,
|
||||||
|
result: 1,
|
||||||
|
minValue: '7.5',
|
||||||
|
maxValue: '12.5'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 3,
|
||||||
|
name: '漏电流',
|
||||||
|
value: 0,
|
||||||
|
unit: 'A',
|
||||||
|
accuracy: 1,
|
||||||
|
result: 1,
|
||||||
|
minValue: '0',
|
||||||
|
maxValue: '0'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
|
||||||
|
const logBoxRef = ref(null);
|
||||||
|
const MAX_LOG_LENGTH = 800;
|
||||||
|
|
||||||
|
const activeDeviceIndex = ref(0);
|
||||||
|
|
||||||
|
const activeDeviceInfo = ref({
|
||||||
|
id: 0,
|
||||||
|
devicePort: '',
|
||||||
|
deviceSN: '',
|
||||||
|
connectStatus: 0,
|
||||||
|
switch: 0,
|
||||||
|
result: 0,
|
||||||
|
resultTxt: ''
|
||||||
|
});
|
||||||
|
|
||||||
const defaultPropList = ref([]);
|
const defaultPropList = ref([]);
|
||||||
|
|
||||||
const currentScheme = ref({
|
const currentScheme = ref({
|
||||||
|
@ -328,16 +608,29 @@ const currentScheme = ref({
|
||||||
steps: []
|
steps: []
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const logTabChange = (tab, event) => {
|
||||||
|
console.log(tab, event)
|
||||||
|
}
|
||||||
|
|
||||||
|
const selectDevice = (item, index) => {
|
||||||
|
activeDeviceInfo.value = item;
|
||||||
|
activeDeviceIndex.value = index;
|
||||||
|
// 添加日志到日志列表
|
||||||
|
// logList.value = [];
|
||||||
|
logVisible.value = true;
|
||||||
|
};
|
||||||
|
|
||||||
const generateMockDevices = () => {
|
const generateMockDevices = () => {
|
||||||
const mockDevices = [];
|
const mockDevices = [];
|
||||||
for (let i = 1; i <= 16; i++) {
|
for (let i = 1; i <= 16; i++) {
|
||||||
mockDevices.push({
|
mockDevices.push({
|
||||||
id: i,
|
id: i,
|
||||||
code: `设备 ${i}`,
|
code: `设备 ${i}`,
|
||||||
deviceCode: Math.floor(1000000000000 + Math.random() * 9000000000000).toString(),
|
deviceSN: Math.floor(1000000000000 + Math.random() * 9000000000000).toString(),
|
||||||
address: `192.168.1.${i}`,
|
devicePort: `192.168.1.${i}`,
|
||||||
status: i % 3 === 0 ? 'disconnected' : 'connected', // Mock status
|
connectStatus: i % 3 === 0 ? 1 : 0,
|
||||||
result: i % 3 !== 0 ? (i % 2 === 0 ? '' : '成功') : '失败' // Mock result
|
result: i % 3 !== 0 ? (i % 2 === 0 ? '' : '成功') : '失败',
|
||||||
|
resultTxt: i % 3 !== 0 ? (i % 2 === 0 ? '' : '成功') : '失败'
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
devices.value = mockDevices;
|
devices.value = mockDevices;
|
||||||
|
@ -419,33 +712,58 @@ const generateLogs = () => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 安全解析 JSON
|
||||||
|
const tryParseJSON = data => {
|
||||||
|
try {
|
||||||
|
return JSON.parse(data);
|
||||||
|
} catch {
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
// 节流滚动
|
||||||
|
const throttledScroll = throttle(() => {
|
||||||
|
logBoxRef.value.scrollTop = logBoxRef.value.scrollHeight;
|
||||||
|
}, 100);
|
||||||
|
|
||||||
const getSocketMeassage = message => {
|
const getSocketMeassage = message => {
|
||||||
let msg = JSON.parse(message.data);
|
const msg = tryParseJSON(message.data);
|
||||||
if (msg.msgType !== undefined) {
|
const newLog = {
|
||||||
if (logs.value.length > 400) {
|
|
||||||
logs.value.shift();
|
|
||||||
}
|
|
||||||
logs.value.push({
|
|
||||||
time: dayjs().format('YYYY-MM-DD HH:mm:ss'),
|
time: dayjs().format('YYYY-MM-DD HH:mm:ss'),
|
||||||
msg: msg.data,
|
msg: msg.data ?? msg,
|
||||||
type: msg.msgType
|
type: msg.msgType ?? null
|
||||||
});
|
};
|
||||||
} else {
|
|
||||||
if (logs.value.length > 400) {
|
// 批量更新日志数组
|
||||||
logs.value.shift();
|
logs.value = [...logs.value.slice(-MAX_LOG_LENGTH + 1), newLog];
|
||||||
}
|
|
||||||
logs.value.push({
|
// 按需触发滚动
|
||||||
time: dayjs().format('YYYY-MM-DD HH:mm:ss'),
|
if (isScroll.value) throttledScroll();
|
||||||
msg,
|
|
||||||
type: null
|
// let msg = JSON.parse(message.data);
|
||||||
});
|
// if (msg.msgType !== undefined) {
|
||||||
}
|
// if (logs.value.length > 400) {
|
||||||
if (isScroll.value) {
|
// logs.value.shift();
|
||||||
setTimeout(() => {
|
// }
|
||||||
let div = document.querySelector('#log-box-main');
|
// logs.value.push({
|
||||||
div.scrollTop = div.scrollHeight;
|
// time: dayjs().format('YYYY-MM-DD HH:mm:ss'),
|
||||||
}, 200);
|
// msg: msg.data,
|
||||||
}
|
// type: msg.msgType
|
||||||
|
// });
|
||||||
|
// } else {
|
||||||
|
// if (logs.value.length > 400) {
|
||||||
|
// logs.value.shift();
|
||||||
|
// }
|
||||||
|
// logs.value.push({
|
||||||
|
// time: dayjs().format('YYYY-MM-DD HH:mm:ss'),
|
||||||
|
// msg,
|
||||||
|
// type: null
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
// if (isScroll.value) {
|
||||||
|
// requestAnimationFrame(() => {
|
||||||
|
// logBoxRef.value.scrollTop = logBoxRef.value.scrollHeight;
|
||||||
|
// });
|
||||||
|
// }
|
||||||
};
|
};
|
||||||
|
|
||||||
const initSocket = () => {
|
const initSocket = () => {
|
||||||
|
@ -458,7 +776,14 @@ const socketStatus = computed(() => {
|
||||||
});
|
});
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
|
logBoxRef.value = document.querySelector('#log-box-main');
|
||||||
initSocket();
|
initSocket();
|
||||||
|
if (window.electron && typeof window.electron.getAppVersion === 'function') {
|
||||||
|
window.electron.getAppVersion().then(v => {
|
||||||
|
version.value = v;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// generateMockDevices();
|
||||||
getSchemeDefaultConf();
|
getSchemeDefaultConf();
|
||||||
getSchemeDefaultProp();
|
getSchemeDefaultProp();
|
||||||
generateDeviceList();
|
generateDeviceList();
|
||||||
|
@ -675,6 +1000,10 @@ const toggleOpenLog = () => {
|
||||||
isOpenLog.value = !isOpenLog.value;
|
isOpenLog.value = !isOpenLog.value;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const clearLog = () => {
|
||||||
|
logs.value = [];
|
||||||
|
};
|
||||||
|
|
||||||
// 删除标定步骤
|
// 删除标定步骤
|
||||||
const deleteCalibrationStep = index => {
|
const deleteCalibrationStep = index => {
|
||||||
currentScheme.value.steps.splice(index, 1);
|
currentScheme.value.steps.splice(index, 1);
|
||||||
|
@ -683,6 +1012,22 @@ const deleteCalibrationStep = index => {
|
||||||
step.id = idx + 1;
|
step.id = idx + 1;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 设备日志转置,便于表格渲染
|
||||||
|
const transposedLogList = computed(() => {
|
||||||
|
if (!logList.value.length) return [];
|
||||||
|
// 假设每个dataList参数顺序一致
|
||||||
|
const paramCount = logList.value[0].dataList.length;
|
||||||
|
const result = [];
|
||||||
|
for (let i = 0; i < paramCount; i++) {
|
||||||
|
const param = {
|
||||||
|
name: logList.value[0].dataList[i].name + (logList.value[0].dataList[i].unit ? '(' + logList.value[0].dataList[i].unit + ')' : ''),
|
||||||
|
data: logList.value.map(log => log.dataList[i])
|
||||||
|
};
|
||||||
|
result.push(param);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
|
@ -709,7 +1054,9 @@ const deleteCalibrationStep = index => {
|
||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
&.list-two {
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
|
}
|
||||||
.scheme-item {
|
.scheme-item {
|
||||||
margin-left: 10px;
|
margin-left: 10px;
|
||||||
&:first-child {
|
&:first-child {
|
||||||
|
@ -719,6 +1066,12 @@ const deleteCalibrationStep = index => {
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
&.list-one {
|
||||||
|
padding-bottom: 0;
|
||||||
|
.scheme-item {
|
||||||
|
margin-right: 55px;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.header-left,
|
.header-left,
|
||||||
|
@ -745,7 +1098,12 @@ const deleteCalibrationStep = index => {
|
||||||
}
|
}
|
||||||
|
|
||||||
.device-card {
|
.device-card {
|
||||||
|
cursor: pointer;
|
||||||
/* background-color: #ffffff; */ /* Default card color is fine */
|
/* background-color: #ffffff; */ /* Default card color is fine */
|
||||||
|
border: 1px solid #e6e6e6;
|
||||||
|
&.active {
|
||||||
|
border: 1px solid #67c23a;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.device-card-header {
|
.device-card-header {
|
||||||
|
@ -770,11 +1128,13 @@ const deleteCalibrationStep = index => {
|
||||||
}
|
}
|
||||||
|
|
||||||
.color-green {
|
.color-green {
|
||||||
color: #67c23a; /* Green for connected */
|
color: #67c23a;
|
||||||
|
/* Green for connected */
|
||||||
}
|
}
|
||||||
|
|
||||||
.color-red {
|
.color-red {
|
||||||
color: #f56c6c; /* Red for disconnected */
|
color: #f56c6c;
|
||||||
|
/* Red for disconnected */
|
||||||
}
|
}
|
||||||
|
|
||||||
.calibration-footer {
|
.calibration-footer {
|
||||||
|
@ -785,6 +1145,7 @@ const deleteCalibrationStep = index => {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
|
|
||||||
&.open-log {
|
&.open-log {
|
||||||
height: 350px;
|
height: 350px;
|
||||||
}
|
}
|
||||||
|
@ -795,7 +1156,8 @@ const deleteCalibrationStep = index => {
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
font-family: 'Courier New', Courier, monospace;
|
font-family: 'Courier New', Courier, monospace;
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
white-space: pre-wrap; /* Ensures logs wrap and preserve formatting */
|
white-space: pre-wrap;
|
||||||
|
/* Ensures logs wrap and preserve formatting */
|
||||||
border: 1px solid #555;
|
border: 1px solid #555;
|
||||||
padding: 5px;
|
padding: 5px;
|
||||||
background-color: #202020;
|
background-color: #202020;
|
||||||
|
@ -805,6 +1167,7 @@ const deleteCalibrationStep = index => {
|
||||||
margin: 2px 0;
|
margin: 2px 0;
|
||||||
color: #dcdcdc;
|
color: #dcdcdc;
|
||||||
}
|
}
|
||||||
|
|
||||||
.log-box-main {
|
.log-box-main {
|
||||||
font-family: 'Courier New', Courier, monospace;
|
font-family: 'Courier New', Courier, monospace;
|
||||||
padding: 5px;
|
padding: 5px;
|
||||||
|
@ -816,6 +1179,7 @@ const deleteCalibrationStep = index => {
|
||||||
background-color: #202020;
|
background-color: #202020;
|
||||||
color: #dcdcdc;
|
color: #dcdcdc;
|
||||||
scroll-behavior: smooth;
|
scroll-behavior: smooth;
|
||||||
|
|
||||||
.log-item {
|
.log-item {
|
||||||
word-wrap: break-word;
|
word-wrap: break-word;
|
||||||
word-break: break-all;
|
word-break: break-all;
|
||||||
|
@ -824,6 +1188,7 @@ const deleteCalibrationStep = index => {
|
||||||
line-height: 18px;
|
line-height: 18px;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
margin-left: 8px;
|
margin-left: 8px;
|
||||||
|
|
||||||
.iconfont {
|
.iconfont {
|
||||||
&.icon-icon_fuzhi {
|
&.icon-icon_fuzhi {
|
||||||
line-height: 26px;
|
line-height: 26px;
|
||||||
|
@ -835,26 +1200,31 @@ const deleteCalibrationStep = index => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.calibration-footer-btn {
|
.calibration-footer-btn {
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
padding-top: 5px;
|
padding-top: 5px;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
|
|
||||||
.btn-box {
|
.btn-box {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|
||||||
.log-box-operate-item {
|
.log-box-operate-item {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
margin-right: 10px;
|
margin-right: 10px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
|
||||||
.icon-icon_gengxin {
|
.icon-icon_gengxin {
|
||||||
margin-left: 2px;
|
margin-left: 2px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.version-info {
|
.version-info {
|
||||||
text-align: right;
|
text-align: right;
|
||||||
color: #888;
|
color: #888;
|
||||||
|
@ -862,34 +1232,34 @@ const deleteCalibrationStep = index => {
|
||||||
|
|
||||||
/* Element Plus component overrides if needed */
|
/* Element Plus component overrides if needed */
|
||||||
.el-header {
|
.el-header {
|
||||||
--el-header-padding: 0 20px; /* Adjust if necessary */
|
--el-header-padding: 0 20px;
|
||||||
--el-header-height: 60px; /* Ensure this matches fixed height */
|
/* Adjust if necessary */
|
||||||
|
--el-header-height: 60px;
|
||||||
|
/* Ensure this matches fixed height */
|
||||||
}
|
}
|
||||||
|
|
||||||
.el-footer {
|
.el-footer {
|
||||||
--el-footer-padding: 0px; /* Adjust if necessary */
|
--el-footer-padding: 0px;
|
||||||
--el-footer-height: 200px; /* Ensure this matches fixed height */
|
/* Adjust if necessary */
|
||||||
|
--el-footer-height: 200px;
|
||||||
|
/* Ensure this matches fixed height */
|
||||||
}
|
}
|
||||||
|
|
||||||
.el-main {
|
.el-main {
|
||||||
--el-main-padding: 20px; /* Adjust if necessary */
|
--el-main-padding: 20px;
|
||||||
|
/* Adjust if necessary */
|
||||||
}
|
}
|
||||||
|
|
||||||
.el-select .el-input__inner {
|
.el-select .el-input__inner {
|
||||||
background-color: #555; /* Darker input fields */
|
background-color: #555;
|
||||||
|
/* Darker input fields */
|
||||||
color: white;
|
color: white;
|
||||||
border-color: #666;
|
border-color: #666;
|
||||||
}
|
}
|
||||||
|
|
||||||
//.el-button--primary {
|
:deep(.log-content .el-table .cell) {
|
||||||
// background-color: #007bff; /* Example primary button color */
|
padding: 0 !important;
|
||||||
// border-color: #007bff;
|
}
|
||||||
//}
|
|
||||||
//
|
|
||||||
//.el-button--danger {
|
|
||||||
// background-color: #dc3545; /* Example danger button color */
|
|
||||||
// border-color: #dc3545;
|
|
||||||
//}
|
|
||||||
|
|
||||||
:deep(.device-grid .el-card__header) {
|
:deep(.device-grid .el-card__header) {
|
||||||
padding: 10px 5px;
|
padding: 10px 5px;
|
||||||
|
@ -903,6 +1273,17 @@ const deleteCalibrationStep = index => {
|
||||||
|
|
||||||
.scheme-drawer-content {
|
.scheme-drawer-content {
|
||||||
padding: 20px;
|
padding: 20px;
|
||||||
|
.device-info {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
background: #ddd;
|
||||||
|
padding: 10px;
|
||||||
|
font-size: 13px;
|
||||||
|
align-items: center;
|
||||||
|
.device-info-item {
|
||||||
|
margin-right: 10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.scheme-list-header {
|
.scheme-list-header {
|
||||||
|
|
Loading…
Reference in New Issue