Files
FT541-WMS/RuoYi-App-master/pages/in/qualityCheck.vue

429 lines
10 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="order-list" v-if="orderList.length > 0">
<uni-card v-for="(item, index) in orderList" :key="index" class="order-card">
<view class="order-info" @click="handleOrderClick(item)">
<view class="info-row">
<text class="label">单据编号:</text>
<text class="value">{{ item.stockinId }}</text>
</view>
<view class="info-row">
<text class="label">供应商:</text>
<text class="value">{{ item.supplierName }}</text>
</view>
<view class="info-row">
<text class="label">仓库</text>
<text class="value">{{ item.warehouseName }}</text>
</view>
<view class="info-row">
<text class="label">创建时间:</text>
<text class="value">{{ item.createDate }}</text>
</view>
<view class="expand-icon" :class="{'expanded': item.isExpanded}">
<text>{{ item.isExpanded ? '收起' : '展开' }}</text>
</view>
</view>
<!-- 物料详情 -->
<view class="material-detail" v-if="item.isExpanded && item.materials && item.materials.length > 0">
<view class="material-header">
<button class="check-all-button" @click="handleCheckAll(index)">全部质检</button>
</view>
<view class="material-list">
<view v-for="(material, mIndex) in item.materials" :key="mIndex" class="material-item">
<view class="material-row" :class="{'checked': material.stockStatus === '1'}">
<!-- <text class="material-code">{{ material.productId }}</text> -->
<text class="material-name">{{ material.extraField.materialDesc }}</text>
<view class="material-quantity">
<text>数量:</text>
<uni-easyinput
v-model="material.quantity"
type="number"
@input="handleQuantityChange(index, mIndex, $event)"
style="width: 200rpx; display: inline-block;"
/>
</view>
<text class="material-status" :class="{'status-checked': material.stockStatus == '1'}">
{{ material.stockStatus == '1' ? '已质检' : '待质检' }}
</text>
<button class="check-button" @click="handleQualityCheck(index, mIndex)">质检</button>
</view>
</view>
</view>
</view>
</uni-card>
</view>
<view v-else class="no-data">
<text>暂无待质检单据</text>
</view>
</view>
</template>
<script>
import { getQualityCheckOrders, getOrderMaterials,updateReceiveStockinStatus,updateAllReceiveStockinStatus } from '@/api/in/order.js'
export default {
data() {
return {
orderList: []
}
},
onReady() {
this.fetchOrderList()
},
methods: {
// 获取质检单据列表
async fetchOrderList() {
try {
const response = await getQualityCheckOrders({status:'0'})
if (response.code === 200) {
this.orderList = response.rows.map(order => ({
...order,
isExpanded: false,
materials: []
}))
} else {
uni.showToast({
title: response.msg || '获取单据列表失败',
icon: 'none'
})
}
} catch (error) {
console.error('获取单据列表失败:', error)
uni.showToast({
title: '获取单据列表失败',
icon: 'none'
})
}
},
// 点击单据卡片
async handleOrderClick(order) {
const index = this.orderList.findIndex(item => item.stockinId === order.stockinId)
if (index === -1) return
// 切换展开状态
this.$set(this.orderList[index], 'isExpanded', !this.orderList[index].isExpanded)
// 如果是展开状态且还没有加载物料信息,则获取物料信息
if (this.orderList[index].isExpanded && this.orderList[index].materials.length === 0) {
try {
const response = await getOrderMaterials({
stockinId: order.stockinId,
status: '0'
})
if (response.code === 200) {
this.$set(this.orderList[index], 'materials', response.rows)
} else {
uni.showToast({
title: response.msg || '获取物料信息失败',
icon: 'none'
})
}
} catch (error) {
console.error('获取物料信息失败:', error)
uni.showToast({
title: '获取物料信息失败',
icon: 'none'
})
}
}
},
// 全部质检
async handleCheckAll(index) {
const order = this.orderList[index]
if (!order.materials || order.materials.length === 0) {
uni.showToast({
title: '暂无可质检的物料',
icon: 'none'
})
return
}
// 收集所有未质检物料的信息
const materials = order.materials
.map(material => ({
stockinDetailId: material.stockinDetailId,
quantity: material.quantity
}))
if (materials.length === 0) {
uni.showToast({
title: '所有物料已完成质检',
icon: 'none'
})
return
}
try {
const response = await updateAllReceiveStockinStatus({
stockinGuid: order.stockinGuid,
list: materials
})
if (response.code === 200) {
uni.showToast({
title: '批量质检完成',
icon: 'success'
})
// 重新获取当前单据的物料列表
// const materialsResponse = await getOrderMaterials({
// stockinId: order.stockinId,
// status: '0'
// })
// if (materialsResponse.code === 200) {
// this.$set(this.orderList[index], 'materials', materialsResponse.rows)
// }
this.fetchOrderList()
} else {
uni.showToast({
title: response.msg || '批量质检失败',
icon: 'none'
})
}
} catch (error) {
console.error('批量质检失败:', error)
uni.showToast({
title: '批量质检失败',
icon: 'none'
})
}
},
// 质检操作
async handleQualityCheck(index, mIndex) {
const material = this.orderList[index].materials[mIndex]
const response = await updateReceiveStockinStatus({
stockinDetailId: material.stockinDetailId,
quantity: material.quantity,
stockinGuid:material.stockinGuid,
stockStatus: '1'
})
if (response.code === 200) {
uni.showToast({
title: `${material.extraField.materialDesc} 质检完成`,
icon: 'success'
})
// 重新获取当前单据的物料列表
const materialsResponse = await getOrderMaterials({
stockinId: this.orderList[index].stockinId,
status: '0'
})
if (materialsResponse.code === 200) {
this.$set(this.orderList[index], 'materials', materialsResponse.rows)
}
} else {
uni.showToast({
title: response.msg || '质检操作失败',
icon: 'none'
})
}
},
// 在methods中添加数量变化处理方法
async handleQuantityChange(index, mIndex, value) {
const material = this.orderList[index].materials[mIndex]
const newQuantity = Number(value)
// 验证输入值
if (isNaN(newQuantity) || newQuantity < 0) {
uni.showToast({
title: '请输入有效的数量',
icon: 'none'
})
material.quantity = material.quantity
return
}
// TODO: 调用后端接口更新数量
// 这里可以添加调用后端接口的逻辑
},
}
}
</script>
<style lang="scss">
.container {
padding: 20rpx;
.order-list {
.order-card {
margin-bottom: 20rpx;
background: #fff;
border-radius: 12rpx;
box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.1);
.order-info {
position: relative;
padding: 24rpx 100rpx 24rpx 24rpx;
.info-row {
display: flex;
margin-bottom: 16rpx;
&:last-child {
margin-bottom: 0;
}
.label {
color: #909399;
width: 160rpx;
font-size: 28rpx;
}
.value {
color: #303133;
flex: 1;
font-size: 28rpx;
}
}
.expand-icon {
position: absolute;
right: 24rpx;
top: 50%;
transform: translateY(-50%);
color: #409EFF;
font-size: 26rpx;
padding: 12rpx 20rpx;
border-radius: 6rpx;
transition: all 0.3s ease;
&.expanded {
color: #909399;
transform: translateY(-50%) rotate(180deg);
}
}
}
.material-detail {
margin: 0 24rpx 24rpx;
transition: all 0.3s ease;
max-height: 600rpx;
overflow-y: auto;
.material-header {
padding: 20rpx 0;
border-bottom: 1px solid #EBEEF5;
.check-all-button {
background-color: #409EFF;
color: #fff;
border: none;
border-radius: 4rpx;
padding: 12rpx 24rpx;
font-size: 26rpx;
cursor: pointer;
&:active {
background-color: #3a8ee6;
}
}
}
.material-list {
.material-item {
border-bottom: 1px solid #EBEEF5;
.material-row {
display: flex;
align-items: center;
padding: 20rpx 0;
gap: 20rpx;
flex-wrap: nowrap;
.material-code {
color: #909399;
font-size: 24rpx;
width: 160rpx;
}
.material-name {
flex: 1;
font-size: 28rpx;
color: #303133;
min-width: 200rpx;
word-break: break-word;
white-space: normal;
overflow: hidden;
}
.material-quantity {
font-size: 26rpx;
color: #606266;
width: 250rpx;
display: flex;
align-items: center;
gap: 10rpx;
}
.check-button {
background-color: #409EFF;
color: #fff;
border: none;
border-radius: 4rpx;
padding: 12rpx 24rpx;
font-size: 26rpx;
cursor: pointer;
min-width: 100rpx;
&:active {
background-color: #3a8ee6;
}
&.button-disabled {
background-color: #c0c4cc !important;
cursor: not-allowed;
opacity: 0.7;
&:active {
background-color: #c0c4cc !important;
}
}
}
}
}
}
}
}
}
.no-data {
text-align: center;
padding: 60rpx;
color: #909399;
font-size: 28rpx;
}
}
.material-row {
&.checked {
background-color: #f5f7fa;
}
.material-status {
font-size: 26rpx;
padding: 4rpx 12rpx;
border-radius: 4rpx;
background-color: #e6a23c;
color: #fff;
&.status-checked {
background-color: #67c23a;
}
}
.check-button {
&.button-disabled {
background-color: #c0c4cc;
cursor: not-allowed;
&:active {
background-color: #c0c4cc;
}
}
}
}
</style>