| | |
| | | import React from "react"; |
| | | import React, { useState } from "react"; |
| | | import { |
| | | BooleanInput, |
| | | FormDataConsumer, |
| | | NumberInput, |
| | | SelectInput, |
| | | TextInput, |
| | | useNotify, |
| | | } from "react-admin"; |
| | | import { Grid, Typography } from "@mui/material"; |
| | | import { Alert, Button, Grid, Stack, Typography } from "@mui/material"; |
| | | import StatusSelectInput from "@/page/components/StatusSelectInput"; |
| | | import { validateAiParamDraft } from "@/api/ai/configCenter"; |
| | | |
| | | const providerChoices = [ |
| | | { id: "OPENAI_COMPATIBLE", name: "OPENAI_COMPATIBLE" }, |
| | | ]; |
| | | |
| | | const AiParamValidateSection = ({ formData, readOnly }) => { |
| | | const notify = useNotify(); |
| | | const [loading, setLoading] = useState(false); |
| | | const [result, setResult] = useState(null); |
| | | |
| | | const handleValidate = async () => { |
| | | setLoading(true); |
| | | try { |
| | | const data = await validateAiParamDraft(formData); |
| | | setResult(data); |
| | | notify(data?.message || "AI 参数验证成功"); |
| | | } catch (error) { |
| | | const nextResult = { |
| | | status: "INVALID", |
| | | message: error?.message || "AI 参数验证失败", |
| | | }; |
| | | setResult(nextResult); |
| | | notify(nextResult.message, { type: "error" }); |
| | | } finally { |
| | | setLoading(false); |
| | | } |
| | | }; |
| | | |
| | | return ( |
| | | <> |
| | | {!readOnly && ( |
| | | <Grid item xs={12}> |
| | | <Stack direction="row" spacing={1} alignItems="center"> |
| | | <Button variant="outlined" onClick={handleValidate} disabled={loading}> |
| | | {loading ? "验证中..." : "保存前验证"} |
| | | </Button> |
| | | <Typography variant="body2" color="text.secondary"> |
| | | 会直接校验当前 Base URL、API Key 与模型是否可调用。 |
| | | </Typography> |
| | | </Stack> |
| | | </Grid> |
| | | )} |
| | | {result && ( |
| | | <Grid item xs={12}> |
| | | <Alert severity={result.status === "VALID" ? "success" : "error"}> |
| | | {result.message} |
| | | {result.elapsedMs ? ` · ${result.elapsedMs} ms` : ""} |
| | | {result.validatedAt ? ` · ${result.validatedAt}` : ""} |
| | | </Alert> |
| | | </Grid> |
| | | )} |
| | | </> |
| | | ); |
| | | }; |
| | | |
| | | const AiParamForm = ({ readOnly = false }) => ( |
| | | <Grid container spacing={2} width={{ xs: "100%", xl: "80%" }}> |
| | |
| | | <Grid item xs={12}> |
| | | <TextInput source="memo" label="备注" fullWidth multiline minRows={3} disabled={readOnly} /> |
| | | </Grid> |
| | | <FormDataConsumer> |
| | | {({ formData }) => <AiParamValidateSection formData={formData} readOnly={readOnly} />} |
| | | </FormDataConsumer> |
| | | <Grid item xs={12}> |
| | | <Typography variant="h6">运行与审计信息</Typography> |
| | | </Grid> |
| | | <Grid item xs={12} md={3}> |
| | | <TextInput source="validateStatus" label="最近校验状态" fullWidth disabled /> |
| | | </Grid> |
| | | <Grid item xs={12} md={3}> |
| | | <TextInput source="lastValidateElapsedMs" label="最近校验耗时(ms)" fullWidth disabled /> |
| | | </Grid> |
| | | <Grid item xs={12} md={3}> |
| | | <TextInput source="lastValidateTime$" label="最近校验时间" fullWidth disabled /> |
| | | </Grid> |
| | | <Grid item xs={12} md={3}> |
| | | <TextInput source="updateBy" label="最近更新人" fullWidth disabled /> |
| | | </Grid> |
| | | <Grid item xs={12}> |
| | | <TextInput source="lastValidateMessage" label="最近校验结果" fullWidth multiline minRows={3} disabled /> |
| | | </Grid> |
| | | <Grid item xs={12}> |
| | | <TextInput source="updateTime$" label="最近更新时间" fullWidth disabled /> |
| | | </Grid> |
| | | </Grid> |
| | | ); |
| | | |