2026-06-25 10:53:27 +08:00
|
|
|
|
<template>
|
|
|
|
|
|
<div class="app-container count-container">
|
|
|
|
|
|
<DragResizePanel :initialSize="280" :minSize="280" :maxSize="600">
|
|
|
|
|
|
<template #panelA>
|
|
|
|
|
|
<div class="left-panel">
|
|
|
|
|
|
<div class="panel-header">
|
|
|
|
|
|
<div class="header-title">
|
|
|
|
|
|
<i class="el-icon-s-tools"></i>
|
2026-07-03 16:56:44 +08:00
|
|
|
|
<span>检修单</span>
|
2026-06-25 10:53:27 +08:00
|
|
|
|
<el-button size="mini" type="text" icon="el-icon-refresh" @click="getList" style="margin-left:4px;" title="刷新列表"></el-button>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<div class="search-row">
|
|
|
|
|
|
<el-input v-model="queryParams.planNo" placeholder="搜索计划编号..." clearable prefix-icon="el-icon-search"
|
|
|
|
|
|
size="small" @keyup.enter.native="handleQuery" @clear="handleQuery" />
|
|
|
|
|
|
<el-button type="primary" size="small" @click="handleAdd">
|
|
|
|
|
|
<i class="el-icon-plus"></i>
|
|
|
|
|
|
</el-button>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<div v-loading="loading" class="list-body">
|
|
|
|
|
|
<div v-for="item in dataList" :key="item.planId" class="list-item"
|
|
|
|
|
|
:class="{ active: currentRow && currentRow.planId === item.planId }" @click="handleRowClick(item)">
|
|
|
|
|
|
<div class="item-main">
|
|
|
|
|
|
<span class="item-title">{{ item.planNo }}</span>
|
|
|
|
|
|
<span class="item-sub">{{ item.planName }}</span>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="item-actions">
|
|
|
|
|
|
<el-button size="mini" type="text" icon="el-icon-edit" @click.stop="handleUpdate(item)"></el-button>
|
|
|
|
|
|
<el-button size="mini" type="text" icon="el-icon-delete" @click.stop="handleDelete(item)"></el-button>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div v-if="dataList.length === 0 && !loading" class="list-empty">
|
|
|
|
|
|
<i class="el-icon-folder-opened"></i>
|
2026-07-03 16:56:44 +08:00
|
|
|
|
<span>暂无检修单数据</span>
|
2026-06-25 10:53:27 +08:00
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<div class="list-footer">
|
|
|
|
|
|
<pagination :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize"
|
|
|
|
|
|
@pagination="getList" />
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
|
|
<template #panelB>
|
|
|
|
|
|
<div class="right-panel">
|
|
|
|
|
|
<div v-if="!currentRow" class="empty-tip">
|
|
|
|
|
|
<i class="el-icon-info"></i>
|
2026-07-03 16:56:44 +08:00
|
|
|
|
<span>请在左侧列表中选择一条检修单查看详情</span>
|
2026-06-25 10:53:27 +08:00
|
|
|
|
</div>
|
2026-07-03 16:56:44 +08:00
|
|
|
|
<div v-else class="right-content">
|
|
|
|
|
|
<!-- 基本信息栏 -->
|
|
|
|
|
|
<div class="info-bar">
|
|
|
|
|
|
<div class="info-bar-left">
|
|
|
|
|
|
<span class="info-label">产线:</span>
|
|
|
|
|
|
<span class="info-value">{{ currentRow.productionLine || '未设置' }}</span>
|
|
|
|
|
|
<el-divider direction="vertical" />
|
|
|
|
|
|
<span class="info-label">时间:</span>
|
|
|
|
|
|
<span class="info-value">{{ parseTime(currentRow.plannedStartTime, '{y}-{m}-{d}') }} ~ {{ parseTime(currentRow.plannedEndTime, '{y}-{m}-{d}') }}</span>
|
2026-06-25 10:53:27 +08:00
|
|
|
|
</div>
|
2026-07-03 16:56:44 +08:00
|
|
|
|
<div class="info-bar-right">
|
|
|
|
|
|
<el-button size="mini" icon="el-icon-search" @click="queryInspectionRecords" :disabled="!currentRow.productionLine">查询检修记录</el-button>
|
|
|
|
|
|
<el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(currentRow)">编辑</el-button>
|
|
|
|
|
|
<el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(currentRow)">删除</el-button>
|
2026-06-25 10:53:27 +08:00
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
2026-07-03 16:56:44 +08:00
|
|
|
|
<!-- 上半部分:检修记录 -->
|
|
|
|
|
|
<div class="section inspection-section">
|
|
|
|
|
|
<div class="section-header">
|
|
|
|
|
|
<span class="section-title">检修记录 <span class="en-sub">· Inspection Records</span></span>
|
|
|
|
|
|
<span class="section-count" v-if="inspectionRecords.length">共 {{ inspectionTotal }} 条</span>
|
|
|
|
|
|
</div>
|
2026-07-08 10:49:00 +08:00
|
|
|
|
<el-table :data="inspectionRecords" border size="small" v-loading="inspectionLoading" max-height="300"
|
2026-07-03 16:56:44 +08:00
|
|
|
|
@selection-change="handleInspectionSelectionChange" ref="inspectionTable">
|
|
|
|
|
|
<el-table-column type="selection" width="40" />
|
|
|
|
|
|
<el-table-column label="设备部件" align="center" prop="partName" min-width="120" show-overflow-tooltip />
|
|
|
|
|
|
<el-table-column label="班次" align="center" width="70">
|
|
|
|
|
|
<template slot-scope="scope">{{ scope.row.shift == 1 ? '白班' : '夜班' }}</template>
|
|
|
|
|
|
</el-table-column>
|
|
|
|
|
|
<el-table-column label="巡检时间" align="center" width="150">
|
|
|
|
|
|
<template slot-scope="scope">{{ parseTime(scope.row.inspectTime, '{y}-{m}-{d} {h}:{i}') }}</template>
|
|
|
|
|
|
</el-table-column>
|
|
|
|
|
|
<el-table-column label="运行状态" align="center" width="80">
|
|
|
|
|
|
<template slot-scope="scope">
|
|
|
|
|
|
<el-tag v-if="scope.row.runStatus == 1" type="success" size="mini">正常</el-tag>
|
|
|
|
|
|
<el-tag v-else type="danger" size="mini">故障</el-tag>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
</el-table-column>
|
|
|
|
|
|
<el-table-column label="巡检人" align="center" prop="inspector" width="90" />
|
|
|
|
|
|
<el-table-column label="异常描述" align="center" prop="abnormalDesc" min-width="150" show-overflow-tooltip />
|
|
|
|
|
|
<el-table-column label="备注" align="center" prop="remark" min-width="120" show-overflow-tooltip />
|
|
|
|
|
|
</el-table>
|
|
|
|
|
|
<div v-if="!inspectionLoading && inspectionQueried && inspectionRecords.length === 0" class="empty-data">
|
|
|
|
|
|
该产线该时间段内暂无检修记录
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div v-if="!inspectionQueried" class="empty-data">
|
|
|
|
|
|
点击"查询检修记录"查看该产线时间段内的巡检数据
|
|
|
|
|
|
</div>
|
2026-06-25 10:53:27 +08:00
|
|
|
|
</div>
|
|
|
|
|
|
|
2026-07-03 16:56:44 +08:00
|
|
|
|
<!-- 下半部分:维修明细 -->
|
|
|
|
|
|
<div class="section detail-section">
|
|
|
|
|
|
<div class="section-header">
|
|
|
|
|
|
<span class="section-title">维修明细 <span class="en-sub">· Maintenance Details</span></span>
|
|
|
|
|
|
<div class="section-actions">
|
|
|
|
|
|
<el-button size="mini" type="primary" plain icon="el-icon-plus" @click="handleAddDetail">新增</el-button>
|
|
|
|
|
|
<el-button v-if="selectedInspectionRows.length"
|
|
|
|
|
|
size="mini" type="success" plain icon="el-icon-plus" @click="addDetailFromSelection">
|
|
|
|
|
|
从选中记录添加({{ selectedInspectionRows.length }})
|
|
|
|
|
|
</el-button>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
2026-07-08 10:49:00 +08:00
|
|
|
|
<el-table :data="detailList" border size="small" v-loading="detailLoading" max-height="300">
|
|
|
|
|
|
<el-table-column label="设备部件" align="center" prop="componentName" min-width="120" show-overflow-tooltip />
|
|
|
|
|
|
<el-table-column label="产线" align="center" prop="productionLine" width="110" />
|
|
|
|
|
|
<el-table-column label="类型" align="center" width="70">
|
2026-07-03 16:56:44 +08:00
|
|
|
|
<template slot-scope="scope">
|
2026-07-08 10:49:00 +08:00
|
|
|
|
<el-tag v-if="scope.row.maintenanceCategory === 0" size="mini">保养</el-tag>
|
|
|
|
|
|
<el-tag v-else-if="scope.row.maintenanceCategory === 1" size="mini" type="warning">维修</el-tag>
|
2026-07-03 16:56:44 +08:00
|
|
|
|
</template>
|
|
|
|
|
|
</el-table-column>
|
2026-07-08 10:49:00 +08:00
|
|
|
|
<el-table-column label="维修内容" align="center" prop="repairContent" min-width="150" show-overflow-tooltip />
|
|
|
|
|
|
<el-table-column label="负责人" align="center" prop="repairUser" width="90" />
|
|
|
|
|
|
<el-table-column label="计划日期" align="center" width="100">
|
|
|
|
|
|
<template slot-scope="scope">{{ parseTime(scope.row.itemPlanDate, '{y}-{m}-{d}') }}</template>
|
2026-07-03 16:56:44 +08:00
|
|
|
|
</el-table-column>
|
2026-07-08 10:49:00 +08:00
|
|
|
|
<el-table-column label="目标厂家" align="center" prop="targetManufacturer" width="110" />
|
|
|
|
|
|
<el-table-column label="操作" align="center" width="100" fixed="right">
|
2026-07-03 16:56:44 +08:00
|
|
|
|
<template slot-scope="scope">
|
2026-07-08 10:49:00 +08:00
|
|
|
|
<el-button size="mini" type="text" icon="el-icon-edit" @click="handleEditDetail(scope.row)"></el-button>
|
|
|
|
|
|
<el-button size="mini" type="text" icon="el-icon-delete" @click="handleDeleteDetail(scope.row)"></el-button>
|
2026-07-03 16:56:44 +08:00
|
|
|
|
</template>
|
|
|
|
|
|
</el-table-column>
|
|
|
|
|
|
</el-table>
|
|
|
|
|
|
<div v-if="detailList.length === 0 && !detailLoading" class="empty-data">暂无维修明细,请手动添加</div>
|
2026-06-25 10:53:27 +08:00
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
</DragResizePanel>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- 新增/编辑计划弹窗 -->
|
2026-07-03 16:56:44 +08:00
|
|
|
|
<el-dialog :title="title" :visible.sync="open" width="580px" append-to-body>
|
2026-06-25 10:53:27 +08:00
|
|
|
|
<el-form ref="form" :model="form" :rules="rules" label-width="110px">
|
|
|
|
|
|
<el-form-item label="计划名称" prop="planName">
|
|
|
|
|
|
<el-input v-model="form.planName" placeholder="请输入计划名称" />
|
|
|
|
|
|
</el-form-item>
|
2026-07-03 16:56:44 +08:00
|
|
|
|
<el-form-item label="产线" prop="productionLine">
|
|
|
|
|
|
<el-select v-model="form.productionLine" placeholder="请选择产线" clearable style="width:100%">
|
|
|
|
|
|
<el-option v-for="item in lineList" :key="item.lineId" :label="item.lineName" :value="item.lineName" />
|
|
|
|
|
|
</el-select>
|
|
|
|
|
|
</el-form-item>
|
|
|
|
|
|
<el-form-item label="开始时间" prop="plannedStartTime">
|
|
|
|
|
|
<el-date-picker clearable v-model="form.plannedStartTime" type="datetime" value-format="yyyy-MM-dd HH:mm:ss" placeholder="请选择" style="width:100%" />
|
|
|
|
|
|
</el-form-item>
|
|
|
|
|
|
<el-form-item label="结束时间" prop="plannedEndTime">
|
|
|
|
|
|
<el-date-picker clearable v-model="form.plannedEndTime" type="datetime" value-format="yyyy-MM-dd HH:mm:ss" placeholder="请选择" style="width:100%" />
|
|
|
|
|
|
</el-form-item>
|
2026-06-25 10:53:27 +08:00
|
|
|
|
<el-form-item label="维修类型" prop="repairType">
|
|
|
|
|
|
<el-select v-model="form.repairType" placeholder="请选择" style="width:100%">
|
|
|
|
|
|
<el-option label="定期保养" :value="1" />
|
|
|
|
|
|
<el-option label="安全整改" :value="2" />
|
|
|
|
|
|
<el-option label="专项检修" :value="3" />
|
|
|
|
|
|
<el-option label="故障维修" :value="4" />
|
|
|
|
|
|
</el-select>
|
|
|
|
|
|
</el-form-item>
|
|
|
|
|
|
<el-form-item label="优先级" prop="priorityLevel">
|
|
|
|
|
|
<el-select v-model="form.priorityLevel" placeholder="请选择" style="width:100%">
|
|
|
|
|
|
<el-option label="普通" :value="1" />
|
|
|
|
|
|
<el-option label="重要" :value="2" />
|
|
|
|
|
|
</el-select>
|
|
|
|
|
|
</el-form-item>
|
2026-07-03 16:56:44 +08:00
|
|
|
|
<el-form-item label="计划说明" prop="planDescription">
|
|
|
|
|
|
<el-input v-model="form.planDescription" type="textarea" :rows="3" placeholder="请输入计划说明" />
|
2026-06-25 10:53:27 +08:00
|
|
|
|
</el-form-item>
|
|
|
|
|
|
<el-form-item label="负责部门" prop="dutyDept">
|
|
|
|
|
|
<el-input v-model="form.dutyDept" placeholder="请输入负责部门" />
|
|
|
|
|
|
</el-form-item>
|
2026-07-03 16:56:44 +08:00
|
|
|
|
<el-form-item label="负责人" prop="planOwner">
|
2026-06-25 10:53:27 +08:00
|
|
|
|
<el-input v-model="form.planOwner" placeholder="请输入负责人" />
|
|
|
|
|
|
</el-form-item>
|
|
|
|
|
|
<el-form-item label="预算金额(元)" prop="budgetAmount">
|
|
|
|
|
|
<el-input-number v-model="form.budgetAmount" :min="0" :precision="2" style="width:100%" placeholder="请输入预算金额" />
|
|
|
|
|
|
</el-form-item>
|
|
|
|
|
|
<el-form-item label="备注" prop="remark">
|
|
|
|
|
|
<el-input v-model="form.remark" type="textarea" :rows="2" placeholder="请输入备注" />
|
|
|
|
|
|
</el-form-item>
|
|
|
|
|
|
</el-form>
|
|
|
|
|
|
<div slot="footer" class="dialog-footer">
|
|
|
|
|
|
<el-button :loading="buttonLoading" type="primary" @click="submitForm">确 定</el-button>
|
|
|
|
|
|
<el-button @click="cancel">取 消</el-button>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</el-dialog>
|
|
|
|
|
|
|
2026-07-08 10:49:00 +08:00
|
|
|
|
<!-- 明细编辑弹窗 -->
|
|
|
|
|
|
<el-dialog :title="detailDialogTitle" :visible.sync="detailDialogVisible" width="550px" append-to-body>
|
|
|
|
|
|
<el-form ref="detailForm" :model="detailForm" label-width="110px">
|
|
|
|
|
|
<el-form-item label="设备部件" prop="componentName">
|
|
|
|
|
|
<el-input v-model="detailForm.componentName" placeholder="请输入设备部件名称" />
|
|
|
|
|
|
</el-form-item>
|
|
|
|
|
|
<el-form-item label="产线" prop="productionLine">
|
|
|
|
|
|
<el-select v-model="detailForm.productionLine" placeholder="请选择" clearable style="width:100%">
|
|
|
|
|
|
<el-option v-for="item in lineList" :key="item.lineId" :label="item.lineName" :value="item.lineName" />
|
|
|
|
|
|
</el-select>
|
|
|
|
|
|
</el-form-item>
|
|
|
|
|
|
<el-form-item label="明细类型" prop="maintenanceCategory">
|
|
|
|
|
|
<el-select v-model="detailForm.maintenanceCategory" placeholder="请选择" style="width:100%">
|
|
|
|
|
|
<el-option label="保养" :value="0" />
|
|
|
|
|
|
<el-option label="维修" :value="1" />
|
|
|
|
|
|
</el-select>
|
|
|
|
|
|
</el-form-item>
|
|
|
|
|
|
<el-form-item label="维修内容" prop="repairContent">
|
|
|
|
|
|
<el-input v-model="detailForm.repairContent" type="textarea" :rows="2" placeholder="请输入维修内容" />
|
|
|
|
|
|
</el-form-item>
|
|
|
|
|
|
<el-form-item label="负责人" prop="repairUser">
|
|
|
|
|
|
<el-input v-model="detailForm.repairUser" placeholder="请输入维修负责人" />
|
|
|
|
|
|
</el-form-item>
|
|
|
|
|
|
<el-form-item label="计划日期" prop="itemPlanDate">
|
|
|
|
|
|
<el-date-picker clearable v-model="detailForm.itemPlanDate" type="date" value-format="yyyy-MM-dd" placeholder="请选择" style="width:100%" />
|
|
|
|
|
|
</el-form-item>
|
|
|
|
|
|
<el-form-item label="目标厂家" prop="targetManufacturer">
|
|
|
|
|
|
<el-input v-model="detailForm.targetManufacturer" placeholder="请输入目标厂家" />
|
|
|
|
|
|
</el-form-item>
|
|
|
|
|
|
</el-form>
|
|
|
|
|
|
<div slot="footer" class="dialog-footer">
|
|
|
|
|
|
<el-button @click="detailDialogVisible = false">取 消</el-button>
|
|
|
|
|
|
<el-button type="primary" :loading="detailButtonLoading" @click="submitDetailForm">确 定</el-button>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</el-dialog>
|
2026-06-25 10:53:27 +08:00
|
|
|
|
</div>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
|
|
<script>
|
|
|
|
|
|
import { listMaintenancePlan, getMaintenancePlan, addMaintenancePlan, updateMaintenancePlan, delMaintenancePlan } from "@/api/flow/maintenancePlan";
|
|
|
|
|
|
import { listMaintenancePlanDetail, addMaintenancePlanDetail, updateMaintenancePlanDetail, delMaintenancePlanDetail } from "@/api/flow/maintenancePlanDetail";
|
|
|
|
|
|
import { listEquipmentInspectionRecord } from "@/api/mes/eqp/equipmentInspectionRecord";
|
|
|
|
|
|
import { listProductionLine } from "@/api/wms/productionLine";
|
|
|
|
|
|
import DragResizePanel from "@/components/DragResizePanel/index.vue";
|
|
|
|
|
|
import { parseTime } from '@/utils/klp'
|
|
|
|
|
|
|
|
|
|
|
|
export default {
|
|
|
|
|
|
name: "EqpMaintenance",
|
|
|
|
|
|
components: { DragResizePanel },
|
|
|
|
|
|
data() {
|
|
|
|
|
|
return {
|
|
|
|
|
|
loading: false,
|
|
|
|
|
|
detailLoading: false,
|
|
|
|
|
|
buttonLoading: false,
|
2026-07-03 16:56:44 +08:00
|
|
|
|
inspectionLoading: false,
|
2026-06-25 10:53:27 +08:00
|
|
|
|
detailButtonLoading: false,
|
|
|
|
|
|
total: 0,
|
|
|
|
|
|
dataList: [],
|
|
|
|
|
|
currentRow: null,
|
|
|
|
|
|
title: "",
|
|
|
|
|
|
open: false,
|
|
|
|
|
|
form: {},
|
|
|
|
|
|
rules: {
|
|
|
|
|
|
planName: [{ required: true, message: "请输入计划名称", trigger: "blur" }],
|
2026-07-03 16:56:44 +08:00
|
|
|
|
productionLine: [{ required: true, message: "请选择产线", trigger: "change" }],
|
|
|
|
|
|
plannedStartTime: [{ required: true, message: "请选择开始时间", trigger: "change" }],
|
|
|
|
|
|
plannedEndTime: [{ required: true, message: "请选择结束时间", trigger: "change" }],
|
2026-06-25 10:53:27 +08:00
|
|
|
|
repairType: [{ required: true, message: "请选择维修类型", trigger: "change" }]
|
|
|
|
|
|
},
|
2026-07-03 16:56:44 +08:00
|
|
|
|
queryParams: { pageNum: 1, pageSize: 10, planNo: undefined },
|
2026-06-25 10:53:27 +08:00
|
|
|
|
lineList: [],
|
2026-07-03 16:56:44 +08:00
|
|
|
|
// 检修记录
|
|
|
|
|
|
inspectionRecords: [],
|
|
|
|
|
|
inspectionTotal: 0,
|
|
|
|
|
|
inspectionQueried: false,
|
|
|
|
|
|
selectedInspectionRows: [],
|
|
|
|
|
|
// 维修明细
|
2026-07-08 10:49:00 +08:00
|
|
|
|
detailList: [],
|
|
|
|
|
|
detailDialogVisible: false,
|
|
|
|
|
|
detailDialogTitle: "",
|
|
|
|
|
|
detailForm: {},
|
|
|
|
|
|
editingDetailId: null
|
2026-06-25 10:53:27 +08:00
|
|
|
|
};
|
|
|
|
|
|
},
|
|
|
|
|
|
created() {
|
|
|
|
|
|
this.loadLineList();
|
|
|
|
|
|
},
|
|
|
|
|
|
methods: {
|
|
|
|
|
|
parseTime,
|
|
|
|
|
|
async loadLineList() {
|
|
|
|
|
|
try {
|
|
|
|
|
|
const res = await listProductionLine({ pageSize: 999 });
|
|
|
|
|
|
if (res.rows) this.lineList = res.rows;
|
|
|
|
|
|
this.getList();
|
|
|
|
|
|
} catch (e) { console.error('加载产线列表失败', e); }
|
|
|
|
|
|
},
|
|
|
|
|
|
getList() {
|
|
|
|
|
|
this.loading = true;
|
|
|
|
|
|
var self = this;
|
|
|
|
|
|
listMaintenancePlan(this.queryParams).then(function(response) {
|
|
|
|
|
|
self.dataList = response.rows;
|
|
|
|
|
|
self.total = response.total;
|
|
|
|
|
|
self.loading = false;
|
|
|
|
|
|
});
|
|
|
|
|
|
},
|
|
|
|
|
|
handleQuery() {
|
|
|
|
|
|
this.queryParams.pageNum = 1;
|
|
|
|
|
|
this.getList();
|
|
|
|
|
|
},
|
|
|
|
|
|
handleRowClick(row) {
|
|
|
|
|
|
this.currentRow = row;
|
2026-07-03 16:56:44 +08:00
|
|
|
|
this.inspectionQueried = false;
|
|
|
|
|
|
this.inspectionRecords = [];
|
|
|
|
|
|
this.selectedInspectionRows = [];
|
2026-06-25 10:53:27 +08:00
|
|
|
|
this.loadDetail(row.planId);
|
|
|
|
|
|
},
|
|
|
|
|
|
loadDetail(planId) {
|
|
|
|
|
|
this.detailLoading = true;
|
|
|
|
|
|
var self = this;
|
|
|
|
|
|
getMaintenancePlan(planId).then(function(response) {
|
|
|
|
|
|
self.currentRow = response.data;
|
|
|
|
|
|
self.loadDetailList(planId);
|
2026-07-03 16:56:44 +08:00
|
|
|
|
self.detailLoading = false;
|
|
|
|
|
|
}).catch(function() { self.detailLoading = false; });
|
2026-06-25 10:53:27 +08:00
|
|
|
|
},
|
|
|
|
|
|
loadDetailList(planId) {
|
|
|
|
|
|
var self = this;
|
|
|
|
|
|
listMaintenancePlanDetail({ planId: planId, pageNum: 1, pageSize: 999 }).then(function(r) {
|
2026-07-08 10:49:00 +08:00
|
|
|
|
self.detailList = r.rows || [];
|
2026-06-25 10:53:27 +08:00
|
|
|
|
});
|
|
|
|
|
|
},
|
2026-07-03 16:56:44 +08:00
|
|
|
|
// ---- 检修记录查询 ----
|
|
|
|
|
|
queryInspectionRecords() {
|
|
|
|
|
|
if (!this.currentRow || !this.currentRow.productionLine) {
|
|
|
|
|
|
this.$modal.msgWarning("请先在编辑中设置产线");
|
|
|
|
|
|
return;
|
2026-06-25 10:53:27 +08:00
|
|
|
|
}
|
2026-07-03 16:56:44 +08:00
|
|
|
|
this.inspectionLoading = true;
|
|
|
|
|
|
var self = this;
|
|
|
|
|
|
var params = {
|
|
|
|
|
|
pageNum: 1,
|
|
|
|
|
|
pageSize: 9999,
|
|
|
|
|
|
productionLine: this.getProductionLineId(this.currentRow.productionLine),
|
|
|
|
|
|
startTime: this.currentRow.plannedStartTime ? parseTime(this.currentRow.plannedStartTime, '{y}-{m}-{d}') : undefined,
|
|
|
|
|
|
endTime: this.currentRow.plannedEndTime ? parseTime(this.currentRow.plannedEndTime, '{y}-{m}-{d}') : undefined
|
|
|
|
|
|
};
|
|
|
|
|
|
listEquipmentInspectionRecord(params).then(function(response) {
|
|
|
|
|
|
self.inspectionRecords = response.rows || [];
|
|
|
|
|
|
self.inspectionTotal = response.total || 0;
|
|
|
|
|
|
self.inspectionQueried = true;
|
|
|
|
|
|
self.$nextTick(function() {
|
|
|
|
|
|
if (self.$refs.inspectionTable) {
|
|
|
|
|
|
self.$refs.inspectionTable.clearSelection();
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
}).finally(function() {
|
|
|
|
|
|
self.inspectionLoading = false;
|
|
|
|
|
|
});
|
|
|
|
|
|
},
|
|
|
|
|
|
getProductionLineId(name) {
|
|
|
|
|
|
var line = this.lineList.find(function(l) { return l.lineName === name; });
|
|
|
|
|
|
return line ? line.lineId : null;
|
2026-06-25 10:53:27 +08:00
|
|
|
|
},
|
2026-07-03 16:56:44 +08:00
|
|
|
|
handleInspectionSelectionChange(selection) {
|
|
|
|
|
|
this.selectedInspectionRows = selection;
|
|
|
|
|
|
},
|
|
|
|
|
|
addDetailFromSelection() {
|
|
|
|
|
|
if (this.selectedInspectionRows.length === 0) return;
|
|
|
|
|
|
var self = this;
|
|
|
|
|
|
var planId = this.currentRow.planId;
|
|
|
|
|
|
this.$modal.loading("正在添加维修明细...");
|
|
|
|
|
|
var promises = this.selectedInspectionRows.map(function(rec) {
|
|
|
|
|
|
return addMaintenancePlanDetail({
|
|
|
|
|
|
planId: planId,
|
|
|
|
|
|
componentName: rec.partName || '',
|
|
|
|
|
|
productionLine: self.currentRow.productionLine || rec.productionLine || '',
|
|
|
|
|
|
maintenanceCategory: 1,
|
|
|
|
|
|
repairContent: rec.abnormalDesc || '',
|
|
|
|
|
|
repairUser: rec.inspector || '',
|
2026-07-08 10:49:00 +08:00
|
|
|
|
detailStatus: 0
|
2026-07-03 16:56:44 +08:00
|
|
|
|
});
|
|
|
|
|
|
});
|
|
|
|
|
|
Promise.all(promises).then(function() {
|
|
|
|
|
|
self.$modal.closeLoading();
|
|
|
|
|
|
self.$modal.msgSuccess("已从检修记录添加 " + self.selectedInspectionRows.length + " 条明细");
|
|
|
|
|
|
self.loadDetailList(planId);
|
|
|
|
|
|
self.$refs.inspectionTable.clearSelection();
|
|
|
|
|
|
self.selectedInspectionRows = [];
|
|
|
|
|
|
}).catch(function() {
|
|
|
|
|
|
self.$modal.closeLoading();
|
|
|
|
|
|
self.$modal.msgError("操作失败");
|
|
|
|
|
|
});
|
|
|
|
|
|
},
|
|
|
|
|
|
// ---- 计划 CRUD ----
|
2026-06-25 10:53:27 +08:00
|
|
|
|
handleAdd() {
|
|
|
|
|
|
this.reset();
|
|
|
|
|
|
this.open = true;
|
2026-07-03 16:56:44 +08:00
|
|
|
|
this.title = "新增检修单";
|
2026-06-25 10:53:27 +08:00
|
|
|
|
},
|
|
|
|
|
|
handleUpdate(row) {
|
|
|
|
|
|
this.reset();
|
|
|
|
|
|
var self = this;
|
|
|
|
|
|
getMaintenancePlan(row.planId).then(function(response) {
|
|
|
|
|
|
self.form = response.data;
|
|
|
|
|
|
self.open = true;
|
2026-07-03 16:56:44 +08:00
|
|
|
|
self.title = "修改检修单";
|
2026-06-25 10:53:27 +08:00
|
|
|
|
});
|
|
|
|
|
|
},
|
|
|
|
|
|
reset() {
|
|
|
|
|
|
this.form = {
|
|
|
|
|
|
planId: undefined, planNo: undefined, planName: undefined,
|
2026-07-03 16:56:44 +08:00
|
|
|
|
productionLine: undefined,
|
2026-06-25 10:53:27 +08:00
|
|
|
|
repairType: undefined, priorityLevel: 1,
|
|
|
|
|
|
plannedStartTime: undefined, plannedEndTime: undefined,
|
|
|
|
|
|
dutyDept: undefined, planOwner: undefined,
|
|
|
|
|
|
budgetAmount: undefined, planDescription: undefined,
|
2026-07-03 16:56:44 +08:00
|
|
|
|
remark: undefined
|
2026-06-25 10:53:27 +08:00
|
|
|
|
};
|
|
|
|
|
|
this.resetForm("form");
|
|
|
|
|
|
},
|
|
|
|
|
|
cancel() {
|
|
|
|
|
|
this.open = false;
|
|
|
|
|
|
this.reset();
|
|
|
|
|
|
},
|
|
|
|
|
|
submitForm() {
|
|
|
|
|
|
var self = this;
|
|
|
|
|
|
this.$refs["form"].validate(function(valid) {
|
|
|
|
|
|
if (valid) {
|
|
|
|
|
|
self.buttonLoading = true;
|
|
|
|
|
|
self.form.planNo = self.form.planNo || self.form.planName;
|
|
|
|
|
|
if (self.form.planId != null) {
|
|
|
|
|
|
updateMaintenancePlan(self.form).then(function() {
|
|
|
|
|
|
self.$modal.msgSuccess("修改成功");
|
|
|
|
|
|
self.open = false;
|
|
|
|
|
|
self.getList();
|
|
|
|
|
|
if (self.currentRow && self.currentRow.planId === self.form.planId) {
|
|
|
|
|
|
self.loadDetail(self.currentRow.planId);
|
|
|
|
|
|
}
|
|
|
|
|
|
}).finally(function() { self.buttonLoading = false; });
|
|
|
|
|
|
} else {
|
|
|
|
|
|
addMaintenancePlan(self.form).then(function(response) {
|
|
|
|
|
|
self.$modal.msgSuccess("新增成功");
|
|
|
|
|
|
self.open = false;
|
|
|
|
|
|
self.getList();
|
|
|
|
|
|
}).finally(function() { self.buttonLoading = false; });
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
},
|
|
|
|
|
|
handleDelete(row) {
|
|
|
|
|
|
var self = this;
|
2026-07-03 16:56:44 +08:00
|
|
|
|
this.$modal.confirm('是否确认删除检修单"' + row.planNo + '"?').then(function() {
|
2026-06-25 10:53:27 +08:00
|
|
|
|
self.loading = true;
|
|
|
|
|
|
return delMaintenancePlan(row.planId);
|
|
|
|
|
|
}).then(function() {
|
|
|
|
|
|
self.loading = false;
|
|
|
|
|
|
self.getList();
|
|
|
|
|
|
if (self.currentRow && self.currentRow.planId === row.planId) {
|
|
|
|
|
|
self.currentRow = null;
|
|
|
|
|
|
self.detailList = [];
|
2026-07-03 16:56:44 +08:00
|
|
|
|
self.inspectionRecords = [];
|
|
|
|
|
|
self.inspectionQueried = false;
|
2026-06-25 10:53:27 +08:00
|
|
|
|
}
|
|
|
|
|
|
self.$modal.msgSuccess("删除成功");
|
|
|
|
|
|
}).catch(function() { }).finally(function() { self.loading = false; });
|
|
|
|
|
|
},
|
2026-07-03 16:56:44 +08:00
|
|
|
|
// ---- 明细管理 ----
|
2026-07-08 10:49:00 +08:00
|
|
|
|
handleAddDetail() {
|
|
|
|
|
|
this.detailForm = {
|
|
|
|
|
|
planId: this.currentRow.planId,
|
2026-07-03 16:56:44 +08:00
|
|
|
|
componentName: '',
|
2026-07-08 10:49:00 +08:00
|
|
|
|
productionLine: this.currentRow.productionLine || '',
|
2026-07-03 16:56:44 +08:00
|
|
|
|
maintenanceCategory: 1,
|
|
|
|
|
|
repairContent: '',
|
|
|
|
|
|
repairUser: '',
|
2026-07-08 10:49:00 +08:00
|
|
|
|
itemPlanDate: undefined,
|
2026-07-03 16:56:44 +08:00
|
|
|
|
targetManufacturer: '',
|
2026-07-08 10:49:00 +08:00
|
|
|
|
detailStatus: 0
|
2026-06-25 10:53:27 +08:00
|
|
|
|
};
|
2026-07-08 10:49:00 +08:00
|
|
|
|
this.editingDetailId = null;
|
|
|
|
|
|
this.detailDialogTitle = "添加维修明细";
|
|
|
|
|
|
this.detailDialogVisible = true;
|
2026-06-25 10:53:27 +08:00
|
|
|
|
},
|
|
|
|
|
|
handleEditDetail(row) {
|
2026-07-08 10:49:00 +08:00
|
|
|
|
this.detailForm = Object.assign({}, row);
|
|
|
|
|
|
this.editingDetailId = row.detailId;
|
|
|
|
|
|
this.detailDialogTitle = "编辑维修明细";
|
|
|
|
|
|
this.detailDialogVisible = true;
|
2026-06-25 10:53:27 +08:00
|
|
|
|
},
|
2026-07-08 10:49:00 +08:00
|
|
|
|
submitDetailForm() {
|
|
|
|
|
|
if (!this.detailForm.componentName) {
|
|
|
|
|
|
this.$modal.msgWarning("请输入设备部件名称");
|
2026-06-25 10:53:27 +08:00
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
var self = this;
|
|
|
|
|
|
this.detailButtonLoading = true;
|
2026-07-08 10:49:00 +08:00
|
|
|
|
if (this.editingDetailId) {
|
|
|
|
|
|
updateMaintenancePlanDetail(this.detailForm).then(function() {
|
2026-06-25 10:53:27 +08:00
|
|
|
|
self.$modal.msgSuccess("修改成功");
|
2026-07-08 10:49:00 +08:00
|
|
|
|
self.detailDialogVisible = false;
|
2026-06-25 10:53:27 +08:00
|
|
|
|
self.loadDetailList(self.currentRow.planId);
|
|
|
|
|
|
}).finally(function() { self.detailButtonLoading = false; });
|
|
|
|
|
|
} else {
|
2026-07-08 10:49:00 +08:00
|
|
|
|
addMaintenancePlanDetail(this.detailForm).then(function() {
|
2026-06-25 10:53:27 +08:00
|
|
|
|
self.$modal.msgSuccess("添加成功");
|
2026-07-08 10:49:00 +08:00
|
|
|
|
self.detailDialogVisible = false;
|
2026-06-25 10:53:27 +08:00
|
|
|
|
self.loadDetailList(self.currentRow.planId);
|
|
|
|
|
|
}).finally(function() { self.detailButtonLoading = false; });
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
handleDeleteDetail(row) {
|
|
|
|
|
|
var self = this;
|
|
|
|
|
|
this.$modal.confirm('确认删除该维修明细?').then(function() {
|
|
|
|
|
|
return delMaintenancePlanDetail(row.detailId);
|
|
|
|
|
|
}).then(function() {
|
|
|
|
|
|
self.$modal.msgSuccess("删除成功");
|
|
|
|
|
|
self.loadDetailList(self.currentRow.planId);
|
|
|
|
|
|
}).catch(function() { });
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
|
|
<style scoped>
|
|
|
|
|
|
.count-container { height: calc(100vh - 84px); }
|
|
|
|
|
|
|
|
|
|
|
|
/* ========== 左侧面板 ========== */
|
|
|
|
|
|
.left-panel { display: flex; flex-direction: column; height: 100%; background: #f5f7fa; border-right: 1px solid #e4e7ed; }
|
|
|
|
|
|
.panel-header { display: flex; align-items: center; justify-content: space-between; padding: 12px 14px 8px; background: #f5f7fa; }
|
|
|
|
|
|
.header-title { display: flex; align-items: center; gap: 6px; font-size: 14px; font-weight: 600; color: #303133; }
|
|
|
|
|
|
.header-title i { color: #409eff; font-size: 16px; }
|
|
|
|
|
|
.search-row { display: flex; align-items: center; gap: 6px; padding: 0 14px 10px; background: #f5f7fa; }
|
2026-07-03 16:56:44 +08:00
|
|
|
|
.search-row .el-input { flex: 1; }
|
2026-06-25 10:53:27 +08:00
|
|
|
|
.list-body { flex: 1; overflow-y: auto; padding: 0 6px; }
|
|
|
|
|
|
.list-item { display: flex; align-items: center; padding: 10px 12px; margin-bottom: 2px; cursor: pointer; border-radius: 6px; transition: all 0.15s; }
|
|
|
|
|
|
.list-item:hover { background: #ebeef5; }
|
|
|
|
|
|
.list-item.active { background: #d9ecff; }
|
|
|
|
|
|
.list-item.active .item-title { color: #409eff; font-weight: 600; }
|
|
|
|
|
|
.item-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
|
|
|
|
|
|
.item-title { font-size: 13px; font-weight: 500; color: #303133; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
|
|
|
|
|
.item-sub { font-size: 12px; color: #909399; }
|
|
|
|
|
|
.item-actions { flex-shrink: 0; opacity: 0; transition: opacity 0.15s; }
|
|
|
|
|
|
.list-item:hover .item-actions { opacity: 1; }
|
|
|
|
|
|
.list-empty { display: flex; flex-direction: column; align-items: center; justify-content: center; padding: 60px 0; color: #c0c4cc; font-size: 13px; gap: 8px; }
|
|
|
|
|
|
.list-empty i { font-size: 32px; }
|
|
|
|
|
|
.list-footer { border-top: 1px solid #e4e7ed; padding: 2px 8px 0; background: #f5f7fa; }
|
|
|
|
|
|
|
2026-07-03 16:56:44 +08:00
|
|
|
|
/* ========== 右侧面板 ========== */
|
|
|
|
|
|
.right-panel { height: 100%; overflow: hidden; display: flex; flex-direction: column; background: #faf8f5; }
|
2026-06-25 10:53:27 +08:00
|
|
|
|
.empty-tip { display: flex; align-items: center; justify-content: center; height: 100%; color: #909399; font-size: 14px; gap: 8px; }
|
2026-07-08 10:49:00 +08:00
|
|
|
|
.right-content { flex: 1; display: flex; flex-direction: column; overflow: hidden; padding: 12px 16px; }
|
2026-06-25 10:53:27 +08:00
|
|
|
|
|
2026-07-03 16:56:44 +08:00
|
|
|
|
/* 基本信息栏 */
|
|
|
|
|
|
.info-bar { display: flex; align-items: center; justify-content: space-between; padding: 8px 16px; background: #fff; border: 1px solid #e4e7ed; border-radius: 4px; margin-bottom: 10px; flex-shrink: 0; }
|
|
|
|
|
|
.info-bar-left { display: flex; align-items: center; gap: 6px; font-size: 13px; }
|
|
|
|
|
|
.info-label { color: #909399; }
|
|
|
|
|
|
.info-value { color: #303133; font-weight: 500; }
|
|
|
|
|
|
.info-bar-right { display: flex; align-items: center; gap: 8px; flex-shrink: 0; }
|
2026-06-25 10:53:27 +08:00
|
|
|
|
|
2026-07-03 16:56:44 +08:00
|
|
|
|
/* 上半部分:检修记录 */
|
|
|
|
|
|
.inspection-section { flex: 1; min-height: 0; display: flex; flex-direction: column; overflow: hidden; background: #fff; border: 1px solid #e4e7ed; border-radius: 4px; margin-bottom: 10px; }
|
|
|
|
|
|
.section-header { display: flex; align-items: center; justify-content: space-between; padding: 8px 12px; border-bottom: 1px solid #ebeef5; flex-shrink: 0; }
|
|
|
|
|
|
.section-title { font-size: 13px; font-weight: 600; color: #303133; }
|
|
|
|
|
|
.section-title .en-sub { font-size: 11px; font-weight: 400; color: #c0c4cc; font-style: italic; }
|
|
|
|
|
|
.section-count { font-size: 12px; color: #909399; }
|
|
|
|
|
|
.section-actions { display: flex; align-items: center; gap: 6px; }
|
|
|
|
|
|
.inspection-section .el-table { flex: 1; overflow-y: auto; }
|
2026-06-25 10:53:27 +08:00
|
|
|
|
|
2026-07-03 16:56:44 +08:00
|
|
|
|
/* 下半部分:维修明细 */
|
|
|
|
|
|
.detail-section { flex: 1; min-height: 0; display: flex; flex-direction: column; overflow: hidden; background: #fff; border: 1px solid #e4e7ed; border-radius: 4px; }
|
|
|
|
|
|
.detail-section .el-table { flex: 1; overflow-y: auto; }
|
2026-06-25 10:53:27 +08:00
|
|
|
|
|
2026-07-03 16:56:44 +08:00
|
|
|
|
.empty-data { padding: 24px 0; text-align: center; color: #c0c4cc; font-size: 13px; }
|
2026-06-25 10:53:27 +08:00
|
|
|
|
|
2026-07-03 16:56:44 +08:00
|
|
|
|
/* 表格样式 */
|
|
|
|
|
|
.right-panel .el-table { border: none !important; }
|
|
|
|
|
|
.right-panel .el-table th { background: #f5f7fa !important; color: #606266 !important; font-size: 12px !important; padding: 6px 0 !important; }
|
|
|
|
|
|
.right-panel .el-table td { padding: 6px 0 !important; font-size: 12px !important; color: #303133 !important; }
|
|
|
|
|
|
.right-panel .el-divider--vertical { margin: 0 6px; }
|
2026-06-25 10:53:27 +08:00
|
|
|
|
</style>
|