mirror of
https://github.com/labring/FastGPT.git
synced 2025-07-23 13:03:50 +00:00
feat: model set avatar
This commit is contained in:
@@ -90,9 +90,6 @@ export const theme = extendTheme({
|
||||
fonts: {
|
||||
body: '-apple-system,BlinkMacSystemFont,"Segoe UI",Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol"'
|
||||
},
|
||||
fontWeights: {
|
||||
bold: 500
|
||||
},
|
||||
breakpoints: {
|
||||
sm: '900px',
|
||||
md: '1200px',
|
||||
|
@@ -9,7 +9,7 @@ import { authModel } from '@/service/utils/auth';
|
||||
/* 获取我的模型 */
|
||||
export default async function handler(req: NextApiRequest, res: NextApiResponse<any>) {
|
||||
try {
|
||||
const { name, search, share, service, security, systemPrompt, temperature } =
|
||||
const { name, avatar, search, share, service, security, systemPrompt, temperature } =
|
||||
req.body as ModelUpdateParams;
|
||||
const { modelId } = req.query as { modelId: string };
|
||||
const { authorization } = req.headers;
|
||||
@@ -40,6 +40,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse<
|
||||
},
|
||||
{
|
||||
name,
|
||||
avatar,
|
||||
systemPrompt,
|
||||
temperature,
|
||||
'share.isShare': share.isShare,
|
||||
|
@@ -1,4 +1,4 @@
|
||||
import React, { useState } from 'react';
|
||||
import React, { useState, useCallback } from 'react';
|
||||
import {
|
||||
Box,
|
||||
Card,
|
||||
@@ -15,7 +15,8 @@ import {
|
||||
Button,
|
||||
Select,
|
||||
Grid,
|
||||
Switch
|
||||
Switch,
|
||||
Image
|
||||
} from '@chakra-ui/react';
|
||||
import { QuestionOutlineIcon } from '@chakra-ui/icons';
|
||||
import type { ModelSchema } from '@/types/mongoSchema';
|
||||
@@ -23,6 +24,9 @@ import { UseFormReturn } from 'react-hook-form';
|
||||
import { modelList, ModelVectorSearchModeMap } from '@/constants/model';
|
||||
import { formatPrice } from '@/utils/user';
|
||||
import { useConfirm } from '@/hooks/useConfirm';
|
||||
import { useSelectFile } from '@/hooks/useSelectFile';
|
||||
import { useToast } from '@/hooks/useToast';
|
||||
import { fileToBase64 } from '@/utils/file';
|
||||
|
||||
const ModelEditForm = ({
|
||||
formHooks,
|
||||
@@ -40,11 +44,50 @@ const ModelEditForm = ({
|
||||
});
|
||||
const { register, setValue, getValues } = formHooks;
|
||||
const [refresh, setRefresh] = useState(false);
|
||||
const { File, onOpen: onOpenSelectFile } = useSelectFile({
|
||||
fileType: '.jpg,.png',
|
||||
multiple: false
|
||||
});
|
||||
const { toast } = useToast();
|
||||
|
||||
const onSelectFile = useCallback(
|
||||
async (e: File[]) => {
|
||||
const file = e[0];
|
||||
if (!file) return;
|
||||
|
||||
if (file.size > 100 * 1024) {
|
||||
return toast({
|
||||
title: '头像需小于 100kb',
|
||||
status: 'warning'
|
||||
});
|
||||
}
|
||||
|
||||
const base64 = (await fileToBase64(file)) as string;
|
||||
setValue('avatar', base64);
|
||||
setRefresh((state) => !state);
|
||||
},
|
||||
[setValue, toast]
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Card p={4}>
|
||||
<Box fontWeight={'bold'}>基本信息</Box>
|
||||
<Flex mt={4} alignItems={'center'}>
|
||||
<Box flex={'0 0 80px'} w={0}>
|
||||
头像:
|
||||
</Box>
|
||||
<Image
|
||||
src={getValues('avatar')}
|
||||
alt={'avatar'}
|
||||
w={'36px'}
|
||||
h={'36px'}
|
||||
objectFit={'contain'}
|
||||
cursor={'pointer'}
|
||||
title={'点击切换头像'}
|
||||
onClick={onOpenSelectFile}
|
||||
/>
|
||||
</Flex>
|
||||
<FormControl mt={4}>
|
||||
<Flex alignItems={'center'}>
|
||||
<Box flex={'0 0 80px'} w={0}>
|
||||
@@ -167,7 +210,7 @@ const ModelEditForm = ({
|
||||
<Box mt={4}>
|
||||
<Box mb={1}>系统提示词</Box>
|
||||
<Textarea
|
||||
rows={6}
|
||||
rows={8}
|
||||
maxLength={-1}
|
||||
isDisabled={!isOwner}
|
||||
placeholder={
|
||||
@@ -235,6 +278,7 @@ const ModelEditForm = ({
|
||||
</Grid>
|
||||
</Card>
|
||||
)}
|
||||
<File onSelect={onSelectFile} />
|
||||
|
||||
{/* <Card p={4}>
|
||||
<Box fontWeight={'bold'}>安全策略</Box>
|
||||
|
@@ -85,6 +85,7 @@ const ModelDetail = ({ modelId }: { modelId: string }) => {
|
||||
try {
|
||||
await putModelById(data._id, {
|
||||
name: data.name,
|
||||
avatar: data.avatar,
|
||||
systemPrompt: data.systemPrompt,
|
||||
temperature: data.temperature,
|
||||
search: data.search,
|
||||
|
1
src/types/model.d.ts
vendored
1
src/types/model.d.ts
vendored
@@ -2,6 +2,7 @@ import { ModelStatusEnum } from '@/constants/model';
|
||||
import type { ModelSchema } from './mongoSchema';
|
||||
export interface ModelUpdateParams {
|
||||
name: string;
|
||||
avatar: string;
|
||||
systemPrompt: string;
|
||||
temperature: number;
|
||||
search: ModelSchema['search'];
|
||||
|
@@ -155,7 +155,7 @@ export const splitText = ({
|
||||
slideLen: number;
|
||||
}) => {
|
||||
const textArr =
|
||||
text.match(/[!?。\n.]+|[^\s]+/g)?.filter((item) => {
|
||||
text.split(/(?<=[。!?\.!\?\n])/g)?.filter((item) => {
|
||||
const text = item.replace(/(\\n)/g, '\n').trim();
|
||||
if (text && text !== '\n') return true;
|
||||
return false;
|
||||
@@ -188,3 +188,12 @@ export const splitText = ({
|
||||
const result = chunks.map((item) => item.arr.join(''));
|
||||
return result;
|
||||
};
|
||||
|
||||
export const fileToBase64 = (file: File) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
const reader = new FileReader();
|
||||
reader.readAsDataURL(file);
|
||||
reader.onload = () => resolve(reader.result);
|
||||
reader.onerror = (error) => reject(error);
|
||||
});
|
||||
};
|
||||
|
Reference in New Issue
Block a user