Merge remote-tracking branch 'origin/0.8.X' into 0.8.X

This commit is contained in:
2025-11-15 15:02:17 +08:00
2 changed files with 173 additions and 20 deletions

View File

@@ -1,10 +1,18 @@
import { listCategory } from '@/api/wms/category';
import { listProduct } from '@/api/wms/product';
import { listRawMaterial } from '@/api/wms/rawMaterial';
import { listBomItem } from '@/api/wms/bomItem';
// 目前存在一个问题,当新增或删除,修改分类、产品、物料时,需要刷新整个页面,才能看到最新的数据
// 需要优化当新增或删除修改分类、产品、物料时只刷新相关的数据而不是整个页面修改和删除可以解决新增由于没有返回id所以需要重新获取整个列表
// 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: [],
@@ -53,15 +61,37 @@ const actions = {
return Promise.resolve(state.productMap);
}
const pageSize = 2000; // 每次获取2000条
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
// 1. 获取第一页数据拿到总条数total(带重试)
let currentPage = 1;
const firstRes = await listProduct({ pageNum: currentPage, pageSize });
const firstRes = await fetchWithRetry(currentPage);
const total = firstRes.total || 0;
const firstRows = firstRes.rows || [];
@@ -71,10 +101,10 @@ const actions = {
productMap[item.productId.toString()] = item;
});
// 2. 计算总页数,循环获取剩余页面数据
// 2. 计算总页数,循环获取剩余页面数据(每一页都带重试)
const totalPages = Math.ceil(total / pageSize);
for (currentPage = 2; currentPage <= totalPages; currentPage++) {
const res = await listProduct({ pageNum: currentPage, pageSize });
const res = await fetchWithRetry(currentPage);
const rows = res.rows || [];
// 合并当前页数据到总列表和映射表
@@ -100,15 +130,37 @@ const actions = {
return Promise.resolve(state.rawMaterialMap);
}
const pageSize = 2000; // 每次获取2000条
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. 获取第一页数据拿到总条数total
// 1. 获取第一页数据(带重试)
let currentPage = 1;
const firstRes = await listRawMaterial({ pageNum: currentPage, pageSize });
const firstRes = await fetchWithRetry(currentPage);
const total = firstRes.total || 0;
const firstRows = firstRes.rows || [];
@@ -118,27 +170,27 @@ const actions = {
rawMaterialMap[item.rawMaterialId.toString()] = item;
});
// 2. 计算总页数,循环获取剩余页面数据
// 2. 循环获取剩余页面数据(每一页都带重试)
const totalPages = Math.ceil(total / pageSize);
for (currentPage = 2; currentPage <= totalPages; currentPage++) {
const res = await listRawMaterial({ pageNum: currentPage, pageSize });
const res = await fetchWithRetry(currentPage);
const rows = res.rows || [];
// 合并当前页数据到总列表和映射表
// 合并当前页数据
allRows.push(...rows);
rows.forEach(item => {
rawMaterialMap[item.rawMaterialId.toString()] = item;
});
}
// 3. 所有数据获取完成后,更新状态
// 3. 更新状态
commit('SET_RAW_MATERIAL_MAP', rawMaterialMap);
commit('SET_RAW_MATERIAL_LIST', allRows);
return rawMaterialMap;
};
// 返回Promise,确保外部可通过.then获取结果
// 返回Promise供外部调用
return fetchAllRawMaterials();
},
getBomMap({ state, commit }) {

101
klp-ui/src/utils/veilReq.js Normal file
View File

@@ -0,0 +1,101 @@
import axios from 'axios'
import { MessageBox } from 'element-ui'
import store from '@/store'
import { getToken } from '@/utils/auth'
import errorCode from '@/utils/errorCode'
import { tansParams, } from "@/utils/klp";
import cache from '@/plugins/cache'
// 创建axios实例
const service = axios.create({
// axios中请求配置有baseURL选项表示请求URL公共部分
baseURL: process.env.VUE_APP_BASE_API,
// 超时
timeout: 600000
})
// request拦截器
service.interceptors.request.use(config => {
// 是否需要设置 token
const isToken = (config.headers || {}).isToken === false
// 是否需要防止数据重复提交
const isRepeatSubmit = (config.headers || {}).repeatSubmit === false
if (getToken() && !isToken) {
config.headers['Authorization'] = 'Bearer ' + getToken() // 让每个请求携带自定义token 请根据实际情况自行修改
}
// get请求映射params参数
if (config.method === 'get' && config.params) {
let url = config.url + '?' + tansParams(config.params);
url = url.slice(0, -1);
config.params = {};
config.url = url;
}
if (!isRepeatSubmit && (config.method === 'post' || config.method === 'put')) {
const requestObj = {
url: config.url,
data: typeof config.data === 'object' ? JSON.stringify(config.data) : config.data,
time: new Date().getTime()
}
const sessionObj = cache.session.getJSON('sessionObj')
if (sessionObj === undefined || sessionObj === null || sessionObj === '') {
cache.session.setJSON('sessionObj', requestObj)
} else {
const s_url = sessionObj.url; // 请求地址
const s_data = sessionObj.data; // 请求数据
const s_time = sessionObj.time; // 请求时间
const interval = 1000; // 间隔时间(ms),小于此时间视为重复提交
if (s_data === requestObj.data && requestObj.time - s_time < interval && s_url === requestObj.url) {
const message = '数据正在处理,请勿重复提交';
console.warn(`[${s_url}]: ` + message)
return Promise.reject(new Error(message))
} else {
cache.session.setJSON('sessionObj', requestObj)
}
}
}
return config
}, error => {
console.log(error)
Promise.reject(error)
})
// 响应拦截器
service.interceptors.response.use(res => {
// 未设置状态码则默认成功状态
const code = res.data.code || 200;
// 获取错误信息
const msg = errorCode[code] || res.data.msg || errorCode['default']
// 二进制数据则直接返回
if (res.request.responseType === 'blob' || res.request.responseType === 'arraybuffer') {
return res.data
}
if (code === 401) {
if (!isRelogin.show) {
isRelogin.show = true;
MessageBox.confirm('登录状态已过期,您可以继续留在该页面,或者重新登录', '系统提示', { confirmButtonText: '重新登录', cancelButtonText: '取消', type: 'warning' }).then(() => {
isRelogin.show = false;
store.dispatch('LogOut').then(() => {
location.href = process.env.VUE_APP_CONTEXT_PATH + "index";
})
}).catch(() => {
isRelogin.show = false;
});
}
return Promise.reject('无效的会话,或者会话已过期,请重新登录。')
} else if (code === 500) {
return Promise.reject(new Error(msg))
} else if (code === 601) {
return Promise.reject('error')
} else if (code !== 200) {
return Promise.reject('error')
} else {
return res.data
}
},
error => {
console.log('err' + error)
return Promise.reject(error)
}
)
export default service