Files
klp-oa/klp-ui/src/store/modules/category.js
砂糖 25e45e06bb feat(store): 增加分页请求重试机制并提高单页数据量
为产品和原材料列表请求添加重试机制,最多重试5次
将单页请求数据量从2000条提升至5000条
2025-11-15 14:50:39 +08:00

250 lines
7.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 { listCategory } from '@/api/wms/category';
// import { listBomItem } from '@/api/wms/bomItem';
// import { listProduct } from '@/api/wms/product';
// import { listRawMaterial } from '@/api/wms/rawMaterial';
import veilReq from '@/utils/veilReq';
const listRawMaterial = (params) => veilReq({
url: '/wms/rawMaterial/list',
method: 'get',
params
});
const listProduct = (params) => veilReq({
url: '/wms/product/list',
method: 'get',
params
});
const state = {
categoryList: [],
productMap: {},
rawMaterialMap: {},
productList: [],
rawMaterialList: [],
bomMap: {}
};
const mutations = {
SET_CATEGORY_LIST(state, list) {
state.categoryList = list;
},
SET_PRODUCT_MAP(state, map) {
state.productMap = map;
},
SET_RAW_MATERIAL_MAP(state, map) {
state.rawMaterialMap = map;
},
SET_PRODUCT_LIST(state, list) {
state.productList = list;
},
SET_RAW_MATERIAL_LIST(state, list) {
state.rawMaterialList = list;
},
SET_BOM_MAP(state, map) {
state.bomMap = map;
}
};
const actions = {
getCategoryList({ state, commit }) {
if (state.categoryList.length > 0) {
return Promise.resolve(state.categoryList);
}
return listCategory({ pageNum: 1, pageSize: 10000 }).then(res => {
commit('SET_CATEGORY_LIST', res.rows || []);
return res.rows || [];
});
},
getProductMap({ state, commit }) {
// 若已有缓存数据,直接返回
if (Object.keys(state.productMap).length > 0) {
return Promise.resolve(state.productMap);
}
const pageSize = 5000; // 每次获取5000条
const allRows = []; // 存储所有批次的列表数据
const productMap = {}; // 最终的产品映射表
const maxRetries = 5; // 最大重试次数
// 带重试机制的请求函数
const fetchWithRetry = async (pageNum) => {
let retries = 0;
while (retries < maxRetries) {
try {
// 尝试调用接口
const res = await listProduct({ pageNum, pageSize });
return res; // 成功则返回结果
} catch (error) {
retries++;
if (retries >= maxRetries) {
// 达到最大重试次数,抛出错误
throw new Error(`获取第${pageNum}页产品数据失败,已重试${maxRetries}次: ${error.message}`);
}
// 可选添加重试间隔如1秒避免频繁请求
await new Promise(resolve => setTimeout(resolve, 1000));
console.log(`获取第${pageNum}页失败,正在进行第${retries}次重试...`);
}
}
};
// 异步处理分批次获取逻辑
const fetchAllProducts = async () => {
// 1. 获取第一页数据拿到总条数total带重试
let currentPage = 1;
const firstRes = await fetchWithRetry(currentPage);
const total = firstRes.total || 0;
const firstRows = firstRes.rows || [];
// 处理第一页数据
allRows.push(...firstRows);
firstRows.forEach(item => {
productMap[item.productId.toString()] = item;
});
// 2. 计算总页数,循环获取剩余页面数据(每一页都带重试)
const totalPages = Math.ceil(total / pageSize);
for (currentPage = 2; currentPage <= totalPages; currentPage++) {
const res = await fetchWithRetry(currentPage);
const rows = res.rows || [];
// 合并当前页数据到总列表和映射表
allRows.push(...rows);
rows.forEach(item => {
productMap[item.productId.toString()] = item;
});
}
// 3. 所有数据获取完成后,更新状态
commit('SET_PRODUCT_MAP', productMap);
commit('SET_PRODUCT_LIST', allRows);
return productMap;
};
// 返回Promise确保外部可通过.then获取结果
return fetchAllProducts();
},
getRawMaterialMap({ state, commit }) {
// 若已有缓存数据,直接返回
if (Object.keys(state.rawMaterialMap).length > 0) {
return Promise.resolve(state.rawMaterialMap);
}
const pageSize = 5000; // 每次获取5000条
const allRows = []; // 存储所有批次的原材料列表
const rawMaterialMap = {}; // 最终的原材料映射表
const maxRetries = 5; // 最大重试次数
// 带重试机制的请求函数(针对原材料接口)
const fetchWithRetry = async (pageNum) => {
let retries = 0;
while (retries < maxRetries) {
try {
// 尝试调用原材料列表接口
const res = await listRawMaterial({ pageNum, pageSize });
return res; // 成功则返回结果
} catch (error) {
retries++;
if (retries >= maxRetries) {
// 达到最大重试次数,抛出错误(包含具体页码)
throw new Error(`获取第${pageNum}页原材料数据失败,已重试${maxRetries}次: ${error.message}`);
}
// 重试间隔1秒避免频繁请求
await new Promise(resolve => setTimeout(resolve, 1000));
console.log(`获取第${pageNum}页原材料失败,正在进行第${retries}次重试...`);
}
}
};
// 异步处理分批次获取逻辑
const fetchAllRawMaterials = async () => {
// 1. 获取第一页数据(带重试)
let currentPage = 1;
const firstRes = await fetchWithRetry(currentPage);
const total = firstRes.total || 0;
const firstRows = firstRes.rows || [];
// 处理第一页数据
allRows.push(...firstRows);
firstRows.forEach(item => {
rawMaterialMap[item.rawMaterialId.toString()] = item;
});
// 2. 循环获取剩余页面数据(每一页都带重试)
const totalPages = Math.ceil(total / pageSize);
for (currentPage = 2; currentPage <= totalPages; currentPage++) {
const res = await fetchWithRetry(currentPage);
const rows = res.rows || [];
// 合并当前页数据
allRows.push(...rows);
rows.forEach(item => {
rawMaterialMap[item.rawMaterialId.toString()] = item;
});
}
// 3. 更新状态
commit('SET_RAW_MATERIAL_MAP', rawMaterialMap);
commit('SET_RAW_MATERIAL_LIST', allRows);
return rawMaterialMap;
};
// 返回Promise供外部调用
return fetchAllRawMaterials();
},
getBomMap({ state, commit }) {
if (Object.keys(state.bomMap).length > 0) {
return Promise.resolve(state.bomMap);
}
return listBomItem({ pageNum: 1, pageSize: 100000 }).then(res => {
console.log('bomItem', res)
const map = {};
res.rows.forEach(item => {
if (!map[item.bomId]) {
map[item.bomId] = [];
}
map[item.bomId].push(item);
});
commit('SET_BOM_MAP', map);
return map;
})
}
};
export function findItemWithBom(itemType, itemId) {
if (!itemType || !itemId) {
return null;
}
let map = {}
if (itemType === 'product') {
map = state.productMap;
} else if (itemType === 'raw_material') {
map = state.rawMaterialMap;
} else {
return null;
}
const item = map[itemId];
if (!item) {
return null;
}
const bomId = item.bomId
if (!bomId) {
return null;
}
const bomItems = state.bomMap[bomId];
return {
...item,
boms: bomItems || [],
itemName: itemType === 'product' ? item.productName : item.rawMaterialName,
itemType,
};
}
export default {
namespaced: true,
state,
mutations,
actions,
};