hookehuyr

✨ feat: 新增axios接口去重、数据持久化测试

......@@ -25,12 +25,14 @@ export const getComponentAPI = (params) => fn(fetch.get(Api.QUERY_COMPONENT, par
/**
* @description: 查询部门列表
* @param: form_code 表单code
* { ...params, headers: { "only-data": true, "keep-data": true } }
*/
export const getFlowDeptListAPI = (params) => fn(fetch.get(Api.FLOW_DEPT_LIST, params));
/**
* @description: 查询角色列表
* @param: form_code 表单code
* { ...params, headers: { "only-data": true, "keep-data": true } }
*/
export const getFlowRoleListAPI = (params) => fn(fetch.get(Api.FLOW_ROLE_LIST, params));
......
<!--
* @Date: 2022-08-29 14:31:20
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2024-11-21 12:41:40
* @LastEditTime: 2024-11-25 15:34:53
* @FilePath: /data-table/src/components/OrgPickerField/MyComponent.vue
* @Description: 树形组件
-->
......@@ -341,6 +341,44 @@ const treeCheckedCount = computed(() => {
});
onMounted(async () => {
// 挂载逻辑调整为手动触发,测试持久化保存接口数据
mountedLogic();
// // TAG: 获取后台数据
// const flowDeptList = await getFlowDeptListAPI({ form_code: $route.query.code });
// if (flowDeptList.code) {
// role_list = flowDeptList.data;
// }
// const flowRoleList = await getFlowRoleListAPI({ form_code: $route.query.code });
// if (flowRoleList.code) {
// dept_list = flowRoleList.data;
// }
// // TODO:等待后台数据
// check_type.value = '';
// // 获取已选中数据
// // 如果有默认值处理
// props.value = props.component_props.default;
// //
// if (props.value) {
// props.value.forEach(item => {
// if (item.type === 'dept') {
// emitCheckedGroup.value.dept.push(item);
// } else if (item.type === 'role') {
// emitCheckedGroup.value.role.push(item);
// } else if (item.type === 'user') {
// emitCheckedGroup.value.user.push(item);
// }
// });
// // 发送到表单数据
// tree_select_value.value = [].concat(...Object.values(emitCheckedGroup.value));
// }
// // 获取宽度处理成员角色值可能太长显示问题
// nextTick(() => {
// maxWidth.value = $('.select-tree-box').width();
// })
});
const mountedLogic = async () => {
await nextTick();
// TAG: 获取后台数据
const flowDeptList = await getFlowDeptListAPI({ form_code: $route.query.code });
if (flowDeptList.code) {
......@@ -373,13 +411,17 @@ onMounted(async () => {
nextTick(() => {
maxWidth.value = $('.select-tree-box').width();
})
});
};
const openTree = () => { // 点击组件展示框回调
const openTree = async () => { // 点击组件展示框回调
if (props.component_props.readonly) return false; // 只读判断
// 打开弹窗
showPopover.value = true;
if (!role_list.length) {
await mountedLogic();
}
// 获取数据
nextTick(() => {
// 动态判断点击显示的tab,默认点击第一个
......@@ -394,7 +436,6 @@ const openTree = () => { // 点击组件展示框回调
if (!$('#deptTree').find('.tree-placeholder').length) {
$('#deptTree').find('.ctree-tree__block-area').append('<div class="tree-placeholder" style="height: 10vh;"></div>');
}
});
}
/**
......
......@@ -2,7 +2,7 @@
* @Author: hookehuyr hookehuyr@gmail.com
* @Date: 2022-05-28 10:17:40
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2024-08-12 12:37:11
* @LastEditTime: 2024-11-25 15:56:19
* @FilePath: /data-table/src/utils/axios.js
* @Description:
*/
......@@ -17,6 +17,112 @@ axios.defaults.params = {
f: 'custom_form',
};
//去重缓存数据
const onlyDataCache = {
// 缓存列表
list: [],
// 根据请求的信息(请求方式,url,请求get/post数据),产生map的key
getRequestKey(config) {
const fullPath = config.headers["full-path"];
const { method, url, params, data } = config;
var key = [method, url].join("&");
if (fullPath) {
key = [method, url, stringify(params), stringify(data)].join("&");
}
return key;
},
query() {
console.log("onlyData=" + JSON.stringify(this.list));
},
add(config, cancel) {
var key = this.getRequestKey(config);
//console.log("onlyData add key=" + key);
var index = this.list.findIndex(t => t.key === key);
if (index > -1) {
this.list[index].cancel();
this.list[index].cancel = cancel;
} else {
// 添加到缓存列表中
this.list.push({ key, cancel });
}
},
delete(config) {
var targetKey = this.getRequestKey(config);
//console.log("onlyData delete key=" + targetKey);
if (targetKey) {
this.list.forEach((item, index) => {
if (item.key === targetKey) {
item.cancel();
this.list.splice(index, 1);
}
});
}
},
deleteAll() {
this.list.forEach((item, index) => {
item.cancel();
this.list.splice(index, 1);
});
}
};
// 持久化缓存数据
const keepDataCache = {
// 缓存列表
list: [],
// 最大缓存数
MAX_NUM: 100,
// 最大缓存时间
EXPIRED_TIME: 60000,
// 根据请求的信息(请求方式,url,请求get/post数据),产生map的key
getRequestKey(config) {
const { method, url, params, data } = config;
const key = [method, url, JSON.stringify(params), JSON.stringify(data)].join("&");
return key;
},
query() {
console.log("keepData=" + JSON.stringify(this.list));
},
// 添加缓存结果
add({ config, data }) {
if (config.data) config.data = JSON.parse(config.data);
var key = this.getRequestKey(config);
// console.log("keepData add key=" + key);
var index = this.list.findIndex(t => t.key === key);
if (index > -1) {
// 保存请求结果
this.list[index].data = data;
} else {
// 添加到缓存列表中
this.list.push({ time: Date.now(), key, data });
}
},
// 查找缓存结果
find(config) {
// 根据请求信息生成key
var key = this.getRequestKey(config);
// console.log("keepData find key=" + key);
var index = this.list.findIndex(t => t.key === key);
// 判断缓存当中是否有该请求结果
if (index > -1) {
let data = this.list[index];
// 判断是否超出了最大缓存时间
if (Date.now() - data.time > this.EXPIRED_TIME) {
// 清除该缓存
this.list.splice(index, 1);
} else {
// 返回缓存
return data;
}
}
// 判断是否超出了最大缓存数量
if (this.list.length === this.MAX_NUM) {
this.list.shift();
}
// 返回undefined,让请求拦截不执行config.adapter
return undefined;
}
};
/**
* @description 请求拦截器
*/
......@@ -30,8 +136,53 @@ axios.interceptors.request.use(
* 序列化POST请求时需要屏蔽上传相关接口,上传相关接口序列化后报错
*/
// config.data = config.method === 'post' && !strExist(['a=upload', 'upload.qiniup.com'], config.url) ? qs.stringify(config.data) : config.data;
// config.params.headers 合并到 config.headers 里面, 适配去重配置
if (config.params.headers) {
config.headers = { ...config.headers, ...config.params.headers };
delete config.params.headers;
}
// 绑定默认请求头
config.params = { ...config.params, timestamp }
// config.params = { ...config.params, timestamp };
// TAG:请求去重和持久化缓存
if (config.headers) {
//判断是否需要去重
const onlyData = config.headers["only-data"];
if (onlyData) {
//console.log("删除接口onlyData缓存数据!");
onlyDataCache.delete(config);
config.cancelToken = new axios.CancelToken(cancel => {
//console.log("保存接口onlyData缓存数据!");
onlyDataCache.add(config, cancel);
});
}
//判断是否需要持久化,并判断是否有缓存数据
const keepData = config.headers["keep-data"];
if (keepData) {
// console.log("加载接口keepData缓存数据!");
var cacheData = keepDataCache.find(config);
// 查看缓存当中有没有
if (cacheData) {
// console.log("加载成功过,keepData有缓冲数据!");
// 通过config.adapter,允许自定义处理请求
config.adapter = function (config) {
return new Promise(resolve => {
const res = {
status: 200,
statusText: "",
headers: { "content-type": "text/html; charset=UTF-8" },
config,
request: {}
};
resolve({ ...res, data: cacheData.data });
});
};
}
}
}
return config;
},
error => {
......@@ -56,10 +207,39 @@ axios.interceptors.response.use(
}
})
}
// TAG:请求持久化缓存
const config = response.config;
if (response) {
const keepData = config.headers["keep-data"];
if (keepData) {
if (response.status === 200 && response.data.code === 1) {
if (
response.headers["content-type"] &&
response.headers["content-type"].indexOf("text/html; charset=UTF-8") >=
0 &&
response.request.responseType != "blob"
) {
// console.log("保存接口keepData缓存数据!");
//缓存结果到缓存中
keepDataCache.add(response);
}
}
}
}
return response;
},
error => {
// TAG: 处理请求去重
if (axios.isCancel(error)) { // 取消请求的情况下,终端Promise调用链
return new Promise(() => {
console.error('取消请求响应', error);
return false;
});
} else { // 其他的错误处理
return Promise.reject(error);
}
});
export default axios;
......