|
|
@@ -3,10 +3,10 @@
|
|
|
<!-- 页面头部 -->
|
|
|
<div class="page-header">
|
|
|
<div class="header-left">
|
|
|
- <el-button icon="el-icon-arrow-left" @click="goBack">返回</el-button>
|
|
|
<span class="page-title">{{ pageTitle }}</span>
|
|
|
</div>
|
|
|
<div class="header-right">
|
|
|
+ <el-button icon="el-icon-arrow-left" @click="goBack">返回</el-button>
|
|
|
<el-button type="primary" @click="handleSubmit" :loading="submitting">
|
|
|
{{ isPlannedStatus ? '提交申请' : (formData.planId && formData.approvalStatus === '1' ? '再次提交申请' : '确 定') }}
|
|
|
</el-button>
|
|
|
@@ -18,118 +18,128 @@
|
|
|
<el-form ref="form" :model="formData" :rules="rules" label-width="120px">
|
|
|
<!-- 基础信息区域 -->
|
|
|
<div class="form-section">
|
|
|
- <div class="section-header">
|
|
|
- <i class="el-icon-info"></i>
|
|
|
- <span class="section-title">基础信息</span>
|
|
|
- </div>
|
|
|
- <el-row :gutter="20">
|
|
|
- <el-col :span="8">
|
|
|
- <el-form-item label="选择设备" prop="devId">
|
|
|
- <el-select
|
|
|
- v-model="formData.devId"
|
|
|
- filterable
|
|
|
- remote
|
|
|
- :remote-method="searchDevice"
|
|
|
- :loading="deviceLoading"
|
|
|
- placeholder="请输入设备位号或名称搜索"
|
|
|
- style="width: 100%"
|
|
|
- @change="handleDeviceChange"
|
|
|
- @focus="handleDeviceFocus"
|
|
|
- :disabled="!!formData.planId"
|
|
|
- clearable>
|
|
|
- <el-option
|
|
|
- v-for="device in deviceOptions"
|
|
|
- :key="device.devId"
|
|
|
- :label="`${device.devTag} - ${device.devName}`"
|
|
|
- :value="device.devId">
|
|
|
- <span style="float: left">{{ device.devTag }}</span>
|
|
|
- <span style="float: right; color: #8492a6; font-size: 13px">{{ device.devName }}</span>
|
|
|
- </el-option>
|
|
|
- </el-select>
|
|
|
- </el-form-item>
|
|
|
- </el-col>
|
|
|
- <el-col :span="8">
|
|
|
- <el-form-item label="计划开始时间" prop="planTime">
|
|
|
- <el-date-picker
|
|
|
- v-model="formData.planTime"
|
|
|
- type="date"
|
|
|
- value-format="yyyy-MM-dd"
|
|
|
- placeholder="选择开始时间"
|
|
|
- style="width: 100%">
|
|
|
- </el-date-picker>
|
|
|
- </el-form-item>
|
|
|
- </el-col>
|
|
|
- <el-col :span="8">
|
|
|
- <el-form-item label="计划结束时间" prop="planEndTime">
|
|
|
- <el-date-picker
|
|
|
- v-model="formData.planEndTime"
|
|
|
- type="date"
|
|
|
- value-format="yyyy-MM-dd"
|
|
|
- placeholder="选择结束时间"
|
|
|
- style="width: 100%">
|
|
|
- </el-date-picker>
|
|
|
- </el-form-item>
|
|
|
- </el-col>
|
|
|
- </el-row>
|
|
|
<el-row :gutter="20">
|
|
|
- <el-col :span="8">
|
|
|
- <el-form-item label="责任人" prop="responsible">
|
|
|
- <el-select
|
|
|
- v-model="formData.responsible"
|
|
|
- placeholder="请选择责任人"
|
|
|
- style="width: 100%"
|
|
|
- clearable
|
|
|
- filterable>
|
|
|
- <el-option
|
|
|
- v-for="staff in staffOptions"
|
|
|
- :key="staff.staffid"
|
|
|
- :label="`${staff.name} (${staff.staffid})`"
|
|
|
- :value="staff.staffid">
|
|
|
- </el-option>
|
|
|
- </el-select>
|
|
|
- </el-form-item>
|
|
|
- </el-col>
|
|
|
- <el-col :span="8">
|
|
|
- <el-form-item label="审批人" prop="approver">
|
|
|
- <el-select
|
|
|
- v-model="formData.approver"
|
|
|
- placeholder="请选择审批人"
|
|
|
- style="width: 100%"
|
|
|
- clearable
|
|
|
- filterable
|
|
|
- :disabled="isApproverDisabled">
|
|
|
- <el-option
|
|
|
- v-for="staff in staffOptions"
|
|
|
- :key="staff.staffid"
|
|
|
- :label="`${staff.name} (${staff.staffid})`"
|
|
|
- :value="staff.staffid">
|
|
|
- </el-option>
|
|
|
- </el-select>
|
|
|
- </el-form-item>
|
|
|
+ <!-- 左侧:基础信息 -->
|
|
|
+ <el-col :span="14">
|
|
|
+ <div class="section-header">
|
|
|
+ <i class="el-icon-info"></i>
|
|
|
+ <span class="section-title">计划基础信息</span>
|
|
|
+ </div>
|
|
|
+ <el-row :gutter="20">
|
|
|
+ <el-col :span="12">
|
|
|
+ <el-form-item label="选择设备" prop="devId">
|
|
|
+ <el-select
|
|
|
+ v-model="formData.devId"
|
|
|
+ filterable
|
|
|
+ remote
|
|
|
+ :remote-method="searchDevice"
|
|
|
+ :loading="deviceLoading"
|
|
|
+ placeholder="请输入设备位号或名称搜索"
|
|
|
+ style="width: 100%"
|
|
|
+ @change="handleDeviceChange"
|
|
|
+ @focus="handleDeviceFocus"
|
|
|
+ :disabled="!!formData.planId"
|
|
|
+ clearable>
|
|
|
+ <el-option
|
|
|
+ v-for="device in deviceOptions"
|
|
|
+ :key="device.devId"
|
|
|
+ :label="`${device.devTag} - ${device.devName}`"
|
|
|
+ :value="device.devId">
|
|
|
+ <span style="float: left">{{ device.devTag }}</span>
|
|
|
+ <span style="float: right; color: #8492a6; font-size: 13px">{{ device.devName }}</span>
|
|
|
+ </el-option>
|
|
|
+ </el-select>
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="12">
|
|
|
+ <el-form-item label="计划开始时间" prop="planTime">
|
|
|
+ <el-date-picker
|
|
|
+ v-model="formData.planTime"
|
|
|
+ type="date"
|
|
|
+ value-format="yyyy-MM-dd"
|
|
|
+ placeholder="选择开始时间"
|
|
|
+ style="width: 100%">
|
|
|
+ </el-date-picker>
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+ <el-row :gutter="20">
|
|
|
+ <el-col :span="12">
|
|
|
+ <el-form-item label="计划结束时间" prop="planEndTime">
|
|
|
+ <el-date-picker
|
|
|
+ v-model="formData.planEndTime"
|
|
|
+ type="date"
|
|
|
+ value-format="yyyy-MM-dd"
|
|
|
+ placeholder="选择结束时间"
|
|
|
+ style="width: 100%">
|
|
|
+ </el-date-picker>
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="12">
|
|
|
+ <el-form-item label="责任人" prop="responsible">
|
|
|
+ <el-select
|
|
|
+ v-model="formData.responsible"
|
|
|
+ placeholder="请选择责任人"
|
|
|
+ style="width: 100%"
|
|
|
+ clearable
|
|
|
+ filterable>
|
|
|
+ <el-option
|
|
|
+ v-for="staff in staffOptions"
|
|
|
+ :key="staff.staffid"
|
|
|
+ :label="`${staff.name} (${staff.staffid})`"
|
|
|
+ :value="staff.staffid">
|
|
|
+ </el-option>
|
|
|
+ </el-select>
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+ <el-row :gutter="20">
|
|
|
+ <el-col :span="12">
|
|
|
+ <el-form-item label="审批人" prop="approver">
|
|
|
+ <el-select
|
|
|
+ v-model="formData.approver"
|
|
|
+ placeholder="请选择审批人"
|
|
|
+ style="width: 100%"
|
|
|
+ clearable
|
|
|
+ filterable
|
|
|
+ :disabled="isApproverDisabled">
|
|
|
+ <el-option
|
|
|
+ v-for="staff in staffOptions"
|
|
|
+ :key="staff.staffid"
|
|
|
+ :label="`${staff.name} (${staff.staffid})`"
|
|
|
+ :value="staff.staffid">
|
|
|
+ </el-option>
|
|
|
+ </el-select>
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="12">
|
|
|
+ <el-form-item label="备注" prop="remarks">
|
|
|
+ <el-input v-model="formData.remarks" type="textarea" :rows="1" placeholder="请输入备注" />
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
</el-col>
|
|
|
- <el-col :span="8">
|
|
|
- <el-form-item label="备注" prop="remarks">
|
|
|
- <el-input v-model="formData.remarks" type="textarea" :rows="1" placeholder="请输入备注" />
|
|
|
- </el-form-item>
|
|
|
+
|
|
|
+ <!-- 设备信息展示:右侧 -->
|
|
|
+ <el-col :span="10" v-if="selectedDevice">
|
|
|
+ <!-- 设备信息展示 -->
|
|
|
+ <div class="section-header">
|
|
|
+ <i class="el-icon-s-platform"></i>
|
|
|
+ <span class="section-title">设备信息</span>
|
|
|
+ </div>
|
|
|
+ <el-descriptions :column="2" border size="small">
|
|
|
+ <!-- 设备名称单独占一行 -->
|
|
|
+ <el-descriptions-item label="设备名称" :span="2">{{ selectedDevice.devName }}</el-descriptions-item>
|
|
|
+ <!-- 其余字段两列排列 -->
|
|
|
+ <el-descriptions-item label="设备位号">{{ selectedDevice.devTag }}</el-descriptions-item>
|
|
|
+ <el-descriptions-item label="位置">{{ selectedDevice.devLoc }}</el-descriptions-item>
|
|
|
+ <el-descriptions-item label="设备类型">{{ selectedDevice.devType }}</el-descriptions-item>
|
|
|
+ <el-descriptions-item label="区域负责人">{{ getStaffNameById(selectedDevice.areaResponsible) }}</el-descriptions-item>
|
|
|
+ </el-descriptions>
|
|
|
</el-col>
|
|
|
</el-row>
|
|
|
</div>
|
|
|
|
|
|
- <!-- 设备信息展示 -->
|
|
|
- <div class="form-section" v-if="selectedDevice">
|
|
|
- <div class="section-header">
|
|
|
- <i class="el-icon-s-platform"></i>
|
|
|
- <span class="section-title">设备信息</span>
|
|
|
- </div>
|
|
|
- <el-descriptions :column="5" border size="small">
|
|
|
- <el-descriptions-item label="设备位号">{{ selectedDevice.devTag }}</el-descriptions-item>
|
|
|
- <el-descriptions-item label="设备名称">{{ selectedDevice.devName }}</el-descriptions-item>
|
|
|
- <el-descriptions-item label="位置">{{ selectedDevice.devLoc }}</el-descriptions-item>
|
|
|
- <el-descriptions-item label="设备类型">{{ selectedDevice.devType }}</el-descriptions-item>
|
|
|
- <el-descriptions-item label="区域负责人">{{ selectedDevice.areaResponsible }}</el-descriptions-item>
|
|
|
- </el-descriptions>
|
|
|
- </div>
|
|
|
-
|
|
|
<!-- 部件列表及维修记录选择 -->
|
|
|
<div class="form-section" v-if="compoList.length > 0">
|
|
|
<div class="section-header">
|
|
|
@@ -148,7 +158,7 @@
|
|
|
{{ (compoCurrentPage - 1) * compoPageSize + scope.$index + 1 }}
|
|
|
</template>
|
|
|
</el-table-column>
|
|
|
- <el-table-column label="部件名称" prop="compoName" width="150" :show-overflow-tooltip="true" />
|
|
|
+ <el-table-column label="部件名称" prop="compoName" :show-overflow-tooltip="true" />
|
|
|
<el-table-column label="检查频率/日期" width="120" align="center">
|
|
|
<template slot-scope="scope">
|
|
|
<div style="line-height: 1.2;">
|
|
|
@@ -313,10 +323,16 @@ export default {
|
|
|
this.initPage();
|
|
|
// 计算表格高度
|
|
|
this.$nextTick(() => {
|
|
|
- this.tableHeight = Math.max(300, window.innerHeight - 500);
|
|
|
+ this.tableHeight = Math.max(380, window.innerHeight - 440);
|
|
|
});
|
|
|
},
|
|
|
methods: {
|
|
|
+ /** 根据员工号获取姓名 */
|
|
|
+ getStaffNameById(staffid) {
|
|
|
+ if (!staffid) return '';
|
|
|
+ const staff = this.staffOptions.find(s => s.staffid === staffid);
|
|
|
+ return staff ? staff.name : staffid;
|
|
|
+ },
|
|
|
/** 初始化页面 */
|
|
|
initPage() {
|
|
|
const planId = this.$route.query.planId;
|
|
|
@@ -326,17 +342,21 @@ export default {
|
|
|
} else {
|
|
|
// 新增模式
|
|
|
this.resetForm();
|
|
|
+
|
|
|
// 检查是否有从设备页面传递过来的参数
|
|
|
const { devId, plant, devName, devTag } = this.$route.query;
|
|
|
- if (devId || devTag) {
|
|
|
- this.formData.devId = devId ? Number(devId) : null;
|
|
|
+
|
|
|
+ // 如果带了 devId,直接复用 handleDeviceChange 逻辑,加载完整设备信息和部件
|
|
|
+ if (devId) {
|
|
|
+ const idNum = Number(devId);
|
|
|
+ this.formData.devId = idNum;
|
|
|
+ this.handleDeviceChange(idNum);
|
|
|
+ } else if (devTag || plant || devName) {
|
|
|
+ // 兼容只传 devTag/plant/devName 的场景,尽量预填基础字段和部件列表
|
|
|
this.formData.plant = plant || null;
|
|
|
+ this.formData.devName = devName || null;
|
|
|
this.formData.devTag = devTag || null;
|
|
|
- // 预填设备信息
|
|
|
- if (devId && devName && devTag) {
|
|
|
- this.selectedDevice = { devId: Number(devId), devName, devTag, plant };
|
|
|
- this.deviceOptions = [this.selectedDevice];
|
|
|
- // 加载该设备的部件列表
|
|
|
+ if (devTag) {
|
|
|
this.loadCompoList(devTag);
|
|
|
}
|
|
|
}
|
|
|
@@ -363,8 +383,16 @@ export default {
|
|
|
},
|
|
|
/** 查询人员列表 */
|
|
|
getStaffList() {
|
|
|
- listStaffmgrAll().then(response => {
|
|
|
+ return listStaffmgrAll().then(response => {
|
|
|
this.staffOptions = response.rows || response.data || [];
|
|
|
+
|
|
|
+ // 如果此时已经选中了设备且尚未设置责任人,根据设备的区域负责人预填责任人
|
|
|
+ if (this.selectedDevice && this.selectedDevice.areaResponsible && !this.formData.responsible) {
|
|
|
+ const staff = this.staffOptions.find(s => s.staffid === this.selectedDevice.areaResponsible);
|
|
|
+ if (staff) {
|
|
|
+ this.formData.responsible = staff.staffid;
|
|
|
+ }
|
|
|
+ }
|
|
|
});
|
|
|
},
|
|
|
/** 表单重置 */
|
|
|
@@ -423,6 +451,16 @@ export default {
|
|
|
this.formData.plant = response.data.plant;
|
|
|
this.formData.devName = response.data.devName;
|
|
|
this.formData.devTag = response.data.devTag;
|
|
|
+
|
|
|
+ // 确保设备下拉框选项中包含当前设备,便于“选择设备”下拉回显
|
|
|
+ if (response.data && response.data.devId) {
|
|
|
+ const exists = this.deviceOptions.some(d => d.devId === response.data.devId);
|
|
|
+ if (!exists) {
|
|
|
+ this.deviceOptions = [response.data, ...this.deviceOptions];
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 根据设备的区域负责人预填责任人(前提是人员列表已加载)
|
|
|
if (response.data.areaResponsible && this.staffOptions.length > 0) {
|
|
|
const staff = this.staffOptions.find(s => s.staffid === response.data.areaResponsible);
|
|
|
if (staff) {
|
|
|
@@ -543,47 +581,60 @@ export default {
|
|
|
},
|
|
|
/** 提交表单 */
|
|
|
handleSubmit() {
|
|
|
+ // 前端防止重复提交:如果已经在提交中,直接返回
|
|
|
+ if (this.submitting) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 先标记为提交中,避免校验期间被多次点击
|
|
|
+ this.submitting = true;
|
|
|
+
|
|
|
this.$refs.form.validate(valid => {
|
|
|
- if (valid) {
|
|
|
- this.submitting = true;
|
|
|
- if (this.compoList.length > 0) {
|
|
|
- const maintComponents = this.compoList
|
|
|
- .filter(compo => compo.needMaint)
|
|
|
- .map(compo => ({
|
|
|
- compoId: compo.compoId,
|
|
|
- compoName: compo.compoName,
|
|
|
- maintType: compo.maintType,
|
|
|
- responsible: compo.maintResponsible
|
|
|
- }));
|
|
|
- this.formData.maintComponents = maintComponents;
|
|
|
- }
|
|
|
+ if (!valid) {
|
|
|
+ // 校验失败,恢复提交状态
|
|
|
+ this.submitting = false;
|
|
|
+ return;
|
|
|
+ }
|
|
|
|
|
|
- // 选择合适的API
|
|
|
- let apiCall;
|
|
|
- if (!this.formData.planId || this.isPlannedStatus) {
|
|
|
- apiCall = submitApprove(this.formData);
|
|
|
- } else if (this.formData.approvalStatus === '1') {
|
|
|
- apiCall = resubmitApprove(this.formData);
|
|
|
- } else {
|
|
|
- apiCall = submitApprove(this.formData);
|
|
|
- }
|
|
|
+ if (this.compoList.length > 0) {
|
|
|
+ const maintComponents = this.compoList
|
|
|
+ .filter(compo => compo.needMaint)
|
|
|
+ .map(compo => ({
|
|
|
+ compoId: compo.compoId,
|
|
|
+ compoName: compo.compoName,
|
|
|
+ maintType: compo.maintType,
|
|
|
+ responsible: compo.maintResponsible
|
|
|
+ }));
|
|
|
+ this.formData.maintComponents = maintComponents;
|
|
|
+ }
|
|
|
|
|
|
- apiCall.then(response => {
|
|
|
- this.$modal.msgSuccess("操作成功");
|
|
|
- this.goBack();
|
|
|
- }).finally(() => {
|
|
|
- this.submitting = false;
|
|
|
- });
|
|
|
+ // 选择合适的API
|
|
|
+ let apiCall;
|
|
|
+ if (!this.formData.planId || this.isPlannedStatus) {
|
|
|
+ apiCall = submitApprove(this.formData);
|
|
|
+ } else if (this.formData.approvalStatus === '1') {
|
|
|
+ apiCall = resubmitApprove(this.formData);
|
|
|
+ } else {
|
|
|
+ apiCall = submitApprove(this.formData);
|
|
|
}
|
|
|
+
|
|
|
+ apiCall.then(response => {
|
|
|
+ // 使用 Element UI 消息提示,避免 $modal 未注册导致报错
|
|
|
+ this.$message.success("操作成功");
|
|
|
+ this.goBack();
|
|
|
+ }).finally(() => {
|
|
|
+ this.submitting = false;
|
|
|
+ });
|
|
|
});
|
|
|
},
|
|
|
/** 返回列表页 */
|
|
|
goBack() {
|
|
|
- // 先跳转再关闭当前标签,避免闪烁
|
|
|
+ // 先记录当前视图
|
|
|
const view = this.$route;
|
|
|
- this.$router.push({ path: "/reliability/rel_maint_plan" }).then(() => {
|
|
|
- this.$store.dispatch("tagsView/delView", view);
|
|
|
- });
|
|
|
+ // 跳转到维修计划列表
|
|
|
+ this.$router.push({ path: "/reliability/rel_maint_plan" });
|
|
|
+ // 直接关闭当前标签(当前项目中 $router.push 不返回 Promise,不能再调用 .then)
|
|
|
+ this.$store.dispatch("tagsView/delView", view);
|
|
|
}
|
|
|
}
|
|
|
};
|
|
|
@@ -591,12 +642,16 @@ export default {
|
|
|
|
|
|
<style scoped lang="scss">
|
|
|
.maint-plan-form-page {
|
|
|
+ // 缩小与顶部的间距
|
|
|
+ padding-top: 8px;
|
|
|
+ margin-top: 0;
|
|
|
+
|
|
|
.page-header {
|
|
|
display: flex;
|
|
|
justify-content: space-between;
|
|
|
align-items: center;
|
|
|
- margin-bottom: 10px;
|
|
|
- padding: 8px 0;
|
|
|
+ margin-bottom: 8px;
|
|
|
+ padding: 4px 0 6px;
|
|
|
border-bottom: 1px solid #ebeef5;
|
|
|
|
|
|
.header-left {
|
|
|
@@ -604,12 +659,20 @@ export default {
|
|
|
align-items: center;
|
|
|
|
|
|
.page-title {
|
|
|
- margin-left: 15px;
|
|
|
font-size: 18px;
|
|
|
font-weight: 600;
|
|
|
color: #303133;
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ .header-right {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+
|
|
|
+ .el-button + .el-button {
|
|
|
+ margin-left: 8px;
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
.form-card {
|
|
|
@@ -618,7 +681,7 @@ export default {
|
|
|
}
|
|
|
|
|
|
.form-section {
|
|
|
- margin-bottom: 12px;
|
|
|
+ margin-bottom: 2px;
|
|
|
|
|
|
.section-header {
|
|
|
display: flex;
|