[fix]:[FL-153][系统参数状态交互对齐]

Co-authored-by: multica-agent <github@multica.ai>
This commit is contained in:
chengkai3
2026-06-20 11:09:19 +08:00
parent f8eef853a7
commit faa47e26cd
2 changed files with 69 additions and 17 deletions
+17
View File
@@ -374,3 +374,20 @@
- 风险与关注点:
- 改动仅影响 `/admin/syslog` 前端筛选交互、分页展示和空态文案,不改变 `/api/v1/admin/audit-logs` 字段或权限语义。
- 当前 dev 分支存在 unrelated `elevation-records` TypeScript 错误,会阻断全量 `tsc``next build`
## Follow-up - 系统参数状态修改交互对齐(FL-153)
- 背景:
- 复核指出系统参数页状态修改仍在编辑弹窗内完成,而用户管理页状态修改通过行内 Dropdown 独立完成。
- 本次处理:
- 系统参数编辑弹窗移除“状态”字段,编辑保存仅更新参数名称、参数值和说明。
- 表格行与移动卡片的更多菜单补齐“启用/禁用”独立操作,状态切换走单独 PATCH 请求和行级 loading。
- 新建参数仍默认创建为 `enabled`,保持原创建语义不变。
- 验证:
- 修改后:`npm --workspace web exec eslint src/app/admin/system-params/page.tsx --max-warnings=0` 通过。
- 修改后:`npm --workspace web exec tsc --noEmit` 通过。
- 风险与关注点:
- 改动仅影响系统参数页前端交互组织方式,不改变后端接口字段、权限码或参数状态语义。
+52 -17
View File
@@ -41,7 +41,6 @@ type FormState = {
param_name: string;
param_value: string;
description: string;
status: "enabled" | "disabled";
};
const EMPTY_FORM: FormState = {
@@ -49,14 +48,8 @@ const EMPTY_FORM: FormState = {
param_name: "",
param_value: "",
description: "",
status: "enabled",
};
const PARAM_STATUS_OPTIONS = [
{ label: "已启用", value: "enabled" },
{ label: "已禁用", value: "disabled" },
] as const satisfies ReadonlyArray<{ label: string; value: FormState["status"] }>;
const AntCard = Card as unknown as ComponentType<CardProps & RefAttributes<HTMLDivElement>>;
const PARAM_TABLE_MIN_SCROLL_Y = 180;
@@ -83,6 +76,7 @@ export default function AdminSystemParamsPage() {
const [error, setError] = useState("");
const [success, setSuccess] = useState("");
const [deletingId, setDeletingId] = useState<number | null>(null);
const [updatingStatusId, setUpdatingStatusId] = useState<number | null>(null);
const [pagination, setPagination] = useState({ current: 1, pageSize: 20 });
const [tableScrollY, setTableScrollY] = useState(PARAM_TABLE_MIN_SCROLL_Y);
const tableScrollAnchorRef = useRef<HTMLDivElement | null>(null);
@@ -167,7 +161,6 @@ export default function AdminSystemParamsPage() {
param_name: item.param_name,
param_value: item.param_value,
description: item.description ?? "",
status: item.status,
});
setEditorOpen(true);
}, [formApi]);
@@ -264,7 +257,7 @@ export default function AdminSystemParamsPage() {
param_name: values.param_name.trim(),
param_value: values.param_value,
description: values.description,
status: values.status,
status: "enabled",
}),
});
if (!response.ok) {
@@ -280,7 +273,6 @@ export default function AdminSystemParamsPage() {
param_name: values.param_name.trim(),
param_value: values.param_value,
description: values.description,
status: values.status,
}),
});
if (!response.ok) {
@@ -339,6 +331,39 @@ export default function AdminSystemParamsPage() {
}
}, [deleteMutation]);
const updateStatusMutation = useMutation({
mutationFn: async ({ item, status }: { item: SystemParamSummary; status: SystemParamSummary["status"] }) => {
const response = await fetchWithAuth(`/api/v1/admin/system-params/${item.id}`, {
method: "PATCH",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ status }),
});
if (!response.ok) {
throw new Error(await readApiError(response));
}
return status;
},
onMutate: ({ item }) => {
setUpdatingStatusId(item.id);
setError("");
setSuccess("");
},
onSuccess: async (status) => {
setSuccess(status === "enabled" ? "系统参数已启用" : "系统参数已禁用");
await refreshList();
},
onError: (candidate) => {
setSuccess("");
setError(candidate instanceof Error ? candidate.message : "更新系统参数状态失败");
},
onSettled: () => setUpdatingStatusId(null),
});
const toggleParamStatus = useCallback((item: SystemParamSummary) => {
const nextStatus: SystemParamSummary["status"] = item.status === "enabled" ? "disabled" : "enabled";
updateStatusMutation.mutate({ item, status: nextStatus });
}, [updateStatusMutation]);
const handleKeywordChange = (value: string) => {
setKeywordInput(value);
@@ -444,7 +469,8 @@ export default function AdminSystemParamsPage() {
const renderParamCard = (param: SystemParamSummary) => {
const deleteLoading = deletingId === param.id;
const rowBusy = deleteLoading;
const statusLoading = updatingStatusId === param.id;
const rowBusy = deleteLoading || statusLoading;
const moreMenuItems: MenuProps["items"] = [
{
@@ -456,6 +482,12 @@ export default function AdminSystemParamsPage() {
setSuccess(`已复制参数键: ${param.param_key}`);
},
},
{
key: "toggle-status",
label: param.status === "enabled" ? "禁用" : "启用",
disabled: rowBusy || !canManage,
onClick: () => toggleParamStatus(param),
},
{
key: "delete",
label: "删除",
@@ -591,7 +623,8 @@ export default function AdminSystemParamsPage() {
width: 180,
render: (_, record) => {
const deleteLoading = deletingId === record.id;
const rowBusy = deleteLoading;
const statusLoading = updatingStatusId === record.id;
const rowBusy = deleteLoading || statusLoading;
const moreMenuItems: MenuProps["items"] = [
{
@@ -603,6 +636,12 @@ export default function AdminSystemParamsPage() {
setSuccess(`已复制参数键: ${record.param_key}`);
},
},
{
key: "toggle-status",
label: record.status === "enabled" ? "禁用" : "启用",
disabled: rowBusy,
onClick: () => toggleParamStatus(record),
},
];
return (
@@ -633,7 +672,7 @@ export default function AdminSystemParamsPage() {
}
return baseColumns;
}, [canManage, deletingId, removeParam, startEdit]);
}, [canManage, deletingId, removeParam, startEdit, toggleParamStatus, updatingStatusId]);
const updateTableScrollY = useCallback(() => {
if (typeof window === "undefined") {
@@ -931,10 +970,6 @@ export default function AdminSystemParamsPage() {
>
<Input.TextArea rows={3} />
</Form.Item>
<Form.Item<FormState> label="状态" name="status">
<Select options={[...PARAM_STATUS_OPTIONS]} />
</Form.Item>
</div>
</Form>
</Modal>