feat(web): model logo update

This commit is contained in:
zhaoying
2026-01-28 10:50:48 +08:00
parent ce01e588c9
commit 2c21712d58
8 changed files with 47 additions and 29 deletions

View File

@@ -7,14 +7,15 @@ import { useTranslation } from 'react-i18next';
import PlusIcon from '@/assets/images/plus.svg'
import { cookieUtils } from '@/utils/request'
import { fileUploadUrl } from '@/api/fileStorage'
import styles from './index.module.less'
interface UploadImagesProps extends Omit<UploadProps, 'onChange'> {
interface UploadImagesProps extends Omit<UploadProps, 'onChange' | 'fileList'> {
/** 上传接口地址 */
action?: string;
/** 是否支持多选 */
multiple?: boolean;
/** 已上传的文件列表 */
fileList?: UploadFile[];
fileList?: UploadFile[] | UploadFile;
/** 文件列表变化回调 */
onChange?: (fileList?: UploadFile[] | UploadFile) => void;
/** 禁用上传 */
@@ -73,12 +74,18 @@ const UploadImages = forwardRef<UploadImagesRef, UploadImagesProps>(({
}, ref) => {
const { t } = useTranslation();
const { message, modal } = App.useApp()
const [fileList, setFileList] = useState<UploadFile[]>(propFileList);
const [fileList, setFileList] = useState<UploadFile[]>([]);
const [accept, setAccept] = useState<string | undefined>();
// const [loading, setLoading] = useState(false);
const [previewOpen, setPreviewOpen] = useState(false);
const [previewImage, setPreviewImage] = useState('');
useEffect(() => {
if (!Array.isArray(propFileList) && typeof propFileList === 'object') {
setFileList([propFileList]);
}
}, [propFileList])
const updateValue = (list: UploadFile[]) => {
if (maxCount === 1) {
onChange?.(list[0])
@@ -185,6 +192,7 @@ const UploadImages = forwardRef<UploadImagesRef, UploadImagesProps>(({
showRemoveIcon: true,
showDownloadIcon: false,
},
className: `${styles.imageUpload} ${className}`,
...props,
};

View File

@@ -0,0 +1,7 @@
.image-upload:global(.ant-upload-wrapper.ant-upload-picture-card-wrapper .ant-upload-list.ant-upload-list-picture-card .ant-upload-list-item-container),
.image-upload:global(.ant-upload-wrapper.ant-upload-picture-circle-wrapper .ant-upload-list.ant-upload-list-picture-card .ant-upload-list-item-container),
.image-upload:global(.ant-upload-wrapper.ant-upload-picture-card-wrapper .ant-upload-list.ant-upload-list-picture-circle .ant-upload-list-item-container),
.image-upload:global(.ant-upload-wrapper.ant-upload-picture-circle-wrapper .ant-upload-list.ant-upload-list-picture-circle .ant-upload-list-item-container) {
width: 96px;
height: 96px;
}

View File

@@ -20,7 +20,7 @@ import type {
} from './types'
import type { Variable } from './components/VariableList/types'
import type { KnowledgeConfig } from './components/Knowledge/types'
import type { Model } from '@/views/ModelManagement/types'
import type { ModelListItem } from '@/views/ModelManagement/types'
import { getModelList } from '@/api/models';
import { saveAgentConfig } from '@/api/application'
import Knowledge from './components/Knowledge/Knowledge'
@@ -96,8 +96,8 @@ const Agent = forwardRef<AgentRef>((_props, ref) => {
const [loading, setLoading] = useState(false)
const [data, setData] = useState<Config | null>(null);
const modelConfigModalRef = useRef<ModelConfigModalRef>(null)
const [modelList, setModelList] = useState<Model[]>([])
const [defaultModel, setDefaultModel] = useState<Model | null>(null)
const [modelList, setModelList] = useState<ModelListItem[]>([])
const [defaultModel, setDefaultModel] = useState<ModelListItem | null>(null)
const [chatList, setChatList] = useState<ChatData[]>([])
const values = Form.useWatch<Config>([], form)
const [isSave, setIsSave] = useState(false)
@@ -239,7 +239,7 @@ const Agent = forwardRef<AgentRef>((_props, ref) => {
const getModels = () => {
getModelList({ type: 'llm,chat', pagesize: 100, page: 1, is_active: true })
.then(res => {
const response = res as { items: Model[] }
const response = res as { items: ModelListItem[] }
setModelList(response.items)
})
}
@@ -249,7 +249,7 @@ const Agent = forwardRef<AgentRef>((_props, ref) => {
useEffect(() => {
if (values?.default_model_config_id && modelList.length > 0) {
const filterValue = modelList.find(item => item.id === values.default_model_config_id)
setDefaultModel(filterValue as Model | null)
setDefaultModel(filterValue as ModelListItem | null)
setChatList([{
label: filterValue?.name || '',
model_config_id: filterValue?.id || '',

View File

@@ -86,6 +86,7 @@ const ModelSquare = forwardRef <BaseRef, { query: any; handleEdit: (vo?: ModelPl
<ModelSquareDetail
ref={modelSquareDetailRef}
refresh={getList}
handleEdit={handleEdit}
/>
</>
)

View File

@@ -34,6 +34,7 @@ const CustomModelModal = forwardRef<CustomModelModalRef, CustomModelModalProps>(
setModel(model);
form.setFieldsValue({
...model,
logo: model.logo ? { url: model.logo, uid: model.logo, status: 'done', name: 'logo' } : undefined
});
} else {
setIsEdit(false);
@@ -48,7 +49,7 @@ const CustomModelModal = forwardRef<CustomModelModalRef, CustomModelModalProps>(
setLoading(true)
values.is_official = false;
const logo = values.logo as any;
if (typeof logo === 'object') {
if (typeof logo === 'object' && logo?.response?.data.file_id) {
getFileLink(logo?.response?.data.file_id).then(res => {
const logoRes = res as { url: string }
values.logo = logoRes.url
@@ -64,6 +65,7 @@ const CustomModelModal = forwardRef<CustomModelModalRef, CustomModelModalProps>(
});
})
} else {
values.logo = typeof logo === 'string' ? logo : logo.url
updateCustomModel(model.id, values).then(() => {
if (refresh) {
refresh();
@@ -111,7 +113,7 @@ const CustomModelModal = forwardRef<CustomModelModalRef, CustomModelModalProps>(
<Form.Item
name="name"
label={t('modelNew.model_name')}
rules={[{ required: true, message: t('common.inputPlaceholder', { title: t('modelNew.displayName') }) }]}
rules={[{ required: true, message: t('common.inputPlaceholder', { title: t('modelNew.model_name') }) }]}
>
<Input placeholder={t('common.pleaseEnter')} />
</Form.Item>

View File

@@ -36,7 +36,7 @@ const GroupModelModal = forwardRef<GroupModelModalRef, GroupModelModalProps>(({
form.setFieldsValue({
...model,
api_key_ids: model.api_keys,
logo: model.logo ? [{url: model.logo, uid: model.logo, status: 'done', name: 'logo'}] : undefined
logo: model.logo ? { url: model.logo, uid: model.logo, status: 'done', name: 'logo' } : undefined
})
} else {
setIsEdit(false);
@@ -48,7 +48,7 @@ const GroupModelModal = forwardRef<GroupModelModalRef, GroupModelModalProps>(({
form
.validateFields()
.then((values) => {
const { api_key_ids, logo, ...rest } = values
const { api_key_ids = [], logo, ...rest } = values
const formData: CompositeModelForm = {
...rest,
@@ -62,6 +62,7 @@ const GroupModelModal = forwardRef<GroupModelModalRef, GroupModelModalProps>(({
handleUpdate(formData)
})
} else {
formData.logo = typeof logo === 'string' ? logo : logo.url
handleUpdate(formData)
}
})

View File

@@ -1,6 +1,7 @@
import { useState, useImperativeHandle, forwardRef } from 'react';
import { useTranslation } from 'react-i18next';
import { Button, Space, App } from 'antd'
import { Button, Space, App, Flex } from 'antd'
import { UsergroupAddOutlined } from '@ant-design/icons';
import type { ModelPlaza, ModelPlazaItem, ModelSquareDetailRef } from '../types';
import RbDrawer from '@/components/RbDrawer';
@@ -11,8 +12,9 @@ import PageEmpty from '@/components/Empty/PageEmpty';
interface ModelSquareDetailProps {
refresh: () => void;
handleEdit: (vo: ModelPlazaItem) => void;
}
const ModelSquareDetail = forwardRef<ModelSquareDetailRef, ModelSquareDetailProps>(({ refresh }, ref) => {
const ModelSquareDetail = forwardRef<ModelSquareDetailRef, ModelSquareDetailProps>(({ refresh, handleEdit }, ref) => {
const { t } = useTranslation();
const { message } = App.useApp()
const [model, setModel] = useState<ModelPlaza>({} as ModelPlaza)
@@ -71,10 +73,17 @@ const ModelSquareDetail = forwardRef<ModelSquareDetailRef, ModelSquareDetailProp
<Tag>{t(`modelNew.${item.type}`)}</Tag>
<div className="rb:text-[#5B6167] rb:text-[12px] rb:leading-4.5 rb:mt-3 rb:h-9">{item.description}</div>
<Space size={8} className="rb:mt-3">{item.tags.map((tag, tagIndex) => <Tag key={tagIndex}>{tag}</Tag>)}</Space>
{item.is_added
? <Button className="rb:mt-3" type="primary" disabled block>{t('modelNew.added')}</Button>
: <Button className="rb:mt-3" type="primary" ghost block onClick={() => handleAdd(item)}>+ {t('common.add')}</Button>
}
<Flex justify="space-between">
<Space size={8}><UsergroupAddOutlined /> {item.add_count}</Space>
<Space>
{!item.is_official && <Button type="primary" disabled={item.is_deprecated} onClick={() => handleEdit(item)}>{t('modelNew.edit')}</Button>}
{item.is_added
? <Button type="primary" disabled>{t('modelNew.added')}</Button>
: <Button type="primary" ghost disabled={item.is_deprecated} onClick={() => handleAdd(item)}>+ {t('common.add')}</Button>
}
</Space>
</Flex>
</RbCard>
))}
</div>

View File

@@ -27,16 +27,6 @@ export interface GroupModelModalRef {
export interface GroupModelModalProps {
refresh?: () => void;
}
export interface SubModelModalForm {
provider: string;
model_ids: string[]
}
export interface SubModelModalRef {
handleOpen: (model?: SubModelModalForm) => void;
}
export interface SubModelModalProps {
refresh?: () => void;
}
export interface ModelListDetailRef {
handleOpen: (vo: ProviderModelItem) => void;
}
@@ -131,7 +121,7 @@ export interface CustomModelForm {
name: string;
type: string;
provider: string;
logo: string;
logo?: any;
description: string;
is_official: boolean;
tags: string[];