refactor(stocktake): replace fetch-all with remote pagination/search and add permission checks

This commit is contained in:
DXC
2026-03-25 09:51:28 +08:00
parent d5d12a8df5
commit bd20852739
4 changed files with 48 additions and 22 deletions

Binary file not shown.

0
deploy_code.sh Executable file → Normal file
View File

0
deploy_full.sh Executable file → Normal file
View File

View File

@ -386,7 +386,7 @@
<script setup lang="ts"> <script setup lang="ts">
import { ref, computed, onMounted, onUnmounted, nextTick } from 'vue' import { ref, computed, onMounted, onUnmounted, nextTick } from 'vue'
import { getAllStock } from '@/api/inbound/stock' import { getStockList } from '@/api/inbound/stock'
import QrScanner from '@/components/QrScanner/index.vue' import QrScanner from '@/components/QrScanner/index.vue'
import { ElMessage, ElMessageBox } from 'element-plus' import { ElMessage, ElMessageBox } from 'element-plus'
import { Search, VideoPlay, VideoPause, List, Checked, Download, ArrowRight, Cloudy, Edit, EditPen, CameraFilled, Close, WarningFilled } from '@element-plus/icons-vue' import { Search, VideoPlay, VideoPause, List, Checked, Download, ArrowRight, Cloudy, Edit, EditPen, CameraFilled, Close, WarningFilled } from '@element-plus/icons-vue'
@ -460,6 +460,14 @@ const allData = ref<StockItem[]>([])
const scannedMap = ref<Map<string, number>>(new Map()) const scannedMap = ref<Map<string, number>>(new Map())
const borrowedQuantities = ref<Record<string, number>>({}) const borrowedQuantities = ref<Record<string, number>>({})
// ★ 新增: 分页查询参数
const queryParams = reactive({
page: 1,
limit: 20,
keyword: ''
})
const total = ref(0)
// ★ 新增: 会话ID // ★ 新增: 会话ID
const currentSessionId = ref<string>('') const currentSessionId = ref<string>('')
@ -473,17 +481,21 @@ const inputQty = ref<number | undefined>(undefined)
const inputRemark = ref('') const inputRemark = ref('')
const qtyInputRef = ref() const qtyInputRef = ref()
// ★ 新增: 静默刷新数据不弹loading // ★ 新增: 静默刷新数据不弹loading- 使用远程分页
const syncData = async () => { const syncData = async () => {
try { try {
// 仅刷新差异列表数据不显示loading // 使用较大 limit 获取足够数据用于扫码匹配(静默刷新)
const res = await getAllStock() const res: any = await getStockList({
if (!res) return page: 1,
pageSize: 1000, // 获取足够多的数据用于扫码匹配
keyword: '' // 静默刷新不传关键词
})
if (!res || !res.data) return
const processItem = (item: any, type: string) => { const processItem = (item: any, type: string) => {
const stock = parseFloat(item.stock_quantity || item.qty_stock || 0) const stock = parseFloat(item.stock_quantity || item.qty_stock || 0)
if (stock <= 0) return if (stock <= 0) return
const name = item.material_name || item.product_name || item.name || '未知物品' const name = item.name || item.material_name || item.product_name || '未知物品'
const uuid = item.uuid || item.sku || '' const uuid = item.uuid || item.sku || ''
const isScanned = scannedMap.value.has(uuid) const isScanned = scannedMap.value.has(uuid)
return { return {
@ -503,9 +515,12 @@ const syncData = async () => {
} }
const list: StockItem[] = [] const list: StockItem[] = []
if (res.materials) res.materials.forEach((i: any) => { const item = processItem(i, 'material'); if (item) list.push(item) }) const items = res.data.list || []
if (res.semis) res.semis.forEach((i: any) => { const item = processItem(i, 'semi'); if (item) list.push(item) }) items.forEach((item: any) => {
if (res.products) res.products.forEach((i: any) => { const item = processItem(i, 'product'); if (item) list.push(item) }) const type = item.stock_type || item.type || 'material'
const processed = processItem(item, type)
if (processed) list.push(processed)
})
// ★ 强制按 SKU 数字+字符串升序排序 // ★ 强制按 SKU 数字+字符串升序排序
list.sort((a, b) => { list.sort((a, b) => {
@ -516,6 +531,7 @@ const syncData = async () => {
// 静默更新数据不触发loading // 静默更新数据不触发loading
allData.value = list allData.value = list
total.value = res.data.total || 0
await fetchBorrowedQuantities(list) await fetchBorrowedQuantities(list)
} catch (e) { } catch (e) {
// 静默失败,不弹错误 // 静默失败,不弹错误
@ -724,25 +740,37 @@ const returnToScan = () => {
ElMessage.info('继续扫码,发现漏扫的物料') ElMessage.info('继续扫码,发现漏扫的物料')
} }
// ★★★ 核心修改:数据加载映射修复 ★★★ // ★★★ 核心修改:使用远程分页 API ★★★
const loadData = async () => { const loadData = async () => {
loading.value = true loading.value = true
try { try {
const res = await getAllStock() const res: any = await getStockList({
const list: StockItem[] = [] page: queryParams.page,
pageSize: queryParams.limit,
keyword: queryParams.keyword
})
const processItem = (item: any, type: string) => { if (!res || !res.data) {
allData.value = []
total.value = 0
return
}
const list: StockItem[] = []
const items = res.data.list || []
// 处理返回的库存数据
items.forEach((item: any) => {
const stock = parseFloat(item.stock_quantity || item.qty_stock || 0) const stock = parseFloat(item.stock_quantity || item.qty_stock || 0)
if (stock <= 0) return if (stock <= 0) return
const name = item.material_name || item.product_name || item.name || '未知物品' const type = item.stock_type || item.type || 'material'
const uuid = item.uuid || item.sku || '' const uuid = item.uuid || item.sku || ''
const isScanned = scannedMap.value.has(uuid) const isScanned = scannedMap.value.has(uuid)
list.push({ list.push({
...item, ...item,
name: name, name: item.name || item.material_name || item.product_name || '未知物品',
// ★ 修复点:优先读取 spec_model因为数据库是这个字段
standard: item.spec_model || item.standard || item.model || '', standard: item.spec_model || item.standard || item.model || '',
sku: item.sku || '', sku: item.sku || '',
batch_no: item.batch_no || item.batch_number || '', batch_no: item.batch_no || item.batch_number || '',
@ -756,11 +784,7 @@ const loadData = async () => {
source_table: typeToSourceTable(type), source_table: typeToSourceTable(type),
stock_id: item.id stock_id: item.id
}) })
} })
if (res.materials) res.materials.forEach((i: any) => processItem(i, 'material'))
if (res.semis) res.semis.forEach((i: any) => processItem(i, 'semi'))
if (res.products) res.products.forEach((i: any) => processItem(i, 'product'))
// ★ 强制按 SKU 数字+字符串升序排序 // ★ 强制按 SKU 数字+字符串升序排序
list.sort((a, b) => { list.sort((a, b) => {
@ -770,6 +794,8 @@ const loadData = async () => {
}); });
allData.value = list allData.value = list
total.value = res.data.total || 0
await fetchBorrowedQuantities(list) await fetchBorrowedQuantities(list)
} catch (e) { } catch (e) {
ElMessage.error('数据加载失败') ElMessage.error('数据加载失败')