From 51877df13075ad10ef51107f15bcd21f1661febe Mon Sep 17 00:00:00 2001
From: zhou zhou <3272660260@qq.com>
Date: 星期二, 17 三月 2026 09:48:01 +0800
Subject: [PATCH] #AI

---
 rsf-admin/src/page/system/aiParam/AiParamList.jsx |  165 +++++++++++++++++++++++++++++++++++++++---------------
 1 files changed, 118 insertions(+), 47 deletions(-)

diff --git a/rsf-admin/src/page/system/aiParam/AiParamList.jsx b/rsf-admin/src/page/system/aiParam/AiParamList.jsx
index 8f12399..41fb75c 100644
--- a/rsf-admin/src/page/system/aiParam/AiParamList.jsx
+++ b/rsf-admin/src/page/system/aiParam/AiParamList.jsx
@@ -1,42 +1,25 @@
 import React, { useState } from "react";
 import {
     List,
-    DatagridConfigurable,
     SearchInput,
     TopToolbar,
     SelectColumnsButton,
-    EditButton,
     FilterButton,
-    BulkDeleteButton,
-    WrapperField,
-    TextField,
-    NumberField,
-    DateField,
-    BooleanField,
     TextInput,
     DateInput,
     SelectInput,
+    useListContext,
+    Pagination,
+    EditButton,
     DeleteButton,
 } from 'react-admin';
-import { Box } from '@mui/material';
-import { styled } from '@mui/material/styles';
+import { Box, Chip, Grid, Stack, Typography } from '@mui/material';
 import EmptyData from "@/page/components/EmptyData";
 import MyCreateButton from "@/page/components/MyCreateButton";
 import MyExportButton from '@/page/components/MyExportButton';
 import { OPERATE_MODE, DEFAULT_PAGE_SIZE } from '@/config/setting';
 import AiParamCreate from "./AiParamCreate";
-
-const StyledDatagrid = styled(DatagridConfigurable)(({ theme }) => ({
-    '& .css-1vooibu-MuiSvgIcon-root': {
-        height: '.9em'
-    },
-    '& .RaDatagrid-row': {
-        cursor: 'auto'
-    },
-    '& .opt': {
-        width: 200
-    },
-}));
+import { AiConsoleLayout, AiConsolePanel, aiCardSx } from "@/page/components/AiConsoleLayout";
 
 const filters = [
     <SearchInput source="condition" alwaysOn />,
@@ -63,14 +46,123 @@
             { id: '0', name: 'common.enums.statusFalse' },
         ]}
     />,
