252 lines
6.4 KiB
JavaScript
252 lines
6.4 KiB
JavaScript
/**
|
||
* 数据管理 Mixin
|
||
* 提供通用的数据获取、分页加载功能
|
||
* 支持多种数据格式和灵活的配置
|
||
*/
|
||
export const dataManagerMixin = {
|
||
data() {
|
||
return {
|
||
// 数据数组
|
||
dataList: [],
|
||
// 加载状态
|
||
loading: false,
|
||
// 分页参数
|
||
pageNum: 1,
|
||
pageSize: 20,
|
||
hasMore: true,
|
||
// 总数据量
|
||
total: 0,
|
||
// 当前查询参数
|
||
currentParams: {},
|
||
};
|
||
},
|
||
|
||
methods: {
|
||
/**
|
||
* 获取数据
|
||
* @param {Object} options 配置选项
|
||
* @param {boolean} options.isLoadMore 是否为加载更多
|
||
* @param {Function} options.apiCall API调用函数
|
||
* @param {Function} options.dataTransformer 数据转换函数
|
||
* @param {Object} options.params 查询参数
|
||
* @param {string} options.dataPath 数据路径,如 'data.list.rows'
|
||
* @param {string} options.totalPath 总数路径,如 'data.total'
|
||
* @param {Function} options.onSuccess 成功回调
|
||
* @param {Function} options.onError 错误回调
|
||
* @param {boolean} options.showLoading 是否显示loading
|
||
* @param {boolean} options.showError 是否显示错误提示
|
||
*/
|
||
async fetchData(options = {}) {
|
||
console.log("@@@@@@@@@@@@@@@@@", options);
|
||
const {
|
||
isLoadMore = false,
|
||
apiCall,
|
||
dataTransformer,
|
||
dataPath = "rows",
|
||
totalPath = "total",
|
||
onSuccess,
|
||
onError,
|
||
showLoading = true,
|
||
showError = true,
|
||
params = {},
|
||
} = options;
|
||
|
||
if (!apiCall) {
|
||
console.error("fetchData: apiCall 是必需的");
|
||
return;
|
||
}
|
||
|
||
// 设置loading状态
|
||
if (showLoading) {
|
||
this.loading = true;
|
||
}
|
||
|
||
try {
|
||
console.log("isLoadMore", isLoadMore);
|
||
// 更新页码
|
||
if (isLoadMore) {
|
||
this.pageNum++;
|
||
console.log("this.pageNum", this.pageNum);
|
||
} else {
|
||
this.pageNum = 1;
|
||
}
|
||
|
||
// 构建请求参数
|
||
const requestParams = {
|
||
// ...this.currentParams,
|
||
...params,
|
||
pageNum: this.pageNum,
|
||
pageSize: this.pageSize,
|
||
};
|
||
console.log("requestParams", requestParams);
|
||
// 调用API
|
||
const response = await apiCall(requestParams);
|
||
|
||
console.log("API响应:", response);
|
||
console.log("数据路径:", dataPath);
|
||
console.log("总数路径:", totalPath);
|
||
|
||
if (response.code === 200) {
|
||
// 根据路径获取数据
|
||
const dataArray = this.getNestedValue(response, dataPath) || [];
|
||
const total = this.getNestedValue(response, totalPath) || 0;
|
||
|
||
console.log("提取的数据数组:", dataArray);
|
||
console.log("总数:", total);
|
||
|
||
// 转换数据
|
||
const newData = dataTransformer
|
||
? dataTransformer(dataArray)
|
||
: dataArray;
|
||
|
||
console.log("转换后的数据:", newData);
|
||
|
||
// 更新数据
|
||
if (isLoadMore) {
|
||
this.dataList = [...this.dataList, ...newData];
|
||
} else {
|
||
this.dataList = newData;
|
||
}
|
||
|
||
console.log("更新后的 dataList:", this.dataList);
|
||
|
||
// 更新状态
|
||
this.total = total;
|
||
|
||
this.currentParams = { ...requestParams };
|
||
console.log("@@@hasMore", this.hasMore);
|
||
this.hasMore =
|
||
this.pageSize * this.currentParams.pageNum < this.total;
|
||
|
||
console.log("this.hasMore", this.hasMore);
|
||
console.log("this.total", this.total);
|
||
console.log("this.pageSize", this.pageSize);
|
||
console.log("this.currentParams.pageNum", this.currentParams.pageNum);
|
||
|
||
// 成功回调
|
||
if (onSuccess) {
|
||
onSuccess(newData, response);
|
||
}
|
||
} else {
|
||
const errorMsg = response.msg || "获取数据失败";
|
||
if (showError) {
|
||
uni.showToast({
|
||
title: errorMsg,
|
||
icon: "none",
|
||
});
|
||
}
|
||
if (onError) {
|
||
onError(errorMsg, response);
|
||
}
|
||
}
|
||
} catch (error) {
|
||
console.error("获取数据失败:", error);
|
||
const errorMsg = "网络错误";
|
||
if (showError) {
|
||
uni.showToast({
|
||
title: errorMsg,
|
||
icon: "none",
|
||
});
|
||
}
|
||
if (onError) {
|
||
onError(errorMsg, error);
|
||
}
|
||
} finally {
|
||
if (showLoading) {
|
||
this.loading = false;
|
||
}
|
||
}
|
||
},
|
||
|
||
/**
|
||
* 刷新数据
|
||
* @param {Object} options 配置选项
|
||
*/
|
||
refreshData(options = {}) {
|
||
return this.fetchData({
|
||
isLoadMore: false,
|
||
...options,
|
||
});
|
||
},
|
||
|
||
/**
|
||
* 加载更多数据
|
||
* @param {Object} options 配置选项
|
||
*/
|
||
loadMoreData(options = {}) {
|
||
if (this.hasMore && !this.loading) {
|
||
return this.fetchData({
|
||
isLoadMore: true,
|
||
...options,
|
||
});
|
||
}
|
||
},
|
||
|
||
/**
|
||
* 搜索数据
|
||
* @param {Object} searchParams 搜索参数
|
||
* @param {Object} options 配置选项
|
||
*/
|
||
searchData(searchParams = {}, options = {}) {
|
||
console.log("@@@@@@@@@@@", searchParams);
|
||
console.log("@@@@@@@@@@@", options);
|
||
|
||
return this.fetchData({
|
||
// isLoadMore: false,
|
||
|
||
...options,
|
||
params: searchParams,
|
||
});
|
||
},
|
||
|
||
/**
|
||
* 重置分页状态
|
||
*/
|
||
resetPagination() {
|
||
this.pageNum = 1;
|
||
this.hasMore = true; //可能就单页
|
||
this.dataList = [];
|
||
this.total = 0;
|
||
this.currentParams = {};
|
||
},
|
||
|
||
/**
|
||
* 获取嵌套对象的值
|
||
* @param {Object} obj 对象
|
||
* @param {string} path 路径,如 'data.list.rows'
|
||
* @returns {*} 值
|
||
*/
|
||
getNestedValue(obj, path) {
|
||
if (!path) return obj;
|
||
return path.split(".").reduce((current, key) => {
|
||
return current && current[key] !== undefined ? current[key] : null;
|
||
}, obj);
|
||
},
|
||
|
||
/**
|
||
* 设置分页大小
|
||
* @param {number} pageSize 分页大小
|
||
*/
|
||
setPageSize(pageSize) {
|
||
this.pageSize = pageSize;
|
||
this.resetPagination();
|
||
},
|
||
|
||
/**
|
||
* 获取当前数据状态
|
||
* @returns {Object} 数据状态
|
||
*/
|
||
getDataState() {
|
||
return {
|
||
dataList: this.dataList,
|
||
loading: this.loading,
|
||
pageNum: this.pageNum,
|
||
pageSize: this.pageSize,
|
||
hasMore: this.hasMore,
|
||
total: this.total,
|
||
currentParams: this.currentParams,
|
||
};
|
||
},
|
||
},
|
||
};
|