赵正易 8fc9532f4b feat(物料管理): 实现涂装物料收退料功能及接口调整
- 重命名queryCallMaterialMRP为queryCallMaterialMRPList以保持命名一致性
- 新增queryCallReceiveList接口用于获取收料清单
- 在paint_receive.vue中实现完整的收退料功能,包括:
  - 动态获取线体选项
  - 调用真实API获取收料数据
  - 实现收料和退料操作
- 移除模拟数据,使用真实接口返回的数据结构
2025-08-06 17:18:44 +08:00

362 lines
9.5 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 => {
uni.hideLoading();
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 => {
uni.hideLoading();
console.error('获取MRP数据失败', err);
this.mrpList = [];
this.$modal.showToast('获取MRP数据失败');
});
},
// 叫料操作
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 => {
uni.hideLoading();
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 => {
uni.hideLoading();
console.error('叫料失败', err);
this.$modal.showToast('叫料失败');
});
},
// 取消叫料
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>