293 lines
6.8 KiB
Vue
293 lines
6.8 KiB
Vue
<template>
|
|
<view class="container">
|
|
<view class="search-box">
|
|
<uni-easyinput
|
|
v-model="stockoutId"
|
|
:placeholder="$t('outbound.pkout.searchPlaceholder')"
|
|
:clearable="true"
|
|
@clear="handleClear"
|
|
@confirm="handleSearch"
|
|
@input="handleSearch"
|
|
ref="detailIdInput">
|
|
<template #right>
|
|
<text class="scan-icon" @click="handleScan">📷</text>
|
|
</template>
|
|
</uni-easyinput>
|
|
</view>
|
|
<view class="card-list">
|
|
<view v-if="orderList && orderList.length > 0">
|
|
<view v-for="(order, index) in orderList" :key="index" class="order-card" @click="handleOrderClick(order)">
|
|
<uni-card>
|
|
<view class="card-content">
|
|
<view class="info-row">
|
|
<text class="label">{{ $t('outbound.pkout.orderNumber') }}</text>
|
|
<text class="value">{{ order.stockoutId }}</text>
|
|
</view>
|
|
<view class="info-row">
|
|
<text class="label">{{ $t('outbound.pkout.createTime') }}</text>
|
|
<text class="value">{{ order.createDate }}</text>
|
|
</view>
|
|
<view class="info-row">
|
|
<text class="label">{{ $t('outbound.pkout.customer') }}</text>
|
|
<text class="value">{{ order.customerName }}</text>
|
|
</view>
|
|
<!-- 展开时显示物料信息 -->
|
|
<view v-if="order.expanded && order.goodsList" class="goods-list">
|
|
<view class="goods-title">{{ $t('outbound.pkout.goodsInfo') }}</view>
|
|
<view class="goods-table">
|
|
<view class="table-header">
|
|
<text class="header-cell" style="display: none;">{{ $t('outbound.pkout.productCode') }}</text>
|
|
<text class="header-cell">{{ $t('outbound.pkout.productName') }}</text>
|
|
<text class="header-cell">{{ $t('outbound.pkout.planQuantity') }}</text>
|
|
<text class="header-cell">{{ $t('outbound.pkout.outboundQuantity') }}</text>
|
|
<text class="header-cell">{{ $t('outbound.pkout.operation') }}</text>
|
|
</view>
|
|
<view v-for="(goods, goodsIndex) in order.goodsList" :key="goodsIndex" class="table-row">
|
|
<text class="table-cell" style="display: none;">{{ goods.productId }}</text>
|
|
<text class="table-cell">{{ goods.extraField.materialDesc }}</text>
|
|
<text class="table-cell">{{ goods.quantity }}</text>
|
|
<text class="table-cell">{{ goods.quantity - goods.assignNum }}</text>
|
|
<view class="table-cell">
|
|
<button class="operate-btn" @click.stop="handleOutStock(goods)" :disabled="(goods.quantity - goods.assignNum) <= 0" :class="{'operate-btn-disabled': (goods.quantity - goods.assignNum) <= 0}">
|
|
{{ $t('outbound.pkout.outbound') }}
|
|
</button>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</uni-card>
|
|
</view>
|
|
</view>
|
|
<view v-else class="no-data">{{ $t('outbound.pkout.noOrderInfo') }}</view>
|
|
</view>
|
|
</view>
|
|
</template>
|
|
|
|
<script>
|
|
import { getOutOrderList, getOutOrderDetail, pkOut } from '@/api/out/productOut'
|
|
|
|
export default {
|
|
data() {
|
|
return {
|
|
stockoutId: "",
|
|
orderList: [],
|
|
needRefresh: false
|
|
}
|
|
},
|
|
onReady() {
|
|
setTimeout(() => {
|
|
this.$nextTick(() => {
|
|
this.$refs.detailIdInput.onFocus()
|
|
})
|
|
}, 100)
|
|
},
|
|
onLoad() {
|
|
this.getOrderList()
|
|
},
|
|
onShow() {
|
|
if (this.needRefresh) {
|
|
this.getOrderList()
|
|
this.needRefresh = false
|
|
}
|
|
},
|
|
methods: {
|
|
// 获取出库单列表
|
|
async getOrderList() {
|
|
try {
|
|
const response = await getOutOrderList({"stockoutId":this.stockoutId})
|
|
this.orderList = response.map(order => ({
|
|
...order,
|
|
expanded: false,
|
|
goodsList: null
|
|
}))
|
|
} catch (error) {
|
|
console.error(this.$t('outbound.pkout.getOrderListFailed'), error)
|
|
uni.showToast({
|
|
title: this.$t('outbound.pkout.getOrderListFailed'),
|
|
icon: 'none'
|
|
})
|
|
}
|
|
},
|
|
// 获取物品列表
|
|
async getGoodsList(order) {
|
|
try {
|
|
const goodsResponse = await getOutOrderDetail({
|
|
stockoutId: order.stockoutId,
|
|
pageSize:100,
|
|
pageNum:1,
|
|
status:1
|
|
})
|
|
order.goodsList = goodsResponse.rows.map(item => ({
|
|
...item
|
|
// outQuantity: item.quantity-item.assignNum
|
|
}))
|
|
} catch (error) {
|
|
console.error(this.$t('outbound.pkout.getItemInfoFailed'), error)
|
|
uni.showToast({
|
|
title: this.$t('outbound.pkout.getItemInfoFailed'),
|
|
icon: 'none'
|
|
})
|
|
}
|
|
},
|
|
// 处理出库单点击
|
|
async handleOrderClick(order) {
|
|
// 切换展开状态
|
|
order.expanded = !order.expanded
|
|
// 如果展开且还没有加载物品列表,则加载物品列表
|
|
if (order.expanded && !order.goodsList) {
|
|
await this.getGoodsList(order)
|
|
}
|
|
},
|
|
// 处理搜索
|
|
handleSearch(value) {
|
|
this.stockoutId = value
|
|
this.getOrderList()
|
|
},
|
|
// 处理清除
|
|
handleClear() {
|
|
this.stockoutId = ""
|
|
this.getOrderList()
|
|
},
|
|
// 处理扫码
|
|
handleScan() {
|
|
uni.scanCode({
|
|
success: (res) => {
|
|
this.stockoutId = res.result
|
|
this.getOrderList()
|
|
}
|
|
})
|
|
},
|
|
// 处理出库数量变化
|
|
handleOutQuantityChange(goods) {
|
|
if (goods.outQuantity > goods.quantity - goods.assignNum) {
|
|
goods.outQuantity = goods.quantity - goods.assignNum
|
|
}
|
|
},
|
|
// 验证数量是否有效
|
|
isValidQuantity(goods) {
|
|
return goods.outQuantity > 0 && goods.outQuantity <= goods.quantity - goods.assignNum
|
|
},
|
|
// 处理出库
|
|
async handleOutStock(goods) {
|
|
// if (!this.isValidQuantity(goods)) return
|
|
|
|
try {
|
|
await pkOut({
|
|
stockinDetailId: goods.stockoutDetailId
|
|
|
|
})
|
|
|
|
uni.showToast({
|
|
title: this.$t('outbound.pkout.outboundSuccess'),
|
|
icon: 'success'
|
|
})
|
|
|
|
// 刷新数据
|
|
this.getOrderList()
|
|
} catch (error) {
|
|
console.error('出库失败:', error)
|
|
uni.showToast({
|
|
title: this.$t('outbound.pkout.outboundFailed'),
|
|
icon: 'none'
|
|
})
|
|
}
|
|
}
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
.container {
|
|
padding: 20rpx;
|
|
}
|
|
|
|
.search-box {
|
|
margin-bottom: 20rpx;
|
|
}
|
|
|
|
.scan-icon {
|
|
font-size: 40rpx;
|
|
padding: 0 20rpx;
|
|
}
|
|
|
|
.card-list {
|
|
.order-card {
|
|
margin-bottom: 20rpx;
|
|
}
|
|
}
|
|
|
|
.info-row {
|
|
display: flex;
|
|
margin-bottom: 10rpx;
|
|
|
|
.label {
|
|
color: #666;
|
|
width: 160rpx;
|
|
}
|
|
|
|
.value {
|
|
color: #333;
|
|
flex: 1;
|
|
}
|
|
}
|
|
|
|
.goods-list {
|
|
margin-top: 20rpx;
|
|
|
|
.goods-title {
|
|
font-size: 28rpx;
|
|
font-weight: bold;
|
|
margin-bottom: 10rpx;
|
|
}
|
|
}
|
|
|
|
.goods-table {
|
|
.table-header {
|
|
display: flex;
|
|
background-color: #f5f5f5;
|
|
padding: 20rpx 0;
|
|
|
|
.header-cell {
|
|
flex: 1;
|
|
text-align: center;
|
|
font-size: 24rpx;
|
|
color: #666;
|
|
}
|
|
}
|
|
|
|
.table-row {
|
|
display: flex;
|
|
padding: 20rpx 0;
|
|
border-bottom: 1rpx solid #eee;
|
|
|
|
.table-cell {
|
|
flex: 1;
|
|
text-align: center;
|
|
font-size: 24rpx;
|
|
color: #333;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
}
|
|
}
|
|
}
|
|
|
|
.operate-btn {
|
|
background-color: #007AFF;
|
|
color: #fff;
|
|
font-size: 24rpx;
|
|
padding: 10rpx 20rpx;
|
|
border-radius: 4rpx;
|
|
|
|
&.operate-btn-disabled {
|
|
background-color: #ccc;
|
|
}
|
|
}
|
|
|
|
.no-data {
|
|
text-align: center;
|
|
color: #999;
|
|
padding: 40rpx 0;
|
|
}
|
|
</style> |