remove invalid code (#2785)

This commit is contained in:
Archer
2024-09-25 09:49:51 +08:00
committed by shilin66
parent d4d3be34a6
commit 4f4f63735f
11 changed files with 95 additions and 192 deletions

View File

@@ -1,35 +0,0 @@
import type { NextApiRequest, NextApiResponse } from 'next';
import { NextAPI } from '@/service/middleware/entry';
import { MongoAppVersion } from '@fastgpt/service/core/app/version/schema';
import { PaginationProps, PaginationResponse } from '@fastgpt/web/common/fetch/type';
import { AppVersionSchemaType } from '@fastgpt/global/core/app/version';
import { ApiRequestProps } from '@fastgpt/service/type/next';
type Props = PaginationProps<{
appId: string;
}>;
type Response = PaginationResponse<AppVersionSchemaType>;
async function handler(req: ApiRequestProps<Props>, res: NextApiResponse<any>): Promise<Response> {
const { offset, pageSize, appId } = req.body;
const [result, total] = await Promise.all([
MongoAppVersion.find({
appId
})
.sort({
time: -1
})
.skip(offset)
.limit(pageSize),
MongoAppVersion.countDocuments({ appId })
]);
return {
total,
list: result
};
}
export default NextAPI(handler);

View File

@@ -1,83 +0,0 @@
import type { NextApiRequest, NextApiResponse } from 'next';
import { NextAPI } from '@/service/middleware/entry';
import { authApp } from '@fastgpt/service/support/permission/app/auth';
import { MongoAppVersion } from '@fastgpt/service/core/app/version/schema';
import { mongoSessionRun } from '@fastgpt/service/common/mongo/sessionRun';
import { MongoApp } from '@fastgpt/service/core/app/schema';
import { beforeUpdateAppFormat } from '@fastgpt/service/core/app/controller';
import { getNextTimeByCronStringAndTimezone } from '@fastgpt/global/common/string/time';
import { PostRevertAppProps } from '@/global/core/app/api';
import { WritePermissionVal } from '@fastgpt/global/support/permission/constant';
import { AppTypeEnum } from '@fastgpt/global/core/app/constants';
type Response = {};
async function handler(req: NextApiRequest, res: NextApiResponse<any>): Promise<{}> {
const { appId } = req.query as { appId: string };
const {
editNodes = [],
editEdges = [],
editChatConfig,
versionId
} = req.body as PostRevertAppProps;
const { app } = await authApp({ appId, req, per: WritePermissionVal, authToken: true });
const version = await MongoAppVersion.findOne({
_id: versionId,
appId
});
if (!version) {
throw new Error('version not found');
}
const { nodes: formatEditNodes } = beforeUpdateAppFormat({ nodes: editNodes });
const scheduledTriggerConfig = version.chatConfig?.scheduledTriggerConfig;
await mongoSessionRun(async (session) => {
// 为编辑中的数据创建一个版本
await MongoAppVersion.create(
[
{
appId,
nodes: formatEditNodes,
edges: editEdges,
chatConfig: editChatConfig
}
],
{ session }
);
// 为历史版本再创建一个版本
const [{ _id }] = await MongoAppVersion.create(
[
{
appId,
nodes: version.nodes,
edges: version.edges,
chatConfig: version.chatConfig
}
],
{ session }
);
// update app
await MongoApp.findByIdAndUpdate(appId, {
modules: version.nodes,
edges: version.edges,
chatConfig: version.chatConfig,
updateTime: new Date(),
scheduledTriggerConfig: scheduledTriggerConfig ? scheduledTriggerConfig : null,
scheduledTriggerNextTime: scheduledTriggerConfig?.cronString
? getNextTimeByCronStringAndTimezone(scheduledTriggerConfig)
: null,
'pluginData.nodeVersion': _id
});
});
return {};
}
export default NextAPI(handler);

View File

@@ -23,7 +23,7 @@ import { useUserStore } from '@/web/support/user/useUserStore';
import { useRequest2 } from '@fastgpt/web/hooks/useRequest'; import { useRequest2 } from '@fastgpt/web/hooks/useRequest';
import { useSystemStore } from '@/web/common/system/useSystemStore'; import { useSystemStore } from '@/web/common/system/useSystemStore';
import { useToast } from '@fastgpt/web/hooks/useToast'; import { useToast } from '@fastgpt/web/hooks/useToast';
import { versionListResponse } from '@/pages/api/core/app/version/listWorkflow'; import type { versionListResponse } from '@/pages/api/core/app/version/list';
const PublishHistoriesSlider = ({ const PublishHistoriesSlider = ({
onClose, onClose,

View File

@@ -15,10 +15,11 @@ import { cardStyles } from '../constants';
import styles from './styles.module.scss'; import styles from './styles.module.scss';
import { useSystem } from '@fastgpt/web/hooks/useSystem'; import { useSystem } from '@fastgpt/web/hooks/useSystem';
import { storeEdgesRenderEdge, storeNode2FlowNode } from '@/web/core/workflow/utils'; import { storeNode2FlowNode } from '@/web/core/workflow/utils';
import { useTranslation } from 'next-i18next'; import { useTranslation } from 'next-i18next';
import { uiWorkflow2StoreWorkflow } from '../WorkflowComponents/utils'; import { uiWorkflow2StoreWorkflow } from '../WorkflowComponents/utils';
import { SnapshotsType } from '../WorkflowComponents/context'; import { SnapshotsType } from '../WorkflowComponents/context';
import { SaveSnapshotFnType } from './useSnapshots';
const Edit = ({ const Edit = ({
appForm, appForm,
@@ -29,32 +30,33 @@ const Edit = ({
appForm: AppSimpleEditFormType; appForm: AppSimpleEditFormType;
setAppForm: React.Dispatch<React.SetStateAction<AppSimpleEditFormType>>; setAppForm: React.Dispatch<React.SetStateAction<AppSimpleEditFormType>>;
past: SnapshotsType[]; past: SnapshotsType[];
saveSnapshot: ( saveSnapshot: SaveSnapshotFnType;
this: any,
{ pastNodes, pastEdges, chatConfig, customTitle, isSaved }: any
) => Promise<boolean>;
}) => { }) => {
const { isPc } = useSystem(); const { isPc } = useSystem();
const { loadAllDatasets } = useDatasetStore(); const { loadAllDatasets } = useDatasetStore();
const { appDetail } = useContextSelector(AppContext, (v) => v); const { appDetail } = useContextSelector(AppContext, (v) => v);
const { t } = useTranslation(); const { t } = useTranslation();
// show selected dataset // Init app form
useMount(() => { useMount(() => {
// show selected dataset
loadAllDatasets(); loadAllDatasets();
saveSnapshot({
pastNodes: appDetail.modules?.map((item) => storeNode2FlowNode({ item, t })), // Get the latest snapshot
pastEdges: appDetail.edges?.map((item) => storeEdgesRenderEdge({ edge: item })),
chatConfig: appDetail.chatConfig,
isSaved: true
});
if (past.length > 0) { if (past.length > 0) {
const storeWorkflow = uiWorkflow2StoreWorkflow(past[0]); const storeWorkflow = uiWorkflow2StoreWorkflow(past[0]);
const currentAppForm = appWorkflow2Form({ ...storeWorkflow, chatConfig: past[0].chatConfig }); const currentAppForm = appWorkflow2Form({ ...storeWorkflow, chatConfig: past[0].chatConfig });
setAppForm(currentAppForm); return setAppForm(currentAppForm);
return;
} }
// Set the first snapshot
saveSnapshot({
pastNodes: appDetail.modules?.map((item) => storeNode2FlowNode({ item, t })),
chatConfig: appDetail.chatConfig,
isSaved: true
});
setAppForm( setAppForm(
appWorkflow2Form({ appWorkflow2Form({
nodes: appDetail.modules, nodes: appDetail.modules,

View File

@@ -30,6 +30,7 @@ import {
storeNode2FlowNode storeNode2FlowNode
} from '@/web/core/workflow/utils'; } from '@/web/core/workflow/utils';
import { uiWorkflow2StoreWorkflow } from '../WorkflowComponents/utils'; import { uiWorkflow2StoreWorkflow } from '../WorkflowComponents/utils';
import { SaveSnapshotFnType } from './useSnapshots';
const PublishHistories = dynamic(() => import('../PublishHistoriesSlider')); const PublishHistories = dynamic(() => import('../PublishHistoriesSlider'));
@@ -44,15 +45,12 @@ const Header = ({
setAppForm: (form: AppSimpleEditFormType) => void; setAppForm: (form: AppSimpleEditFormType) => void;
past: SnapshotsType[]; past: SnapshotsType[];
setPast: (value: React.SetStateAction<SnapshotsType[]>) => void; setPast: (value: React.SetStateAction<SnapshotsType[]>) => void;
saveSnapshot: ( saveSnapshot: SaveSnapshotFnType;
this: any,
{ pastNodes, pastEdges, chatConfig, customTitle, isSaved }: any
) => Promise<boolean>;
}) => { }) => {
const { t } = useTranslation(); const { t } = useTranslation();
const { isPc } = useSystem(); const { isPc } = useSystem();
const router = useRouter(); const router = useRouter();
const { appId, appDetail, onSaveApp, currentTab } = useContextSelector(AppContext, (v) => v); const { appId, onSaveApp, currentTab } = useContextSelector(AppContext, (v) => v);
const { lastAppListRouteType } = useSystemStore(); const { lastAppListRouteType } = useSystemStore();
const { allDatasets } = useDatasetStore(); const { allDatasets } = useDatasetStore();
@@ -62,8 +60,6 @@ const Header = ({
}); });
const onClickRoute = useCallback( const onClickRoute = useCallback(
(parentId: string) => { (parentId: string) => {
localStorage.removeItem(`${appDetail._id}-past`);
router.push({ router.push({
pathname: '/app/list', pathname: '/app/list',
query: { query: {
@@ -75,8 +71,6 @@ const Header = ({
[router, lastAppListRouteType] [router, lastAppListRouteType]
); );
const [isPublished, setIsPublished] = useState(false);
const { runAsync: onClickSave, loading } = useRequest2( const { runAsync: onClickSave, loading } = useRequest2(
async ({ async ({
isPublish, isPublish,
@@ -109,20 +103,23 @@ const Header = ({
const [historiesDefaultData, setHistoriesDefaultData] = useState<InitProps>(); const [historiesDefaultData, setHistoriesDefaultData] = useState<InitProps>();
const resetSnapshot = (data: SnapshotsType) => { const resetSnapshot = useCallback(
const storeWorkflow = uiWorkflow2StoreWorkflow(data); (data: SnapshotsType) => {
const currentAppForm = appWorkflow2Form({ ...storeWorkflow, chatConfig: data.chatConfig }); const storeWorkflow = uiWorkflow2StoreWorkflow(data);
const currentAppForm = appWorkflow2Form({ ...storeWorkflow, chatConfig: data.chatConfig });
setAppForm(currentAppForm); setAppForm(currentAppForm);
}; },
[setAppForm]
);
// Save snapshot to local
useDebounceEffect( useDebounceEffect(
() => { () => {
const data = form2AppWorkflow(appForm, t); const data = form2AppWorkflow(appForm, t);
saveSnapshot({ saveSnapshot({
pastNodes: data.nodes?.map((item) => storeNode2FlowNode({ item, t })), pastNodes: data.nodes?.map((item) => storeNode2FlowNode({ item, t })),
pastEdges: data.edges?.map((item) => storeEdgesRenderEdge({ edge: item })),
chatConfig: data.chatConfig chatConfig: data.chatConfig
}); });
}, },
@@ -130,10 +127,13 @@ const Header = ({
{ wait: 500 } { wait: 500 }
); );
// Check if the workflow is published
const [isPublished, setIsPublished] = useState(false);
useDebounceEffect( useDebounceEffect(
() => { () => {
const savedSnapshot = past.find((snapshot) => snapshot.isSaved); const savedSnapshot = past.find((snapshot) => snapshot.isSaved);
const data = form2AppWorkflow(appForm, t); const editFormData = form2AppWorkflow(appForm, t);
console.log(savedSnapshot?.nodes, editFormData.chatConfig);
const val = compareSnapshot( const val = compareSnapshot(
{ {
nodes: savedSnapshot?.nodes, nodes: savedSnapshot?.nodes,
@@ -141,14 +141,14 @@ const Header = ({
chatConfig: savedSnapshot?.chatConfig chatConfig: savedSnapshot?.chatConfig
}, },
{ {
nodes: data.nodes?.map((item) => storeNode2FlowNode({ item, t })), nodes: editFormData.nodes?.map((item) => storeNode2FlowNode({ item, t })),
edges: [], edges: [],
chatConfig: data.chatConfig chatConfig: editFormData.chatConfig
} }
); );
setIsPublished(val); setIsPublished(val);
}, },
[past], [past, allDatasets],
{ wait: 500 } { wait: 500 }
); );

View File

@@ -1,8 +1,16 @@
import { useLocalStorageState, useMemoizedFn } from 'ahooks'; import { useLocalStorageState, useMemoizedFn } from 'ahooks';
import { SnapshotsType } from '../WorkflowComponents/context'; import { SaveSnapshotParams, SnapshotsType } from '../WorkflowComponents/context';
import { SetStateAction } from 'react'; import { SetStateAction, useEffect } from 'react';
import { compareSnapshot } from '@/web/core/workflow/utils'; import { compareSnapshot } from '@/web/core/workflow/utils';
import { formatTime2YMDHMS } from '@fastgpt/global/common/string/time'; import { formatTime2YMDHMS } from '@fastgpt/global/common/string/time';
import { AppChatConfigType } from '@fastgpt/global/core/app/type';
import { Node } from 'reactflow';
export type SaveSnapshotFnType = (
props: SaveSnapshotParams & {
isSaved?: boolean;
}
) => Promise<boolean>;
const useSnapshots = (appId: string) => { const useSnapshots = (appId: string) => {
const [past, setPast] = useLocalStorageState<SnapshotsType[]>(`${appId}-past-simple`, { const [past, setPast] = useLocalStorageState<SnapshotsType[]>(`${appId}-past-simple`, {
@@ -10,13 +18,16 @@ const useSnapshots = (appId: string) => {
listenStorageChange: true listenStorageChange: true
}) as [SnapshotsType[], (value: SetStateAction<SnapshotsType[]>) => void]; }) as [SnapshotsType[], (value: SetStateAction<SnapshotsType[]>) => void];
const saveSnapshot = useMemoizedFn( const saveSnapshot: SaveSnapshotFnType = useMemoizedFn(
async ({ pastNodes, pastEdges, chatConfig, customTitle, isSaved }) => { async ({ pastNodes, chatConfig, customTitle, isSaved }) => {
if (!pastNodes) return false;
const pastState = past[0]; const pastState = past[0];
const isPastEqual = compareSnapshot( const isPastEqual = compareSnapshot(
{ {
nodes: pastNodes, nodes: pastNodes,
edges: pastEdges, edges: [],
chatConfig: chatConfig chatConfig: chatConfig
}, },
{ {
@@ -30,7 +41,7 @@ const useSnapshots = (appId: string) => {
setPast((past) => [ setPast((past) => [
{ {
nodes: pastNodes, nodes: pastNodes,
edges: pastEdges, edges: [],
title: customTitle || formatTime2YMDHMS(new Date()), title: customTitle || formatTime2YMDHMS(new Date()),
chatConfig, chatConfig,
isSaved isSaved
@@ -41,6 +52,18 @@ const useSnapshots = (appId: string) => {
} }
); );
// remove other app's snapshot
useEffect(() => {
const keys = Object.keys(localStorage);
const snapshotKeys = keys.filter((key) => key.endsWith('-past-simple'));
snapshotKeys.forEach((key) => {
const keyAppId = key.split('-')[0];
if (keyAppId !== appId) {
localStorage.removeItem(key);
}
});
}, [appId]);
return { past, setPast, saveSnapshot }; return { past, setPast, saveSnapshot };
}; };

View File

@@ -279,20 +279,22 @@ const Header = () => {
currentTab, currentTab,
isPublished, isPublished,
onBack, onBack,
isOpenBackConfirm,
onOpenBackConfirm, onOpenBackConfirm,
onCloseBackConfirm,
t,
loading,
isV2Workflow, isV2Workflow,
historiesDefaultData, historiesDefaultData,
t,
loading,
onClickSave, onClickSave,
flowData2StoreDataAndCheck,
past,
saveSnapshot,
resetSnapshot,
isOpenBackConfirm,
onCloseBackConfirm,
setHistoriesDefaultData, setHistoriesDefaultData,
appDetail.chatConfig, appDetail.chatConfig,
flowData2StoreDataAndCheck,
setWorkflowTestData, setWorkflowTestData,
toast, toast
past
]); ]);
return Render; return Render;

View File

@@ -63,7 +63,7 @@ export type SaveSnapshotParams = {
pastNodes?: Node[]; pastNodes?: Node[];
pastEdges?: Edge[]; pastEdges?: Edge[];
customTitle?: string; customTitle?: string;
chatConfig?: AppChatConfigType; chatConfig: AppChatConfigType;
}; };
export type InitProps = { export type InitProps = {
nodes: AppSchema['modules']; nodes: AppSchema['modules'];
@@ -892,6 +892,18 @@ const WorkflowContextProvider = ({
} }
}); });
// remove other app's snapshot
useEffect(() => {
const keys = Object.keys(localStorage);
const snapshotKeys = keys.filter((key) => key.endsWith('-past') || key.endsWith('-future'));
snapshotKeys.forEach((key) => {
const keyAppId = key.split('-')[0];
if (keyAppId !== appId) {
localStorage.removeItem(key);
}
});
}, [appId]);
const initData = useMemoizedFn( const initData = useMemoizedFn(
async (e: Parameters<WorkflowContextType['initData']>[0], isInit?: boolean) => { async (e: Parameters<WorkflowContextType['initData']>[0], isInit?: boolean) => {
/* /*
@@ -925,18 +937,6 @@ const WorkflowContextProvider = ({
} }
); );
// remove other app's snapshot
useEffect(() => {
const keys = Object.keys(localStorage);
const snapshotKeys = keys.filter((key) => key.endsWith('-past') || key.endsWith('-future'));
snapshotKeys.forEach((key) => {
const keyAppId = key.split('-')[0];
if (keyAppId !== appId) {
localStorage.removeItem(key);
}
});
}, [appId]);
/* Version histories */ /* Version histories */
const [historiesDefaultData, setHistoriesDefaultData] = useState<InitProps>(); const [historiesDefaultData, setHistoriesDefaultData] = useState<InitProps>();

View File

@@ -1,13 +1,13 @@
import { PostPublishAppProps, PostRevertAppProps } from '@/global/core/app/api'; import { PostPublishAppProps, PostRevertAppProps } from '@/global/core/app/api';
import { GET, POST, DELETE, PUT } from '@/web/common/api/request'; import { GET, POST, DELETE, PUT } from '@/web/common/api/request';
import { AppVersionSchemaType } from '@fastgpt/global/core/app/version'; import type { AppVersionSchemaType } from '@fastgpt/global/core/app/version';
import { PaginationProps, PaginationResponse } from '@fastgpt/web/common/fetch/type'; import { PaginationProps, PaginationResponse } from '@fastgpt/web/common/fetch/type';
import type { import type {
getLatestVersionQuery, getLatestVersionQuery,
getLatestVersionResponse getLatestVersionResponse
} from '@/pages/api/core/app/version/latest'; } from '@/pages/api/core/app/version/latest';
import { UpdateAppVersionBody } from '@/pages/api/core/app/version/update'; import type { UpdateAppVersionBody } from '@/pages/api/core/app/version/update';
import { versionListResponse } from '@/pages/api/core/app/version/listWorkflow'; import type { versionListResponse } from '@/pages/api/core/app/version/list';
export const getAppLatestVersion = (data: getLatestVersionQuery) => export const getAppLatestVersion = (data: getLatestVersionQuery) =>
GET<getLatestVersionResponse>('/core/app/version/latest', data); GET<getLatestVersionResponse>('/core/app/version/latest', data);
@@ -15,17 +15,11 @@ export const getAppLatestVersion = (data: getLatestVersionQuery) =>
export const postPublishApp = (appId: string, data: PostPublishAppProps) => export const postPublishApp = (appId: string, data: PostPublishAppProps) =>
POST(`/core/app/version/publish?appId=${appId}`, data); POST(`/core/app/version/publish?appId=${appId}`, data);
// export const getPublishList = (data: PaginationProps<{ appId: string }>) =>
// POST<PaginationResponse<AppVersionSchemaType>>('/core/app/version/list', data);
export const getWorkflowVersionList = (data: PaginationProps<{ appId: string }>) => export const getWorkflowVersionList = (data: PaginationProps<{ appId: string }>) =>
POST<PaginationResponse<versionListResponse>>('/core/app/version/listWorkflow', data); POST<PaginationResponse<versionListResponse>>('/core/app/version/list', data);
export const getAppVersionDetail = (versionId: string, appId: string) => export const getAppVersionDetail = (versionId: string, appId: string) =>
GET<AppVersionSchemaType>(`/core/app/version/detail?versionId=${versionId}&appId=${appId}`); GET<AppVersionSchemaType>(`/core/app/version/detail?versionId=${versionId}&appId=${appId}`);
// export const postRevertVersion = (appId: string, data: PostRevertAppProps) =>
// POST(`/core/app/version/revert?appId=${appId}`, data);
export const updateAppVersion = (data: UpdateAppVersionBody) => export const updateAppVersion = (data: UpdateAppVersionBody) =>
POST(`/core/app/version/update`, data); POST(`/core/app/version/update`, data);

View File

@@ -440,14 +440,14 @@ export const getLatestNodeTemplate = (
export const compareSnapshot = ( export const compareSnapshot = (
snapshot1: { snapshot1: {
nodes: Node<FlowNodeItemType, string | undefined>[] | undefined; nodes?: Node[];
edges: Edge<any>[] | undefined; edges: Edge<any>[] | undefined;
chatConfig: AppChatConfigType | undefined; chatConfig?: AppChatConfigType;
}, },
snapshot2: { snapshot2: {
nodes: Node<FlowNodeItemType, string | undefined>[]; nodes?: Node[];
edges: Edge<any>[]; edges: Edge<any>[];
chatConfig: AppChatConfigType; chatConfig?: AppChatConfigType;
} }
) => { ) => {
const clone1 = cloneDeep(snapshot1); const clone1 = cloneDeep(snapshot1);