feat(mes,wms): 新增设备送检审批流程及相关功能

1. 新增设备送检审批的API接口层
2. 在待办页面添加设备送检审批标签页
3. 完善设备巡检日报的送检提交功能
4. 修复报表模板查询的参数传递问题
5. 优化设备送检审批单的业务逻辑处理
This commit is contained in:
2026-05-29 17:05:23 +08:00
parent d6099a781f
commit aad568f320
6 changed files with 340 additions and 11 deletions

View File

@@ -81,12 +81,8 @@ public class EqpEquipmentInspectionApprovalServiceImpl implements IEqpEquipmentI
@Override
public Boolean insertByBo(EqpEquipmentInspectionApprovalBo bo) {
EqpEquipmentInspectionApproval add = BeanUtil.toBean(bo, EqpEquipmentInspectionApproval.class);
if (StringUtils.isBlank(bo.getApprovalUser())) {
add.setApprovalUser(LoginHelper.getNickName());
}
if (bo.getApplyTime() == null) {
add.setApplyTime(new Date());
}
add.setApplyUser(LoginHelper.getNickName());
add.setApplyTime(new Date());
validEntityBeforeSave(add);
boolean flag = baseMapper.insert(add) > 0;
if (flag) {
@@ -101,6 +97,10 @@ public class EqpEquipmentInspectionApprovalServiceImpl implements IEqpEquipmentI
@Override
public Boolean updateByBo(EqpEquipmentInspectionApprovalBo bo) {
EqpEquipmentInspectionApproval update = BeanUtil.toBean(bo, EqpEquipmentInspectionApproval.class);
if (bo.getApprovalStatus() != null && (bo.getApprovalStatus() == 2 || bo.getApprovalStatus() == 3)) {
update.setApprovalUser(LoginHelper.getNickName());
update.setApprovalTime(new Date());
}
validEntityBeforeSave(update);
return baseMapper.updateById(update) > 0;
}

View File

@@ -0,0 +1,39 @@
import request from '@/utils/request'
export function listEquipmentInspectionApproval(query) {
return request({
url: '/eqp/equipmentInspectionApproval/list',
method: 'get',
params: query
})
}
export function getEquipmentInspectionApproval(approvalId) {
return request({
url: '/eqp/equipmentInspectionApproval/' + approvalId,
method: 'get'
})
}
export function addEquipmentInspectionApproval(data) {
return request({
url: '/eqp/equipmentInspectionApproval',
method: 'post',
data: data
})
}
export function updateEquipmentInspectionApproval(data) {
return request({
url: '/eqp/equipmentInspectionApproval',
method: 'put',
data: data
})
}
export function delEquipmentInspectionApproval(approvalId) {
return request({
url: '/eqp/equipmentInspectionApproval/' + approvalId,
method: 'delete'
})
}

View File

@@ -0,0 +1,251 @@
<template>
<div class="app-container">
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
<el-form-item label="产线">
<el-select v-model="queryParams.productionLine" placeholder="请选择产线" clearable @change="handleQuery" style="width: 150px;">
<el-option v-for="item in lineList" :key="item.lineId" :label="item.lineName" :value="item.lineId" />
</el-select>
</el-form-item>
<el-form-item label="审批状态" prop="approvalStatus">
<el-select v-model="queryParams.approvalStatus" placeholder="请选择状态" clearable @change="handleQuery" style="width: 120px;">
<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>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8" v-if="!readonly">
<el-col :span="1.5">
<el-button
type="danger"
plain
icon="el-icon-delete"
size="mini"
:disabled="multiple"
@click="handleDelete"
>删除</el-button>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<el-table v-loading="loading" :data="approvalList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" v-if="!readonly" />
<el-table-column label="产线" align="center" prop="productionLine" width="100">
<template slot-scope="scope">
{{ getLineName(scope.row.productionLine) }}
</template>
</el-table-column>
<el-table-column label="巡检开始时间" align="center" prop="insStartTime" width="180">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.insStartTime, '{y}-{m}-{d} {h}:{i}:{s}') }}</span>
</template>
</el-table-column>
<el-table-column label="巡检结束时间" align="center" prop="insEndTime" width="180">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.insEndTime, '{y}-{m}-{d} {h}:{i}:{s}') }}</span>
</template>
</el-table-column>
<el-table-column label="申请人" align="center" prop="applyUser" width="100" />
<el-table-column label="申请时间" align="center" prop="applyTime" width="180">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.applyTime, '{y}-{m}-{d} {h}:{i}:{s}') }}</span>
</template>
</el-table-column>
<el-table-column label="审批状态" align="center" prop="approvalStatus" width="90">
<template slot-scope="scope">
<el-tag v-if="scope.row.approvalStatus === 1" type="warning">待审批</el-tag>
<el-tag v-else-if="scope.row.approvalStatus === 2" type="success">已通过</el-tag>
<el-tag v-else-if="scope.row.approvalStatus === 3" type="danger">已驳回</el-tag>
<el-tag v-else-if="scope.row.approvalStatus === 4" type="info">已撤销</el-tag>
</template>
</el-table-column>
<el-table-column label="审批人" align="center" prop="approvalUser" width="100" />
<el-table-column label="审批时间" align="center" prop="approvalTime" width="180">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.approvalTime, '{y}-{m}-{d} {h}:{i}:{s}') }}</span>
</template>
</el-table-column>
<el-table-column label="审批意见" align="center" prop="approvalOpinion" show-overflow-tooltip />
<el-table-column label="备注" align="center" prop="remark" show-overflow-tooltip />
<el-table-column label="操作" align="center" width="280" fixed="right">
<template slot-scope="scope">
<el-button size="mini" type="text" icon="el-icon-view" @click="handleDetail(scope.row)">详情</el-button>
<el-button v-if="scope.row.approvalStatus === 1" size="mini" type="text" icon="el-icon-check" @click="handleApprove(scope.row)">通过</el-button>
<el-button v-if="scope.row.approvalStatus === 1" size="mini" type="text" icon="el-icon-close" @click="handleReject(scope.row)">驳回</el-button>
<el-button v-if="scope.row.approvalStatus === 1 || scope.row.approvalStatus === 4" size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)">删除</el-button>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
<el-dialog :title="dialogTitle" :visible.sync="dialogVisible" width="500px" append-to-body>
<el-form ref="dialogForm" :model="dialogForm" :rules="dialogRules" label-width="80px">
<el-form-item label="审批意见" prop="approvalOpinion">
<el-input v-model="dialogForm.approvalOpinion" type="textarea" rows="3" placeholder="请输入审批意见" />
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button :loading="buttonLoading" type="primary" @click="submitApproval"> </el-button>
<el-button @click="dialogVisible = false"> </el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import { listEquipmentInspectionApproval, delEquipmentInspectionApproval, updateEquipmentInspectionApproval } from "@/api/mes/eqp/equipmentInspectionApproval";
import { listProductionLine } from "@/api/wms/productionLine";
export default {
name: "EquipmentInspectionApproval",
props: {
readonly: {
type: Boolean,
default: false,
},
defaultStatus: {
type: Number,
default: undefined,
},
},
data() {
return {
buttonLoading: false,
loading: true,
ids: [],
single: true,
multiple: true,
showSearch: true,
total: 0,
approvalList: [],
dialogTitle: "",
dialogVisible: false,
approvalAction: "",
currentRow: null,
lineList: [],
queryParams: {
pageNum: 1,
pageSize: 10,
productionLine: undefined,
approvalStatus: this.defaultStatus,
},
dialogForm: {
approvalOpinion: "",
},
dialogRules: {},
};
},
created() {
this.loadLineList();
},
methods: {
async loadLineList() {
try {
const res = await listProductionLine({ pageSize: 999 });
if (res.rows) this.lineList = res.rows;
this.getList();
} catch (e) { console.error('加载产线列表失败', e); }
},
getLineName(lineId) {
const found = this.lineList.find(l => l.lineId === lineId);
return found ? found.lineName : '';
},
getList() {
this.loading = true;
listEquipmentInspectionApproval(this.queryParams).then(response => {
this.approvalList = response.rows;
this.total = response.total;
this.loading = false;
});
},
handleQuery() {
this.queryParams.pageNum = 1;
this.getList();
},
resetQuery() {
this.resetForm("queryForm");
this.handleQuery();
},
handleSelectionChange(selection) {
this.ids = selection.map(item => item.approvalId);
this.single = selection.length !== 1;
this.multiple = !selection.length;
},
formatQueryDate(date) {
if (!date) return '';
const d = new Date(date);
return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, "0")}-${String(d.getDate()).padStart(2, "0")}`;
},
handleDetail(row) {
this.$router.push({
path: '/eqp/day',
query: {
productionLine: row.productionLine,
startDate: this.formatQueryDate(row.insStartTime),
endDate: this.formatQueryDate(row.insEndTime),
}
});
},
handleApprove(row) {
this.currentRow = row;
this.approvalAction = 'approve';
this.dialogTitle = "审批通过";
this.dialogForm.approvalOpinion = "";
this.dialogVisible = true;
},
handleReject(row) {
this.currentRow = row;
this.approvalAction = 'reject';
this.dialogTitle = "审批驳回";
this.dialogForm.approvalOpinion = "";
this.dialogVisible = true;
},
submitApproval() {
this.$refs["dialogForm"].validate(valid => {
if (valid) {
this.buttonLoading = true;
const status = this.approvalAction === 'approve' ? 2 : 3;
updateEquipmentInspectionApproval({
approvalId: this.currentRow.approvalId,
approvalStatus: status,
approvalOpinion: this.dialogForm.approvalOpinion,
}).then(() => {
const msg = this.approvalAction === 'approve' ? '审批通过' : '已驳回';
this.$modal.msgSuccess(msg);
this.dialogVisible = false;
this.getList();
}).finally(() => {
this.buttonLoading = false;
});
}
});
},
handleDelete(row) {
const approvalIds = row.approvalId || this.ids;
this.$modal.confirm('是否确认删除审批记录编号为"' + approvalIds + '"的数据项?').then(() => {
this.loading = true;
return delEquipmentInspectionApproval(approvalIds);
}).then(() => {
this.loading = false;
this.getList();
this.$modal.msgSuccess("删除成功");
}).catch(() => {
this.loading = false;
});
},
},
};
</script>

View File

@@ -15,6 +15,9 @@
<el-form-item>
<el-button type="primary" @click="handleQuery">查询</el-button>
</el-form-item>
<el-form-item v-hasPermi="['mes:eqp:submit']">
<el-button type="success" icon="el-icon-s-promotion" @click="handleSubmitForApproval">送检</el-button>
</el-form-item>
</el-form>
</el-row>
@@ -107,17 +110,25 @@
import { listEquipmentPart } from "@/api/mes/eqp/equipmentPart";
import { listEquipmentInspectionRecord } from "@/api/mes/eqp/equipmentInspectionRecord";
import { listProductionLine } from "@/api/wms/productionLine";
import { addEquipmentInspectionApproval } from "@/api/mes/eqp/equipmentInspectionApproval";
export default {
name: "DailyInspectionReport",
data() {
const d = new Date();
const today = `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, "0")}-${String(d.getDate()).padStart(2, "0")}`;
const routeQuery = this.$route && this.$route.query || {};
const hasRouteQuery = !!(routeQuery.productionLine || (routeQuery.startDate && routeQuery.endDate));
return {
loading: false,
dateRange: [this.getToday(), this.getToday()],
productionLine: 2,
dateRange: (routeQuery.startDate && routeQuery.endDate)
? [routeQuery.startDate, routeQuery.endDate]
: [today, today],
productionLine: routeQuery.productionLine ? Number(routeQuery.productionLine) : 2,
lineList: [],
partList: [],
records: [],
hasRouteQuery,
};
},
computed: {
@@ -253,11 +264,34 @@ export default {
this.loading = false;
}
},
handleSubmitForApproval() {
if (!this.dateRange || this.dateRange.length !== 2) {
this.$modal.msgWarning("请选择时间段");
return;
}
if (!this.productionLine) {
this.$modal.msgWarning("请选择产线");
return;
}
this.$modal.confirm('确认将该时间段"' + this.dateRange[0] + '至' + this.dateRange[1] + '"的巡检日报提交审批吗?').then(() => {
this.loading = true;
return addEquipmentInspectionApproval({
productionLine: this.productionLine,
insStartTime: this.dateRange[0] + ' 00:00:00',
insEndTime: this.dateRange[1] + ' 23:59:59',
});
}).then(() => {
this.$modal.msgSuccess("送检成功");
this.loading = false;
}).catch(() => {
this.loading = false;
});
},
async loadLineList() {
try {
const res = await listProductionLine({ pageSize: 999 });
if (res.rows) this.lineList = res.rows;
if (this.lineList.length > 0) {
if (!this.hasRouteQuery && this.lineList.length > 0) {
const suanYa = this.lineList.find(l => l.lineName === '酸轧线');
this.productionLine = suanYa ? suanYa.lineId : this.lineList[0].lineId;
}

View File

@@ -654,7 +654,7 @@ export default {
const [lossRes, outRes] = await Promise.all([
listCoilWithIds({ ...this.queryParams, actionIds: lossActionIds.join(',') || '', startTime: '', endTime: '', selectType: 'raw_material' }),
listCoilWithIds({ ...this.queryParams, coilIds: outIds.join(',') || '', byCreateTimeStart: this.queryParams.startTime, byCreateTimeEnd: this.queryParams.endTime, selectType: 'product' }),
listCoilWithIds({ ...this.queryParams, coilIds: outIds.join(',') || '', startTime: '', endTime: '', byCreateTimeStart: this.queryParams.startTime, byCreateTimeEnd: this.queryParams.endTime, selectType: 'product' }),
]);
this.lossList = lossRes.rows.map(item => {
@@ -692,7 +692,7 @@ export default {
const [lossRes, outRes] = await Promise.all([
listCoilWithIds({ ...this.queryParams, actionIds: lossActionIds.join(',') || '', startTime: '', endTime: '', selectType: 'raw_material' }),
listCoilWithIds({ ...this.queryParams, coilIds: outIds.join(',') || '', startTime: '', endTime: '', selectType: 'product' }),
listCoilWithIds({ ...this.queryParams, coilIds: outIds.join(',') || '', startTime: '', endTime: '', byCreateTimeStart: this.queryParams.startTime, byCreateTimeEnd: this.queryParams.endTime, selectType: 'product' }),
]);
if (this.reportType === 'out') {

View File

@@ -9,6 +9,9 @@
<el-tab-pane label="质保书审批" name="fourth" v-hasPermi="['qc:certificate:approve']">
<CertificateBook />
</el-tab-pane>
<el-tab-pane label="设备送检记录" name="fifth" v-hasPermi="['mes:eqp:approval']">
<EquipmentInspectionApproval readonly :defaultStatus="1" />
</el-tab-pane>
<el-tab-pane label="其他代办" name="second">
<el-empty description="暂无其他代办事项" />
</el-tab-pane>
@@ -19,6 +22,7 @@
import TranferCoilTable from '@/views/wms/coil/views/base/tranfer.vue'
import InspectionTask from '@/views/mes/qc/inspection/task.vue'
import CertificateBook from '@/views/mes/qc/certificate/book.vue'
import EquipmentInspectionApproval from '@/views/mes/eqp/check/approval.vue'
export default {
name: 'TodoIndex',
@@ -26,6 +30,7 @@
TranferCoilTable,
InspectionTask,
CertificateBook,
EquipmentInspectionApproval,
},
data() {
return {