259 lines
6.4 KiB
JavaScript
259 lines
6.4 KiB
JavaScript
|
|
import { useState, useEffect } from 'react';
|
||
|
|
import { useTranslation } from 'react-i18next';
|
||
|
|
import { API, showError, showSuccess } from '../../helpers';
|
||
|
|
import { ITEMS_PER_PAGE } from '../../constants';
|
||
|
|
import { useTableCompactMode } from '../common/useTableCompactMode';
|
||
|
|
|
||
|
|
export const useUsersData = () => {
|
||
|
|
const { t } = useTranslation();
|
||
|
|
const [compactMode, setCompactMode] = useTableCompactMode('users');
|
||
|
|
|
||
|
|
// State management
|
||
|
|
const [users, setUsers] = useState([]);
|
||
|
|
const [loading, setLoading] = useState(true);
|
||
|
|
const [activePage, setActivePage] = useState(1);
|
||
|
|
const [pageSize, setPageSize] = useState(ITEMS_PER_PAGE);
|
||
|
|
const [searching, setSearching] = useState(false);
|
||
|
|
const [groupOptions, setGroupOptions] = useState([]);
|
||
|
|
const [userCount, setUserCount] = useState(ITEMS_PER_PAGE);
|
||
|
|
|
||
|
|
// Modal states
|
||
|
|
const [showAddUser, setShowAddUser] = useState(false);
|
||
|
|
const [showEditUser, setShowEditUser] = useState(false);
|
||
|
|
const [editingUser, setEditingUser] = useState({
|
||
|
|
id: undefined,
|
||
|
|
});
|
||
|
|
|
||
|
|
// Form initial values
|
||
|
|
const formInitValues = {
|
||
|
|
searchKeyword: '',
|
||
|
|
searchGroup: '',
|
||
|
|
};
|
||
|
|
|
||
|
|
// Form API reference
|
||
|
|
const [formApi, setFormApi] = useState(null);
|
||
|
|
|
||
|
|
// Get form values helper function
|
||
|
|
const getFormValues = () => {
|
||
|
|
const formValues = formApi ? formApi.getValues() : {};
|
||
|
|
return {
|
||
|
|
searchKeyword: formValues.searchKeyword || '',
|
||
|
|
searchGroup: formValues.searchGroup || '',
|
||
|
|
};
|
||
|
|
};
|
||
|
|
|
||
|
|
// Set user format with key field
|
||
|
|
const setUserFormat = (users) => {
|
||
|
|
for (let i = 0; i < users.length; i++) {
|
||
|
|
users[i].key = users[i].id;
|
||
|
|
}
|
||
|
|
setUsers(users);
|
||
|
|
};
|
||
|
|
|
||
|
|
// Load users data
|
||
|
|
const loadUsers = async (startIdx, pageSize) => {
|
||
|
|
const res = await API.get(`/api/user/?p=${startIdx}&page_size=${pageSize}`);
|
||
|
|
const { success, message, data } = res.data;
|
||
|
|
if (success) {
|
||
|
|
const newPageData = data.items;
|
||
|
|
setActivePage(data.page);
|
||
|
|
setUserCount(data.total);
|
||
|
|
setUserFormat(newPageData);
|
||
|
|
} else {
|
||
|
|
showError(message);
|
||
|
|
}
|
||
|
|
setLoading(false);
|
||
|
|
};
|
||
|
|
|
||
|
|
// Search users with keyword and group
|
||
|
|
const searchUsers = async (
|
||
|
|
startIdx,
|
||
|
|
pageSize,
|
||
|
|
searchKeyword = null,
|
||
|
|
searchGroup = null,
|
||
|
|
) => {
|
||
|
|
// If no parameters passed, get values from form
|
||
|
|
if (searchKeyword === null || searchGroup === null) {
|
||
|
|
const formValues = getFormValues();
|
||
|
|
searchKeyword = formValues.searchKeyword;
|
||
|
|
searchGroup = formValues.searchGroup;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (searchKeyword === '' && searchGroup === '') {
|
||
|
|
// If keyword is blank, load files instead
|
||
|
|
await loadUsers(startIdx, pageSize);
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
setSearching(true);
|
||
|
|
const res = await API.get(
|
||
|
|
`/api/user/search?keyword=${searchKeyword}&group=${searchGroup}&p=${startIdx}&page_size=${pageSize}`,
|
||
|
|
);
|
||
|
|
const { success, message, data } = res.data;
|
||
|
|
if (success) {
|
||
|
|
const newPageData = data.items;
|
||
|
|
setActivePage(data.page);
|
||
|
|
setUserCount(data.total);
|
||
|
|
setUserFormat(newPageData);
|
||
|
|
} else {
|
||
|
|
showError(message);
|
||
|
|
}
|
||
|
|
setSearching(false);
|
||
|
|
};
|
||
|
|
|
||
|
|
// Manage user operations (promote, demote, enable, disable, delete)
|
||
|
|
const manageUser = async (userId, action, record) => {
|
||
|
|
const res = await API.post('/api/user/manage', {
|
||
|
|
id: userId,
|
||
|
|
action,
|
||
|
|
});
|
||
|
|
const { success, message } = res.data;
|
||
|
|
if (success) {
|
||
|
|
showSuccess('操作成功完成!');
|
||
|
|
let user = res.data.data;
|
||
|
|
let newUsers = [...users];
|
||
|
|
if (action === 'delete') {
|
||
|
|
// Mark as deleted
|
||
|
|
const index = newUsers.findIndex(u => u.id === userId);
|
||
|
|
if (index > -1) {
|
||
|
|
newUsers[index].DeletedAt = new Date();
|
||
|
|
}
|
||
|
|
} else {
|
||
|
|
// Update status and role
|
||
|
|
record.status = user.status;
|
||
|
|
record.role = user.role;
|
||
|
|
}
|
||
|
|
setUsers(newUsers);
|
||
|
|
} else {
|
||
|
|
showError(message);
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
// Handle page change
|
||
|
|
const handlePageChange = (page) => {
|
||
|
|
setActivePage(page);
|
||
|
|
const { searchKeyword, searchGroup } = getFormValues();
|
||
|
|
if (searchKeyword === '' && searchGroup === '') {
|
||
|
|
loadUsers(page, pageSize).then();
|
||
|
|
} else {
|
||
|
|
searchUsers(page, pageSize, searchKeyword, searchGroup).then();
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
// Handle page size change
|
||
|
|
const handlePageSizeChange = async (size) => {
|
||
|
|
localStorage.setItem('page-size', size + '');
|
||
|
|
setPageSize(size);
|
||
|
|
setActivePage(1);
|
||
|
|
loadUsers(activePage, size)
|
||
|
|
.then()
|
||
|
|
.catch((reason) => {
|
||
|
|
showError(reason);
|
||
|
|
});
|
||
|
|
};
|
||
|
|
|
||
|
|
// Handle table row styling for disabled/deleted users
|
||
|
|
const handleRow = (record, index) => {
|
||
|
|
if (record.DeletedAt !== null || record.status !== 1) {
|
||
|
|
return {
|
||
|
|
style: {
|
||
|
|
background: 'var(--semi-color-disabled-border)',
|
||
|
|
},
|
||
|
|
};
|
||
|
|
} else {
|
||
|
|
return {};
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
// Refresh data
|
||
|
|
const refresh = async (page = activePage) => {
|
||
|
|
const { searchKeyword, searchGroup } = getFormValues();
|
||
|
|
if (searchKeyword === '' && searchGroup === '') {
|
||
|
|
await loadUsers(page, pageSize);
|
||
|
|
} else {
|
||
|
|
await searchUsers(page, pageSize, searchKeyword, searchGroup);
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
// Fetch groups data
|
||
|
|
const fetchGroups = async () => {
|
||
|
|
try {
|
||
|
|
let res = await API.get(`/api/group/`);
|
||
|
|
if (res === undefined) {
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
setGroupOptions(
|
||
|
|
res.data.data.map((group) => ({
|
||
|
|
label: group,
|
||
|
|
value: group,
|
||
|
|
})),
|
||
|
|
);
|
||
|
|
} catch (error) {
|
||
|
|
showError(error.message);
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
// Modal control functions
|
||
|
|
const closeAddUser = () => {
|
||
|
|
setShowAddUser(false);
|
||
|
|
};
|
||
|
|
|
||
|
|
const closeEditUser = () => {
|
||
|
|
setShowEditUser(false);
|
||
|
|
setEditingUser({
|
||
|
|
id: undefined,
|
||
|
|
});
|
||
|
|
};
|
||
|
|
|
||
|
|
// Initialize data on component mount
|
||
|
|
useEffect(() => {
|
||
|
|
loadUsers(0, pageSize)
|
||
|
|
.then()
|
||
|
|
.catch((reason) => {
|
||
|
|
showError(reason);
|
||
|
|
});
|
||
|
|
fetchGroups().then();
|
||
|
|
}, []);
|
||
|
|
|
||
|
|
return {
|
||
|
|
// Data state
|
||
|
|
users,
|
||
|
|
loading,
|
||
|
|
activePage,
|
||
|
|
pageSize,
|
||
|
|
userCount,
|
||
|
|
searching,
|
||
|
|
groupOptions,
|
||
|
|
|
||
|
|
// Modal state
|
||
|
|
showAddUser,
|
||
|
|
showEditUser,
|
||
|
|
editingUser,
|
||
|
|
setShowAddUser,
|
||
|
|
setShowEditUser,
|
||
|
|
setEditingUser,
|
||
|
|
|
||
|
|
// Form state
|
||
|
|
formInitValues,
|
||
|
|
formApi,
|
||
|
|
setFormApi,
|
||
|
|
|
||
|
|
// UI state
|
||
|
|
compactMode,
|
||
|
|
setCompactMode,
|
||
|
|
|
||
|
|
// Actions
|
||
|
|
loadUsers,
|
||
|
|
searchUsers,
|
||
|
|
manageUser,
|
||
|
|
handlePageChange,
|
||
|
|
handlePageSizeChange,
|
||
|
|
handleRow,
|
||
|
|
refresh,
|
||
|
|
closeAddUser,
|
||
|
|
closeEditUser,
|
||
|
|
getFormValues,
|
||
|
|
|
||
|
|
// Translation
|
||
|
|
t,
|
||
|
|
};
|
||
|
|
};
|