feat(renderer): 优化标定结果展示、socket日志记录功能、socket日志结果处理接口、调整标定日志结构
- 更新 iconfont 文件,增加新的图标 - 优化标定结果展示,增加未标定状态 - 重构日志记录功能,支持不同类型的标定结果 - 修复设备信息同步问题 - socket日志结果处理接口 - 调整标定日志结构
This commit is contained in:
parent
9ad0b09214
commit
530033e2b7
|
@ -1,8 +1,8 @@
|
|||
@font-face {
|
||||
font-family: "iconfont"; /* Project id 4622943 */
|
||||
src: url('iconfont.woff2?t=1750322442953') format('woff2'),
|
||||
url('iconfont.woff?t=1750322442953') format('woff'),
|
||||
url('iconfont.ttf?t=1750322442953') format('truetype');
|
||||
src: url('iconfont.woff2?t=1751007258575') format('woff2'),
|
||||
url('iconfont.woff?t=1751007258575') format('woff'),
|
||||
url('iconfont.ttf?t=1751007258575') format('truetype');
|
||||
}
|
||||
|
||||
.iconfont {
|
||||
|
@ -13,6 +13,14 @@
|
|||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
.icon-xwtubiaoku-13:before {
|
||||
content: "\e61a";
|
||||
}
|
||||
|
||||
.icon-xwtubiaoku-15:before {
|
||||
content: "\e61d";
|
||||
}
|
||||
|
||||
.icon-rizhi:before {
|
||||
content: "\e61c";
|
||||
}
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -52,7 +52,7 @@
|
|||
<p>
|
||||
标定结果:
|
||||
<span :class="['device-result', device.result === 1 ? 'color-green' : device.result === -1 ? 'color-red' : '']">{{
|
||||
device.result === 1 ? '成功' : device.result === -1 ? '失败' : '' || '无'
|
||||
device.result === 1 ? '成功' : device.result === -1 ? '失败' : '未标定' || '无'
|
||||
}}</span>
|
||||
</p>
|
||||
<p>
|
||||
|
@ -70,28 +70,23 @@
|
|||
|
||||
<el-footer class="calibration-footer" :class="isOpenLog ? 'open-log' : ''">
|
||||
<div id="log-box-main" class="log-box-main">
|
||||
<div class="log-list">
|
||||
<div v-for="(item, index) in logs" :key="index" class="log-item">
|
||||
<el-tooltip v-if="item.type == 'subscribe'" effect="light" content="订阅" placement="top">
|
||||
<span class="iconfont icon-icon_shanghang" style="color: #00a73c"></span>
|
||||
</el-tooltip>
|
||||
<el-tooltip v-else-if="item.type == 'calibrate_error'" effect="light" content="错误信息" placement="top">
|
||||
<span class="iconfont icon-bug-fill" style="color: #ff3b2b"></span>
|
||||
</el-tooltip>
|
||||
<!-- <el-tooltip-->
|
||||
<!-- effect="light"-->
|
||||
<!-- content="消息"-->
|
||||
<!-- placement="top"-->
|
||||
<!-- v-else-if="item.type == 'calibrate_info'"-->
|
||||
<!-- >-->
|
||||
<!-- <span class="iconfont icon-rizhi1" style="color: #0066cc"></span>-->
|
||||
<!-- </el-tooltip>-->
|
||||
<el-tooltip v-else effect="light" content="系统" placement="top">
|
||||
<span class="iconfont icon-rizhi1"></span>
|
||||
</el-tooltip>
|
||||
{{ item.time }} {{ item.msg }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="log-list">
|
||||
<div v-for="(item, index) in logs" :key="index" class="log-item">
|
||||
<el-tooltip v-if="item.type == 'calibrate_error'" effect="light" content="错误信息" placement="top">
|
||||
<span class="iconfont icon-bug-fill" style="color: #ff3b2b"></span>
|
||||
</el-tooltip>
|
||||
<el-tooltip v-else-if="item.type == 'calibrate_result_error'" effect="light" content="标定错误" placement="top">
|
||||
<span class="iconfont icon-xwtubiaoku-15" style="color: #ff3b2b"></span>
|
||||
</el-tooltip>
|
||||
<el-tooltip v-else-if="item.type == 'calibrate_result_success'" effect="light" content="标定成功" placement="top">
|
||||
<span class="iconfont icon-xwtubiaoku-13" style="color: #55e800"></span>
|
||||
</el-tooltip>
|
||||
<el-tooltip v-else effect="light" content="系统" placement="top">
|
||||
<span class="iconfont icon-rizhi1"></span>
|
||||
</el-tooltip>
|
||||
<span class="log-item-txt">{{ item.time }} {{ item.msg }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="calibration-footer-btn">
|
||||
<div class="btn-box">
|
||||
|
@ -102,7 +97,7 @@
|
|||
</div>
|
||||
<div v-else style="color: #ff3b2b; display: flex; align-items: center" @click="reconnectSocket">
|
||||
<el-tooltip class="box-item" content="重新连接" effect="dark" placement="bottom">
|
||||
<div style="display: flex; align-items: center">断连<span class="iconfont icon-icon_gengxin"></span></div>
|
||||
<div style="display: flex; align-items: center"><span>断连</span><span class="iconfont icon-icon_gengxin"></span></div>
|
||||
</el-tooltip>
|
||||
</div>
|
||||
</view>
|
||||
|
@ -278,7 +273,7 @@
|
|||
<div class="device-info-item">
|
||||
标定结果:
|
||||
<span style="font-weight: bold" :class="['device-result', activeDeviceInfo.result === 1 ? 'color-green' : activeDeviceInfo.result === -1 ? 'color-red' : '']">{{
|
||||
activeDeviceInfo.result === 1 ? '成功' : activeDeviceInfo.result === -1 ? '失败' : '' || '无'
|
||||
activeDeviceInfo.result === 1 ? '成功' : activeDeviceInfo.result === -1 ? '失败' : '未标定' || '无'
|
||||
}}</span>
|
||||
</div>
|
||||
<div class="device-info-item">结果描述: {{ activeDeviceInfo.resultTxt || '-' }}</div>
|
||||
|
@ -290,15 +285,15 @@
|
|||
<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>
|
||||
<span :style="{ color: scope.row.data[index]?.result != 1 ? 'red' : 'green' }">{{ scope.row.data[index]?.value === null?'': 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="center">
|
||||
<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 : '-'
|
||||
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>
|
||||
|
@ -332,6 +327,7 @@ const version = ref('V1.0.0');
|
|||
const logTabActive = ref('log');
|
||||
|
||||
const loading = ref(true);
|
||||
const fullscreenLoading = ref(false)
|
||||
const isOpenLog = ref(false);
|
||||
const logSocketStateHover = ref(false);
|
||||
|
||||
|
@ -425,6 +421,7 @@ const fetchDeviceLogs = async deviceId => {
|
|||
const response = await axios.get(config.url + '/master/calibrate/result', {
|
||||
params: { devId: deviceId }
|
||||
});
|
||||
|
||||
if (response.data.code === 0) {
|
||||
processLogData(response.data.data.result);
|
||||
} else {
|
||||
|
@ -464,7 +461,7 @@ const processLogData = apiData => {
|
|||
// 根据ExpectedMin和expectedMax计算result值
|
||||
const minValue = parseFloat(item.ExpectedMin);
|
||||
const maxValue = parseFloat(item.expectedMax);
|
||||
const outputValue = parseFloat(item.outputValue);
|
||||
const outputValue = parseFloat(item.actualValue);
|
||||
|
||||
let result = 0; // 默认失败
|
||||
if (!isNaN(minValue) && !isNaN(maxValue) && !isNaN(outputValue)) {
|
||||
|
@ -481,7 +478,7 @@ const processLogData = apiData => {
|
|||
return {
|
||||
id: item.id,
|
||||
name: paramInfo?.name || item.valueName || item.valueKey,
|
||||
value: item.outputValue,
|
||||
value: item.actualValue,
|
||||
unit: paramInfo?.unit || item.valueUnit,
|
||||
accuracy: item.expectedError,
|
||||
result: result,
|
||||
|
@ -495,23 +492,43 @@ const processLogData = apiData => {
|
|||
dataList: dataList
|
||||
};
|
||||
});
|
||||
|
||||
logList.value = processedLogs;
|
||||
};
|
||||
|
||||
// 设备日志转置,便于表格渲染
|
||||
const transposedLogList = computed(() => {
|
||||
if (!logList.value.length) return [];
|
||||
// 假设每个dataList参数顺序一致
|
||||
const paramCount = logList.value[0].dataList.length;
|
||||
|
||||
// 收集所有步骤中出现的所有valueKey
|
||||
const allValueKeys = new Set();
|
||||
logList.value.forEach(step => {
|
||||
step.dataList.forEach(item => {
|
||||
allValueKeys.add(item.valueKey || item.name);
|
||||
});
|
||||
});
|
||||
|
||||
// 为每个valueKey创建一行
|
||||
const result = [];
|
||||
for (let i = 0; i < paramCount; i++) {
|
||||
allValueKeys.forEach(valueKey => {
|
||||
// 找到第一个包含该valueKey的步骤,获取参数信息
|
||||
const firstStepWithKey = logList.value.find(step =>
|
||||
step.dataList.some(item => (item.valueKey || item.name) === valueKey)
|
||||
);
|
||||
const firstItem = firstStepWithKey?.dataList.find(item =>
|
||||
(item.valueKey || item.name) === valueKey
|
||||
);
|
||||
|
||||
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])
|
||||
name: (firstItem?.name || valueKey) + (firstItem?.unit ? '(' + firstItem.unit + ')' : ''),
|
||||
data: logList.value.map(step => {
|
||||
// 在当前步骤中查找该valueKey的数据
|
||||
const item = step.dataList.find(item => (item.valueKey || item.name) === valueKey);
|
||||
return item || null; // 如果没有找到,返回null
|
||||
})
|
||||
};
|
||||
result.push(param);
|
||||
}
|
||||
});
|
||||
|
||||
return result;
|
||||
});
|
||||
|
||||
|
@ -537,14 +554,44 @@ const throttledScroll = throttle(() => {
|
|||
logBoxRef.value.scrollTop = logBoxRef.value.scrollHeight;
|
||||
}, 100);
|
||||
|
||||
const setDeviceInfo = msg => {
|
||||
let deviceInfo = tryParseJSON(msg);
|
||||
let type = false;
|
||||
if(deviceInfo){
|
||||
devices.value.forEach((item,index) => {
|
||||
if (item.id === deviceInfo.id) {
|
||||
// debugger
|
||||
devices.value[index] = deviceInfo;
|
||||
// item=deviceInfo;
|
||||
if(deviceInfo.result === -1){
|
||||
type = 'calibrate_result_error';
|
||||
}else if (deviceInfo.result === 1){
|
||||
type = 'calibrate_result_success';
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
return type;
|
||||
};
|
||||
|
||||
const getSocketMeassage = message => {
|
||||
const msg = tryParseJSON(message.data);
|
||||
// message = {data:{"msgType":"calibrate_result","data":"{\"id\":1,\"devicePort\":\"com3\",\"deviceSN\":\"SN\",\"connectStatus\":1,\"switch\":0,\"result\":-1,\"resultTxt\":\"\"}"}};
|
||||
const msg = tryParseJSON(message.data);
|
||||
console.log("msg",msg);
|
||||
const newLog = {
|
||||
time: dayjs().format('YYYY-MM-DD HH:mm:ss'),
|
||||
msg: msg.data ?? msg,
|
||||
type: msg.msgType ?? null
|
||||
};
|
||||
|
||||
if(msg.msgType === 'calibrate_result'){
|
||||
let resultType = setDeviceInfo(msg.data);
|
||||
if(resultType){
|
||||
newLog.type = resultType;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 批量更新日志数组
|
||||
logs.value = [...logs.value.slice(-MAX_LOG_LENGTH + 1), newLog];
|
||||
|
||||
|
@ -605,6 +652,7 @@ onMounted(() => {
|
|||
getSchemeDefaultProp();
|
||||
generateDeviceList();
|
||||
loadSchemes();
|
||||
|
||||
});
|
||||
|
||||
onUnmounted(() => {
|
||||
|
@ -835,6 +883,8 @@ const generateDeviceList = async () => {
|
|||
const response = await axios.get(config.url + '/master/device/list');
|
||||
if (response.data.code === 0) {
|
||||
devices.value = response.data.data.result || [];
|
||||
//测试输出结果
|
||||
// setDeviceInfo("{\"id\":1,\"devicePort\":\"com3\",\"deviceSN\":\"SN\",\"connectStatus\":1,\"switch\":0,\"result\":-1,\"resultTxt\":\"\"}")
|
||||
} else {
|
||||
ElMessage.error(response.data.message || '刷新列表失败');
|
||||
}
|
||||
|
@ -1013,12 +1063,12 @@ const playCalibration = async () => {
|
|||
word-wrap: break-word;
|
||||
word-break: break-all;
|
||||
font-size: 12px;
|
||||
user-select: text;
|
||||
line-height: 18px;
|
||||
font-weight: 500;
|
||||
margin-left: 8px;
|
||||
|
||||
.iconfont {
|
||||
font-size: 14px;
|
||||
line-height: 18px;
|
||||
&.icon-icon_fuzhi {
|
||||
line-height: 26px;
|
||||
margin-left: 8px;
|
||||
|
@ -1027,6 +1077,10 @@ const playCalibration = async () => {
|
|||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
.log-item-txt{
|
||||
margin-left: 5px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue