refactor(stocktake): replace fetch-all with remote pagination/search and add permission checks
This commit is contained in:
BIN
deploy.tar.gz
BIN
deploy.tar.gz
Binary file not shown.
0
deploy_code.sh
Executable file → Normal file
0
deploy_code.sh
Executable file → Normal file
0
deploy_full.sh
Executable file → Normal file
0
deploy_full.sh
Executable file → Normal 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('数据加载失败')
|
||||||
|
|||||||
Reference in New Issue
Block a user