|
|
@@ -254,6 +254,36 @@
|
|
|
</el-tooltip>
|
|
|
</template>
|
|
|
</el-table-column>
|
|
|
+ <el-table-column :label="t('operationFillForm.mainSumKil')" align="center" prop="mainMileage" v-if="hasMileageRuleInCurrentPage"
|
|
|
+ :formatter="erpPriceTableColumnFormatter" :width="columnWidths.mainMileage">
|
|
|
+ <template #default="{ row }">
|
|
|
+ <el-tooltip
|
|
|
+ :disabled="!row.mainMileageError"
|
|
|
+ :content="row.mainMileageError"
|
|
|
+ placement="top"
|
|
|
+ effect="light"
|
|
|
+ popper-class="main-runtime-tooltip"
|
|
|
+ :show-after="0"
|
|
|
+ >
|
|
|
+ <div class="main-runtime-input-wrapper">
|
|
|
+ <el-input-number
|
|
|
+ v-model="row.mainMileage"
|
|
|
+ :precision="2"
|
|
|
+ :min="0"
|
|
|
+ :controls="false"
|
|
|
+ style="width: 100%"
|
|
|
+ :disabled="row.status === 1"
|
|
|
+ @change="validateMainMileage(row)"
|
|
|
+ @blur="validateMainMileage(row)"
|
|
|
+ :class="{
|
|
|
+ 'is-required-input': row.mainMileageError,
|
|
|
+ 'error-input': row.mainMileageError
|
|
|
+ }"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ </el-tooltip>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
<el-table-column :label="t('mainPlan.lastMaintenanceDate')" prop="lastMaintenanceDate" :width="columnWidths.lastMaintenanceDate">
|
|
|
<template #default="{ row }">
|
|
|
<div class="full-content-cell">
|
|
|
@@ -1238,13 +1268,20 @@ const handleSizeChange = (newSize: number) => {
|
|
|
const handleStatusChange = (row: IotMainWorkOrderBomVO) => {
|
|
|
// 如果是从未完成(0)切换到完成(1)
|
|
|
if (row.status === 1 && row.initialStatus === 0) {
|
|
|
- // 先校验 mainRuntime
|
|
|
+ // 校验 mainRuntime
|
|
|
if (!validateMainRuntime(row)) {
|
|
|
message.error(`${row.deviceCode}-${formatMaintItemName(row.name)} ${t('mainPlan.mainRuntimeError')}`);
|
|
|
row.status = 0; // 重置状态
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
+ // 校验 mainMileage
|
|
|
+ if (!validateMainMileage(row)) {
|
|
|
+ message.error(`${row.deviceCode}-${formatMaintItemName(row.name)} ${t('mainPlan.mainMileageError')}`);
|
|
|
+ row.status = 0; // 重置状态
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
// 检查消耗物料规则:如果设置为不消耗物料(rule=1),则跳过物料校验
|
|
|
if (row.rule === 1) {
|
|
|
console.log(`保养项 ${row.name} 设置为不消耗物料,跳过物料校验`);
|
|
|
@@ -1301,6 +1338,11 @@ const validateMainRuntime = (row: IotMainWorkOrderBomVO) => {
|
|
|
const totalRunTime = Number(row.totalRunTime ?? row.tempTotalRunTime) || 0;
|
|
|
const lastRunningTime = Number(row.lastRunningTime) || 0;
|
|
|
|
|
|
+ // 如果 mainRuntime 为 0 或空,不显示错误(允许为空)如果设置了累计运行时长保养规则 mainRuntime 必填
|
|
|
+ /* if (!mainRuntime || mainRuntime === 0) {
|
|
|
+ return true;
|
|
|
+ } */
|
|
|
+
|
|
|
// 校验规则:lastRunningTime ≤ mainRuntime ≤ totalRunTime
|
|
|
if (mainRuntime < lastRunningTime) {
|
|
|
row.mainRuntimeError = `保养时累计运行时间不能小于上次保养时长(${lastRunningTime})`;
|
|
|
@@ -1311,7 +1353,37 @@ const validateMainRuntime = (row: IotMainWorkOrderBomVO) => {
|
|
|
row.mainRuntimeError = `保养时累计运行时间不能大于累计运行时间(${totalRunTime})`;
|
|
|
return false;
|
|
|
}
|
|
|
+ // 校验通过时确保错误信息被清除
|
|
|
+ row.mainRuntimeError = '';
|
|
|
+ return true;
|
|
|
+};
|
|
|
+
|
|
|
+// 校验 mainMileage 的方法
|
|
|
+const validateMainMileage = (row: IotMainWorkOrderBomVO) => {
|
|
|
+ // 清除之前的错误
|
|
|
+ row.mainMileageError = '';
|
|
|
+
|
|
|
+ const mainMileage = Number(row.mainMileage) || 0;
|
|
|
+ const totalMileage = Number(row.totalMileage ?? row.tempTotalMileage) || 0;
|
|
|
+ const lastRunningKilometers = Number(row.lastRunningKilometers) || 0;
|
|
|
+
|
|
|
+ // 如果 mainMileage 为 0 或空,不显示错误(允许为空)如果设置了累计运行时长保养规则 mainMileage 必填
|
|
|
+ /* if (!mainMileage || mainMileage === 0) {
|
|
|
+ return true;
|
|
|
+ } */
|
|
|
+
|
|
|
+ // 校验规则:lastRunningKilometers ≤ mainMileage ≤ totalMileage
|
|
|
+ if (mainMileage < lastRunningKilometers) {
|
|
|
+ row.mainMileageError = `保养时累计运行公里数不能小于上次保养里程数(${lastRunningKilometers})`;
|
|
|
+ return false;
|
|
|
+ }
|
|
|
|
|
|
+ if (mainMileage > totalMileage) {
|
|
|
+ row.mainMileageError = `保养时累计运行公里数不能大于累计运行公里数(${totalMileage})`;
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ // 校验通过时确保错误信息被清除
|
|
|
+ row.mainMileageError = '';
|
|
|
return true;
|
|
|
};
|
|
|
|
|
|
@@ -1326,6 +1398,17 @@ const validateAllMainRuntimes = (): boolean => {
|
|
|
return isValid;
|
|
|
};
|
|
|
|
|
|
+// 全局校验所有 mainMileage
|
|
|
+const validateAllMainMileages = (): boolean => {
|
|
|
+ let isValid = true;
|
|
|
+ list.value.forEach(row => {
|
|
|
+ if (!validateMainMileage(row)) {
|
|
|
+ isValid = false;
|
|
|
+ }
|
|
|
+ });
|
|
|
+ return isValid;
|
|
|
+};
|
|
|
+
|
|
|
/** 新增物料 */
|
|
|
const handleAddMaterial = () => {
|
|
|
// 检查是否选中保养项
|
|
|
@@ -1470,7 +1553,7 @@ const selectChoose = (selectedMaterial) => {
|
|
|
}
|
|
|
});
|
|
|
|
|
|
- // 关键修复:立即更新当前显示的物料列表
|
|
|
+ // 立即更新当前显示的物料列表
|
|
|
refreshCurrentBomItemMaterials();
|
|
|
|
|
|
// 选择物料后立即计算费用
|
|
|
@@ -1792,6 +1875,12 @@ const submitForm = async () => {
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
+ // 保养时 累计运行公里数 mainMileage 全局校验
|
|
|
+ if (!validateAllMainMileages()) {
|
|
|
+ message.error(t('mainPlan.mainMileageError'));
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
// 校验所有设置为完成状态的保养项的物料数据
|
|
|
const invalidBomItems = [];
|
|
|
|
|
|
@@ -2109,6 +2198,11 @@ const calculateAllColumnsWidth = () => {
|
|
|
label: t('operationFillForm.mainSumTime'),
|
|
|
getValue: (row) => row.mainRuntime
|
|
|
},
|
|
|
+ {
|
|
|
+ prop: 'mainMileage',
|
|
|
+ label: t('operationFillForm.mainSumKil'),
|
|
|
+ getValue: (row) => row.mainMileage
|
|
|
+ },
|
|
|
{ prop: 'name', label: t('bomList.bomNode') },
|
|
|
{ prop: 'lastMaintenanceDate', label: t('mainPlan.lastMaintenanceDate') },
|
|
|
{ prop: 'mileageRule', label: t('main.mileage') },
|
|
|
@@ -2218,8 +2312,36 @@ const updateListWithCumulativeData = (cumulativeData: any[]) => {
|
|
|
// 根据 bomNodeId 找到对应的行
|
|
|
const targetRow = list.value.find(row => row.bomNodeId === item.bomNodeId)
|
|
|
if (targetRow) {
|
|
|
- // 更新累计运行时间到 mainRuntime 字段
|
|
|
- targetRow.mainRuntime = item.mainRuntime
|
|
|
+ // 按照优先级设置 mainRuntime 字段的值 保养时长
|
|
|
+ // 优先级:mainRuntime > tempMainRunTime
|
|
|
+ if (item.mainRuntime && Number(item.mainRuntime) > 0) {
|
|
|
+ // 如果 mainRuntime 有值且大于0,使用 mainRuntime
|
|
|
+ targetRow.mainRuntime = Number(item.mainRuntime)
|
|
|
+ } else if (item.tempMainRunTime && Number(item.tempMainRunTime) > 0) {
|
|
|
+ // 如果 mainRuntime 没有有效值,但 tempMainRunTime 有值且大于0,使用 tempMainRunTime
|
|
|
+ targetRow.mainRuntime = Number(item.tempMainRunTime)
|
|
|
+ } else {
|
|
|
+ // 两个字段都没有有效值,保持原值或设置为0
|
|
|
+ targetRow.mainRuntime = 0
|
|
|
+ }
|
|
|
+
|
|
|
+ // 按照优先级设置 mainMileage 字段的值 保养里程数
|
|
|
+ // 优先级:mainMileage > tempMainMileage
|
|
|
+ if (item.mainMileage && Number(item.mainMileage) > 0) {
|
|
|
+ // 如果 mainMileage 有值且大于0,使用 mainMileage
|
|
|
+ targetRow.mainMileage = Number(item.mainMileage)
|
|
|
+ } else if (item.tempMainMileage && Number(item.tempMainMileage) > 0) {
|
|
|
+ // 如果 mainMileage 没有有效值,但 tempMainMileage 有值且大于0,使用 tempMainMileage
|
|
|
+ targetRow.mainMileage = Number(item.tempMainMileage)
|
|
|
+ } else {
|
|
|
+ // 两个字段都没有有效值,保持原值或设置为0
|
|
|
+ targetRow.mainMileage = 0
|
|
|
+ }
|
|
|
+
|
|
|
+ // 更新数据后立即重新校验,清除可能的错误状态
|
|
|
+ nextTick(() => {
|
|
|
+ validateMainRuntime(targetRow)
|
|
|
+ })
|
|
|
}
|
|
|
})
|
|
|
}
|
|
|
@@ -2249,6 +2371,19 @@ const fetchCumulativeData = async () => {
|
|
|
|
|
|
if (response && Array.isArray(response)) {
|
|
|
updateListWithCumulativeData(response);
|
|
|
+ // 在所有数据更新完成后,重新校验所有行的 mainRuntime
|
|
|
+ nextTick(() => {
|
|
|
+ list.value.forEach(row => {
|
|
|
+ // 校验 保养时累计运行时长
|
|
|
+ if (row.mainRuntime) {
|
|
|
+ validateMainRuntime(row);
|
|
|
+ }
|
|
|
+ // 校验 保养时累计运行公里数
|
|
|
+ if (row.mainMileage) {
|
|
|
+ validateMainMileage(row);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ });
|
|
|
message.success('累计运行数据更新成功');
|
|
|
}
|
|
|
} catch (error) {
|
|
|
@@ -2888,25 +3023,6 @@ const handleRowClick = (row) => {
|
|
|
box-shadow: 0 0 0 1px rgba(245, 108, 108, 0.2) !important;
|
|
|
}
|
|
|
|
|
|
-/* 调整tooltip样式
|
|
|
-:deep(.el-tooltip__popper) {
|
|
|
- max-width: 300px;
|
|
|
- background-color: #fff0f0;
|
|
|
- border: 1px solid #f56c6c;
|
|
|
- color: #f56c6c;
|
|
|
-} */
|
|
|
-
|
|
|
-/* Tooltip提示样式优化
|
|
|
-:deep(.el-tooltip__popper.is-warning) {
|
|
|
- background-color: #fff3cd !important;
|
|
|
- border-color: #ffeeba !important;
|
|
|
- color: #856404 !important;
|
|
|
-}
|
|
|
-:deep(.el-tooltip__popper.is-warning .el-tooltip__arrow) {
|
|
|
- border-top-color: #ffeeba !important;
|
|
|
- border-bottom-color: #ffeeba !important;
|
|
|
-} */
|
|
|
-
|
|
|
/* 状态列容器样式 - 水平排列 */
|
|
|
.status-container {
|
|
|
display: flex;
|