Compare commits
2 Commits
032479fe38
...
7c9331d78a
| Author | SHA1 | Date | |
|---|---|---|---|
| 7c9331d78a | |||
| 13e910645d |
@ -718,7 +718,15 @@ def export_stocktake():
|
|||||||
diff_headers = ["物料名称", "SKU", "规格型号", "库位", "调整后账面数", "实盘数", "差异数", "盘点人", "盘点时间", "备注"]
|
diff_headers = ["物料名称", "SKU", "规格型号", "库位", "调整后账面数", "实盘数", "差异数", "盘点人", "盘点时间", "备注"]
|
||||||
set_header_row(ws2, diff_headers)
|
set_header_row(ws2, diff_headers)
|
||||||
|
|
||||||
|
# 按 SKU 排序:先获取全部数据,再在 Python 中按 SKU 排序
|
||||||
diff_drafts = StocktakeDraft.query.filter(StocktakeDraft.diff_qty != 0).all()
|
diff_drafts = StocktakeDraft.query.filter(StocktakeDraft.diff_qty != 0).all()
|
||||||
|
diff_drafts_with_sku = []
|
||||||
|
for draft in diff_drafts:
|
||||||
|
mat_info = get_material_info(draft.source_table, draft.stock_id)
|
||||||
|
diff_drafts_with_sku.append((mat_info.get('sku', ''), draft))
|
||||||
|
diff_drafts_with_sku.sort(key=lambda x: x[0] if x[0] else '')
|
||||||
|
diff_drafts = [d[1] for d in diff_drafts_with_sku]
|
||||||
|
|
||||||
for row_idx, draft in enumerate(diff_drafts, 2):
|
for row_idx, draft in enumerate(diff_drafts, 2):
|
||||||
mat_info = get_material_info(draft.source_table, draft.stock_id)
|
mat_info = get_material_info(draft.source_table, draft.stock_id)
|
||||||
# 写入 Sheet 2 (差异明细)
|
# 写入 Sheet 2 (差异明细)
|
||||||
@ -751,7 +759,15 @@ def export_stocktake():
|
|||||||
normal_headers = ["物料名称", "SKU", "规格型号", "库位", "调整后账面数", "实盘数", "差异数", "盘点人", "盘点时间", "备注"]
|
normal_headers = ["物料名称", "SKU", "规格型号", "库位", "调整后账面数", "实盘数", "差异数", "盘点人", "盘点时间", "备注"]
|
||||||
set_header_row(ws3, normal_headers)
|
set_header_row(ws3, normal_headers)
|
||||||
|
|
||||||
|
# 按 SKU 排序
|
||||||
normal_drafts = StocktakeDraft.query.filter(StocktakeDraft.diff_qty == 0).all()
|
normal_drafts = StocktakeDraft.query.filter(StocktakeDraft.diff_qty == 0).all()
|
||||||
|
normal_drafts_with_sku = []
|
||||||
|
for draft in normal_drafts:
|
||||||
|
mat_info = get_material_info(draft.source_table, draft.stock_id)
|
||||||
|
normal_drafts_with_sku.append((mat_info.get('sku', ''), draft))
|
||||||
|
normal_drafts_with_sku.sort(key=lambda x: x[0] if x[0] else '')
|
||||||
|
normal_drafts = [d[1] for d in normal_drafts_with_sku]
|
||||||
|
|
||||||
for row_idx, draft in enumerate(normal_drafts, 2):
|
for row_idx, draft in enumerate(normal_drafts, 2):
|
||||||
mat_info = get_material_info(draft.source_table, draft.stock_id)
|
mat_info = get_material_info(draft.source_table, draft.stock_id)
|
||||||
# 写入 Sheet 3 (账实相符)
|
# 写入 Sheet 3 (账实相符)
|
||||||
|
|||||||
@ -97,12 +97,17 @@
|
|||||||
|
|
||||||
<div class="main-actions">
|
<div class="main-actions">
|
||||||
<el-row :gutter="10">
|
<el-row :gutter="10">
|
||||||
<el-col :span="12">
|
<el-col :span="8">
|
||||||
|
<el-button type="success" size="large" class="w-100 action-btn" @click="exportToExcel" :icon="Download">
|
||||||
|
导出Excel
|
||||||
|
</el-button>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="8">
|
||||||
<el-button type="primary" plain size="large" class="w-100 action-btn" @click="openInventoryList" :icon="Search">
|
<el-button type="primary" plain size="large" class="w-100 action-btn" @click="openInventoryList" :icon="Search">
|
||||||
盘点明细
|
盘点明细
|
||||||
</el-button>
|
</el-button>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="12">
|
<el-col :span="8">
|
||||||
<el-button v-if="userStore.hasPermission('inventory_stocktake:operation')" type="danger" size="large" class="w-100 action-btn" @click="handleGenerateMissing" :icon="Checked">
|
<el-button v-if="userStore.hasPermission('inventory_stocktake:operation')" type="danger" size="large" class="w-100 action-btn" @click="handleGenerateMissing" :icon="Checked">
|
||||||
结束盘点并生成差异
|
结束盘点并生成差异
|
||||||
</el-button>
|
</el-button>
|
||||||
@ -864,32 +869,43 @@ const handleManualConfirm = () => {
|
|||||||
if (!currentItem.value) return
|
if (!currentItem.value) return
|
||||||
const val = inputQty.value === undefined ? 0 : inputQty.value
|
const val = inputQty.value === undefined ? 0 : inputQty.value
|
||||||
|
|
||||||
updateAndSync(currentItem.value, val, inputRemark.value)
|
// ★★★ 乐观更新:立即本地更新 UI,不等待后端响应 ★★★
|
||||||
|
currentItem.value.scanned = true
|
||||||
|
currentItem.value.qty_actual = val
|
||||||
|
scannedMap.value.set(currentItem.value.uuid, val)
|
||||||
|
|
||||||
|
// 保存备注用于异步提交
|
||||||
|
const remark = inputRemark.value
|
||||||
|
|
||||||
showQtyDialog.value = false
|
showQtyDialog.value = false
|
||||||
// 重置备注
|
// 重置备注
|
||||||
inputRemark.value = ''
|
inputRemark.value = ''
|
||||||
ElMessage.success(`已记录实盘: ${val}`)
|
ElMessage.success(`已记录实盘: ${val}`)
|
||||||
|
|
||||||
// ★★★ 核心修改:确认数量后自动重新打开全屏扫码,实现无缝闭环
|
// ★★★ 取消自动弹摄像头,把开启摄像头的控制权完全交还给用户
|
||||||
nextTick(() => {
|
// 用户需主动点击才能开启摄像头
|
||||||
if (hasPermission) {
|
|
||||||
showCamera.value = true
|
// ★★★ 异步保存到后端,不阻塞 UI(fire-and-forget)★★★
|
||||||
}
|
syncToBackend(currentItem.value.uuid, val, remark)
|
||||||
})
|
}
|
||||||
|
|
||||||
|
// ★★★ 乐观更新:异步保存到后端,不阻塞 UI ★★★
|
||||||
|
const syncToBackend = (uuid: string, quantity: number, remark: string) => {
|
||||||
|
syncStatus.value = 'syncing'
|
||||||
|
api.addDraft({ uuid, quantity, remark })
|
||||||
|
.then(() => {
|
||||||
|
syncStatus.value = 'success'
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
syncStatus.value = 'failed'
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const updateAndSync = async (item: StockItem, quantity: number, remark: string = '') => {
|
const updateAndSync = async (item: StockItem, quantity: number, remark: string = '') => {
|
||||||
|
// ★★★ 保留原有逻辑用于兼容性,但不再使用 ★★★
|
||||||
item.scanned = true
|
item.scanned = true
|
||||||
item.qty_actual = quantity
|
item.qty_actual = quantity
|
||||||
scannedMap.value.set(item.uuid, quantity)
|
scannedMap.value.set(item.uuid, quantity)
|
||||||
|
|
||||||
syncStatus.value = 'syncing'
|
|
||||||
try {
|
|
||||||
await api.addDraft({ uuid: item.uuid, quantity: quantity, remark: remark })
|
|
||||||
syncStatus.value = 'success'
|
|
||||||
} catch (e) {
|
|
||||||
syncStatus.value = 'failed'
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const closeOverlays = () => {
|
const closeOverlays = () => {
|
||||||
|
|||||||
Reference in New Issue
Block a user