Files
his/openhis-ui-vue3/src/utils/apiRequestManager.js
zhangfei 9c3e603b94 Fix Bug #443: 手术计费:点击签发耗材时异常报错
当手术计费弹窗中点击"签发"耗材时,因耗材的locationId(发放库房)为空导致后端异常。
在DoctorStationAdviceAppServiceImpl.handDevice方法中,当locationId为null时,使用登录用户的科室ID作为默认值,
与NurseBillingAppService中的处理方式保持一致。
2026-05-08 09:14:18 +08:00

197 lines
5.3 KiB
JavaScript
Executable File
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 globalRequestController from './globalRequestController.js';
/**
* API请求管理器 - 用于合并相同参数的请求,避免重复请求
* 在医院信息系统中特别重要,因为医疗数据的频繁请求可能影响系统性能
*/
class ApiRequestManager {
constructor() {
// 存储正在进行的请求
this.pendingRequests = new Map();
// 缓存成功的响应结果
this.responseCache = new Map();
// 缓存过期时间(毫秒)
this.cacheTimeout = 10000; // 10秒医疗系统中数据更新可能较频繁
// 添加调试模式
this.debugMode = true;
}
/**
* 生成请求的唯一键值
* @param {string} url - 请求URL
* @param {object} params - 请求参数
* @returns {string} 唯一键值
*/
generateRequestKey(url, params = {}) {
// 对参数进行排序以确保相同参数产生相同键值
const sortedParams = Object.keys(params)
.sort()
.reduce((acc, key) => {
acc[key] = params[key];
return acc;
}, {});
const key = `${url}?${JSON.stringify(sortedParams)}`;
if (this.debugMode) {
console.log(`Generated request key: ${key}`);
}
return key;
}
/**
* 检查是否存在相同的进行中请求
* @param {string} requestKey - 请求键值
* @returns {Promise|undefined} 如果存在则返回Promise否则返回undefined
*/
getPendingRequest(requestKey) {
return this.pendingRequests.get(requestKey);
}
/**
* 添加进行中的请求
* @param {string} requestKey - 请求键值
* @param {Promise} promise - 请求Promise
*/
addPendingRequest(requestKey, promise) {
this.pendingRequests.set(requestKey, promise);
}
/**
* 移除进行中的请求
* @param {string} requestKey - 请求键值
*/
removePendingRequest(requestKey) {
this.pendingRequests.delete(requestKey);
}
/**
* 检查是否存在缓存的响应
* @param {string} requestKey - 请求键值
* @returns {object|undefined} 如果存在则返回缓存的响应否则返回undefined
*/
getCachedResponse(requestKey) {
const cached = this.responseCache.get(requestKey);
if (cached && Date.now() < cached.expiry) {
return cached.data;
}
// 如果缓存已过期,删除它
if (cached) {
this.responseCache.delete(requestKey);
}
return undefined;
}
/**
* 添加缓存的响应
* @param {string} requestKey - 请求键值
* @param {object} data - 响应数据
*/
addCachedResponse(requestKey, data) {
this.responseCache.set(requestKey, {
data,
expiry: Date.now() + this.cacheTimeout
});
}
/**
* 清除指定的缓存
* @param {string} requestKey - 请求键值
*/
clearCache(requestKey) {
this.responseCache.delete(requestKey);
}
/**
* 清除所有缓存
*/
clearAllCache() {
this.responseCache.clear();
}
/**
* 清除所有进行中的请求
*/
clearAllPending() {
this.pendingRequests.clear();
}
/**
* 执行API请求带去重和缓存
* @param {Function} apiFunction - API函数
* @param {string} url - 请求URL
* @param {object} params - 请求参数
* @returns {Promise} API响应Promise
*/
async execute(apiFunction, url, params = {}) {
const requestKey = this.generateRequestKey(url, params);
if (this.debugMode) {
console.log(`Executing request with key: ${requestKey}`);
console.log(`Pending requests count: ${this.pendingRequests.size}`);
console.log(`Cached responses count: ${this.responseCache.size}`);
}
// 检查是否有缓存的响应
const cachedResponse = this.getCachedResponse(requestKey);
if (cachedResponse) {
if (this.debugMode) {
console.log(`Returning cached response for: ${requestKey}`);
}
return Promise.resolve(cachedResponse);
}
// 使用全局请求控制器来确保唯一性
const requestPromise = globalRequestController.execute(apiFunction, url, params)
.then(response => {
if (this.debugMode) {
console.log(`Request completed for: ${requestKey}`, response);
}
// 请求成功后,添加到缓存
this.addCachedResponse(requestKey, response);
return response;
})
.catch(error => {
if (this.debugMode) {
console.error(`Request failed for: ${requestKey}`, error);
}
throw error; // 不在这里处理错误,让调用方处理
});
return requestPromise;
}
/**
* 执行POST请求带去重和缓存
* @param {Function} apiFunction - API函数
* @param {string} url - 请求URL
* @param {object} data - 请求数据
* @returns {Promise} API响应Promise
*/
async executePost(apiFunction, url, data = {}) {
const requestKey = this.generateRequestKey(url, data);
// POST请求通常不缓存但仍然可以去重
const pendingRequest = this.getPendingRequest(requestKey);
if (pendingRequest) {
return pendingRequest;
}
const requestPromise = apiFunction(data)
.finally(() => {
this.removePendingRequest(requestKey);
});
this.addPendingRequest(requestKey, requestPromise);
return requestPromise;
}
}
// 创建全局实例
const apiRequestManager = new ApiRequestManager();
export default apiRequestManager;