feat(ems): 添加备件库存预警功能并优化相关业务逻辑

- 在 SparePartsInventory 模型中添加库存阈值字段
- 实现库存预警相关的前端展示和提示功能
- 优化日常故障记录中的处置时长计算逻辑
- 在备件盘点记录中添加创建时间字段
- 实现备件库存数量的自动更新机制
boardTest
zch 3 weeks ago
parent aed3225e1f
commit 25f2e39ef1

@ -233,7 +233,7 @@
/> />
</el-form-item> </el-form-item>
<el-form-item label="处置时长" prop="handlingDuration"> <el-form-item label="处置时长" prop="handlingDuration">
<el-input v-model="form.handlingDuration" placeholder="请输入处置时长" /> <el-input v-model="form.handlingDuration" placeholder="自动计算" disabled />
</el-form-item> </el-form-item>
</el-form> </el-form>
<div slot="footer" class="dialog-footer"> <div slot="footer" class="dialog-footer">
@ -350,6 +350,14 @@
this.upload.url = process.env.VUE_APP_BASE_API + "/ems/info/dailyFaultRecord/importData"; this.upload.url = process.env.VUE_APP_BASE_API + "/ems/info/dailyFaultRecord/importData";
this.upload.headers = { Authorization: "Bearer " + this.$store.getters.token }; this.upload.headers = { Authorization: "Bearer " + this.$store.getters.token };
}, },
watch: {
'form.faultOccurrenceTime'(newVal) {
this.calculateHandlingDuration();
},
'form.handlingCompletionTime'(newVal) {
this.calculateHandlingDuration();
},
},
methods: { methods: {
/** 查询日常故障记录列表 */ /** 查询日常故障记录列表 */
getList() { getList() {
@ -475,7 +483,22 @@
// //
submitFileForm() { submitFileForm() {
this.$refs.upload.submit(); this.$refs.upload.submit();
} },
calculateHandlingDuration() {
if (this.form.faultOccurrenceTime && this.form.handlingCompletionTime) {
const startTime = new Date(`2023-01-01T${this.form.faultOccurrenceTime}`);
const endTime = new Date(`2023-01-01T${this.form.handlingCompletionTime}`);
if (!isNaN(startTime.getTime()) && !isNaN(endTime.getTime()) && endTime > startTime) {
const durationMs = endTime - startTime;
const durationSeconds = Math.floor(durationMs / 1000);
this.form.handlingDuration = `${durationSeconds}`;
} else {
this.form.handlingDuration = '无效时间';
}
} else {
this.form.handlingDuration = '';
}
},
} }
}; };
</script> </script>

