赵正易 dda9b03e44 refactor(物料管理): 优化API调用链式处理并统一错误处理
重构物料管理相关页面的API调用,使用链式Promise处理替代原有嵌套方式
统一添加finally处理隐藏加载状态,确保加载状态正确关闭
移除调试用的console.log语句,保持代码整洁
2025-08-06 17:23:14 +08:00

370 lines
9.7 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<view class="container">
<!-- 筛选查询区域 -->
<view class="filter-section">
<uni-forms ref="filterForm" :modelValue="filterData" validateTrigger="bind">
<view class="form-row">
<uni-forms-item label="线别选择" label-width="80" name="lineCode" required class="form-item">
<uni-data-select :localdata="lineOptions" v-model="filterData.lineCode" placeholder="请选择线体" @change="getMRPList"></uni-data-select>
</uni-forms-item>
<uni-forms-item label="选择日期" label-width="80" name="workOrderDate" required class="form-item">
<uni-datetime-picker type="date" v-model="filterData.workOrderDate" format="yyyy-MM-dd" placeholder="请选择日期"></uni-datetime-picker>
</uni-forms-item>
</view>
<view class="btn-search">
<button type="primary" @click="getMRPList">查询</button>
</view>
</uni-forms>
</view>
<!-- 清单展示区域 -->
<view class="list-section">
<view class="list-header">
<text>MRP叫料清单</text>
</view>
<scroll-view scroll-y class="list-container">
<view v-if="mrpList.length === 0" class="empty-tip">
暂无叫料数据
</view>
<view v-for="(item, index) in mrpList" :key="index" class="list-item">
<view class="item-info">
<view class="info-row">
<text class="label">物料名称:</text>
<text class="value">{{ item.materialName }}</text>
</view>
<view class="info-row">
<text class="label">物料号:</text>
<text class="value">{{ item.materialCode }}</text>
</view>
<view class="info-row">
<text class="label">数量:</text>
<text class="value">{{ item.quantity }}</text>
</view>
</view>
<view class="item-action">
<button type="primary" size="mini" @click="callMaterial(item)">叫料</button>
</view>
</view>
</scroll-view>
</view>
<!-- 叫料弹窗 -->
<uni-popup ref="popup" mode="center">
<view class="popup-content">
<view class="popup-header">
<text class="title">叫料确认</text>
</view>
<view class="popup-body">
<view v-if="currentMaterial" class="info-item">
<text class="label">物料名称:</text>
<text class="value">{{ currentMaterial.materialName }}</text>
</view>
<view v-if="currentMaterial" class="info-item">
<text class="label">物料号:</text>
<text class="value">{{ currentMaterial.materialCode }}</text>
</view>
<view v-if="currentMaterial" class="info-item">
<text class="label">可叫数量:</text>
<text class="value">{{ currentMaterial.quantity }}</text>
</view>
<view class="info-item">
<text class="label">叫料数量:</text>
<input type="number" v-model="callQuantity" placeholder="请输入叫料数量" class="input" />
</view>
</view>
<view class="popup-footer">
<button type="default" size="mini" @click="cancelCall">取消</button>
<button type="primary" size="mini" @click="confirmCall">确认</button>
</view>
</view>
</uni-popup>
</view>
</template>
<script>
import { queryCallMaterialMRPList,getLineOptions,doLineCallMaterial } from '@/api/mmcall';
export default {
data() {
return {
filterData: {
lineCode: '',
workOrderDate: new Date()
},
lineOptions: [],
mrpList: [],
currentMaterial: null,
callQuantity: 0
};
},
onLoad() {
// 默认选择当前日期
this.filterData.workOrderDate = new Date();
// 获取线体数据
this.getLineOptions();
},
methods: {
// 获取线体数据
getLineOptions() {
getLineOptions()
.then(res => {
if (res.code === 200 && res.data) {
// 格式化线体数据为uni-data-select需要的格式
this.lineOptions = res.data.map(item => ({
text: item.groupName, // 显示名称
value: item.groupCode // 实际值
}));
} else {
this.$modal.showToast('获取线体数据失败');
}
})
.catch(err => {
console.error('获取线体数据失败', err);
this.$modal.showToast('获取线体数据失败');
});
},
// 获取MRP叫料清单
getMRPList() {
if (!this.filterData.lineCode) {
this.$modal.showToast('请先选择线体');
return;
}
// 准备请求参数
const params = {
pageNum: 1,
pageSize: 100,
lineCode: this.filterData.lineCode,
workOrderDate: this.$dayjs(this.filterData.workOrderDate).format('YYYY-MM-DD')
};
// 显示加载中提示
uni.showLoading({
title: '加载中...'
});
// 调用API获取MRP清单
queryCallMaterialMRPList(params)
.then(res => {
if (res.code === 200 && res.data) {
this.mrpList = res.data.result;
//console.log('MRP数据:', res.data.result);
} else {
this.mrpList = [];
this.$modal.showToast(res.message || '获取MRP数据失败');
}
})
.catch(err => {
console.error('获取MRP数据失败', err);
this.mrpList = [];
this.$modal.showToast('获取MRP数据失败');
})
.finally(() => {
uni.hideLoading();
});
},
// 叫料操作
callMaterial(item) {
// 设置当前操作的物料和初始叫料数量
this.currentMaterial = item;
this.callQuantity = item.quantity;
// 显示自定义弹窗
this.$refs.popup.open();
},
// 确认叫料
confirmCall() {
if (!this.currentMaterial) return;
// 验证叫料数量
const quantity = parseInt(this.callQuantity);
if (isNaN(quantity) || quantity <= 0 || quantity > this.currentMaterial.quantity) {
this.$modal.showToast('请输入有效的叫料数量(大于0且不超过可叫数量)');
return;
}
// 准备叫料参数
const params = {
id: this.currentMaterial.id, // 物料ID
quantity: quantity, // 叫料数量
lineCode: this.filterData.lineCode, // 线体代码
workOrderDate: this.$dayjs(this.filterData.workOrderDate).format('YYYY-MM-DD') // 日期
};
// 显示加载中提示
uni.showLoading({
title: '叫料中...'
});
// 调用叫料API
doLineCallMaterial(params)
.then(res => {
if (res.code === 200) {
this.$modal.showToast(`成功叫料 ${quantity}${this.currentMaterial.materialName}`);
// 更新物料数量
this.currentMaterial.quantity -= quantity;
// 如果数量为0从列表中移除
if (this.currentMaterial.quantity <= 0) {
this.mrpList = this.mrpList.filter(m => m.id !== this.currentMaterial.id);
}
// 关闭弹窗
this.$refs.popup.close();
} else {
this.$modal.showToast(res.message || '叫料失败');
}
})
.catch(err => {
console.error('叫料失败', err);
this.$modal.showToast('叫料失败');
})
.finally(() => {
uni.hideLoading();
});
},
// 取消叫料
cancelCall() {
this.$refs.popup.close();
}
}
};
</script>
<style scoped>
.container {
padding: 20rpx;
}
.header {
text-align: center;
padding: 20rpx 0;
margin-bottom: 20rpx;
}
.title {
font-size: 36rpx;
font-weight: bold;
}
.filter-section {
background-color: #fff;
border-radius: 16rpx;
padding: 20rpx;
margin-bottom: 20rpx;
box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.1);
}
.form-row {
display: flex;
flex-direction: column;
gap: 20rpx;
padding: 10rpx 0;
}
.form-item {
width: 100%;
}
.uni-forms-item__label {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.btn-search {
margin-top: 20rpx;
}
.list-section {
background-color: #fff;
border-radius: 16rpx;
padding: 20rpx;
box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.1);
}
.list-header {
padding: 10rpx 0;
border-bottom: 1rpx solid #eee;
margin-bottom: 10rpx;
}
.list-header text {
font-size: 32rpx;
font-weight: bold;
}
.list-container {
height: 500rpx;
}
.list-item {
display: flex;
justify-content: space-between;
padding: 20rpx 0;
border-bottom: 1rpx solid #eee;
}
.item-info {
flex: 1;
}
.info-row {
display: flex;
margin-bottom: 10rpx;
}
.label {
width: 120rpx;
color: #999;
}
.value {
flex: 1;
}
.item-action {
display: flex;
align-items: center;
}
.empty-tip {
text-align: center;
padding: 40rpx 0;
color: #999;
}
/* 弹窗样式 */
.popup-content {
width: 80%;
background-color: #fff;
border-radius: 16rpx;
padding: 20rpx;
}
.popup-header {
padding: 10rpx 0;
border-bottom: 1rpx solid #eee;
margin-bottom: 20rpx;
}
.popup-header .title {
font-size: 32rpx;
font-weight: bold;
}
.popup-body {
padding: 10rpx 0;
}
.info-item {
display: flex;
margin-bottom: 20rpx;
align-items: center;
}
.info-item .label {
width: 120rpx;
color: #999;
}
.info-item .value {
flex: 1;
}
.info-item .input {
flex: 1;
border: 1rpx solid #ccc;
padding: 10rpx;
border-radius: 8rpx;
}
.popup-footer {
display: flex;
justify-content: space-around;
margin-top: 20rpx;
}
.popup-footer button {
width: 35%;
}
</style>