feat: model set avatar
This commit is contained in:
parent
606105d633
commit
08ae4073bd
@ -90,9 +90,6 @@ export const theme = extendTheme({
|
|||||||
fonts: {
|
fonts: {
|
||||||
body: '-apple-system,BlinkMacSystemFont,"Segoe UI",Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol"'
|
body: '-apple-system,BlinkMacSystemFont,"Segoe UI",Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol"'
|
||||||
},
|
},
|
||||||
fontWeights: {
|
|
||||||
bold: 500
|
|
||||||
},
|
|
||||||
breakpoints: {
|
breakpoints: {
|
||||||
sm: '900px',
|
sm: '900px',
|
||||||
md: '1200px',
|
md: '1200px',
|
||||||
|
|||||||
@ -9,7 +9,7 @@ import { authModel } from '@/service/utils/auth';
|
|||||||
/* 获取我的模型 */
|
/* 获取我的模型 */
|
||||||
export default async function handler(req: NextApiRequest, res: NextApiResponse<any>) {
|
export default async function handler(req: NextApiRequest, res: NextApiResponse<any>) {
|
||||||
try {
|
try {
|
||||||
const { name, search, share, service, security, systemPrompt, temperature } =
|
const { name, avatar, search, share, service, security, systemPrompt, temperature } =
|
||||||
req.body as ModelUpdateParams;
|
req.body as ModelUpdateParams;
|
||||||
const { modelId } = req.query as { modelId: string };
|
const { modelId } = req.query as { modelId: string };
|
||||||
const { authorization } = req.headers;
|
const { authorization } = req.headers;
|
||||||
@ -40,6 +40,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse<
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name,
|
name,
|
||||||
|
avatar,
|
||||||
systemPrompt,
|
systemPrompt,
|
||||||
temperature,
|
temperature,
|
||||||
'share.isShare': share.isShare,
|
'share.isShare': share.isShare,
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import React, { useState } from 'react';
|
import React, { useState, useCallback } from 'react';
|
||||||
import {
|
import {
|
||||||
Box,
|
Box,
|
||||||
Card,
|
Card,
|
||||||
@ -15,7 +15,8 @@ import {
|
|||||||
Button,
|
Button,
|
||||||
Select,
|
Select,
|
||||||
Grid,
|
Grid,
|
||||||
Switch
|
Switch,
|
||||||
|
Image
|
||||||
} from '@chakra-ui/react';
|
} from '@chakra-ui/react';
|
||||||
import { QuestionOutlineIcon } from '@chakra-ui/icons';
|
import { QuestionOutlineIcon } from '@chakra-ui/icons';
|
||||||
import type { ModelSchema } from '@/types/mongoSchema';
|
import type { ModelSchema } from '@/types/mongoSchema';
|
||||||
@ -23,6 +24,9 @@ import { UseFormReturn } from 'react-hook-form';
|
|||||||
import { modelList, ModelVectorSearchModeMap } from '@/constants/model';
|
import { modelList, ModelVectorSearchModeMap } from '@/constants/model';
|
||||||
import { formatPrice } from '@/utils/user';
|
import { formatPrice } from '@/utils/user';
|
||||||
import { useConfirm } from '@/hooks/useConfirm';
|
import { useConfirm } from '@/hooks/useConfirm';
|
||||||
|
import { useSelectFile } from '@/hooks/useSelectFile';
|
||||||
|
import { useToast } from '@/hooks/useToast';
|
||||||
|
import { fileToBase64 } from '@/utils/file';
|
||||||
|
|
||||||
const ModelEditForm = ({
|
const ModelEditForm = ({
|
||||||
formHooks,
|
formHooks,
|
||||||
@ -40,11 +44,50 @@ const ModelEditForm = ({
|
|||||||
});
|
});
|
||||||
const { register, setValue, getValues } = formHooks;
|
const { register, setValue, getValues } = formHooks;
|
||||||
const [refresh, setRefresh] = useState(false);
|
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 (
|
return (
|
||||||
<>
|
<>
|
||||||
<Card p={4}>
|
<Card p={4}>
|
||||||
<Box fontWeight={'bold'}>基本信息</Box>
|
<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}>
|
<FormControl mt={4}>
|
||||||
<Flex alignItems={'center'}>
|
<Flex alignItems={'center'}>
|
||||||
<Box flex={'0 0 80px'} w={0}>
|
<Box flex={'0 0 80px'} w={0}>
|
||||||
@ -167,7 +210,7 @@ const ModelEditForm = ({
|
|||||||
<Box mt={4}>
|
<Box mt={4}>
|
||||||
<Box mb={1}>系统提示词</Box>
|
<Box mb={1}>系统提示词</Box>
|
||||||
<Textarea
|
<Textarea
|
||||||
rows={6}
|
rows={8}
|
||||||
maxLength={-1}
|
maxLength={-1}
|
||||||
isDisabled={!isOwner}
|
isDisabled={!isOwner}
|
||||||
placeholder={
|
placeholder={
|
||||||
@ -235,6 +278,7 @@ const ModelEditForm = ({
|
|||||||
</Grid>
|
</Grid>
|
||||||
</Card>
|
</Card>
|
||||||
)}
|
)}
|
||||||
|
<File onSelect={onSelectFile} />
|
||||||
|
|
||||||
{/* <Card p={4}>
|
{/* <Card p={4}>
|
||||||
<Box fontWeight={'bold'}>安全策略</Box>
|
<Box fontWeight={'bold'}>安全策略</Box>
|
||||||
|
|||||||
@ -85,6 +85,7 @@ const ModelDetail = ({ modelId }: { modelId: string }) => {
|
|||||||
try {
|
try {
|
||||||
await putModelById(data._id, {
|
await putModelById(data._id, {
|
||||||
name: data.name,
|
name: data.name,
|
||||||
|
avatar: data.avatar,
|
||||||
systemPrompt: data.systemPrompt,
|
systemPrompt: data.systemPrompt,
|
||||||
temperature: data.temperature,
|
temperature: data.temperature,
|
||||||
search: data.search,
|
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';
|
import type { ModelSchema } from './mongoSchema';
|
||||||
export interface ModelUpdateParams {
|
export interface ModelUpdateParams {
|
||||||
name: string;
|
name: string;
|
||||||
|
avatar: string;
|
||||||
systemPrompt: string;
|
systemPrompt: string;
|
||||||
temperature: number;
|
temperature: number;
|
||||||
search: ModelSchema['search'];
|
search: ModelSchema['search'];
|
||||||
|
|||||||
@ -155,7 +155,7 @@ export const splitText = ({
|
|||||||
slideLen: number;
|
slideLen: number;
|
||||||
}) => {
|
}) => {
|
||||||
const textArr =
|
const textArr =
|
||||||
text.match(/[!?。\n.]+|[^\s]+/g)?.filter((item) => {
|
text.split(/(?<=[。!?\.!\?\n])/g)?.filter((item) => {
|
||||||
const text = item.replace(/(\\n)/g, '\n').trim();
|
const text = item.replace(/(\\n)/g, '\n').trim();
|
||||||
if (text && text !== '\n') return true;
|
if (text && text !== '\n') return true;
|
||||||
return false;
|
return false;
|
||||||
@ -188,3 +188,12 @@ export const splitText = ({
|
|||||||
const result = chunks.map((item) => item.arr.join(''));
|
const result = chunks.map((item) => item.arr.join(''));
|
||||||
return result;
|
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);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user