287 lines
7.6 KiB
Vue
287 lines
7.6 KiB
Vue
<template>
|
||
<view class="container">
|
||
<!-- 任务类型选择 -->
|
||
<view class="filter-section">
|
||
<uni-data-checkbox
|
||
v-model="selectedType"
|
||
:localdata="taskTypes"
|
||
@change="handleTypeChange"
|
||
/>
|
||
</view>
|
||
|
||
<!-- 任务列表 -->
|
||
<view class="task-list" v-if="tasks.length > 0">
|
||
<view class="task-item" v-for="(task, index) in tasks" :key="index" @click="handleTaskClick(task)">
|
||
<view class="task-info">
|
||
<text class="task-title">{{ $t('task.list.trayCode') }}:{{ task.trayCode }}</text>
|
||
<text class="task-type">{{ $t('task.list.cargoSpace') }}:{{ task.cargoSpaceName }}</text>
|
||
<text class="task-status">{{ $t('task.list.warehouse') }}:{{ task.warehouseName }}</text>
|
||
<text class="task-status">{{ $t('task.list.createTime') }}:{{ task.createTime }}</text>
|
||
<text class="task-status status-tag">{{ $t('task.list.status') }}:{{ task.status === '1' ? $t('task.list.pending') : task.status === '3' ? $t('task.list.executing') : task.status }}</text>
|
||
<view class="task-actions">
|
||
<button v-if="task.inOrOut < 20" class="action-button in-button" @click.stop="handleInStock(task)">{{ $t('task.list.inbound') }}</button>
|
||
<button v-if="task.inOrOut >= 20 && task.inOrOut != 25 && task.inOrOut != 26" class="action-button out-button" @click.stop="handleOutStock(task)">{{ $t('task.list.outbound') }}</button>
|
||
<button v-if="task.inOrOut == 25 || task.inOrOut == 26" class="action-button out-button" @click.stop="handleCheck(task)">{{ $t('task.list.stocktaking') }}</button>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 空状态 -->
|
||
<view class="empty-state" v-else>
|
||
<text>{{ $t('task.list.noTasks') }}</text>
|
||
</view>
|
||
|
||
<!-- 物料详情弹出层 -->
|
||
<uni-popup ref="materialPopup" type="center">
|
||
<view class="popup-content">
|
||
<view class="popup-header">
|
||
<text class="popup-title">{{ $t('task.list.materialDetails') }}</text>
|
||
<text class="close-btn" @click="closePopup">×</text>
|
||
</view>
|
||
<view class="material-list">
|
||
<view class="material-item" v-for="(material, index) in materialDetails" :key="index">
|
||
<text class="material-code">{{ $t('task.list.materialCode') }}:{{ material.productId }}</text>
|
||
<text class="material-name">{{ $t('task.list.materialName') }}:{{ material.extraField.materialDesc }}</text>
|
||
<text class="material-quantity">{{ $t('task.list.quantity') }}:{{ currentTask.inOrOut < 20 ? material.inQuantity : material.outQuantity }}</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</uni-popup>
|
||
</view>
|
||
</template>
|
||
|
||
<script>
|
||
import { getPrepareTask, finishInJob } from '@/api/search/job.js'
|
||
import { getTaskDetail } from '@/api/out/productOut.js'
|
||
|
||
export default {
|
||
data() {
|
||
return {
|
||
selectedType: '',
|
||
taskTypes: [
|
||
{ value: '', text: this.$t('task.list.all') },
|
||
{ value: '1', text: this.$t('task.list.inbound') },
|
||
{ value: '2', text: this.$t('task.list.outbound') },
|
||
{ value: '4', text: this.$t('task.list.stocktaking') }
|
||
],
|
||
tasks: [],
|
||
materialDetails: [],
|
||
currentTask: null
|
||
}
|
||
},
|
||
created() {
|
||
this.fetchTasks()
|
||
},
|
||
methods: {
|
||
async fetchTasks() {
|
||
try {
|
||
const response = await getPrepareTask({ inOut: this.selectedType })
|
||
if (response.code === 200) {
|
||
this.tasks = response.data
|
||
} else {
|
||
this.tasks = []
|
||
uni.showToast({
|
||
title: this.$t('task.list.getTaskListFailed'),
|
||
icon: 'none'
|
||
})
|
||
}
|
||
} catch (error) {
|
||
console.error('获取任务列表出错:', error)
|
||
this.tasks = []
|
||
uni.showToast({
|
||
title: this.$t('task.list.getTaskListFailed'),
|
||
icon: 'none'
|
||
})
|
||
}
|
||
},
|
||
handleTypeChange() {
|
||
this.fetchTasks()
|
||
},
|
||
async handleInStock(task) {
|
||
try {
|
||
const response = await finishInJob({
|
||
jobId: task.jobId
|
||
})
|
||
|
||
if (response.code === 200) {
|
||
uni.showToast({
|
||
title: this.$t('task.list.inboundSuccess'),
|
||
icon: 'success'
|
||
})
|
||
this.fetchTasks()
|
||
} else {
|
||
uni.showToast({
|
||
title: response.msg || this.$t('task.list.inboundFailed'),
|
||
icon: 'none'
|
||
})
|
||
}
|
||
} catch (error) {
|
||
console.error('入库操作失败:', error)
|
||
uni.showToast({
|
||
title: this.$t('task.list.inboundFailed'),
|
||
icon: 'none'
|
||
})
|
||
}
|
||
},
|
||
async handleOutStock(task) {
|
||
uni.navigateTo({
|
||
url: `/pages/out/ckMakeSureByTray?trayCode=${task.trayCode}`
|
||
})
|
||
},
|
||
|
||
async handleCheck(task) {
|
||
uni.navigateTo({
|
||
url: `/pages/pandian/confirm?trayCode=${task.trayCode}`
|
||
})
|
||
},
|
||
|
||
async handleTaskClick(task) {
|
||
try {
|
||
const response = await getTaskDetail({ trayCode: task.trayCode })
|
||
if (response.code === 200) {
|
||
this.materialDetails = response.data
|
||
this.currentTask = task
|
||
this.$refs.materialPopup.open()
|
||
} else {
|
||
uni.showToast({
|
||
title: this.$t('task.list.getMaterialDetailsFailed'),
|
||
icon: 'none'
|
||
})
|
||
}
|
||
} catch (error) {
|
||
console.error('获取物料详情失败:', error)
|
||
uni.showToast({
|
||
title: this.$t('task.list.getMaterialDetailsFailed'),
|
||
icon: 'none'
|
||
})
|
||
}
|
||
},
|
||
|
||
closePopup() {
|
||
this.$refs.materialPopup.close()
|
||
}
|
||
}
|
||
}
|
||
</script>
|
||
|
||
<style lang="scss">
|
||
.container {
|
||
padding: 20rpx;
|
||
|
||
.filter-section {
|
||
margin-bottom: 20rpx;
|
||
padding: 20rpx;
|
||
background-color: #fff;
|
||
border-radius: 8rpx;
|
||
}
|
||
|
||
.task-list {
|
||
.task-item {
|
||
background-color: #fff;
|
||
padding: 20rpx;
|
||
margin-bottom: 20rpx;
|
||
border-radius: 8rpx;
|
||
|
||
.task-info {
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 10rpx;
|
||
|
||
.task-title {
|
||
font-size: 28rpx;
|
||
font-weight: bold;
|
||
}
|
||
|
||
.task-type,
|
||
.task-status {
|
||
font-size: 24rpx;
|
||
color: #666;
|
||
|
||
|
||
}
|
||
|
||
.task-actions {
|
||
margin-top: 10rpx;
|
||
|
||
.action-button {
|
||
font-size: 24rpx;
|
||
padding: 10rpx 20rpx;
|
||
border-radius: 4rpx;
|
||
border: none;
|
||
color: #fff;
|
||
|
||
&.in-button {
|
||
background-color: #4285f4;
|
||
}
|
||
|
||
&.out-button {
|
||
background-color: #34a853;
|
||
}
|
||
|
||
&:active {
|
||
opacity: 0.8;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
.empty-state {
|
||
text-align: center;
|
||
padding: 40rpx;
|
||
color: #999;
|
||
}
|
||
}
|
||
|
||
.popup-content {
|
||
background-color: #fff;
|
||
width: 600rpx;
|
||
border-radius: 16rpx;
|
||
padding: 30rpx;
|
||
|
||
.popup-header {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
margin-bottom: 20rpx;
|
||
|
||
.popup-title {
|
||
font-size: 32rpx;
|
||
font-weight: bold;
|
||
}
|
||
|
||
.close-btn {
|
||
font-size: 40rpx;
|
||
color: #999;
|
||
padding: 0 20rpx;
|
||
}
|
||
}
|
||
|
||
.material-list {
|
||
max-height: 600rpx;
|
||
overflow-y: auto;
|
||
|
||
.material-item {
|
||
padding: 20rpx 0;
|
||
border-bottom: 1rpx solid #eee;
|
||
|
||
&:last-child {
|
||
border-bottom: none;
|
||
}
|
||
|
||
text {
|
||
display: block;
|
||
font-size: 28rpx;
|
||
color: #333;
|
||
margin-bottom: 10rpx;
|
||
|
||
&:last-child {
|
||
margin-bottom: 0;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
</style> |