From 6e1ef89d6508d060c36611f117fa5e60e2d65501 Mon Sep 17 00:00:00 2001 From: archer <545436317@qq.com> Date: Tue, 4 Jul 2023 15:39:57 +0800 Subject: [PATCH] myapps --- admin/service/route/app.js | 8 +- admin/service/schema.js | 4 +- client/src/api/app.ts | 20 +- client/src/api/chat.ts | 2 +- client/src/api/response/app.d.ts | 6 + client/src/api/response/model.d.ts | 6 - client/src/components/Layout/auth.tsx | 2 +- client/src/components/Layout/navbar.tsx | 12 +- client/src/constants/model.ts | 3 +- client/src/constants/theme.ts | 2 +- client/src/pages/api/{model => app}/create.ts | 6 +- client/src/pages/api/{model => app}/del.ts | 4 +- .../src/pages/api/{model => app}/detail.tsx | 0 client/src/pages/api/{model => app}/list.ts | 8 +- .../api/{model => app}/share/collection.ts | 4 +- .../api/{model => app}/share/getModels.ts | 10 +- client/src/pages/api/{model => app}/update.ts | 8 +- client/src/pages/api/chat/init.ts | 8 +- client/src/pages/api/chat/saveChat.ts | 6 +- client/src/pages/api/chat/shareChat/create.ts | 2 +- .../pages/api/openapi/v1/chat/completions2.ts | 12 +- client/src/pages/api/plugins/kb/delete.ts | 4 +- .../src/pages/app/detail/components/Share.tsx | 2 +- client/src/pages/app/detail/index.tsx | 2 +- .../share => app/list}/index.module.scss | 0 client/src/pages/app/list/index.tsx | 81 +++- .../share => appStore}/components/list.tsx | 4 +- client/src/pages/appStore/index.module.scss | 7 + .../pages/{model/share => appStore}/index.tsx | 4 +- .../src/pages/chat/components/ModelList.tsx | 4 +- .../src/pages/model/components/ModelList.tsx | 172 -------- .../components/detail/components/API.tsx | 85 ---- .../model/components/detail/components/Kb.tsx | 394 ------------------ .../components/detail/components/Share.tsx | 281 ------------- .../pages/model/components/detail/index.tsx | 102 ----- client/src/pages/model/index.tsx | 44 -- .../src/service/models/{model.ts => app.ts} | 6 +- client/src/service/models/installApp.ts | 18 + client/src/service/mongo.ts | 2 +- client/src/service/utils/auth.ts | 4 +- client/src/store/user.ts | 6 +- client/src/types/app.d.ts | 34 ++ client/src/types/model.d.ts | 34 -- client/src/types/mongoSchema.d.ts | 6 - 44 files changed, 213 insertions(+), 1216 deletions(-) create mode 100644 client/src/api/response/app.d.ts delete mode 100644 client/src/api/response/model.d.ts rename client/src/pages/api/{model => app}/create.ts (86%) rename client/src/pages/api/{model => app}/del.ts (90%) rename client/src/pages/api/{model => app}/detail.tsx (100%) rename client/src/pages/api/{model => app}/list.ts (88%) rename client/src/pages/api/{model => app}/share/collection.ts (89%) rename client/src/pages/api/{model => app}/share/getModels.ts (91%) rename client/src/pages/api/{model => app}/update.ts (88%) rename client/src/pages/{model/share => app/list}/index.module.scss (100%) rename client/src/pages/{model/share => appStore}/components/list.tsx (96%) create mode 100644 client/src/pages/appStore/index.module.scss rename client/src/pages/{model/share => appStore}/index.tsx (96%) delete mode 100644 client/src/pages/model/components/ModelList.tsx delete mode 100644 client/src/pages/model/components/detail/components/API.tsx delete mode 100644 client/src/pages/model/components/detail/components/Kb.tsx delete mode 100644 client/src/pages/model/components/detail/components/Share.tsx delete mode 100644 client/src/pages/model/components/detail/index.tsx delete mode 100644 client/src/pages/model/index.tsx rename client/src/service/models/{model.ts => app.ts} (88%) create mode 100644 client/src/service/models/installApp.ts delete mode 100644 client/src/types/model.d.ts diff --git a/admin/service/route/app.js b/admin/service/route/app.js index 556ecb492..be3746b1f 100644 --- a/admin/service/route/app.js +++ b/admin/service/route/app.js @@ -1,4 +1,4 @@ -import { Model, Kb } from '../schema.js'; +import { App, Kb } from '../schema.js'; import { auth } from './system.js'; export const useAppRoute = (app) => { @@ -17,7 +17,7 @@ export const useAppRoute = (app) => { ...(id && { _id: id }) }; - const modelsRaw = await Model.find(where) + const modelsRaw = await App.find(where) .skip(start) .limit(end - start) .sort({ [sort]: order, 'share.isShare': -1, 'share.collection': -1 }); @@ -50,7 +50,7 @@ export const useAppRoute = (app) => { models.push(orderedModel); } - const totalCount = await Model.countDocuments(where); + const totalCount = await App.countDocuments(where); res.header('Access-Control-Expose-Headers', 'X-Total-Count'); res.header('X-Total-Count', totalCount); res.json(models); @@ -70,7 +70,7 @@ export const useAppRoute = (app) => { intro } = req.body; - await Model.findByIdAndUpdate(_id, { + await App.findByIdAndUpdate(_id, { $set: { intro: intro, 'share.topNum': Number(topNum), diff --git a/admin/service/schema.js b/admin/service/schema.js index 3698d3aee..102d57943 100644 --- a/admin/service/schema.js +++ b/admin/service/schema.js @@ -56,7 +56,7 @@ const kbSchema = new mongoose.Schema({ __v: Number }); -const modelSchema = new mongoose.Schema({ +const appSchema = new mongoose.Schema({ userId: mongoose.Schema.Types.ObjectId, name: String, avatar: String, @@ -104,7 +104,7 @@ const SystemSchema = new mongoose.Schema({ } }); -export const Model = mongoose.models['model'] || mongoose.model('model', modelSchema); +export const App = mongoose.models['model'] || mongoose.model('model', appSchema); export const Kb = mongoose.models['kb'] || mongoose.model('kb', kbSchema); export const User = mongoose.models['user'] || mongoose.model('user', userSchema); export const Pay = mongoose.models['pay'] || mongoose.model('pay', paySchema); diff --git a/client/src/api/app.ts b/client/src/api/app.ts index 7f491ffb6..0822b3ae6 100644 --- a/client/src/api/app.ts +++ b/client/src/api/app.ts @@ -1,44 +1,44 @@ import { GET, POST, DELETE, PUT } from './request'; import type { AppSchema } from '@/types/mongoSchema'; -import type { ModelUpdateParams } from '@/types/model'; +import type { AppUpdateParams } from '@/types/app'; import { RequestPaging } from '../types/index'; -import type { ModelListResponse } from './response/model'; +import type { AppListResponse } from './response/app'; /** * 获取模型列表 */ -export const getMyModels = () => GET('/model/list'); +export const getMyModels = () => GET('/app/list'); /** * 创建一个模型 */ -export const postCreateModel = (data: { name: string }) => POST('/model/create', data); +export const postCreateModel = (data: { name: string }) => POST('/app/create', data); /** * 根据 ID 删除模型 */ -export const delModelById = (id: string) => DELETE(`/model/del?modelId=${id}`); +export const delModelById = (id: string) => DELETE(`/app/del?modelId=${id}`); /** * 根据 ID 获取模型 */ -export const getModelById = (id: string) => GET(`/model/detail?modelId=${id}`); +export const getModelById = (id: string) => GET(`/app/detail?modelId=${id}`); /** * 根据 ID 更新模型 */ -export const putAppById = (id: string, data: ModelUpdateParams) => - PUT(`/model/update?appId=${id}`, data); +export const putAppById = (id: string, data: AppUpdateParams) => + PUT(`/app/update?appId=${id}`, data); /* 共享市场 */ /** * 获取共享市场模型 */ export const getShareModelList = (data: { searchText?: string } & RequestPaging) => - POST(`/model/share/getModels`, data); + POST(`/app/share/getModels`, data); /** * 收藏/取消收藏模型 */ export const triggerModelCollection = (modelId: string) => - POST(`/model/share/collection?modelId=${modelId}`); + POST(`/app/share/collection?modelId=${modelId}`); diff --git a/client/src/api/chat.ts b/client/src/api/chat.ts index f9aee72c7..8521ca13e 100644 --- a/client/src/api/chat.ts +++ b/client/src/api/chat.ts @@ -3,7 +3,7 @@ import type { HistoryItemType } from '@/types/chat'; import type { InitChatResponse, InitShareChatResponse } from './response/chat'; import { RequestPaging } from '../types/index'; import type { ShareChatSchema } from '@/types/mongoSchema'; -import type { ShareChatEditType } from '@/types/model'; +import type { ShareChatEditType } from '@/types/app'; import { Obj2Query } from '@/utils/tools'; import type { QuoteItemType } from '@/pages/api/openapi/kb/appKbSearch'; import type { Props as UpdateHistoryProps } from '@/pages/api/chat/history/updateChatHistory'; diff --git a/client/src/api/response/app.d.ts b/client/src/api/response/app.d.ts new file mode 100644 index 000000000..0ac52a2fd --- /dev/null +++ b/client/src/api/response/app.d.ts @@ -0,0 +1,6 @@ +import { AppListItemType } from '@/types/app'; + +export type AppListResponse = { + myApps: AppListItemType[]; + myCollectionApps: AppListItemType[]; +}; diff --git a/client/src/api/response/model.d.ts b/client/src/api/response/model.d.ts deleted file mode 100644 index 65ebd8b6f..000000000 --- a/client/src/api/response/model.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { ModelListItemType } from '@/types/model'; - -export type ModelListResponse = { - myApps: ModelListItemType[]; - myCollectionApps: ModelListItemType[]; -}; diff --git a/client/src/components/Layout/auth.tsx b/client/src/components/Layout/auth.tsx index 73e02d487..6a01b02b8 100644 --- a/client/src/components/Layout/auth.tsx +++ b/client/src/components/Layout/auth.tsx @@ -7,7 +7,7 @@ import { useQuery } from '@tanstack/react-query'; const unAuthPage: { [key: string]: boolean } = { '/': true, '/login': true, - '/model/share': true, + '/appStore': true, '/chat/share': true }; diff --git a/client/src/components/Layout/navbar.tsx b/client/src/components/Layout/navbar.tsx index d6efa73cf..7d22e736f 100644 --- a/client/src/components/Layout/navbar.tsx +++ b/client/src/components/Layout/navbar.tsx @@ -32,12 +32,6 @@ const Navbar = ({ unread }: { unread: number }) => { link: `/app/list`, activeLink: ['/app/list'] }, - { - label: '旧应用', - icon: 'model', - link: `/model?modelId=${lastModelId}`, - activeLink: ['/model'] - }, { label: '知识库', icon: 'kb', @@ -47,8 +41,8 @@ const Navbar = ({ unread }: { unread: number }) => { { label: '市场', icon: 'appStore', - link: '/model/share', - activeLink: ['/model/share'] + link: '/appStore', + activeLink: ['/appStore'] }, { label: '账号', @@ -57,7 +51,7 @@ const Navbar = ({ unread }: { unread: number }) => { activeLink: ['/number'] } ], - [lastChatId, lastChatModelId, lastModelId] + [lastChatId, lastChatModelId] ); const itemStyles: any = { diff --git a/client/src/constants/model.ts b/client/src/constants/model.ts index 4e9df2d1d..f06a55c86 100644 --- a/client/src/constants/model.ts +++ b/client/src/constants/model.ts @@ -1,4 +1,5 @@ -import type { ShareChatEditType } from '@/types/model'; +import { getSystemModelList } from '@/api/system'; +import type { ShareChatEditType } from '@/types/app'; import type { AppSchema } from '@/types/mongoSchema'; export const embeddingModel = 'text-embedding-ada-002'; diff --git a/client/src/constants/theme.ts b/client/src/constants/theme.ts index 38c9de768..0fa847498 100644 --- a/client/src/constants/theme.ts +++ b/client/src/constants/theme.ts @@ -274,7 +274,7 @@ export const theme = extendTheme({ borders: { sm: '1px solid #EFF0F1', base: '1px solid #DEE0E2', - md: '1px solid #BDC1C5' + md: '1px solid #DAE0E2' }, breakpoints: { sm: '900px', diff --git a/client/src/pages/api/model/create.ts b/client/src/pages/api/app/create.ts similarity index 86% rename from client/src/pages/api/model/create.ts rename to client/src/pages/api/app/create.ts index 81d554a27..76084bd0e 100644 --- a/client/src/pages/api/model/create.ts +++ b/client/src/pages/api/app/create.ts @@ -3,7 +3,7 @@ import type { NextApiRequest, NextApiResponse } from 'next'; import { jsonRes } from '@/service/response'; import { connectToDatabase } from '@/service/mongo'; import { authUser } from '@/service/utils/auth'; -import { Model } from '@/service/models/model'; +import { App } from '@/service/models/model'; export default async function handler(req: NextApiRequest, res: NextApiResponse) { try { @@ -21,7 +21,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse< await connectToDatabase(); // 上限校验 - const authCount = await Model.countDocuments({ + const authCount = await App.countDocuments({ userId }); if (authCount >= 50) { @@ -29,7 +29,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse< } // 创建模型 - const response = await Model.create({ + const response = await App.create({ name, userId }); diff --git a/client/src/pages/api/model/del.ts b/client/src/pages/api/app/del.ts similarity index 90% rename from client/src/pages/api/model/del.ts rename to client/src/pages/api/app/del.ts index 9eee33348..91bfcfdb0 100644 --- a/client/src/pages/api/model/del.ts +++ b/client/src/pages/api/app/del.ts @@ -1,6 +1,6 @@ import type { NextApiRequest, NextApiResponse } from 'next'; import { jsonRes } from '@/service/response'; -import { Chat, Model, connectToDatabase, Collection, ShareChat } from '@/service/mongo'; +import { Chat, App, connectToDatabase, Collection, ShareChat } from '@/service/mongo'; import { authUser } from '@/service/utils/auth'; import { authApp } from '@/service/utils/auth'; @@ -40,7 +40,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse< }); // 删除模型 - await Model.deleteOne({ + await App.deleteOne({ _id: modelId, userId }); diff --git a/client/src/pages/api/model/detail.tsx b/client/src/pages/api/app/detail.tsx similarity index 100% rename from client/src/pages/api/model/detail.tsx rename to client/src/pages/api/app/detail.tsx diff --git a/client/src/pages/api/model/list.ts b/client/src/pages/api/app/list.ts similarity index 88% rename from client/src/pages/api/model/list.ts rename to client/src/pages/api/app/list.ts index d229e4f89..4b9e8d30a 100644 --- a/client/src/pages/api/model/list.ts +++ b/client/src/pages/api/app/list.ts @@ -1,8 +1,8 @@ import type { NextApiRequest, NextApiResponse } from 'next'; import { jsonRes } from '@/service/response'; -import { connectToDatabase, Collection, Model } from '@/service/mongo'; +import { connectToDatabase, Collection, App } from '@/service/mongo'; import { authUser } from '@/service/utils/auth'; -import type { ModelListResponse } from '@/api/response/model'; +import type { AppListResponse } from '@/api/response/app'; /* 获取模型列表 */ export default async function handler(req: NextApiRequest, res: NextApiResponse) { @@ -14,7 +14,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse< // 根据 userId 获取模型信息 const [myApps, myCollections] = await Promise.all([ - Model.find( + App.find( { userId }, @@ -31,7 +31,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse< .then((res) => res.filter((item) => item.modelId)) ]); - jsonRes(res, { + jsonRes(res, { data: { myApps: myApps.map((item) => ({ _id: item._id, diff --git a/client/src/pages/api/model/share/collection.ts b/client/src/pages/api/app/share/collection.ts similarity index 89% rename from client/src/pages/api/model/share/collection.ts rename to client/src/pages/api/app/share/collection.ts index ed97ae569..e009a298a 100644 --- a/client/src/pages/api/model/share/collection.ts +++ b/client/src/pages/api/app/share/collection.ts @@ -1,6 +1,6 @@ import type { NextApiRequest, NextApiResponse } from 'next'; import { jsonRes } from '@/service/response'; -import { connectToDatabase, Collection, Model } from '@/service/mongo'; +import { connectToDatabase, Collection, App } from '@/service/mongo'; import { authUser } from '@/service/utils/auth'; /* 模型收藏切换 */ @@ -30,7 +30,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse< }); } - await Model.findByIdAndUpdate(modelId, { + await App.findByIdAndUpdate(modelId, { 'share.collection': await Collection.countDocuments({ modelId }) }); diff --git a/client/src/pages/api/model/share/getModels.ts b/client/src/pages/api/app/share/getModels.ts similarity index 91% rename from client/src/pages/api/model/share/getModels.ts rename to client/src/pages/api/app/share/getModels.ts index eda51df2c..17c653d6b 100644 --- a/client/src/pages/api/model/share/getModels.ts +++ b/client/src/pages/api/app/share/getModels.ts @@ -1,8 +1,8 @@ import type { NextApiRequest, NextApiResponse } from 'next'; import { jsonRes } from '@/service/response'; -import { connectToDatabase, Model } from '@/service/mongo'; +import { connectToDatabase, App } from '@/service/mongo'; import type { PagingData } from '@/types'; -import type { ShareModelItem } from '@/types/model'; +import type { ShareAppItem } from '@/types/app'; import { parseCookie } from '@/service/utils/auth'; import { Types } from 'mongoose'; @@ -91,11 +91,11 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse< // 获取被分享的模型 const [models, total] = await Promise.all([ // @ts-ignore - Model.aggregate(pipeline), - Model.countDocuments(where) + App.aggregate(pipeline), + App.countDocuments(where) ]); - jsonRes>(res, { + jsonRes>(res, { data: { pageNum, pageSize, diff --git a/client/src/pages/api/model/update.ts b/client/src/pages/api/app/update.ts similarity index 88% rename from client/src/pages/api/model/update.ts rename to client/src/pages/api/app/update.ts index 00c365a1f..a537e58bb 100644 --- a/client/src/pages/api/model/update.ts +++ b/client/src/pages/api/app/update.ts @@ -2,14 +2,14 @@ import type { NextApiRequest, NextApiResponse } from 'next'; import { jsonRes } from '@/service/response'; import { connectToDatabase } from '@/service/mongo'; import { authUser } from '@/service/utils/auth'; -import { Model } from '@/service/models/model'; -import type { ModelUpdateParams } from '@/types/model'; +import { App } from '@/service/models/model'; +import type { AppUpdateParams } from '@/types/app'; import { authApp } from '@/service/utils/auth'; /* 获取我的模型 */ export default async function handler(req: NextApiRequest, res: NextApiResponse) { try { - const { name, avatar, chat, share, intro, modules } = req.body as ModelUpdateParams; + const { name, avatar, chat, share, intro, modules } = req.body as AppUpdateParams; const { appId } = req.query as { appId: string }; if (!appId) { @@ -27,7 +27,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse< }); // 更新模型 - await Model.updateOne( + await App.updateOne( { _id: appId, userId diff --git a/client/src/pages/api/chat/init.ts b/client/src/pages/api/chat/init.ts index 65e2ce6ab..918d01479 100644 --- a/client/src/pages/api/chat/init.ts +++ b/client/src/pages/api/chat/init.ts @@ -1,6 +1,6 @@ import type { NextApiRequest, NextApiResponse } from 'next'; import { jsonRes } from '@/service/response'; -import { connectToDatabase, Chat, Model } from '@/service/mongo'; +import { connectToDatabase, Chat, App } from '@/service/mongo'; import type { InitChatResponse } from '@/api/response/chat'; import { authUser } from '@/service/utils/auth'; import { ChatItemType } from '@/types/chat'; @@ -23,13 +23,13 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse) // 没有 modelId 时,直接获取用户的第一个id const app = await (async () => { if (!modelId) { - const myModel = await Model.findOne({ userId }); + const myModel = await App.findOne({ userId }); if (!myModel) { - const { _id } = await Model.create({ + const { _id } = await App.create({ name: '应用1', userId }); - return (await Model.findById(_id)) as AppSchema; + return (await App.findById(_id)) as AppSchema; } else { return myModel; } diff --git a/client/src/pages/api/chat/saveChat.ts b/client/src/pages/api/chat/saveChat.ts index 387fc7e42..b0ab366c2 100644 --- a/client/src/pages/api/chat/saveChat.ts +++ b/client/src/pages/api/chat/saveChat.ts @@ -1,7 +1,7 @@ import type { NextApiRequest, NextApiResponse } from 'next'; import { jsonRes } from '@/service/response'; import { ChatItemType } from '@/types/chat'; -import { connectToDatabase, Chat, Model } from '@/service/mongo'; +import { connectToDatabase, Chat, App } from '@/service/mongo'; import { authApp } from '@/service/utils/auth'; import { authUser } from '@/service/utils/auth'; import { Types } from 'mongoose'; @@ -60,7 +60,7 @@ export async function saveChat({ })); if (String(app.userId) === userId) { - await Model.findByIdAndUpdate(modelId, { + await App.findByIdAndUpdate(modelId, { updateTime: new Date() }); } @@ -96,7 +96,7 @@ export async function saveChat({ // update app ...(String(app.userId) === userId ? [ - Model.findByIdAndUpdate(modelId, { + App.findByIdAndUpdate(modelId, { updateTime: new Date() }) ] diff --git a/client/src/pages/api/chat/shareChat/create.ts b/client/src/pages/api/chat/shareChat/create.ts index 197f7c0c1..8ec481d7b 100644 --- a/client/src/pages/api/chat/shareChat/create.ts +++ b/client/src/pages/api/chat/shareChat/create.ts @@ -2,7 +2,7 @@ import type { NextApiRequest, NextApiResponse } from 'next'; import { jsonRes } from '@/service/response'; import { connectToDatabase, ShareChat } from '@/service/mongo'; import { authApp, authUser } from '@/service/utils/auth'; -import type { ShareChatEditType } from '@/types/model'; +import type { ShareChatEditType } from '@/types/app'; /* create a shareChat */ export default async function handler(req: NextApiRequest, res: NextApiResponse) { diff --git a/client/src/pages/api/openapi/v1/chat/completions2.ts b/client/src/pages/api/openapi/v1/chat/completions2.ts index 79bf4eba8..37a7daabb 100644 --- a/client/src/pages/api/openapi/v1/chat/completions2.ts +++ b/client/src/pages/api/openapi/v1/chat/completions2.ts @@ -117,6 +117,7 @@ export default withNextCors(async function handler(req: NextApiRequest, res: Nex }, stream }); + console.log(responseData, answerText); // save chat if (typeof chatId === 'string') { @@ -282,14 +283,17 @@ async function dispatchModules({ if (res.closed) return Promise.resolve(); console.log('run=========', module.type, module.url); + // direct answer if (module.type === AppModuleItemTypeEnum.answer) { + const text = + module.inputs.find((item) => item.key === SpecificInputEnum.answerText)?.value || ''; pushStore({ - answer: module.inputs.find((item) => item.key === SpecificInputEnum.answerText)?.value || '' + answer: text }); return StreamAnswer({ res, stream, - text: module.inputs.find((item) => item.key === SpecificInputEnum.answerText)?.value + text: text }); } @@ -365,9 +369,9 @@ function StreamAnswer({ }: { res: NextApiResponse; stream?: boolean; - text?: ''; + text?: string; }) { - if (stream) { + if (stream && text) { return sseResponse({ res, event: sseResponseEventEnum.answer, diff --git a/client/src/pages/api/plugins/kb/delete.ts b/client/src/pages/api/plugins/kb/delete.ts index d79ac5931..5306aea57 100644 --- a/client/src/pages/api/plugins/kb/delete.ts +++ b/client/src/pages/api/plugins/kb/delete.ts @@ -1,6 +1,6 @@ import type { NextApiRequest, NextApiResponse } from 'next'; import { jsonRes } from '@/service/response'; -import { connectToDatabase, KB, Model, TrainingData } from '@/service/mongo'; +import { connectToDatabase, KB, App, TrainingData } from '@/service/mongo'; import { authUser } from '@/service/utils/auth'; import { PgClient } from '@/service/pg'; import { Types } from 'mongoose'; @@ -32,7 +32,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse< }); // delete related model - await Model.updateMany( + await App.updateMany( { userId }, diff --git a/client/src/pages/app/detail/components/Share.tsx b/client/src/pages/app/detail/components/Share.tsx index c0273a1fc..ada868683 100644 --- a/client/src/pages/app/detail/components/Share.tsx +++ b/client/src/pages/app/detail/components/Share.tsx @@ -36,7 +36,7 @@ import { getShareChatList, delShareChatById, createShareChat } from '@/api/chat' import { formatTimeToChatTime, useCopyData, getErrText } from '@/utils/tools'; import { useForm } from 'react-hook-form'; import { defaultShareChat } from '@/constants/model'; -import type { ShareChatEditType } from '@/types/model'; +import type { ShareChatEditType } from '@/types/app'; const Share = ({ modelId }: { modelId: string }) => { const { toast } = useToast(); diff --git a/client/src/pages/app/detail/index.tsx b/client/src/pages/app/detail/index.tsx index b0f343c58..bb9847f09 100644 --- a/client/src/pages/app/detail/index.tsx +++ b/client/src/pages/app/detail/index.tsx @@ -4,8 +4,8 @@ import { Box, Flex } from '@chakra-ui/react'; import { useUserStore } from '@/store/user'; import { useGlobalStore } from '@/store/global'; import dynamic from 'next/dynamic'; -import Tabs from '@/components/Tabs'; +import Tabs from '@/components/Tabs'; import Settings from './components/Settings'; import { defaultApp } from '@/constants/model'; diff --git a/client/src/pages/model/share/index.module.scss b/client/src/pages/app/list/index.module.scss similarity index 100% rename from client/src/pages/model/share/index.module.scss rename to client/src/pages/app/list/index.module.scss diff --git a/client/src/pages/app/list/index.tsx b/client/src/pages/app/list/index.tsx index 96f064f98..c6a6f0c5a 100644 --- a/client/src/pages/app/list/index.tsx +++ b/client/src/pages/app/list/index.tsx @@ -1,24 +1,81 @@ import React from 'react'; -import { Box, useTheme } from '@chakra-ui/react'; +import { Box, Grid, Card, useTheme, Flex, IconButton, Button } from '@chakra-ui/react'; import { useRouter } from 'next/router'; +import { useUserStore } from '@/store/user'; +import { useQuery } from '@tanstack/react-query'; +import Avatar from '@/components/Avatar'; + +import styles from './index.module.scss'; +import MyIcon from '@/components/Icon'; +import { AddIcon } from '@chakra-ui/icons'; const MyApps = () => { const theme = useTheme(); const router = useRouter(); + const { myApps, loadMyModels } = useUserStore(); + + /* 加载模型 */ + useQuery(['loadModels'], () => loadMyModels(false)); + return ( - router.push(`/app/detail?appId=642adec15f01d67d4613efdb`)} + + + 我的应用 + + + + - 我的应用 - + {myApps.map((app) => ( + router.push(`/app/detail?appId=${app._id}`)} + > + + + {app.name} + } + variant={'base'} + borderRadius={'md'} + aria-label={'delete'} + display={'none'} + _hover={{ + bg: 'myGray.100' + }} + /> + + + {app.intro || '这个应用还没写介绍~'} + + + ))} + ); }; diff --git a/client/src/pages/model/share/components/list.tsx b/client/src/pages/appStore/components/list.tsx similarity index 96% rename from client/src/pages/model/share/components/list.tsx rename to client/src/pages/appStore/components/list.tsx index f070ebc98..f7e118bd3 100644 --- a/client/src/pages/model/share/components/list.tsx +++ b/client/src/pages/appStore/components/list.tsx @@ -1,6 +1,6 @@ import React from 'react'; import { Box, Flex, Button, Tooltip, Card } from '@chakra-ui/react'; -import type { ShareModelItem } from '@/types/model'; +import type { ShareAppItem } from '@/types/app'; import { useRouter } from 'next/router'; import MyIcon from '@/components/Icon'; import styles from '../index.module.scss'; @@ -10,7 +10,7 @@ const ShareModelList = ({ models = [], onclickCollection }: { - models: ShareModelItem[]; + models: ShareAppItem[]; onclickCollection: (modelId: string) => void; }) => { const router = useRouter(); diff --git a/client/src/pages/appStore/index.module.scss b/client/src/pages/appStore/index.module.scss new file mode 100644 index 000000000..02335e410 --- /dev/null +++ b/client/src/pages/appStore/index.module.scss @@ -0,0 +1,7 @@ +.intro { + display: -webkit-box; + -webkit-line-clamp: 3; + -webkit-box-orient: vertical; + overflow: hidden; + text-overflow: ellipsis; +} diff --git a/client/src/pages/model/share/index.tsx b/client/src/pages/appStore/index.tsx similarity index 96% rename from client/src/pages/model/share/index.tsx rename to client/src/pages/appStore/index.tsx index 842e3dfe1..58ca35bd2 100644 --- a/client/src/pages/model/share/index.tsx +++ b/client/src/pages/appStore/index.tsx @@ -3,7 +3,7 @@ import { Box, Flex, Card, Grid, Input } from '@chakra-ui/react'; import { useLoading } from '@/hooks/useLoading'; import { getShareModelList, triggerModelCollection } from '@/api/app'; import { usePagination } from '@/hooks/usePagination'; -import type { ShareModelItem } from '@/types/model'; +import type { ShareAppItem } from '@/types/app'; import { useUserStore } from '@/store/user'; import ShareModelList from './components/list'; import styles from './index.module.scss'; @@ -21,7 +21,7 @@ const modelList = () => { Pagination, getData, pageNum - } = usePagination({ + } = usePagination({ api: getShareModelList, pageSize: 24, params: { diff --git a/client/src/pages/chat/components/ModelList.tsx b/client/src/pages/chat/components/ModelList.tsx index 74fdc00e0..43c1a8195 100644 --- a/client/src/pages/chat/components/ModelList.tsx +++ b/client/src/pages/chat/components/ModelList.tsx @@ -1,10 +1,10 @@ import React from 'react'; import { Box, Flex } from '@chakra-ui/react'; import { useRouter } from 'next/router'; -import { ModelListItemType } from '@/types/model'; +import { AppListItemType } from '@/types/app'; import Avatar from '@/components/Avatar'; -const ModelList = ({ models, modelId }: { models: ModelListItemType[]; modelId: string }) => { +const ModelList = ({ models, modelId }: { models: AppListItemType[]; modelId: string }) => { const router = useRouter(); return ( diff --git a/client/src/pages/model/components/ModelList.tsx b/client/src/pages/model/components/ModelList.tsx deleted file mode 100644 index 66ff63bf7..000000000 --- a/client/src/pages/model/components/ModelList.tsx +++ /dev/null @@ -1,172 +0,0 @@ -import React, { useCallback, useMemo, useState } from 'react'; -import { Box, Flex, Input, IconButton, Tooltip, useTheme } from '@chakra-ui/react'; -import { AddIcon } from '@chakra-ui/icons'; -import { useRouter } from 'next/router'; -import MyIcon from '@/components/Icon'; -import { postCreateModel } from '@/api/app'; -import { useLoading } from '@/hooks/useLoading'; -import { useToast } from '@/hooks/useToast'; -import { useQuery } from '@tanstack/react-query'; -import { useUserStore } from '@/store/user'; -import { MyModelsTypeEnum } from '@/constants/user'; -import dynamic from 'next/dynamic'; - -const Avatar = dynamic(() => import('@/components/Avatar'), { - ssr: false -}); -const Tabs = dynamic(() => import('@/components/Tabs'), { - ssr: false -}); - -const ModelList = ({ modelId }: { modelId: string }) => { - const [currentTab, setCurrentTab] = useState(MyModelsTypeEnum.my); - - const theme = useTheme(); - const router = useRouter(); - const { toast } = useToast(); - const { Loading, setIsLoading } = useLoading(); - const { myApps, myCollectionApps, loadMyModels, refreshModel } = useUserStore(); - const [searchText, setSearchText] = useState(''); - - /* 加载模型 */ - const { isFetching } = useQuery(['loadModels'], () => loadMyModels(false)); - - const onclickCreateModel = useCallback(async () => { - setIsLoading(true); - try { - const id = await postCreateModel({ - name: `AI应用${myApps.length + 1}` - }); - toast({ - title: '创建成功', - status: 'success' - }); - refreshModel.freshMyModels(); - router.push(`/model?modelId=${id}`); - } catch (err: any) { - toast({ - title: typeof err === 'string' ? err : err.message || '出现了意外', - status: 'error' - }); - } - setIsLoading(false); - }, [myApps.length, refreshModel, router, setIsLoading, toast]); - - const currentModels = useMemo(() => { - const map = { - [MyModelsTypeEnum.my]: { - list: myApps.filter((item) => new RegExp(searchText, 'ig').test(item.name + item.intro)), - emptyText: '还没有 AI 应用~\n快来创建一个吧' - }, - [MyModelsTypeEnum.collection]: { - list: myCollectionApps.filter((item) => - new RegExp(searchText, 'ig').test(item.name + item.intro) - ), - emptyText: '收藏的 AI 应用为空~\n快去市场找一个吧' - } - }; - return map[currentTab]; - }, [currentTab, myCollectionApps, myApps, searchText]); - - return ( - - - - setSearchText(e.target.value)} - /> - {searchText && ( - setSearchText('')} - /> - )} - - - } - aria-label={''} - variant={'base'} - onClick={onclickCreateModel} - /> - - - - - setCurrentTab(id)} - /> - - - {currentModels.list.map((item) => ( - { - if (item._id === modelId) return; - router.push(`/model?modelId=${item._id}`); - }} - > - - - - {item.name} - - - - ))} - {!isFetching && currentModels.list.length === 0 && ( - - - - {currentModels.emptyText} - - - )} - - - - ); -}; - -export default ModelList; diff --git a/client/src/pages/model/components/detail/components/API.tsx b/client/src/pages/model/components/detail/components/API.tsx deleted file mode 100644 index 0b805112e..000000000 --- a/client/src/pages/model/components/detail/components/API.tsx +++ /dev/null @@ -1,85 +0,0 @@ -import React, { useEffect, useState } from 'react'; -import { Box, Divider, Flex, useTheme, Button, Skeleton, useDisclosure } from '@chakra-ui/react'; -import { useCopyData } from '@/utils/tools'; -import dynamic from 'next/dynamic'; -import MyIcon from '@/components/Icon'; - -const APIKeyModal = dynamic(() => import('@/components/APIKeyModal'), { - ssr: false -}); - -const API = ({ modelId }: { modelId: string }) => { - const theme = useTheme(); - const { copyData } = useCopyData(); - const [baseUrl, setBaseUrl] = useState('https://fastgpt.run/api/openapi'); - const { - isOpen: isOpenAPIModal, - onOpen: onOpenAPIModal, - onClose: onCloseAPIModal - } = useDisclosure(); - const [isLoaded, setIsLoaded] = useState(false); - - useEffect(() => { - setBaseUrl(`${location.origin}/api/openapi`); - }, []); - - return ( - - - - AppId: - copyData(modelId, '已复制 AppId')} - > - {modelId} - - - copyData(baseUrl, '已复制 API 地址')} - > - - API服务器 - - - {baseUrl} - - - - - - - -