192 lines
6.0 KiB
JavaScript
192 lines
6.0 KiB
JavaScript
import { useMemo, useState } from "react";
|
|
import { parseForm } from "@/shared/forms/validation";
|
|
import { usePaginatedQuery } from "@/shared/hooks/usePaginatedQuery.js";
|
|
import { useRegionOptions } from "@/shared/hooks/useRegionOptions.js";
|
|
import { createManager, listManagers, updateManager } from "@/features/host-org/api";
|
|
import { useBDAbilities } from "@/features/host-org/permissions.js";
|
|
import { createManagerSchema } from "@/features/host-org/schema";
|
|
import { useToast } from "@/shared/ui/ToastProvider.jsx";
|
|
|
|
const pageSize = 50;
|
|
const emptyData = { items: [], page: 1, pageSize, total: 0 };
|
|
export const managerPermissionFields = [
|
|
"canGrantAvatarFrame",
|
|
"canGrantVehicle",
|
|
"canGrantBadge",
|
|
"canUpdateUserLevel",
|
|
"canAddBdLeader",
|
|
"canAddAdmin",
|
|
"canAddSuperadmin",
|
|
"canBlockUser",
|
|
"canTransferUserCountry",
|
|
];
|
|
|
|
const emptyPermissions = () => Object.fromEntries(managerPermissionFields.map((field) => [field, true]));
|
|
|
|
const emptyManagerForm = () => ({ contact: "", targetUserId: "", ...emptyPermissions() });
|
|
|
|
const managerPermissionPayload = (form) =>
|
|
Object.fromEntries(managerPermissionFields.map((field) => [field, form[field] !== false]));
|
|
|
|
const managerStatusPayload = (item, status) => ({
|
|
contact: item?.contact || "",
|
|
status,
|
|
...Object.fromEntries(managerPermissionFields.map((field) => [field, item?.[field] !== false])),
|
|
});
|
|
|
|
const managerFormFromItem = (item) => ({
|
|
contact: item?.contact || "",
|
|
targetUserId: String(item?.userId || ""),
|
|
...Object.fromEntries(managerPermissionFields.map((field) => [field, item?.[field] !== false])),
|
|
});
|
|
|
|
export function useHostManagersPage() {
|
|
const abilities = useBDAbilities();
|
|
const { showToast } = useToast();
|
|
const { loadingRegions, regionOptions } = useRegionOptions();
|
|
const [activeAction, setActiveAction] = useState("");
|
|
const [editingManager, setEditingManager] = useState(null);
|
|
const [loadingAction, setLoadingAction] = useState("");
|
|
const [managerForm, setManagerForm] = useState(emptyManagerForm);
|
|
const [query, setQuery] = useState("");
|
|
const [status, setStatus] = useState("");
|
|
const [regionId, setRegionId] = useState("");
|
|
const [page, setPage] = useState(1);
|
|
const filters = useMemo(
|
|
() => ({
|
|
keyword: query,
|
|
region_id: regionId,
|
|
status,
|
|
}),
|
|
[query, regionId, status],
|
|
);
|
|
const {
|
|
data = emptyData,
|
|
error,
|
|
loading,
|
|
reload,
|
|
} = usePaginatedQuery({
|
|
errorMessage: "加载经理列表失败",
|
|
fetcher: listManagers,
|
|
filters,
|
|
page,
|
|
pageSize,
|
|
queryKey: ["host-org", "managers", filters, page],
|
|
});
|
|
|
|
const changeQuery = (value) => {
|
|
setQuery(value);
|
|
setPage(1);
|
|
};
|
|
|
|
const changeStatus = (value) => {
|
|
setStatus(value);
|
|
setPage(1);
|
|
};
|
|
|
|
const changeRegionId = (value) => {
|
|
setRegionId(value);
|
|
setPage(1);
|
|
};
|
|
|
|
const resetFilters = () => {
|
|
setQuery("");
|
|
setStatus("");
|
|
setRegionId("");
|
|
setPage(1);
|
|
};
|
|
|
|
const submitManager = async (event) => {
|
|
event.preventDefault();
|
|
const isEdit = activeAction === "manager-edit" && editingManager?.userId;
|
|
setLoadingAction(isEdit ? "manager-update" : "manager-create");
|
|
try {
|
|
const payload = parseForm(createManagerSchema, managerForm);
|
|
if (isEdit) {
|
|
await updateManager(editingManager.userId, {
|
|
contact: payload.contact,
|
|
...managerPermissionPayload(payload),
|
|
});
|
|
showToast("经理权限已更新", "success");
|
|
} else {
|
|
await createManager({
|
|
contact: payload.contact,
|
|
targetUserId: payload.targetUserId,
|
|
...managerPermissionPayload(payload),
|
|
});
|
|
showToast("经理已添加", "success");
|
|
}
|
|
setManagerForm(emptyManagerForm());
|
|
setActiveAction("");
|
|
setEditingManager(null);
|
|
await reload();
|
|
} catch (err) {
|
|
showToast(err.message || (isEdit ? "更新经理权限失败" : "添加经理失败"), "error");
|
|
} finally {
|
|
setLoadingAction("");
|
|
}
|
|
};
|
|
|
|
const closeAction = () => {
|
|
setActiveAction("");
|
|
setEditingManager(null);
|
|
setManagerForm(emptyManagerForm());
|
|
};
|
|
|
|
const openManagerForm = () => {
|
|
setEditingManager(null);
|
|
setManagerForm(emptyManagerForm());
|
|
setActiveAction("manager");
|
|
};
|
|
|
|
const openManagerEdit = (item) => {
|
|
setEditingManager(item);
|
|
setManagerForm(managerFormFromItem(item));
|
|
setActiveAction("manager-edit");
|
|
};
|
|
|
|
const toggleManager = async (item, enabled) => {
|
|
const nextStatus = enabled ? "active" : "disabled";
|
|
setLoadingAction(`manager-status-${item.userId}`);
|
|
try {
|
|
// 状态接口复用经理更新入口;提交当前行的权限快照,避免只改状态时把已有权限开关覆盖成后端默认值。
|
|
await updateManager(item.userId, managerStatusPayload(item, nextStatus));
|
|
showToast(enabled ? "经理已启用" : "经理已停用", "success");
|
|
await reload();
|
|
} catch (err) {
|
|
showToast(err.message || (enabled ? "启用经理失败" : "停用经理失败"), "error");
|
|
} finally {
|
|
setLoadingAction("");
|
|
}
|
|
};
|
|
|
|
return {
|
|
abilities,
|
|
activeAction,
|
|
changeQuery,
|
|
changeRegionId,
|
|
changeStatus,
|
|
closeAction,
|
|
data,
|
|
editingManager,
|
|
error,
|
|
loadingAction,
|
|
loading,
|
|
loadingRegions,
|
|
managerForm,
|
|
openManagerEdit,
|
|
openManagerForm,
|
|
page,
|
|
query,
|
|
regionId,
|
|
regionOptions,
|
|
reload,
|
|
resetFilters,
|
|
setManagerForm,
|
|
setPage,
|
|
status,
|
|
submitManager,
|
|
toggleManager,
|
|
};
|
|
}
|