refactor: 优化首页菜单图标显示方式 fix: 修复SignalR连接初始化问题 style: 更新manifest.json版本号至2.0.0 chore: 新增多个SVG图标资源 perf: 为登录接口添加超时处理 docs: 更新API接口文档 test: 添加油漆件叫料相关测试用例 build: 更新依赖版本
362 lines
9.5 KiB
Vue
362 lines
9.5 KiB
Vue
<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 { queryCallMaterialMRP,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清单
|
||
queryCallMaterialMRP(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> |