110 lines
4.0 KiB
JavaScript
110 lines
4.0 KiB
JavaScript
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
|
||
}
|
||
})
|