feat(calibration): 添加标定后检测步骤功能

- 新增标定后检测步骤表格和相关功能
- 优化标定步骤界面布局和交互
- 修复部分组件样式问题
- 版本号升级到 1.0.12
This commit is contained in:
fhysy 2025-07-31 10:16:05 +08:00
parent a929a7b47d
commit 7d53c34651
5 changed files with 252 additions and 71 deletions

View File

@ -1,6 +1,6 @@
{ {
"name": "gy-calibration", "name": "gy-calibration",
"version": "1.0.10", "version": "1.0.12",
"description": "谷云开发部开发的断路器标定软件", "description": "谷云开发部开发的断路器标定软件",
"main": "./out/main/index.js", "main": "./out/main/index.js",
"author": "example.com", "author": "example.com",

View File

@ -1,7 +1,7 @@
server: server:
serverMain: serverMain:
address: "8000" address: "8000"
serverRoot: "resource/public" #serverRoot: "resource/public"
logger: logger:
path: "logs" path: "logs"

Binary file not shown.

Binary file not shown.

View File

@ -9,9 +9,9 @@
<el-button icon="RemoveFilled" type="danger" @click="stopExecution">停止</el-button> <el-button icon="RemoveFilled" type="danger" @click="stopExecution">停止</el-button>
<span style="margin-left: 10px">操作员编号:</span> <span style="margin-left: 10px">操作员编号:</span>
<el-input v-model="operatorCode" placeholder="输入操作员编号" style="width: 120px; margin-left: 10px" /> <el-input v-model="operatorCode" placeholder="输入操作员编号" style="width: 120px; margin-left: 10px" />
<div class="statistics-box"> <div class="statistics-box">
生产总数/合格数/不合格次数: <span class="statistics-number">{{ equipmentStatistics.totalDevice }}/{{ equipmentStatistics.successDevice }}/{{ equipmentStatistics.failCount }}</span> 生产总数/合格数/不合格次数: <span class="statistics-number">{{ equipmentStatistics.totalDevice }}/{{ equipmentStatistics.successDevice }}/{{ equipmentStatistics.failCount }}</span>
</div> </div>
</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>
@ -317,7 +317,7 @@
</el-form-item> </el-form-item>
</div> </div>
<el-divider>标定步骤</el-divider> <el-divider>标定中检测步骤</el-divider>
<div class="calibration-steps"> <div class="calibration-steps">
<div class="steps-header"> <div class="steps-header">
<el-button type="primary" @click="addCalibrationStep">添加步骤</el-button> <el-button type="primary" @click="addCalibrationStep">添加步骤</el-button>
@ -335,18 +335,32 @@
<el-input-number v-model="scope.row.step" :min="1" /> <el-input-number v-model="scope.row.step" :min="1" />
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="voltage" align="center" label="电压Un(%)"> <el-table-column prop="voltage" align="center" label="电压U(%)">
<template #default="scope"> <template #default="scope">
<el-input-number v-model="scope.row.voltage" :min="0" :precision="1" /> <el-input-number v-model="scope.row.voltage" :min="0" :precision="1" />
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="current" align="center" label="电流Ib(%)"> <el-table-column prop="current" align="center" label="电流I(%)/漏电流(%)">
<template #default="scope"> <template #default="scope">
<el-input-number v-if="!scope.row.isILeak" v-model="scope.row.current" :min="0" :precision="1" /> <div v-if="!scope.row.isILeak" style="display: flex; align-items: center;">
<span v-else>{{ currentScheme.configParam.format[5].value + currentScheme.configParam.format[5].unit }}</span> <!-- <el-tooltip class="box-item" effect="dark" content="电流I(%)" placement="left">
<el-input-number v-model="scope.row.current" :min="0" :precision="1" />
</el-tooltip> -->
<p style="width:50px">电流: </p>
<el-input-number v-model="scope.row.current" :min="0" :precision="1" />
</div>
<!-- <el-input-number v-model="scope.row.current" :min="0" :precision="1" /> -->
<div v-else style="display: flex; align-items: center;">
<!-- <el-tooltip class="box-item" effect="dark" content="漏电流(%)" placement="left">
<el-input-number v-model="scope.row.current" :min="0" :precision="1" />
</el-tooltip> -->
<p style="width:50px">漏电流: </p>
<el-input-number v-model="scope.row.current" :min="0" :precision="1" />
</div>
<!-- <span v-else>{{ currentScheme.configParam.format[5].value + currentScheme.configParam.format[5].unit }}</span> -->
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="powerFactor" align="center" label="功率因数"> <el-table-column prop="powerFactor" align="center" label="功率因数" width="120">
<template #default="scope"> <template #default="scope">
<el-select v-model="scope.row.powerFactor"> <el-select v-model="scope.row.powerFactor">
<el-option label="0.5L" value="0.5L" /> <el-option label="0.5L" value="0.5L" />
@ -370,6 +384,78 @@
</el-table> </el-table>
</div> </div>
<el-divider>标定后检测步骤</el-divider>
<div class="calibration-steps">
<div class="steps-header">
<!-- <el-button type="primary" @click="addCalibrationLaterStep">添加步骤</el-button> -->
</div>
<el-table :data="currentScheme.laterSteps" size="small" style="width: 100%">
<!-- <el-table-column type="index" width="50" />-->
<el-table-column prop="id" align="center" label="排序" width="80" />
<!-- <el-table-column prop="id" align="center" label="步骤值">-->
<!-- <template #default="scope">-->
<!-- <el-input-number v-model="scope.row.id" :min="0" />-->
<!-- </template>-->
<!-- </el-table-column>-->
<el-table-column prop="step" align="center" label="步骤值">
<template #default="scope">
<el-input-number v-model="scope.row.step" :min="1" />
</template>
</el-table-column>
<el-table-column prop="voltage" align="center" label="电压U(%)">
<template #default="scope">
<el-input-number v-model="scope.row.voltage" :min="0" :precision="1" />
</template>
</el-table-column>
<el-table-column prop="current" align="center" label="电流I(%)/漏电流(%)">
<template #default="scope">
<div v-if="!scope.row.isILeak" style="display: flex; align-items: center;">
<!-- <el-tooltip class="box-item" effect="dark" content="电流I(%)" placement="left">
<el-input-number v-model="scope.row.current" :min="0" :precision="1" />
</el-tooltip> -->
<p style="width:50px">电流: </p>
<el-input-number v-model="scope.row.current" :min="0" :precision="1" />
</div>
<!-- <el-input-number v-model="scope.row.current" :min="0" :precision="1" /> -->
<div v-else style="display: flex; align-items: center;">
<!-- <el-tooltip class="box-item" effect="dark" content="漏电流(%)" placement="left">
<el-input-number v-model="scope.row.current" :min="0" :precision="1" />
</el-tooltip> -->
<p style="width:50px">漏电流: </p>
<el-input-number v-model="scope.row.current" :min="0" :precision="1" />
</div>
</template>
</el-table-column>
<!-- <el-table-column prop="current" align="center" label="电流Ib(%)">
<template #default="scope">
<el-input-number v-model="scope.row.current" :min="0" :precision="1" />
</template>
</el-table-column> -->
<el-table-column prop="powerFactor" align="center" label="功率因数" width="120">
<template #default="scope">
<el-select v-model="scope.row.powerFactor">
<el-option label="0.5L" value="0.5L" />
<el-option label="0.8L" value="0.8L" />
<el-option label="1" value="1" />
<el-option label="0.5C" value="0.5C" />
<el-option label="0.8C" value="0.8C" />
</el-select>
</template>
</el-table-column>
<el-table-column prop="isILeak" align="center" label="检测漏电" width="120">
<template #default="scope">
<el-switch v-model="scope.row.isILeak" />
</template>
</el-table-column>
<el-table-column label="操作" width="80">
<template #default="scope">
<!-- <el-button type="danger" link @click="deleteCalibrationLaterStep(scope.$index)">删除</el-button> -->
</template>
</el-table-column>
</el-table>
</div>
<!-- 新增漏电检测设置分组 --> <!-- 新增漏电检测设置分组 -->
<el-divider>漏电检测设置</el-divider> <el-divider>漏电检测设置</el-divider>
<el-row :gutter="20"> <el-row :gutter="20">
@ -425,7 +511,7 @@
<el-table-column v-for="col in logParamColumns" :key="col.key" :prop="'paramMap.' + col.valueKey + '.actualError'" :label="col.valueKey" align="center"> <el-table-column v-for="col in logParamColumns" :key="col.key" :prop="'paramMap.' + col.valueKey + '.actualError'" :label="col.valueKey" align="center">
<template #header> <template #header>
<el-tooltip effect="dark" :content="(col.valueName || col.valueKey) + (col.valueUnit ? ' [' + col.valueUnit + ']' : '')" placement="top"> <el-tooltip effect="dark" :content="(col.valueName || col.valueKey) + (col.valueUnit ? ' [' + col.valueUnit + ']' : '')" placement="top">
<span>{{ col.valueKey }}</span> <span>{{ (col.valueName || col.valueKey) + (col.valueUnit ? ' [' + col.valueUnit + ']' : '') }}</span>
</el-tooltip> </el-tooltip>
</template> </template>
<template #default="scope"> <template #default="scope">
@ -555,9 +641,9 @@ const schemeList = ref([]);
const activeScheme = ref(); const activeScheme = ref();
const equipmentStatistics = ref({ const equipmentStatistics = ref({
totalDevice: 0, totalDevice: 0,
successDevice: 0, successDevice: 0,
failCount: 0 failCount: 0
}); });
const accuracyType = ref({ const accuracyType = ref({
@ -633,10 +719,10 @@ const shortcutKeyList = ref([
label: '↓', label: '↓',
action: '下一个日志(查询时)' action: '下一个日志(查询时)'
}, },
{ {
label: 'Enter', label: 'Enter',
action: '下一个日志(查询时)' action: '下一个日志(查询时)'
}, },
{ {
label: 'Esc', label: 'Esc',
action: '退出查询' action: '退出查询'
@ -671,6 +757,32 @@ const currentScheme = ref({
} }
}, },
steps: [], steps: [],
laterSteps: [
{
id: 1,
step: 1,
voltage: 110,
current: 110,
powerFactor: '0.5L',
isILeak: false
},
{
id: 2,
step: 2,
voltage: 80,
current: 80,
powerFactor: '0.5L',
isILeak: false
},
{
id: 3,
step: 3,
voltage: 100,
current: 2,
powerFactor: '0.5L',
isILeak: true
}
],
iLeakDetectObj: defaultiLeakDetectObj iLeakDetectObj: defaultiLeakDetectObj
}); });
@ -725,8 +837,8 @@ const processLogData = apiData => {
apiData.forEach(item => { apiData.forEach(item => {
let valueName = item.valueName || item.valueKey; let valueName = item.valueName || item.valueKey;
let valueUnit = item.valueUnit || ''; let valueUnit = item.valueUnit || '';
if (activeScheme.value && Array.isArray(activeScheme.value.propertyParam)) { if (activeScheme.value && Array.isArray(defaultPropList.value)) {
const found = activeScheme.value.propertyParam.find(param => param.key === item.valueKey); const found = defaultPropList.value.find(param => param.key === item.valueKey);
if (found) { if (found) {
valueName = found.name || valueName; valueName = found.name || valueName;
valueUnit = found.unit || valueUnit; valueUnit = found.unit || valueUnit;
@ -845,7 +957,7 @@ const getSocketMeassage = message => {
if (msg.msgType === 'calibrate_finish') { if (msg.msgType === 'calibrate_finish') {
playState.value = false; playState.value = false;
ElMessage.success('标定完成'); ElMessage.success('标定完成');
getQquipmentStatistics(); getQquipmentStatistics();
} }
// //
@ -895,7 +1007,6 @@ const socketStatus = computed(() => {
return webSocketStore.socket_open; return webSocketStore.socket_open;
}); });
// //
const handleKeydown = event => { const handleKeydown = event => {
// Ctrl+F: // Ctrl+F:
@ -926,18 +1037,17 @@ const handleKeydown = event => {
} }
}; };
const toggleIsScroll = () => { const toggleIsScroll = () => {
isScroll.value = !isScroll.value; isScroll.value = !isScroll.value;
}; };
const startExecution = () => { const startExecution = () => {
if (selectedScheme.value === '') { if (selectedScheme.value === '') {
ElMessage.error({message:'请先选择方案'}); ElMessage.error({ message: '请先选择方案' });
return; return;
} }
if (operatorCode.value.trim() === '') { if (operatorCode.value.trim() === '') {
ElMessage.error({message:'请先输入操作员编号',duration:1000,showClose: true}); ElMessage.error({ message: '请先输入操作员编号', duration: 1000, showClose: true });
return; return;
} }
// socket // socket
@ -947,7 +1057,7 @@ const startExecution = () => {
ElMessage.success('开始执行方案: ' + scheme[0].schemeName); ElMessage.success('开始执行方案: ' + scheme[0].schemeName);
playState.value = true; playState.value = true;
playCalibration(); playCalibration();
getQquipmentStatistics(); getQquipmentStatistics();
// Add actual start logic here // Add actual start logic here
}; };
@ -1045,14 +1155,16 @@ const loadSchemes = async () => {
} }
if (found) { if (found) {
activeScheme.value = found; activeScheme.value = found;
} else if (schemeList.value.length > 0) { }
selectedScheme.value = schemeList.value[0].id; // else if (schemeList.value.length > 0) {
activeScheme.value = schemeList.value[0]; // selectedScheme.value = schemeList.value[0].id;
} else { // activeScheme.value = schemeList.value[0];
// }
else {
selectedScheme.value = ''; selectedScheme.value = '';
activeScheme.value = {}; activeScheme.value = {};
} }
ElMessage.success({message: '获取方案列表成功', duration: 1000}); ElMessage.success({ message: '获取方案列表成功', duration: 1000 });
} else { } else {
ElMessage.error(response.data.message || '获取方案列表失败'); ElMessage.error(response.data.message || '获取方案列表失败');
} }
@ -1166,6 +1278,32 @@ const addScheme = () => {
} }
}, },
steps: [], steps: [],
laterSteps: [
{
id: 1,
step: 1,
voltage: 110,
current: 110,
powerFactor: '0.5L',
isILeak: false
},
{
id: 2,
step: 2,
voltage: 80,
current: 80,
powerFactor: '0.5L',
isILeak: false
},
{
id: 3,
step: 3,
voltage: 100,
current: 2,
powerFactor: '0.5L',
isILeak: true
}
],
iLeakDetectObj: defaultiLeakDetectObj iLeakDetectObj: defaultiLeakDetectObj
}; };
isEditMode.value = false; isEditMode.value = false;
@ -1195,6 +1333,19 @@ const addCalibrationStep = () => {
isILeak: false isILeak: false
}); });
}; };
//
const addCalibrationLaterStep = () => {
currentScheme.value.laterSteps.push({
id: currentScheme.value.laterSteps.length + 1,
step: currentScheme.value.laterSteps.length + 1,
voltage: 100,
current: 100,
powerFactor: '0.5L',
isILeak: false
});
};
const toggleOpenLog = () => { const toggleOpenLog = () => {
isOpenLog.value = !isOpenLog.value; isOpenLog.value = !isOpenLog.value;
}; };
@ -1314,6 +1465,14 @@ const deleteCalibrationStep = index => {
}); });
}; };
//
const deleteCalibrationLaterStep = index => {
currentScheme.value.laterSteps.splice(index, 1);
//
currentScheme.value.laterSteps.forEach((step, idx) => {
step.id = idx + 1;
});
};
const generateDeviceList = async () => { const generateDeviceList = async () => {
try { try {
const response = await axios.get(config.url + '/master/device/list'); const response = await axios.get(config.url + '/master/device/list');
@ -1336,10 +1495,20 @@ const playCalibration = async () => {
if (response.data.code === 0) { if (response.data.code === 0) {
// devices.value = response.data.data.result || []; // devices.value = response.data.data.result || [];
} else { } else {
ElMessageBox.alert(response.data.message, '告警', {
// if you want to disable its autofocus
// autofocus: false,
dangerouslyUseHTMLString: true,
confirmButtonText: '确定',
confirmButtonClass: 'custom-message-box',
callback: action => {}
});
playState.value = false;
// ElMessage.error(response.data.message || ''); // ElMessage.error(response.data.message || '');
} }
} catch (error) { } catch (error) {
console.error('获取设备列表失败:', error); console.error('获取设备列表失败:', error);
// ElMessage.error(''); // ElMessage.error('');
} }
}; };
@ -1531,16 +1700,18 @@ const handleExportProd = async () => {
}; };
const getQquipmentStatistics = () => { const getQquipmentStatistics = () => {
axios.get(config.url + '/master/calibrate/stat').then(response => { axios
if(response.data.code === 0 && response.data.data.state){ .get(config.url + '/master/calibrate/stat')
equipmentStatistics.value = response.data.data.state; .then(response => {
}else{ if (response.data.code === 0 && response.data.data.state) {
ElMessage.error(response.data.message); equipmentStatistics.value = response.data.data.state;
} } else {
}).catch(error => { ElMessage.error(response.data.message);
ElMessage.error(error); }
}); })
.catch(error => {
ElMessage.error(error);
});
}; };
// //
@ -1558,33 +1729,32 @@ watch(
} }
); );
onMounted(() => { onMounted(() => {
logBoxRef.value = document.querySelector('#log-box-main'); logBoxRef.value = document.querySelector('#log-box-main');
initSocket(); initSocket();
if (window.electron && typeof window.electron.getAppVersion === 'function') { if (window.electron && typeof window.electron.getAppVersion === 'function') {
window.electron.getAppVersion().then(v => { window.electron.getAppVersion().then(v => {
version.value = v; version.value = v;
}); });
} }
// generateMockDevices(); // generateMockDevices();
getSchemeDefaultConf(); getSchemeDefaultConf();
getSchemeDefaultProp(); getSchemeDefaultProp();
generateDeviceList(); generateDeviceList();
loadSchemes(); loadSchemes();
getQquipmentStatistics(); getQquipmentStatistics();
// //
document.addEventListener('keydown', handleKeydown); document.addEventListener('keydown', handleKeydown);
}); });
onUnmounted(() => { onUnmounted(() => {
if (webSocketStore) { if (webSocketStore) {
webSocketStore.close(); webSocketStore.close();
} }
// //
document.removeEventListener('keydown', handleKeydown); document.removeEventListener('keydown', handleKeydown);
}); });
</script> </script>
@ -1647,13 +1817,13 @@ onUnmounted(() => {
.header-center .el-button { .header-center .el-button {
margin-left: 10px; margin-left: 10px;
} }
.statistics-box{ .statistics-box {
margin-left: 10px; margin-left: 10px;
font-size: 13px; font-size: 13px;
.statistics-number{ .statistics-number {
font-size: 16px; font-size: 16px;
font-weight: bold; font-weight: bold;
} }
} }
.calibration-main { .calibration-main {
@ -2095,3 +2265,14 @@ onUnmounted(() => {
/* Red for disconnected */ /* Red for disconnected */
} }
</style> </style>
<style>
.custom-message-box.el-button--primary {
background-color: #f56c6c !important;
border-color: #f56c6c !important;
}
.custom-message-box.el-button--primary:hover {
background-color: #cc0000 !important;
border-color: #cc0000 !important;
}
</style>