material_manage_system/frontend/src/stores/stock.js
2026-09-20 10:31:28 +08:00

121 lines
4.4 KiB
JavaScript
Raw 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.

import { defineStore } from 'pinia'
import { ref } from 'vue'
import { stockApi } from '../api/stock'
export const useStockStore = defineStore('stock', () => {
const stockList = ref([])
const warningList = ref([])
const logs = ref([])
const loading = ref(false)
const stockPage = ref({ currentPage: 1, pageSize: 20, total: 0, totalPages: 0 })
const warningPage = ref({ currentPage: 1, pageSize: 20, total: 0, totalPages: 0 })
const logsPage = ref({ currentPage: 1, pageSize: 20, total: 0, totalPages: 0 })
// 单物料库存缓存(materialId -> 库存对象)。出库和申请只要 total_on_hand,
// 入库表单还要读预警阈值,共用同一份缓存避免重复请求。
const stockCache = ref({})
async function fetchStock(page = 1, search = '', category = '') {
loading.value = true
try {
const pageSize = stockPage.value.pageSize
const offset = (page - 1) * pageSize
const res = await stockApi.getAll({ limit: pageSize, offset, search, category })
stockList.value = res.data?.items || res.data || []
stockPage.value.total = res.data?.total || 0
stockPage.value.currentPage = page
} finally {
loading.value = false
}
}
async function fetchAllStock() {
loading.value = true
try {
const res = await stockApi.getAll({ limit: 1000, offset: 0 })
stockList.value = res.data?.items || res.data || []
stockPage.value.total = res.data?.total || 0
} finally {
loading.value = false
}
}
// 返回完整的库存对象,供需要预警阈值的场景使用。
async function fetchStockDetailByMaterialId(materialId) {
if (!materialId) return null
if (stockCache.value[materialId] !== undefined) {
return stockCache.value[materialId]
}
try {
const res = await stockApi.getById(materialId)
const detail = res.data ?? null
stockCache.value[materialId] = detail
return detail
} catch {
// 失败不写缓存:否则一次网络抖动就把 null 缓存住,该物料之后一直显示 0,
// 只能靠刷新页面恢复。留空让下次调用重新请求。
return null
}
}
async function fetchStockByMaterialId(materialId) {
if (!materialId) return 0
const detail = await fetchStockDetailByMaterialId(materialId)
return detail?.total_on_hand ?? 0
}
// 清空单物料库存缓存。入库、出库等任何改变库存的写操作之后都必须调用它:
// 入库表单选物料时会为了预填预警值而查询库存,把当时(变更前)的数量缓存下来,
// 之后不清掉的话,出库表单会一直显示变更前的旧数字,用户得刷新页面才能看到正确的。
function clearStockCache() {
stockCache.value = {}
}
async function fetchStockWarning(page = 1) {
loading.value = true
try {
const pageSize = warningPage.value.pageSize
const offset = (page - 1) * pageSize
const res = await stockApi.getWarning({ limit: pageSize, offset })
warningList.value = res.data?.items || res.data || []
warningPage.value.total = res.data?.total || 0
warningPage.value.currentPage = page
} finally {
loading.value = false
}
}
async function fetchStockLogs(materialId, page = 1) {
loading.value = true
try {
const pageSize = logsPage.value.pageSize
const offset = (page - 1) * pageSize
const res = materialId
? await stockApi.getLogs(materialId, { limit: pageSize, offset })
: await stockApi.getAllLogs({ limit: pageSize, offset })
logs.value = res.data?.items || res.data || []
logsPage.value.total = res.data?.total || 0
logsPage.value.currentPage = page
} finally {
loading.value = false
}
}
async function updateWarningStock(materialId, warningStock, enabled = true) {
await stockApi.updateWarning(materialId, warningStock, enabled)
// 阈值改了,单物料缓存里的旧值必须作废,否则入库表单会预填到过期数据。
delete stockCache.value[materialId]
await Promise.all([
fetchStock(stockPage.value.currentPage),
fetchStockWarning(warningPage.value.currentPage)
])
}
return {
stockList, warningList, logs, loading,
stockPage, warningPage, logsPage,
fetchStock, fetchAllStock, fetchStockByMaterialId, fetchStockDetailByMaterialId,
fetchStockWarning, fetchStockLogs, clearStockCache,
updateWarningStock
}
})