<template>
|
<!-- 设备保养计划-->
|
<div>
|
<div style="margin: 10px 0 14px;">
|
<div class="plan-top">
|
<div class="plan-top-left">
|
<span class="title" style="margin-bottom: 0;">{{ planInfo.planName || (planYear + '年度设备保养计划') }}</span>
|
<el-select v-model="planYear" size="small" style="width: 110px; margin-left: 16px;" @change="handleYearChange">
|
<el-option v-for="y in yearOptions" :key="y" :label="y" :value="y"></el-option>
|
</el-select>
|
</div>
|
<div>
|
<el-button size="small" type="primary" @click="loadPlan">刷新</el-button>
|
<el-button size="small" type="primary" :disabled="planInfo.status === 1"
|
@click="tellApprove">审核通知</el-button>
|
<el-button size="small" type="primary"
|
:disabled="planInfo.status === 1 || userId != planInfo.auditId" @click="handleApprove">审核</el-button>
|
<el-button size="small" type="primary" :loading="outLoading" @click="handleDownOne">导出</el-button>
|
</div>
|
</div>
|
<div class="plan-info-bar">
|
<span>编制人:{{ planInfo.compiler || '—' }}</span>
|
<span>编制日期:{{ planInfo.datePreparationStr || '—' }}</span>
|
<span v-if="planInfo.status === 1">审核状态:<el-tag type="success">通 过</el-tag></span>
|
<span v-else-if="planInfo.status === 0">审核状态:<el-tag type="danger">不通过</el-tag></span>
|
<span v-else>审核状态:<el-tag type="info">未审核</el-tag></span>
|
<span v-if="planInfo.auditRemark">审核信息:{{ planInfo.auditRemark }}</span>
|
<span v-if="isAudited && planInfo.audit">审核人:{{ planInfo.audit }}</span>
|
<span v-if="isAudited && planInfo.auditDateStr">审核时间:{{ planInfo.auditDateStr }}</span>
|
</div>
|
</div>
|
<div class="search">
|
<div>
|
<el-form :model="searchForm" ref="searchForm" size="small" :inline="true">
|
<el-form-item label="设备名称" prop="deviceName">
|
<el-input v-model="searchForm.deviceName" clearable @keyup.enter="handleQuery"
|
size="small"></el-input>
|
</el-form-item>
|
<el-form-item label="设备编号" prop="deviceNumber">
|
<el-input v-model="searchForm.deviceNumber" @keyup.enter="handleQuery" clearable
|
size="small"></el-input>
|
</el-form-item>
|
<el-form-item>
|
<el-button type="primary" size="small" @click="handleQuery">查询</el-button>
|
<el-button size="small" @click="reset">重置</el-button>
|
</el-form-item>
|
</el-form>
|
</div>
|
</div>
|
<div>
|
<el-table ref="yearTable" v-loading="tableLoading" :data="tableData" border
|
:row-class-name="tableRowClassName" :height="'calc(100vh - 29em)'" style="width: 100%;">
|
<el-table-column align="center" header-align="center" label="序号" prop="prop" type="index"
|
width="70"></el-table-column>
|
<el-table-column label="设备名称及型号" min-width="180" show-overflow-tooltip>
|
<template #default="scope">
|
{{ scope.row.deviceName }}{{ scope.row.specificationModel ? ' ' + scope.row.specificationModel : '' }}
|
</template>
|
</el-table-column>
|
<el-table-column label="设备编号" min-width="140" prop="deviceNumber"></el-table-column>
|
<el-table-column label="归属实验室" min-width="120" prop="storagePoint"></el-table-column>
|
<el-table-column label="保养关键部位" min-width="150" prop="maintenanceSite" show-overflow-tooltip></el-table-column>
|
<el-table-column label="保养内容" min-width="180" prop="maintenanceContent" show-overflow-tooltip></el-table-column>
|
<el-table-column label="保养周期" min-width="100" prop="maintenanceIntervals"></el-table-column>
|
<el-table-column label="计划保养时间" min-width="130" prop="maintenanceDate"
|
:formatter="formatDateCell"></el-table-column>
|
<el-table-column align="center" fixed="right" label="操作" min-width="160">
|
<template #default="scope">
|
<el-button size="small" link type="primary" :disabled="planInfo.status === 1"
|
@click="handleForm('edit', scope.row)">编辑</el-button>
|
<el-button size="small" link type="primary" @click="handleForm('view', scope.row)">查看</el-button>
|
<el-button size="small" link type="danger" :disabled="planInfo.status === 1"
|
@click="deleteRow(scope.row)">删除</el-button>
|
</template>
|
</el-table-column>
|
</el-table>
|
<el-pagination :current-page="pagination1.current" :page-size="pagination1.size"
|
:page-sizes="[10, 20, 30, 50, 100]" background :total="pagination1.total"
|
layout="->,total, sizes, prev, pager, next, jumper" @size-change="handleSizeChange1"
|
@current-change="handleCurrentChange1">
|
</el-pagination>
|
</div>
|
<el-dialog :close-on-click-modal="false" :close-on-press-escape="false" v-model="dialogVisible"
|
title="设备保养计划明细" width="60%" @close="resetForm">
|
<el-form ref="modelForm" :model="form" :rules="rules" label-width="130px">
|
<el-row>
|
<el-col :span="12">
|
<el-form-item label="设备名称:">
|
<el-input v-model="form.deviceName" disabled size="small"></el-input>
|
</el-form-item>
|
</el-col>
|
<el-col :span="12">
|
<el-form-item label="设备编号:">
|
<el-input v-model="form.deviceNumber" disabled size="small"></el-input>
|
</el-form-item>
|
</el-col>
|
<el-col :span="12">
|
<el-form-item label="归属实验室:">
|
<el-input v-model="form.storagePoint" disabled size="small"></el-input>
|
</el-form-item>
|
</el-col>
|
<el-col :span="12">
|
<el-form-item label="保养周期:">
|
<el-input v-model="form.maintenanceIntervals" :disabled="operationType === 'view'" clearable
|
size="small"></el-input>
|
</el-form-item>
|
</el-col>
|
<el-col :span="24">
|
<el-form-item label="保养关键部位:">
|
<el-input v-model="form.maintenanceSite" :disabled="operationType === 'view'" clearable size="small"
|
type="textarea"></el-input>
|
</el-form-item>
|
</el-col>
|
<el-col :span="24">
|
<el-form-item label="保养内容:">
|
<el-input v-model="form.maintenanceContent" :disabled="operationType === 'view'" clearable size="small"
|
type="textarea"></el-input>
|
</el-form-item>
|
</el-col>
|
<el-col :span="12">
|
<el-form-item label="计划保养时间:" prop="maintenanceDate">
|
<el-date-picker v-model="form.maintenanceDate" :disabled="operationType === 'view'" clearable
|
format="YYYY-MM-DD" placeholder="选择日期" size="small" style="width:100%" type="date"
|
value-format="YYYY-MM-DD"></el-date-picker>
|
</el-form-item>
|
</el-col>
|
</el-row>
|
</el-form>
|
<template #footer><span class="dialog-footer">
|
<el-button @click="resetForm">取 消</el-button>
|
<el-button :loading="submitFormLoading" type="primary" @click="submitForm"
|
v-if="operationType !== 'view'">确 认</el-button>
|
</span></template>
|
</el-dialog>
|
<el-dialog v-model="approvalDialog" title="审核" width="30%" @close="approvalDialog = false">
|
<span>
|
审核信息:
|
<el-input v-model="approvalRemark" type="textarea"></el-input>
|
</span>
|
<template #footer><span class="dialog-footer">
|
<el-button :loading="approvalLoading" @click="handleApproval(0)">不通过</el-button>
|
<el-button :loading="approvalLoading" type="primary" @click="handleApproval(1)">通 过</el-button>
|
</span></template>
|
</el-dialog>
|
<el-dialog v-model="notificationDia" title="提交审核" width="30%" @close="closeNotificationDia">
|
<span style="margin-top: 10px;display: inline-block">
|
请选择审核人:
|
<el-select v-model="auditUserId" clearable filterable size="small" style="width: 90%;">
|
<el-option v-for="item in responsibleOptions" :key="item.value" :label="item.label" :value="item.value">
|
</el-option>
|
</el-select>
|
</span>
|
<template #footer><span class="dialog-footer">
|
<el-button :loading="notificationLoading" @click="closeNotificationDia">取 消</el-button>
|
<el-button :loading="notificationLoading" type="primary" @click="notification">提 交</el-button>
|
</span></template>
|
</el-dialog>
|
</div>
|
</template>
|
|
<script>
|
import {
|
selectDeviceMaintenancePlanByPage,
|
submitReviewMaintenancePlanStatus,
|
getMaintenancePlanByYear,
|
pageMaintenancePlanDetail,
|
updateMaintenancePlanDetail,
|
deleteMaintenancePlanDetail,
|
exportDeviceMaintenancePlan,
|
reviewMaintenancePlanStatus,
|
} from '@/api/cnas/resourceDemand/device.js'
|
import { selectUserCondition } from "@/api/business/inspectionTask";
|
import { mapGetters } from "@/utils/store-compat";
|
import { formatDateOnly } from './dateFormat'
|
import { saveBlobOrShowError } from '@/utils/saveBlob'
|
export default {
|
name: "equipment-maintenance-plan",
|
props: {
|
clickNodeVal: {
|
type: Object,
|
default: () => {
|
return {};
|
}
|
}
|
},
|
data() {
|
return {
|
planYear: '',
|
yearOptions: [],
|
planInfo: {},
|
searchForm: {
|
deviceName: '',
|
deviceNumber: '',
|
},
|
tableData: [],
|
tableLoading: false,
|
pagination1: {
|
size: 10,
|
current: 1,
|
total: 0,
|
},
|
dialogVisible: false,
|
operationType: '',
|
form: {},
|
rules: {
|
maintenanceDate: [{ required: true, message: '请选择计划保养时间', trigger: 'change' }],
|
},
|
submitFormLoading: false,
|
outLoading: false,
|
responsibleOptions: [],
|
notificationDia: false,
|
notificationLoading: false,
|
auditUserId: '',
|
approvalDialog: false,
|
approvalLoading: false,
|
approvalRemark: '',
|
}
|
},
|
mounted() {
|
this.loadYearOptions()
|
},
|
methods: {
|
// 年份下拉选项:已有计划年份 + 当前年份
|
loadYearOptions() {
|
const currentYear = String(new Date().getFullYear())
|
const finish = (years) => {
|
if (years.indexOf(currentYear) === -1) {
|
years.push(currentYear)
|
}
|
this.yearOptions = [...new Set(years)].sort((a, b) => b.localeCompare(a))
|
this.planYear = currentYear
|
this.loadPlan()
|
}
|
selectDeviceMaintenancePlanByPage({
|
current: 1,
|
size: 99,
|
}).then(res => {
|
let years = []
|
if (res.code == 200) {
|
years = (res.data.records || []).map(r => r.planYear).filter(Boolean)
|
}
|
finish(years)
|
}).catch(() => {
|
finish([])
|
})
|
},
|
// 切换年份
|
handleYearChange() {
|
this.pagination1.current = 1
|
this.loadPlan()
|
},
|
// 查询年份计划(不存在自动创建并补全到点明细),随后刷新明细
|
loadPlan() {
|
getMaintenancePlanByYear({ planYear: this.planYear }).then(res => {
|
if (res.code == 200) {
|
this.planInfo = res.data || {}
|
}
|
this.getTableList()
|
}).catch(() => {
|
this.planInfo = {}
|
this.tableData = []
|
this.pagination1.total = 0
|
this.tableLoading = false
|
})
|
},
|
// 查询条件变化后从第一页开始查
|
handleQuery() {
|
this.pagination1.current = 1
|
this.getTableList()
|
},
|
// 明细-查询
|
getTableList() {
|
if (!this.planInfo.maintenancePlanId) {
|
return
|
}
|
this.tableLoading = true
|
pageMaintenancePlanDetail({
|
current: this.pagination1.current,
|
size: this.pagination1.size,
|
planId: this.planInfo.maintenancePlanId,
|
deviceName: this.searchForm.deviceName,
|
deviceNumber: this.searchForm.deviceNumber,
|
}).then(res => {
|
if (res.code == 200) {
|
this.tableData = res.data.records
|
this.pagination1.total = res.data.total
|
}
|
this.tableLoading = false
|
}).catch(() => {
|
this.tableLoading = false
|
})
|
},
|
// 到点需保养的行标红
|
formatDateCell(row, column, cellValue) {
|
return formatDateOnly(cellValue)
|
},
|
tableRowClassName({ row }) {
|
return row.redFlag === 1 ? 'red-row' : ''
|
},
|
reset() {
|
this.searchForm = {
|
deviceName: '',
|
deviceNumber: '',
|
}
|
this.pagination1.current = 1
|
this.getTableList()
|
},
|
// 分页
|
handleSizeChange1(val) {
|
this.pagination1.size = val
|
this.getTableList()
|
},
|
// 分页
|
handleCurrentChange1(val) {
|
this.pagination1.current = val
|
this.getTableList()
|
},
|
// 打开明细弹框
|
handleForm(type, row) {
|
this.operationType = type
|
this.form = this.HaveJson(row)
|
this.dialogVisible = true
|
this.$nextTick(() => {
|
if (this.$refs.modelForm) {
|
this.$refs.modelForm.clearValidate()
|
}
|
})
|
},
|
// 提交表单(只回传明细表字段)
|
submitForm() {
|
this.$refs.modelForm.validate(valid => {
|
if (valid) {
|
this.submitFormLoading = true
|
const payload = {
|
maintenancePlanDetailId: this.form.maintenancePlanDetailId,
|
maintenancePlanId: this.form.maintenancePlanId,
|
deviceId: this.form.deviceId,
|
maintenanceSite: this.form.maintenanceSite,
|
maintenanceContent: this.form.maintenanceContent,
|
maintenanceIntervals: this.form.maintenanceIntervals,
|
maintenanceDate: this.form.maintenanceDate,
|
}
|
updateMaintenancePlanDetail(payload).then(res => {
|
if (res.code == 200) {
|
this.$message.success('修改成功')
|
this.dialogVisible = false
|
this.getTableList()
|
}
|
this.submitFormLoading = false
|
}).catch(() => {
|
this.submitFormLoading = false
|
})
|
}
|
})
|
},
|
resetForm() {
|
this.dialogVisible = false
|
},
|
// 明细-删除
|
deleteRow(row) {
|
this.$confirm('此操作将永久删除该条明细, 是否继续?', '提示', {
|
confirmButtonText: '确定',
|
cancelButtonText: '取消',
|
type: 'warning'
|
}).then(() => {
|
deleteMaintenancePlanDetail({ maintenancePlanDetailId: row.maintenancePlanDetailId }).then(() => {
|
this.$message.success('删除成功!');
|
this.getTableList()
|
});
|
}).catch(() => {
|
this.$message({
|
type: 'info',
|
message: '已取消删除'
|
});
|
});
|
},
|
// 打开提交审核弹框
|
tellApprove() {
|
this.getUserList()
|
this.notificationDia = true
|
},
|
// 关闭提交审核弹框
|
closeNotificationDia() {
|
this.notificationDia = false
|
this.auditUserId = ''
|
},
|
// 提交审核通知
|
notification() {
|
if (!this.auditUserId) {
|
this.$message.warning('请选择审核人')
|
return
|
}
|
this.notificationLoading = true
|
submitReviewMaintenancePlanStatus({
|
auditId: this.auditUserId,
|
maintenancePlanId: this.planInfo.maintenancePlanId,
|
}).then(res => {
|
this.notificationLoading = false
|
if (res.code == 200) {
|
this.closeNotificationDia()
|
this.loadPlan()
|
}
|
}).catch(() => {
|
this.notificationLoading = false
|
})
|
},
|
// 打开审核弹框
|
handleApprove() {
|
this.approvalRemark = ''
|
this.approvalDialog = true
|
},
|
// 提交审核结果
|
handleApproval(status) {
|
this.approvalLoading = true
|
reviewMaintenancePlanStatus({
|
maintenancePlanId: this.planInfo.maintenancePlanId,
|
status: status,
|
auditRemark: this.approvalRemark,
|
}).then(res => {
|
if (res.code == 200) {
|
this.$message.success('审核成功!');
|
this.approvalDialog = false
|
this.loadPlan()
|
}
|
this.approvalLoading = false
|
}).catch(() => {
|
this.approvalLoading = false
|
})
|
},
|
// 导出
|
handleDownOne() {
|
this.outLoading = true
|
exportDeviceMaintenancePlan({ maintenancePlanId: this.planInfo.maintenancePlanId }).then(res => {
|
this.outLoading = false
|
saveBlobOrShowError(res, '设备保养计划表.docx', 'application/msword')
|
}).catch(() => {
|
this.outLoading = false
|
})
|
},
|
// 获取负责人信息接口
|
getUserList() {
|
selectUserCondition().then(res => {
|
if (res.code == 200) {
|
this.responsibleOptions = (res.data || []).map(item => ({
|
label: item.name,
|
value: item.id,
|
}))
|
}
|
});
|
}
|
},
|
computed: {
|
...mapGetters(["userId"]),
|
// 是否已完成审核(通过/不通过)
|
isAudited() {
|
return this.planInfo.status === 0 || this.planInfo.status === 1;
|
},
|
},
|
}
|
</script>
|
|
<style scoped>
|
.title {
|
position: relative;
|
font-size: 16px;
|
color: var(--lims-text);
|
font-weight: 400;
|
padding-left: 10px;
|
margin-bottom: 10px;
|
}
|
|
.title::before {
|
position: absolute;
|
left: 0;
|
top: 4px;
|
content: '';
|
width: 4px;
|
height: 16px;
|
background-color: var(--el-color-primary);
|
border-radius: 2px;
|
}
|
|
.plan-top {
|
display: flex;
|
align-items: center;
|
justify-content: space-between;
|
flex-wrap: wrap;
|
}
|
|
.plan-top-left {
|
display: flex;
|
align-items: center;
|
}
|
|
.plan-info-bar {
|
display: flex;
|
align-items: center;
|
flex-wrap: wrap;
|
gap: 32px;
|
background: #f5f7fa;
|
border-radius: 4px;
|
padding: 10px 16px;
|
margin-top: 14px;
|
font-size: 14px;
|
color: #606266;
|
}
|
|
.search {
|
display: flex;
|
justify-content: space-between;
|
margin-bottom: 10px;
|
}
|
|
:deep(.red-row td) {
|
background: #ffcccc !important;
|
}
|
</style>
|