-]
+];
+
+const providerLabel = (provider) => {
+    if (provider === 'openai') {
+        return 'OpenAI Compatible';
+    }
+    if (provider === 'mock') {
+        return 'Mock';
+    }
+    return provider || '鏈厤缃�';
+};
+
+const AiParamBoard = () => {
+    const { data, isLoading } = useListContext();
+    const records = data || [];
+    const enabledCount = records.filter((item) => item.status === 1).length;
+    const defaultCount = records.filter((item) => item.defaultFlag === 1).length;
+    const openaiCount = records.filter((item) => item.provider === 'openai').length;
+    const mockCount = records.filter((item) => item.provider === 'mock').length;
+
+    if (!isLoading && !records.length) {
+        return <EmptyData />;
+    }
+
+    return (
+        <AiConsoleLayout
+            title="AI鍙傛暟"
+            subtitle="淇濇寔褰撳墠绯荤粺鍚庡彴鐨勭櫧搴曞崱鐗囧拰杞昏竟妗嗛鏍硷紝鐢ㄥ崱鐗囨柟寮忓睍绀烘ā鍨嬮厤缃鍐碉紝鏂逛究鍜屽叾浠� AI 椤甸潰缁熶竴鏌ョ湅銆�"
+            stats={[
+                { label: '鍙傛暟鎬绘暟', value: records.length },
+                { label: '鍚敤', value: enabledCount },
+                { label: '榛樿妯″瀷', value: defaultCount },
+                { label: 'OpenAI / Mock', value: `${openaiCount} / ${mockCount}` },
+            ]}
+        >
+            <AiConsolePanel
+                title="妯″瀷閰嶇疆"
+                subtitle="灞曠ず妯″瀷缂栫爜銆佷緵搴斿晢銆佷笂涓嬫枃杞暟鍜岄粯璁ょ姸鎬侊紱鍒涘缓銆佺紪杈戙�佸垹闄や粛娌跨敤鍘熺郴缁熺殑寮圭獥涓庣紪杈戦〉銆�"
+                minHeight={460}
+            >
+                <Box
+                    sx={{
+                        display: 'grid',
+                        gridTemplateColumns: 'repeat(auto-fit, minmax(320px, 1fr))',
+                        gap: 2,
+                    }}
+                >
+                    {records.map((record) => (
+                        <Box key={record.id}>
+                            <Box sx={aiCardSx(record.defaultFlag === 1)}>
+                                <Stack direction="row" justifyContent="space-between" alignItems="flex-start" spacing={1}>
+                                    <Box>
+                                        <Typography variant="subtitle1" sx={{ fontWeight: 700 }}>
+                                            {record.name || record.modelCode || record.uuid}
+                                        </Typography>
+                                        <Typography variant="caption" color="text.secondary">
+                                            {record.modelCode || '鏈~鍐欐ā鍨嬬紪鐮�'}
+                                        </Typography>
+                                    </Box>
+                                    <Stack direction="row" spacing={0.75} flexWrap="wrap" justifyContent="flex-end">
+                                        <Chip size="small" color={record.status === 1 ? 'success' : 'default'} label={record.status === 1 ? '鍚敤' : '鍋滅敤'} />
+                                        {record.defaultFlag === 1 ? <Chip size="small" color="primary" label="榛樿" /> : null}
+                                    </Stack>
+                                </Stack>
+                                <Grid container spacing={1.25} sx={{ mt: 1 }}>
+                                    <Grid item xs={6}>
+                                        <Typography variant="caption" color="text.secondary">渚涘簲鍟�</Typography>
+                                        <Typography variant="body2" sx={{ mt: 0.25 }}>{providerLabel(record.provider)}</Typography>
+                                    </Grid>
+                                    <Grid item xs={6}>
+                                        <Typography variant="caption" color="text.secondary">妯″瀷鍚�</Typography>
+                                        <Typography variant="body2" sx={{ mt: 0.25 }}>{record.modelName || '-'}</Typography>
+                                    </Grid>
+                                    <Grid item xs={6}>
+                                        <Typography variant="caption" color="text.secondary">涓婁笅鏂囪疆鏁�</Typography>
+                                        <Typography variant="body2" sx={{ mt: 0.25 }}>{record.maxContextMessages || 0}</Typography>
+                                    </Grid>
+                                    <Grid item xs={6}>
+                                        <Typography variant="caption" color="text.secondary">鎺掑簭</Typography>
+                                        <Typography variant="body2" sx={{ mt: 0.25 }}>{record.sort || 0}</Typography>
+                                    </Grid>
+                                    <Grid item xs={12}>
+                                        <Typography variant="caption" color="text.secondary">鑱婂ぉ鍦板潃</Typography>
+                                        <Typography variant="body2" sx={{ mt: 0.25, wordBreak: 'break-all' }}>
+                                            {record.chatUrl || '鏈厤缃�'}
+                                        </Typography>
+                                    </Grid>
+                                    <Grid item xs={12}>
+                                        <Typography variant="caption" color="text.secondary">澶囨敞</Typography>
+                                        <Typography variant="body2" sx={{ mt: 0.25, minHeight: 42 }}>
+                                            {record.memo || '鏈~鍐欏娉�'}
+                                        </Typography>
+                                    </Grid>
+                                </Grid>
+                                <Stack direction="row" spacing={1} sx={{ mt: 1.5 }}>
+                                    <EditButton record={record} sx={{ px: 1.25, py: 0.5, minWidth: 64 }} />
+                                    <DeleteButton record={record} sx={{ px: 1.25, py: 0.5, minWidth: 64 }} mutationMode={OPERATE_MODE} />
+                                </Stack>
+                            </Box>
+                        </Box>
+                    ))}
+                </Box>
+                <Box sx={{ mt: 2 }}>
+                    <Pagination rowsPerPageOptions={[DEFAULT_PAGE_SIZE, 25, 50]} />
+                </Box>
+            </AiConsolePanel>
+        </AiConsoleLayout>
+    );
+};
 
 const AiParamList = () => {
     const [createDialog, setCreateDialog] = useState(false);
 
     return (
-        <Box display="flex">
+        <Box display="flex" sx={{ width: '100%' }}>
             <List
+                sx={{ width: '100%', flexGrow: 1 }}
                 title={"menu.aiParam"}
                 empty={<EmptyData onClick={() => { setCreateDialog(true) }} />}
                 filters={filters}
@@ -84,30 +176,9 @@
                     </TopToolbar>
                 )}
                 perPage={DEFAULT_PAGE_SIZE}
+                pagination={false}
             >
-                <StyledDatagrid
-                    preferenceKey='aiParam'
-                    bulkActionButtons={() => <BulkDeleteButton mutationMode={OPERATE_MODE} />}
-                    rowClick={false}
-                    omit={['id', 'createTime', 'memo', 'statusBool', 'defaultFlagBool']}
-                >
-                    <NumberField source="id" />
-                    <TextField source="uuid" label="table.field.aiParam.uuid" />
-                    <TextField source="name" label="table.field.aiParam.name" />
-                    <TextField source="modelCode" label="table.field.aiParam.modelCode" />
-                    <TextField source="provider" label="table.field.aiParam.provider" />
-                    <TextField source="modelName" label="table.field.aiParam.modelName" />
-                    <NumberField source="maxContextMessages" label="table.field.aiParam.maxContextMessages" />
-                    <NumberField source="sort" label="table.field.aiParam.sort" />
-                    <BooleanField source="defaultFlagBool" label="table.field.aiParam.defaultFlag" sortable={false} />
-                    <BooleanField source="statusBool" label="common.field.status" sortable={false} />
-                    <DateField source="updateTime" label="common.field.updateTime" showTime />
-                    <TextField source="memo" label="common.field.memo" sortable={false} />
-                    <WrapperField cellClassName="opt" label="common.field.opt">
-                        <EditButton sx={{ padding: '1px', fontSize: '.75rem' }} />
-                        <DeleteButton sx={{ padding: '1px', fontSize: '.75rem' }} mutationMode={OPERATE_MODE} />
-                    </WrapperField>
-                </StyledDatagrid>
+                <AiParamBoard />
             </List>
             <AiParamCreate
                 open={createDialog}

--
Gitblit v1.9.1