Files
2026-09-11 11:51:35 +08:00

96 lines
6.3 KiB
Vue
Raw Permalink 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 v-if="user" class="page-shell dropship-task-page">
<PortalHeader title="一件代发" :user="user" :fallback-url="'/pages/home/home'" />
<view class="content">
<view class="search-card">
<ScanTargetInput v-model="keyword" name="taskKeyword" label="入仓码查询" placeholder="扫描或输入入仓码" :active="true" @submit="loadTasks" />
<button class="primary-button search-button" :disabled="loading" @tap="loadTasks">{{ loading ? '查询中…' : '查询任务' }}</button>
</view>
<view class="heading-row">
<view><text class="heading">待入库任务</text><text class="summary">{{ loading ? '正在同步' : `共 ${tasks.length} 个任务` }}</text></view>
<button class="refresh-button" :disabled="loading" @tap="refresh">刷新</button>
</view>
<view v-if="error" class="state error" role="alert">{{ error }}</view>
<view v-else-if="!loading && !tasks.length" class="state">暂无待入库任务</view>
<view class="task-list">
<button v-for="task in tasks" :key="task.taskId" class="task-card" :aria-label="`进入一件代发入库任务,入仓码 ${task.inboundCode || '未关联'}`" @tap="openTask(task)">
<view class="task-head"><text class="business-code">{{ task.inboundCode || '入仓码 —' }}</text><text class="status" :class="task.taskStatus === 'CLAIMED' ? 'claimed' : ''">{{ statusLabel(task.taskStatus) }}</text></view>
<text class="customer">{{ task.customerName || '客户未关联' }}</text>
<view class="metrics">
<view><strong>{{ task.totalCartons || 0 }}</strong><text>总箱</text></view>
<view><strong>{{ task.countedCartons || 0 }}</strong><text>已清点</text></view>
<view><strong>{{ task.boundCartons || 0 }}</strong><text>已归托</text></view>
<view><strong>{{ task.unboundCartons || 0 }}</strong><text>待归托</text></view>
</view>
<view class="task-foot"><text>仓库 {{ task.warehouseName || '—' }}</text><text class="enter">进入作业 ›</text></view>
</button>
</view>
</view>
</view>
</template>
<script>
import PortalHeader from '@/components/PortalHeader.vue'
import ScanTargetInput from '@/components/ScanTargetInput.vue'
import { listDropshipPalletizationTasks } from '@/api/pda-dropship.js'
import { session, requireSession } from '@/stores/session.js'
import { formatApiError } from '@/utils/user-facing.js'
export default {
components: { PortalHeader, ScanTargetInput },
data() { return { user: session.currentUser, keyword: '', tasks: [], loading: false, error: '' } },
onShow() { if (!requireSession()) return; this.user = session.currentUser; this.loadTasks() },
methods: {
statusLabel(status) { return status === 'CLAIMED' ? '作业中' : '待领取' },
refresh() { this.keyword = ''; this.loadTasks() },
async loadTasks() {
if (this.loading) return
if (!this.user?.warehouseId) { this.error = '请返回首页选择作业仓库'; return }
this.loading = true; this.error = ''
try {
const records = await listDropshipPalletizationTasks(this.keyword, this.user.warehouseId)
this.tasks = Array.isArray(records) ? records : []
}
catch (error) { this.tasks = []; this.error = formatApiError(error, '一件代发入库任务加载失败') }
finally { this.loading = false }
},
openTask(task) { uni.navigateTo({ url: `/pages/dropship-palletization/dropship-palletization?taskId=${encodeURIComponent(task.taskId)}&warehouseId=${encodeURIComponent(task.warehouseId)}` }) }
}
}
</script>
<style scoped>
.content { padding: 8px 10px 32px; }
.search-card { display: flex; align-items: center; gap: 8px; padding: 0; border: 0; background: transparent; box-shadow: none; }
.search-card :deep(.scan-target-input) { min-width: 0; height: 44px; flex: 1; border-radius: 6px; }
.search-card :deep(.scan-target-value) { height: 42px; }
.search-card :deep(.scan-target-icon) { top: 10px; }
.search-card :deep(.scan-target-input-active .scan-target-icon) { top: 9px; }
.search-card :deep(.scan-target-badge) { top: 10px; }
.primary-button { height: 44px; border: 0; border-radius: 6px; color: #fff; font-size: 14px; font-weight: 700; line-height: 44px; background: #1a73e8; }
.search-button { width: 92px; margin: 0; flex-shrink: 0; }
.heading-row { display: flex; align-items: center; justify-content: space-between; margin: 10px 0 7px; }
.heading-row > view { display: flex; align-items: baseline; gap: 8px; }
.heading { color: #12233f; font-size: 17px; font-weight: 700; }
.summary { color: #667085; font-size: 11px; }
.refresh-button { min-width: 64px; height: 40px; border: 0; border-radius: 6px; color: #155eef; font-size: 13px; line-height: 40px; background: #eaf2ff; }
.state { padding: 24px 12px; border-radius: 10px; color: #667085; font-size: 13px; text-align: center; background: #fff; }
.state.error { color: #b42318; background: #fff1f0; }
.task-list { overflow: hidden; border: 1px solid #dce6f1; border-radius: 7px; background: #fff; }
.task-card { box-sizing: border-box; width: 100%; margin: 0; padding: 9px 11px 7px; border: 0; border-bottom: 1px solid #dce6f1; border-radius: 0; color: #12233f; text-align: left; background: #fff; box-shadow: none; }
.task-card:last-child { border-bottom: 0; }
.task-card:active { background: #f5f8fc; }
.task-head, .task-foot { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.business-code { min-width: 0; font-size: 16px; font-weight: 700; line-height: 22px; overflow-wrap: anywhere; }
.status { flex-shrink: 0; padding: 2px 7px; border-radius: 4px; color: #9a5b13; font-size: 10px; line-height: 18px; background: #fff4e5; }
.status.claimed { color: #155eef; background: #eff4ff; }
.customer { display: block; margin-top: 1px; color: #667085; font-size: 11px; line-height: 17px; }
.metrics { display: grid; grid-template-columns: repeat(4, 1fr); margin-top: 6px; padding: 6px 0; border-top: 1px solid #edf1f5; border-bottom: 1px solid #edf1f5; }
.metrics view { display: flex; align-items: center; flex-direction: column; border-right: 1px solid #edf1f5; }
.metrics view:last-child { border-right: 0; }
.metrics strong { font-size: 16px; line-height: 22px; }
.metrics text { color: #667085; font-size: 10px; line-height: 16px; }
.task-foot { margin-top: 3px; color: #667085; font-size: 11px; line-height: 30px; }
.enter { color: #155eef; font-size: 12px; font-weight: 700; }
</style>