2026-06-24 15:50:08 +08:00

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,
};
}