save code
This commit is contained in:
@@ -0,0 +1,173 @@
|
||||
import { useState, useEffect, useCallback } from 'react';
|
||||
import { useAuth } from '../contexts/AuthContext';
|
||||
|
||||
export const useApi = (apiFunc) => {
|
||||
const [data, setData] = useState(null);
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [error, setError] = useState(null);
|
||||
|
||||
const execute = useCallback(
|
||||
async (...args) => {
|
||||
try {
|
||||
setLoading(true);
|
||||
setError(null);
|
||||
const result = await apiFunc(...args);
|
||||
setData(result);
|
||||
return result;
|
||||
} catch (err) {
|
||||
setError(err);
|
||||
throw err;
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
},
|
||||
[apiFunc]
|
||||
);
|
||||
|
||||
return { data, loading, error, execute };
|
||||
};
|
||||
|
||||
export const useList = (apiFunc, defaultParams = {}) => {
|
||||
const [list, setList] = useState([]);
|
||||
const [total, setTotal] = useState(0);
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [pagination, setPagination] = useState({
|
||||
current: 1,
|
||||
pageSize: 10,
|
||||
});
|
||||
|
||||
const fetchList = useCallback(
|
||||
async (params = {}) => {
|
||||
try {
|
||||
setLoading(true);
|
||||
const mergedParams = { ...defaultParams, ...params };
|
||||
const result = await apiFunc(mergedParams);
|
||||
|
||||
setList(result.items || []);
|
||||
setTotal(result.total || 0);
|
||||
setPagination({
|
||||
current: result.page || 1,
|
||||
pageSize: result.page_size || 10,
|
||||
});
|
||||
|
||||
return result;
|
||||
} catch (error) {
|
||||
console.error('Fetch list error:', error);
|
||||
throw error;
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
},
|
||||
[apiFunc, defaultParams]
|
||||
);
|
||||
|
||||
const handleTableChange = useCallback((newPagination, filters, sorter) => {
|
||||
setPagination(newPagination);
|
||||
|
||||
const sortParams = sorter.field
|
||||
? {
|
||||
sort_by: sorter.field,
|
||||
sort_order: sorter.order === 'ascend' ? 'asc' : 'desc',
|
||||
}
|
||||
: {};
|
||||
|
||||
fetchList({
|
||||
page: newPagination.current,
|
||||
page_size: newPagination.pageSize,
|
||||
...sortParams,
|
||||
});
|
||||
}, [fetchList]);
|
||||
|
||||
const refresh = useCallback(() => {
|
||||
fetchList({
|
||||
page: pagination.current,
|
||||
page_size: pagination.pageSize,
|
||||
});
|
||||
}, [fetchList, pagination.current, pagination.pageSize]);
|
||||
|
||||
return {
|
||||
list,
|
||||
total,
|
||||
loading,
|
||||
pagination,
|
||||
fetchList,
|
||||
handleTableChange,
|
||||
refresh,
|
||||
};
|
||||
};
|
||||
|
||||
export const useCreate = (apiFunc, onSuccess) => {
|
||||
const [loading, setLoading] = useState(false);
|
||||
|
||||
const create = useCallback(
|
||||
async (data) => {
|
||||
try {
|
||||
setLoading(true);
|
||||
await apiFunc(data);
|
||||
if (onSuccess) {
|
||||
onSuccess();
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Create error:', error);
|
||||
throw error;
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
},
|
||||
[apiFunc, onSuccess]
|
||||
);
|
||||
|
||||
return { create, loading };
|
||||
};
|
||||
|
||||
export const useUpdate = (apiFunc, onSuccess) => {
|
||||
const [loading, setLoading] = useState(false);
|
||||
|
||||
const update = useCallback(
|
||||
async (id, data) => {
|
||||
try {
|
||||
setLoading(true);
|
||||
await apiFunc(id, data);
|
||||
if (onSuccess) {
|
||||
onSuccess();
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Update error:', error);
|
||||
throw error;
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
},
|
||||
[apiFunc, onSuccess]
|
||||
);
|
||||
|
||||
return { update, loading };
|
||||
};
|
||||
|
||||
export const useDelete = (apiFunc, onSuccess) => {
|
||||
const [loading, setLoading] = useState(false);
|
||||
|
||||
const handleDelete = useCallback(
|
||||
async (id, options = {}) => {
|
||||
const { title = '确认删除', content = '确定要删除吗?此操作不可恢复。' } = options;
|
||||
|
||||
if (window.confirm(`${title}\n${content}`)) {
|
||||
try {
|
||||
setLoading(true);
|
||||
await apiFunc(id);
|
||||
if (onSuccess) {
|
||||
onSuccess();
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Delete error:', error);
|
||||
throw error;
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
}
|
||||
},
|
||||
[apiFunc, onSuccess]
|
||||
);
|
||||
|
||||
return { handleDelete, loading };
|
||||
};
|
||||
@@ -0,0 +1,40 @@
|
||||
import { useState, useEffect } from 'react';
|
||||
|
||||
export const useDebounce = (value, delay = 300) => {
|
||||
const [debouncedValue, setDebouncedValue] = useState(value);
|
||||
|
||||
useEffect(() => {
|
||||
const timer = setTimeout(() => {
|
||||
setDebouncedValue(value);
|
||||
}, delay);
|
||||
|
||||
return () => {
|
||||
clearTimeout(timer);
|
||||
};
|
||||
}, [value, delay]);
|
||||
|
||||
return debouncedValue;
|
||||
};
|
||||
|
||||
export const useLocalStorage = (key, initialValue) => {
|
||||
const [storedValue, setStoredValue] = useState(() => {
|
||||
try {
|
||||
const item = window.localStorage.getItem(key);
|
||||
return item ? JSON.parse(item) : initialValue;
|
||||
} catch (error) {
|
||||
console.error(`Error reading localStorage key "${key}":`, error);
|
||||
return initialValue;
|
||||
}
|
||||
});
|
||||
|
||||
const setValue = (value) => {
|
||||
try {
|
||||
setStoredValue(value);
|
||||
window.localStorage.setItem(key, JSON.stringify(value));
|
||||
} catch (error) {
|
||||
console.error(`Error setting localStorage key "${key}":`, error);
|
||||
}
|
||||
};
|
||||
|
||||
return [storedValue, setValue];
|
||||
};
|
||||
Reference in New Issue
Block a user