@ -124,10 +124,37 @@
v-hasPermi="['ems/info:sparePartsInventory:add']" v-hasPermi="['ems/info:sparePartsInventory:add']"
>导入</el-button> >导入</el-button>
</el-col> </el-col>
<el-col :span="1.5" v-if="lowStockCount > 0">
<el-badge :value="lowStockCount" class="item" type="danger">
<el-button
type="danger"
plain
icon="el-icon-warning"
size="mini"
@click="filterLowStock"
>库存预警</el-button>
</el-badge>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList" :columns="columns"></right-toolbar> <right-toolbar :showSearch.sync="showSearch" @queryTable="getList" :columns="columns"></right-toolbar>
</el-row> </el-row>
<el-table v-loading="loading" :data="sparePartsInventoryList" @selection-change="handleSelectionChange"> <!-- 库存预警提示 -->
<el-alert
v-if="lowStockCount > 0"
:title="`库存预警:当前有 ${lowStockCount} 项备件库存不足,请及时补充!`"
type="warning"
:closable="false"
show-icon
style="margin-bottom: 15px;"
>
</el-alert>
<el-table
v-loading="loading"
:data="sparePartsInventoryList"
@selection-change="handleSelectionChange"
:row-class-name="getRowClassName"
>
<el-table-column type="selection" width="55" align="center" /> <el-table-column type="selection" width="55" align="center" />
<el-table-column label="主键" align="center" prop="objid" v-if="columns[0].visible"/> <el-table-column label="主键" align="center" prop="objid" v-if="columns[0].visible"/>
<el-table-column label="入库时间" align="center" prop="warehouseDate" v-if="columns[1].visible"/> <el-table-column label="入库时间" align="center" prop="warehouseDate" v-if="columns[1].visible"/>
@ -137,8 +164,23 @@
<el-table-column label="原厂编号" align="center" prop="originalPartNumber" v-if="columns[5].visible"/> <el-table-column label="原厂编号" align="center" prop="originalPartNumber" v-if="columns[5].visible"/>
<el-table-column label="型号" align="center" prop="model" v-if="columns[6].visible"/> <el-table-column label="型号" align="center" prop="model" v-if="columns[6].visible"/>
<el-table-column label="入库数量" align="center" prop="warehouseQuantity" v-if="columns[7].visible"/> <el-table-column label="入库数量" align="center" prop="warehouseQuantity" v-if="columns[7].visible"/>
<el-table-column label="剩余数量" align="center" prop="remainingQuantity" v-if="columns[8].visible"/> <el-table-column label="剩余数量" align="center" prop="remainingQuantity" v-if="columns[8].visible">
<el-table-column label="备注" align="center" prop="remarks" v-if="columns[9].visible"/> <template slot-scope="scope">
<span :class="getRemainingQuantityClass(scope.row)">
<i v-if="isLowStock(scope.row)" class="el-icon-warning" style="margin-right: 4px;"></i>
{{ scope.row.remainingQuantity }}
</span>
</template>
</el-table-column>
<el-table-column label="库存阈值" align="center" prop="threshold" v-if="columns[9].visible">
<template slot-scope="scope">
<span>{{ scope.row.threshold }}</span>
<el-tooltip v-if="isLowStock(scope.row)" effect="dark" content="库存不足!剩余数量已低于阈值" placement="top">
<i class="el-icon-warning-outline" style="color: #E6A23C; margin-left: 4px;"></i>
</el-tooltip>
</template>
</el-table-column>
<el-table-column label="备注" align="center" prop="remarks" v-if="columns[10].visible"/>
<!-- 动态盘点列 --> <!-- 动态盘点列 -->
<el-table-column <el-table-column
@ -152,22 +194,29 @@
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="100"> <el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="120">
<template slot-scope="scope"> <template slot-scope="scope">
<el-button <div v-if="isLowStock(scope.row)" style="margin-bottom: 5px;">
size="mini" <el-tag size="mini" type="danger" effect="dark">
type="text" <i class="el-icon-warning"></i> 库存不足
icon="el-icon-edit" </el-tag>
@click="handleUpdate(scope.row)" </div>
v-hasPermi="['ems/info:sparePartsInventory:edit']" <div>
>修改</el-button> <el-button
<el-button size="mini"
size="mini" type="text"
type="text" icon="el-icon-edit"
icon="el-icon-delete" @click="handleUpdate(scope.row)"
@click="handleDelete(scope.row)" v-hasPermi="['ems/info:sparePartsInventory:edit']"
v-hasPermi="['ems/info:sparePartsInventory:remove']" >修改</el-button>
>删除</el-button> <el-button
size="mini"
type="text"
icon="el-icon-delete"
@click="handleDelete(scope.row)"
v-hasPermi="['ems/info:sparePartsInventory:remove']"
>删除</el-button>
</div>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
@ -233,10 +282,25 @@
</el-col> </el-col>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="剩余数量" prop="remainingQuantity"> <el-form-item label="剩余数量" prop="remainingQuantity">
<el-input v-model="form.remainingQuantity" placeholder="请输入剩余数量" /> <el-input v-model="form.remainingQuantity" placeholder="请输入剩余数量" readonly />
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> </el-row>
<el-row>
<el-col :span="12">
<el-form-item label="库存阈值" prop="threshold">
<el-input-number
v-model="form.threshold"
:min="0"
placeholder="请输入库存阈值"
style="width: 100%"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<!-- 占位列 -->
</el-col>
</el-row>
<el-form-item label="备注" prop="remarks"> <el-form-item label="备注" prop="remarks">
<el-input v-model="form.remarks" type="textarea" placeholder="请输入内容" /> <el-input v-model="form.remarks" type="textarea" placeholder="请输入内容" />
</el-form-item> </el-form-item>
@ -334,6 +398,12 @@
export default { export default {
name: "SparePartsInventory", name: "SparePartsInventory",
computed: {
//
lowStockCount() {
return this.sparePartsInventoryList.filter(item => this.isLowStock(item)).length;
}
},
data() { data() {
return { return {
// //
@ -388,7 +458,8 @@
{ key: 6, label: `型号`, visible: true }, { key: 6, label: `型号`, visible: true },
{ key: 7, label: `入库数量`, visible: true }, { key: 7, label: `入库数量`, visible: true },
{ key: 8, label: `剩余数量`, visible: true }, { key: 8, label: `剩余数量`, visible: true },
{ key: 9, label: `备注`, visible: true }, { key: 9, label: `库存阈值`, visible: true },
{ key: 10, label: `备注`, visible: true },
], ],
upload: { upload: {
title: "导入备件库记录", title: "导入备件库记录",
@ -465,6 +536,7 @@
model: null, model: null,
warehouseQuantity: null, warehouseQuantity: null,
remainingQuantity: null, remainingQuantity: null,
threshold: 0,
remarks: null, remarks: null,
checkData: [] checkData: []
}; };
@ -589,7 +661,85 @@
// //
submitFileForm() { submitFileForm() {
this.$refs.upload.submit(); this.$refs.upload.submit();
},
//
isLowStock(row) {
return row.remainingQuantity != null && row.threshold != null && row.remainingQuantity <= row.threshold;
},
//
getRowClassName({row, rowIndex}) {
if (this.isLowStock(row)) {
return 'low-stock-row';
}
return '';
},
//
filterLowStock() {
this.$message({
message: `正在显示 ${this.lowStockCount} 项库存不足的记录`,
type: 'warning'
});
//
//
},
//
getRemainingQuantityClass(row) {
//
if (this.isLowStock(row)) {
return 'remaining-quantity-warning';
} else {
return 'remaining-quantity-normal';
}
} }
} }
}; };
</script> </script>
<style scoped>
.remaining-quantity-warning {
color: #E6A23C;
font-weight: bold;
background-color: #FDF6EC;
padding: 2px 4px;
border-radius: 3px;
}
.remaining-quantity-normal {
color: #606266;
}
/* 低库存整行警告样式 */
.el-table >>> .low-stock-row {
background-color: #FEF0F0 !important;
border-left: 4px solid #F56C6C;
}
.el-table >>> .low-stock-row:hover {
background-color: #FDE2E2 !important;
}
/* 低库存行中的文本增强显示 */
.el-table >>> .low-stock-row .cell {
font-weight: 500;
}
/* 低库存警告动画效果 */
.el-table >>> .low-stock-row .remaining-quantity-warning {
animation: pulse-warning 2s infinite;
}
@keyframes pulse-warning {
0% {
background-color: #FDF6EC;
}
50% {
background-color: #F9E79F;
}
100% {
background-color: #FDF6EC;
}
}
</style>

Loading…
Cancel
Save