362 lines
9.5 KiB
Vue
Raw Normal View History

<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>