import { defineStore } from 'pinia' import { ref } from 'vue' import { materialsApi } from '../api/materials' export const useMaterialsStore = defineStore('materials', () => { const materials = ref([]) // 有效物料选项,供入库、出库、物料申请等业务单据的表单使用。 const materialOptions = ref([]) // 含已作废物料的选项,只给库存流水这类历史记录的检索框用:查历史时需要能选中 // 已经作废的物料,但业务单据的表单不该出现它们。 const historicalMaterialOptions = ref([]) const loading = ref(false) const pagination = ref({ currentPage: 1, pageSize: 20, total: 0, totalPages: 0 }) const categoryMap = { 'A01': '标准件', 'A02': '成品件', 'A03': '简易加工件', 'A04': '精密加工件', 'A05': '钣金件', 'A06': '塑胶件', 'A07': '其他', 'B01': '成品件', 'B02': '简易加工件', 'B03': 'PCB硬板', 'B04': 'FPC软板', 'B05': '线束', 'B06': '组装组件', 'B07': '其他', 'C01': '连接耗材', 'C02': '密封耗材', 'C03': '其他', 'D01': '自研程序固件', 'D02': '外购软件授权', 'D03': '授权介质', 'D04': '其他', 'E01': '成品', 'E02': '半成品', 'F01': '资料文档', 'F02': '标识标牌', 'F03': '包装物料', 'F04': '随机工具配件', 'F05': '其他' } function getCategoryDisplay(category) { if (!category) return '-' const name = categoryMap[category] || '' return name ? `${category} - ${name}` : category } async function fetchMaterials(page = 1, search = '', status = 'all') { loading.value = true try { const pageSize = pagination.value.pageSize const offset = (page - 1) * pageSize const res = await materialsApi.getAll({ search, status, limit: pageSize, offset }) materials.value = res.data?.items || res.data || [] pagination.value.total = res.data?.total || materials.value.length pagination.value.currentPage = page pagination.value.totalPages = Math.ceil(pagination.value.total / pageSize) || 1 } finally { loading.value = false } } // 接口单页上限是 100,循环翻页把符合条件的物料全部取回来。 async function fetchOptionsByStatus(status) { const pageSize = 100 let offset = 0 let total = 0 const options = [] do { const res = await materialsApi.getAll({ status, limit: pageSize, offset }) const items = res.data?.items || res.data || [] options.push(...items) total = res.data?.total ?? options.length offset += items.length } while (offset < total) return options } async function fetchMaterialOptions() { materialOptions.value = await fetchOptionsByStatus('active') } async function fetchHistoricalMaterialOptions() { historicalMaterialOptions.value = await fetchOptionsByStatus('all') } async function refreshMaterialOptions() { await Promise.all([fetchMaterialOptions(), fetchHistoricalMaterialOptions()]) } async function createMaterial(data) { const res = await materialsApi.create(data) await fetchMaterials(1) return res } async function updateMaterial(id, data) { const res = await materialsApi.update(id, data) await fetchMaterials(pagination.value.currentPage) return res } async function obsoleteMaterial(id) { const res = await materialsApi.obsolete(id) await fetchMaterials(pagination.value.currentPage) // 作废会改变物料在「有效」和「全部」两份选项里的归属,两份都要刷新 await refreshMaterialOptions() return res } async function restoreMaterial(id) { const res = await materialsApi.restore(id) await fetchMaterials(pagination.value.currentPage) await refreshMaterialOptions() return res } return { materials, materialOptions, historicalMaterialOptions, loading, pagination, categoryMap, getCategoryDisplay, fetchMaterials, fetchMaterialOptions, fetchHistoricalMaterialOptions, createMaterial, updateMaterial, obsoleteMaterial, restoreMaterial } })