293 lines
6.4 KiB
Vue
293 lines
6.4 KiB
Vue
<template>
|
||
<view class="container">
|
||
<view class="search-box">
|
||
<uni-easyinput
|
||
v-model="stockoutId"
|
||
placeholder="请输入或扫码输入单据号"
|
||
: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">单据编号:</text>
|
||
<text class="value">{{ order.stockoutId }}</text>
|
||
</view>
|
||
<view class="info-row">
|
||
<text class="label">创建时间:</text>
|
||
<text class="value">{{ order.createDate }}</text>
|
||
</view>
|
||
<view class="info-row">
|
||
<text class="label">客户:</text>
|
||
<text class="value">{{ order.customerName }}</text>
|
||
</view>
|
||
<!-- 展开时显示物料信息 -->
|
||
<view v-if="order.expanded && order.goodsList" class="goods-list">
|
||
<view class="goods-title">物品信息</view>
|
||
<view class="goods-table">
|
||
<view class="table-header">
|
||
<text class="header-cell" style="display: none;">物品编码</text>
|
||
<text class="header-cell">物品名称</text>
|
||
<text class="header-cell">计划数量</text>
|
||
<text class="header-cell">出库数量</text>
|
||
<text class="header-cell">操作</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}">
|
||
出库
|
||
</button>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</uni-card>
|
||
</view>
|
||
</view>
|
||
<view v-else class="no-data">暂无出库单信息</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('获取出库单列表失败', error)
|
||
uni.showToast({
|
||
title: '获取出库单列表失败',
|
||
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('获取物品信息失败', error)
|
||
uni.showToast({
|
||
title: '获取物品信息失败',
|
||
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: '出库成功',
|
||
icon: 'success'
|
||
})
|
||
|
||
// 刷新数据
|
||
this.getOrderList()
|
||
} catch (error) {
|
||
console.error('出库失败:', error)
|
||
uni.showToast({
|
||
title: '出库失败',
|
||
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> |