feat: enhance stocktake UX with 10s delay, sku search, sku retention and remove adjust btn
This commit is contained in:
@ -111,6 +111,32 @@
|
||||
</div>
|
||||
</el-card>
|
||||
|
||||
<!-- ★ 新增: 防呆确认弹窗 -->
|
||||
<el-dialog
|
||||
v-model="showConfirmDialog"
|
||||
title="⚠️ 确认清除盘点数据"
|
||||
width="400"
|
||||
:close-on-click-modal="false"
|
||||
:close-on-press-escape="false"
|
||||
show-close
|
||||
align-center
|
||||
>
|
||||
<div class="confirm-content">
|
||||
<el-icon :size="48" color="#E6A23C"><WarningFilled /></el-icon>
|
||||
<p class="confirm-text">存在未完成记录,开始新盘点将清除它们,确定吗?</p>
|
||||
</div>
|
||||
<template #footer>
|
||||
<el-button @click="cancelConfirm">取消</el-button>
|
||||
<el-button
|
||||
type="danger"
|
||||
:disabled="countdown > 0"
|
||||
@click="confirmClear"
|
||||
>
|
||||
{{ countdown > 0 ? `确认清除 (${countdown}s)` : '确认清除' }}
|
||||
</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
<el-dialog
|
||||
v-model="showQtyDialog"
|
||||
title="🔢 录入实盘数量"
|
||||
@ -266,12 +292,24 @@
|
||||
style="margin-bottom: 15px;"
|
||||
>
|
||||
<template #default>
|
||||
以下列表显示所有已结束盘点但尚未平账的差异记录。请逐条核实后,点击"确认平账"按钮调整系统库存。
|
||||
以下列表显示所有已结束盘点但尚未平账的差异记录。请核实后进行后续处理。
|
||||
</template>
|
||||
</el-alert>
|
||||
|
||||
<!-- ★ 新增: 差异列表搜索 -->
|
||||
<el-input
|
||||
v-model="searchSku"
|
||||
placeholder="输入 SKU/条码/名称快速定位"
|
||||
clearable
|
||||
style="width: 250px; margin-bottom: 15px;"
|
||||
>
|
||||
<template #prefix>
|
||||
<el-icon><Search /></el-icon>
|
||||
</template>
|
||||
</el-input>
|
||||
|
||||
<el-table
|
||||
:data="varianceList"
|
||||
:data="filteredVarianceList"
|
||||
height="500"
|
||||
border
|
||||
stripe
|
||||
@ -315,22 +353,9 @@
|
||||
<el-tag v-else type="warning">待审核</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="120" align="center" fixed="right">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
v-if="!scope.row.is_processed && userStore.hasPermission('inventory_stocktake:operation')"
|
||||
type="primary"
|
||||
size="small"
|
||||
@click="handleAdjust(scope.row)"
|
||||
>
|
||||
确认平账
|
||||
</el-button>
|
||||
<span v-else class="text-gray">-</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<el-empty v-if="varianceList.length === 0" description="暂无待审核的差异记录" />
|
||||
<el-empty v-if="filteredVarianceList.length === 0" :description="searchSku ? '未找到匹配的差异记录' : '暂无待审核的差异记录'" />
|
||||
</div>
|
||||
|
||||
<template #footer>
|
||||
@ -353,7 +378,7 @@ import { ref, computed, onMounted, onUnmounted, nextTick } from 'vue'
|
||||
import { getAllStock } from '@/api/inbound/stock'
|
||||
import QrScanner from '@/components/QrScanner/index.vue'
|
||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||
import { Search, VideoPlay, VideoPause, List, Checked, Download, ArrowRight, Cloudy, Edit, EditPen, CameraFilled, Close } from '@element-plus/icons-vue'
|
||||
import { Search, VideoPlay, VideoPause, List, Checked, Download, ArrowRight, Cloudy, Edit, EditPen, CameraFilled, Close, WarningFilled } from '@element-plus/icons-vue'
|
||||
import request from '@/utils/request'
|
||||
import { useUserStore } from '@/stores/user'
|
||||
|
||||
@ -402,6 +427,16 @@ const showQtyDialog = ref(false)
|
||||
// ★ 新增: 差异审核对话框
|
||||
const showVarianceDialog = ref(false)
|
||||
|
||||
// ★ 新增: 差异列表搜索
|
||||
const searchSku = ref('')
|
||||
|
||||
// ★ 新增: 盘点开始防呆倒计时
|
||||
const countdown = ref(0)
|
||||
let countdownTimer: any = null
|
||||
|
||||
// ★ 新增: 防呆确认弹窗显示状态
|
||||
const showConfirmDialog = ref(false)
|
||||
|
||||
const allData = ref<StockItem[]>([])
|
||||
const scannedMap = ref<Map<string, number>>(new Map())
|
||||
const borrowedQuantities = ref<Record<string, number>>({})
|
||||
@ -492,19 +527,6 @@ const api = {
|
||||
method: 'get',
|
||||
params: {}
|
||||
}),
|
||||
// ★ 新增: 单条库存调整
|
||||
adjustStock: (draftId: number, stockId: number, diffQty: number, sourceTable: string, remark: string) => request({
|
||||
url: '/v1/inbound/stock/adjust',
|
||||
method: 'post',
|
||||
data: {
|
||||
draft_id: draftId,
|
||||
stock_id: stockId, // 库存项ID
|
||||
diff_qty: diffQty, // 差异数量(支持无草稿模式)
|
||||
source_table: sourceTable, // 必须:stock_buy / stock_semi / stock_product
|
||||
operator_name: currentUser,
|
||||
remark: remark
|
||||
}
|
||||
}),
|
||||
// ★ 保留清除功能(用于兼容性)
|
||||
clearDraft: () => request({
|
||||
url: '/v1/inbound/stock/draft/clear',
|
||||
@ -571,11 +593,27 @@ const checkServerDraft = async () => {
|
||||
|
||||
// ★ 重写: 开始新盘点 - 使用新 API
|
||||
const startNewSession = async () => {
|
||||
// ★ 新增: 防呆确认弹窗
|
||||
if (serverDraftCount.value > 0) {
|
||||
showConfirmDialog.value = true
|
||||
countdown.value = 10
|
||||
if (countdownTimer) clearInterval(countdownTimer)
|
||||
countdownTimer = setInterval(() => {
|
||||
countdown.value--
|
||||
if (countdown.value <= 0) {
|
||||
clearInterval(countdownTimer!)
|
||||
countdownTimer = null
|
||||
}
|
||||
}, 1000)
|
||||
return
|
||||
}
|
||||
await doStartNewSession()
|
||||
}
|
||||
|
||||
const doStartNewSession = async () => {
|
||||
showConfirmDialog.value = false
|
||||
btnLoading.value = true
|
||||
try {
|
||||
if (serverDraftCount.value > 0) {
|
||||
await ElMessageBox.confirm('存在未完成记录,开始新盘点将清除它们,确定吗?', '警告', { type: 'warning' })
|
||||
}
|
||||
btnLoading.value = true
|
||||
// 调用新 API 开始新会话
|
||||
const res: any = await api.startNewSession()
|
||||
currentSessionId.value = res.session_id || ''
|
||||
@ -592,6 +630,20 @@ const startNewSession = async () => {
|
||||
} finally { btnLoading.value = false }
|
||||
}
|
||||
|
||||
const confirmClear = () => {
|
||||
if (countdown.value > 0) return
|
||||
doStartNewSession()
|
||||
}
|
||||
|
||||
const cancelConfirm = () => {
|
||||
showConfirmDialog.value = false
|
||||
if (countdownTimer) {
|
||||
clearInterval(countdownTimer)
|
||||
countdownTimer = null
|
||||
}
|
||||
countdown.value = 0
|
||||
}
|
||||
|
||||
// ★ 重写: 继续上次盘点 - 恢复扫码作业
|
||||
const resumeSession = async () => {
|
||||
btnLoading.value = true
|
||||
@ -760,7 +812,6 @@ const handleManualInput = async () => {
|
||||
ElMessage.error(`不在库条码: ${code}`)
|
||||
}
|
||||
} finally {
|
||||
barcodeInput.value = ''
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
@ -888,6 +939,18 @@ const varianceList = computed(() => {
|
||||
}))
|
||||
})
|
||||
|
||||
// ★ 新增: 本地搜索过滤后的差异列表
|
||||
const filteredVarianceList = computed(() => {
|
||||
if (!searchSku.value) return varianceList.value
|
||||
const kw = searchSku.value.toLowerCase()
|
||||
return varianceList.value.filter(i =>
|
||||
(i.uuid && i.uuid.toLowerCase().includes(kw)) ||
|
||||
(i.sku && i.sku.toLowerCase().includes(kw)) ||
|
||||
(i.stock_name && i.stock_name.toLowerCase().includes(kw)) ||
|
||||
(i.stock_spec && i.stock_spec.toLowerCase().includes(kw))
|
||||
)
|
||||
})
|
||||
|
||||
const openInventoryList = () => { showList.value = true }
|
||||
|
||||
// ★ 修改:结束盘点按钮直接调用 finishStocktake,跳过二次确认弹窗
|
||||
@ -946,35 +1009,6 @@ const openVarianceDialog = async () => {
|
||||
varianceLoading.value = false
|
||||
}
|
||||
|
||||
// ★ 新增: 确认平账
|
||||
const handleAdjust = async (row: any) => {
|
||||
try {
|
||||
// ===== 调试代码 =====
|
||||
console.warn('---- 准备平账参数检查 ----');
|
||||
console.warn('当前点击行的完整数据:', row);
|
||||
console.warn(`将要发送的 draftId: ${row.id}, stockId: ${row.stock_id}, sourceTable: ${row.source_table}`);
|
||||
// ===== 调试结束 =====
|
||||
|
||||
await ElMessageBox.confirm(
|
||||
`确定要对 "${row.uuid}" 进行平账调整吗?\n\n差异: ${row.diff_qty > 0 ? '盘盈 +' : '盘亏 '}${row.diff_qty}`,
|
||||
'确认平账',
|
||||
{ type: 'warning', confirmButtonText: '确认调整', cancelButtonText: '取消' }
|
||||
)
|
||||
|
||||
const remark = `盘点差异调整 - ${row.diff_qty > 0 ? '盘盈入库' : '盘亏出库'}`
|
||||
|
||||
const res: any = await api.adjustStock(row.id, row.stock_id, row.diff_qty, row.source_table || 'stock_buy', remark)
|
||||
|
||||
ElMessage.success(res.message || '调整成功')
|
||||
|
||||
// 刷新数据并重新打开差异列表
|
||||
await loadData()
|
||||
await openVarianceDialog()
|
||||
} catch (e: any) {
|
||||
if (e !== 'cancel') ElMessage.error(e?.message || '操作失败')
|
||||
}
|
||||
}
|
||||
|
||||
// ★ 新增: 跳转到差异审核页面
|
||||
const goToVarianceReview = () => {
|
||||
openVarianceDialog()
|
||||
@ -1239,4 +1273,14 @@ const goToVarianceReview = () => {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.confirm-content {
|
||||
text-align: center;
|
||||
padding: 20px 0;
|
||||
}
|
||||
.confirm-content .confirm-text {
|
||||
margin-top: 20px;
|
||||
font-size: 16px;
|
||||
color: #303133;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user