From 1b70a7e4c758c7a2f01d213d736c34650ec70889 Mon Sep 17 00:00:00 2001 From: hjlarry Date: Wed, 21 Jan 2026 18:20:38 +0800 Subject: [PATCH] use contract for api request --- web/contract/console/account.ts | 14 ++ web/contract/console/apps.ts | 15 ++ web/contract/console/workflow-comment.ts | 259 +++++++++++++++++++++++ web/contract/console/workflow.ts | 80 +++++++ web/contract/router.ts | 22 ++ web/service/apps.ts | 7 +- web/service/common.ts | 3 +- web/service/workflow-comment.ts | 186 ++++++---------- web/service/workflow.ts | 36 ++-- 9 files changed, 478 insertions(+), 144 deletions(-) create mode 100644 web/contract/console/account.ts create mode 100644 web/contract/console/apps.ts create mode 100644 web/contract/console/workflow-comment.ts create mode 100644 web/contract/console/workflow.ts diff --git a/web/contract/console/account.ts b/web/contract/console/account.ts new file mode 100644 index 0000000000..a8a468c40d --- /dev/null +++ b/web/contract/console/account.ts @@ -0,0 +1,14 @@ +import { type } from '@orpc/contract' +import { base } from '../base' + +export const accountAvatarContract = base + .route({ + path: '/account/avatar', + method: 'GET', + }) + .input(type<{ + query: { + avatar: string + } + }>()) + .output(type<{ avatar_url: string }>()) diff --git a/web/contract/console/apps.ts b/web/contract/console/apps.ts new file mode 100644 index 0000000000..5d05bb0196 --- /dev/null +++ b/web/contract/console/apps.ts @@ -0,0 +1,15 @@ +import type { WorkflowOnlineUsersResponse } from '@/models/app' +import { type } from '@orpc/contract' +import { base } from '../base' + +export const workflowOnlineUsersContract = base + .route({ + path: '/apps/workflows/online-users', + method: 'GET', + }) + .input(type<{ + query: { + workflow_ids: string + } + }>()) + .output(type()) diff --git a/web/contract/console/workflow-comment.ts b/web/contract/console/workflow-comment.ts new file mode 100644 index 0000000000..cac1307b0a --- /dev/null +++ b/web/contract/console/workflow-comment.ts @@ -0,0 +1,259 @@ +import type { CommonResponse } from '@/models/common' +import { type } from '@orpc/contract' +import { base } from '../base' + +export type UserProfile = { + id: string + name: string + email: string + avatar_url?: string +} + +export type WorkflowCommentList = { + id: string + position_x: number + position_y: number + content: string + created_by: string + created_by_account: UserProfile + created_at: number + updated_at: number + resolved: boolean + resolved_by?: string + resolved_by_account?: UserProfile + resolved_at?: number + mention_count: number + reply_count: number + participants: UserProfile[] +} + +export type WorkflowCommentDetailMention = { + mentioned_user_id: string + mentioned_user_account?: UserProfile | null + reply_id: string | null +} + +export type WorkflowCommentDetailReply = { + id: string + content: string + created_by: string + created_by_account?: UserProfile | null + created_at: number +} + +export type WorkflowCommentDetail = { + id: string + position_x: number + position_y: number + content: string + created_by: string + created_by_account: UserProfile + created_at: number + updated_at: number + resolved: boolean + resolved_by?: string + resolved_by_account?: UserProfile + resolved_at?: number + replies: WorkflowCommentDetailReply[] + mentions: WorkflowCommentDetailMention[] +} + +export type WorkflowCommentCreateRes = { + id: string + created_at: string +} + +export type WorkflowCommentUpdateRes = { + id: string + updated_at: string +} + +export type WorkflowCommentResolveRes = { + id: string + resolved: boolean + resolved_by: string + resolved_at: number +} + +export type WorkflowCommentReply = { + id: string + comment_id: string + content: string + created_by: string + created_at: string + updated_at: string + mentioned_user_ids: string[] + author: { + id: string + name: string + email: string + avatar?: string + } +} + +export type CreateCommentParams = { + position_x: number + position_y: number + content: string + mentioned_user_ids?: string[] +} + +export type UpdateCommentParams = { + content: string + position_x?: number + position_y?: number + mentioned_user_ids?: string[] +} + +export type CreateReplyParams = { + content: string + mentioned_user_ids?: string[] +} + +export const workflowCommentListContract = base + .route({ + path: '/apps/{appId}/workflow/comments', + method: 'GET', + }) + .input(type<{ + params: { + appId: string + } + }>()) + .output(type<{ data: WorkflowCommentList[] }>()) + +export const workflowCommentCreateContract = base + .route({ + path: '/apps/{appId}/workflow/comments', + method: 'POST', + }) + .input(type<{ + params: { + appId: string + } + body: CreateCommentParams + }>()) + .output(type()) + +export const workflowCommentDetailContract = base + .route({ + path: '/apps/{appId}/workflow/comments/{commentId}', + method: 'GET', + }) + .input(type<{ + params: { + appId: string + commentId: string + } + }>()) + .output(type()) + +export const workflowCommentUpdateContract = base + .route({ + path: '/apps/{appId}/workflow/comments/{commentId}', + method: 'PUT', + }) + .input(type<{ + params: { + appId: string + commentId: string + } + body: UpdateCommentParams + }>()) + .output(type()) + +export const workflowCommentDeleteContract = base + .route({ + path: '/apps/{appId}/workflow/comments/{commentId}', + method: 'DELETE', + }) + .input(type<{ + params: { + appId: string + commentId: string + } + }>()) + .output(type()) + +export const workflowCommentResolveContract = base + .route({ + path: '/apps/{appId}/workflow/comments/{commentId}/resolve', + method: 'POST', + }) + .input(type<{ + params: { + appId: string + commentId: string + } + }>()) + .output(type()) + +export const workflowCommentReplyCreateContract = base + .route({ + path: '/apps/{appId}/workflow/comments/{commentId}/replies', + method: 'POST', + }) + .input(type<{ + params: { + appId: string + commentId: string + } + body: CreateReplyParams + }>()) + .output(type()) + +export const workflowCommentReplyUpdateContract = base + .route({ + path: '/apps/{appId}/workflow/comments/{commentId}/replies/{replyId}', + method: 'PUT', + }) + .input(type<{ + params: { + appId: string + commentId: string + replyId: string + } + body: CreateReplyParams + }>()) + .output(type()) + +export const workflowCommentReplyDeleteContract = base + .route({ + path: '/apps/{appId}/workflow/comments/{commentId}/replies/{replyId}', + method: 'DELETE', + }) + .input(type<{ + params: { + appId: string + commentId: string + replyId: string + } + }>()) + .output(type()) + +export const workflowCommentMentionUsersContract = base + .route({ + path: '/apps/{appId}/workflow/comments/mention-users', + method: 'GET', + }) + .input(type<{ + params: { + appId: string + } + }>()) + .output(type<{ users: UserProfile[] }>()) + +export const workflowCommentContracts = { + list: workflowCommentListContract, + create: workflowCommentCreateContract, + detail: workflowCommentDetailContract, + update: workflowCommentUpdateContract, + delete: workflowCommentDeleteContract, + resolve: workflowCommentResolveContract, + mentionUsers: workflowCommentMentionUsersContract, + replies: { + create: workflowCommentReplyCreateContract, + update: workflowCommentReplyUpdateContract, + delete: workflowCommentReplyDeleteContract, + }, +} diff --git a/web/contract/console/workflow.ts b/web/contract/console/workflow.ts new file mode 100644 index 0000000000..2c70a58e25 --- /dev/null +++ b/web/contract/console/workflow.ts @@ -0,0 +1,80 @@ +import type { + FileUpload, + RetrieverResource, + SensitiveWordAvoidance, + SpeechToText, + SuggestedQuestionsAfterAnswer, + TextToSpeech, +} from '@/app/components/base/features/types' +import type { ConversationVariable, EnvironmentVariable } from '@/app/components/workflow/types' +import type { CommonResponse } from '@/models/common' +import { type } from '@orpc/contract' +import { base } from '../base' + +export type WorkflowDraftFeaturesPayload = { + opening_statement: string + suggested_questions: string[] + suggested_questions_after_answer?: SuggestedQuestionsAfterAnswer + text_to_speech?: TextToSpeech + speech_to_text?: SpeechToText + retriever_resource?: RetrieverResource + sensitive_word_avoidance?: SensitiveWordAvoidance + file_upload?: FileUpload +} + +export const workflowDraftEnvironmentVariablesContract = base + .route({ + path: '/apps/{appId}/workflows/draft/environment-variables', + method: 'GET', + }) + .input(type<{ + params: { + appId: string + } + }>()) + .output(type<{ items: EnvironmentVariable[] }>()) + +export const workflowDraftUpdateEnvironmentVariablesContract = base + .route({ + path: '/apps/{appId}/workflows/draft/environment-variables', + method: 'POST', + }) + .input(type<{ + params: { + appId: string + } + body: { + environment_variables: EnvironmentVariable[] + } + }>()) + .output(type()) + +export const workflowDraftUpdateConversationVariablesContract = base + .route({ + path: '/apps/{appId}/workflows/draft/conversation-variables', + method: 'POST', + }) + .input(type<{ + params: { + appId: string + } + body: { + conversation_variables: ConversationVariable[] + } + }>()) + .output(type()) + +export const workflowDraftUpdateFeaturesContract = base + .route({ + path: '/apps/{appId}/workflows/draft/features', + method: 'POST', + }) + .input(type<{ + params: { + appId: string + } + body: { + features: WorkflowDraftFeaturesPayload + } + }>()) + .output(type()) diff --git a/web/contract/router.ts b/web/contract/router.ts index b1c100ab08..2c1e74cab3 100644 --- a/web/contract/router.ts +++ b/web/contract/router.ts @@ -1,6 +1,15 @@ import type { InferContractRouterInputs } from '@orpc/contract' +import { accountAvatarContract } from './console/account' +import { workflowOnlineUsersContract } from './console/apps' import { bindPartnerStackContract, invoicesContract } from './console/billing' import { systemFeaturesContract } from './console/system' +import { + workflowDraftEnvironmentVariablesContract, + workflowDraftUpdateConversationVariablesContract, + workflowDraftUpdateEnvironmentVariablesContract, + workflowDraftUpdateFeaturesContract, +} from './console/workflow' +import { workflowCommentContracts } from './console/workflow-comment' import { collectionPluginsContract, collectionsContract, searchAdvancedContract } from './marketplace' export const marketplaceRouterContract = { @@ -12,11 +21,24 @@ export const marketplaceRouterContract = { export type MarketPlaceInputs = InferContractRouterInputs export const consoleRouterContract = { + account: { + avatar: accountAvatarContract, + }, systemFeatures: systemFeaturesContract, billing: { invoices: invoicesContract, bindPartnerStack: bindPartnerStackContract, }, + apps: { + workflowOnlineUsers: workflowOnlineUsersContract, + }, + workflowDraft: { + environmentVariables: workflowDraftEnvironmentVariablesContract, + updateEnvironmentVariables: workflowDraftUpdateEnvironmentVariablesContract, + updateConversationVariables: workflowDraftUpdateConversationVariablesContract, + updateFeatures: workflowDraftUpdateFeaturesContract, + }, + workflowComments: workflowCommentContracts, } export type ConsoleInputs = InferContractRouterInputs diff --git a/web/service/apps.ts b/web/service/apps.ts index 977228df15..2a186afc78 100644 --- a/web/service/apps.ts +++ b/web/service/apps.ts @@ -1,8 +1,9 @@ import type { TracingProvider } from '@/app/(commonLayout)/app/(appDetailLayout)/[appId]/overview/tracing/type' -import type { ApiKeysListResponse, AppDailyConversationsResponse, AppDailyEndUsersResponse, AppDailyMessagesResponse, AppDetailResponse, AppListResponse, AppStatisticsResponse, AppTemplatesResponse, AppTokenCostsResponse, AppVoicesListResponse, CreateApiKeyResponse, DSLImportMode, DSLImportResponse, GenerationIntroductionResponse, TracingConfig, TracingStatus, UpdateAppModelConfigResponse, UpdateAppSiteCodeResponse, UpdateOpenAIKeyResponse, ValidateOpenAIKeyResponse, WebhookTriggerResponse, WorkflowDailyConversationsResponse, WorkflowOnlineUser, WorkflowOnlineUsersResponse } from '@/models/app' +import type { ApiKeysListResponse, AppDailyConversationsResponse, AppDailyEndUsersResponse, AppDailyMessagesResponse, AppDetailResponse, AppListResponse, AppStatisticsResponse, AppTemplatesResponse, AppTokenCostsResponse, AppVoicesListResponse, CreateApiKeyResponse, DSLImportMode, DSLImportResponse, GenerationIntroductionResponse, TracingConfig, TracingStatus, UpdateAppModelConfigResponse, UpdateAppSiteCodeResponse, UpdateOpenAIKeyResponse, ValidateOpenAIKeyResponse, WebhookTriggerResponse, WorkflowDailyConversationsResponse, WorkflowOnlineUser } from '@/models/app' import type { CommonResponse } from '@/models/common' import type { AppIconType, AppModeEnum, ModelConfig } from '@/types/app' import { del, get, patch, post, put } from './base' +import { consoleClient } from './client' export const fetchAppList = ({ url, params }: { url: string, params?: Record }): Promise => { return get(url, { params }) @@ -13,7 +14,9 @@ export const fetchWorkflowOnlineUsers = async ({ workflowIds }: { workflowIds: s return {} const params = { workflow_ids: workflowIds.join(',') } - const response = await get('apps/workflows/online-users', { params }) + const response = await consoleClient.apps.workflowOnlineUsers({ + query: params, + }) if (!response || !response.data) return {} diff --git a/web/service/common.ts b/web/service/common.ts index 02215309a0..01a1c36bd5 100644 --- a/web/service/common.ts +++ b/web/service/common.ts @@ -35,6 +35,7 @@ import type { } from '@/models/common' import type { RETRIEVE_METHOD } from '@/types/app' import { del, get, patch, post, put } from './base' +import { consoleClient } from './client' type LoginSuccess = { result: 'success' @@ -385,4 +386,4 @@ export const checkEmailExisted = (body: { email: string }): Promise('/account/change-email/check-email-unique', { body }, { silent: true }) export const getAvatar = ({ avatar }: { avatar: string }): Promise<{ avatar_url: string }> => - get<{ avatar_url: string }>('/account/avatar', { params: { avatar } }) + consoleClient.account.avatar({ query: { avatar } }) diff --git a/web/service/workflow-comment.ts b/web/service/workflow-comment.ts index 4dd407eabf..28e7729f3b 100644 --- a/web/service/workflow-comment.ts +++ b/web/service/workflow-comment.ts @@ -1,152 +1,102 @@ +import type { + CreateCommentParams, + CreateReplyParams, + UpdateCommentParams, + WorkflowCommentCreateRes, + WorkflowCommentDetail, + WorkflowCommentList, + WorkflowCommentReply, + WorkflowCommentResolveRes, + WorkflowCommentUpdateRes, +} from '@/contract/console/workflow-comment' import type { CommonResponse } from '@/models/common' -import { del, get, post, put } from './base' +import { consoleClient } from './client' -export type UserProfile = { - id: string - name: string - email: string - avatar_url?: string -} - -export type WorkflowCommentList = { - id: string - position_x: number - position_y: number - content: string - created_by: string - created_by_account: UserProfile - created_at: number - updated_at: number - resolved: boolean - resolved_by?: string - resolved_by_account?: UserProfile - resolved_at?: number - mention_count: number - reply_count: number - participants: UserProfile[] -} - -export type WorkflowCommentDetailMention = { - mentioned_user_id: string - mentioned_user_account?: UserProfile | null - reply_id: string | null -} - -export type WorkflowCommentDetailReply = { - id: string - content: string - created_by: string - created_by_account?: UserProfile | null - created_at: number -} - -export type WorkflowCommentDetail = { - id: string - position_x: number - position_y: number - content: string - created_by: string - created_by_account: UserProfile - created_at: number - updated_at: number - resolved: boolean - resolved_by?: string - resolved_by_account?: UserProfile - resolved_at?: number - replies: WorkflowCommentDetailReply[] - mentions: WorkflowCommentDetailMention[] -} - -export type WorkflowCommentCreateRes = { - id: string - created_at: string -} - -export type WorkflowCommentUpdateRes = { - id: string - updated_at: string -} - -export type WorkflowCommentResolveRes = { - id: string - resolved: boolean - resolved_by: string - resolved_at: number -} - -export type WorkflowCommentReply = { - id: string - comment_id: string - content: string - created_by: string - created_at: string - updated_at: string - mentioned_user_ids: string[] - author: { - id: string - name: string - email: string - avatar?: string - } -} - -export type CreateCommentParams = { - position_x: number - position_y: number - content: string - mentioned_user_ids?: string[] -} - -export type UpdateCommentParams = { - content: string - position_x?: number - position_y?: number - mentioned_user_ids?: string[] -} - -export type CreateReplyParams = { - content: string - mentioned_user_ids?: string[] -} +export type { + CreateCommentParams, + CreateReplyParams, + UpdateCommentParams, + UserProfile, + WorkflowCommentCreateRes, + WorkflowCommentDetail, + WorkflowCommentDetailMention, + WorkflowCommentDetailReply, + WorkflowCommentList, + WorkflowCommentReply, + WorkflowCommentResolveRes, + WorkflowCommentUpdateRes, +} from '@/contract/console/workflow-comment' export const fetchWorkflowComments = async (appId: string): Promise => { - const response = await get<{ data: WorkflowCommentList[] }>(`apps/${appId}/workflow/comments`) + const response = await consoleClient.workflowComments.list({ + params: { appId }, + }) return response.data } export const createWorkflowComment = async (appId: string, params: CreateCommentParams): Promise => { - return post(`apps/${appId}/workflow/comments`, { body: params }) + return consoleClient.workflowComments.create({ + params: { appId }, + body: params, + }) } export const fetchWorkflowComment = async (appId: string, commentId: string): Promise => { - return get(`apps/${appId}/workflow/comments/${commentId}`) + return consoleClient.workflowComments.detail({ + params: { appId, commentId }, + }) } export const updateWorkflowComment = async (appId: string, commentId: string, params: UpdateCommentParams): Promise => { - return put(`apps/${appId}/workflow/comments/${commentId}`, { body: params }) + return consoleClient.workflowComments.update({ + params: { appId, commentId }, + body: params, + }) } export const deleteWorkflowComment = async (appId: string, commentId: string): Promise => { - return del(`apps/${appId}/workflow/comments/${commentId}`) + return consoleClient.workflowComments.delete({ + params: { appId, commentId }, + }) } export const resolveWorkflowComment = async (appId: string, commentId: string): Promise => { - return post(`apps/${appId}/workflow/comments/${commentId}/resolve`) + return consoleClient.workflowComments.resolve({ + params: { appId, commentId }, + }) } export const createWorkflowCommentReply = async (appId: string, commentId: string, params: CreateReplyParams): Promise => { - return post(`apps/${appId}/workflow/comments/${commentId}/replies`, { body: params }) + return consoleClient.workflowComments.replies.create({ + params: { appId, commentId }, + body: params, + }) } export const updateWorkflowCommentReply = async (appId: string, commentId: string, replyId: string, params: CreateReplyParams): Promise => { - return put(`apps/${appId}/workflow/comments/${commentId}/replies/${replyId}`, { body: params }) + return consoleClient.workflowComments.replies.update({ + params: { + appId, + commentId, + replyId, + }, + body: params, + }) } export const deleteWorkflowCommentReply = async (appId: string, commentId: string, replyId: string): Promise => { - return del(`apps/${appId}/workflow/comments/${commentId}/replies/${replyId}`) + return consoleClient.workflowComments.replies.delete({ + params: { + appId, + commentId, + replyId, + }, + }) } export const fetchMentionableUsers = async (appId: string) => { - const response = await get<{ users: Array }>(`apps/${appId}/workflow/comments/mention-users`) + const response = await consoleClient.workflowComments.mentionUsers({ + params: { appId }, + }) return response.users } diff --git a/web/service/workflow.ts b/web/service/workflow.ts index 36ccfc67a1..28838a308a 100644 --- a/web/service/workflow.ts +++ b/web/service/workflow.ts @@ -1,12 +1,5 @@ -import type { - FileUpload, - RetrieverResource, - SensitiveWordAvoidance, - SpeechToText, - SuggestedQuestionsAfterAnswer, - TextToSpeech, -} from '@/app/components/base/features/types' import type { BlockEnum, ConversationVariable, EnvironmentVariable } from '@/app/components/workflow/types' +import type { WorkflowDraftFeaturesPayload } from '@/contract/console/workflow' import type { CommonResponse } from '@/models/common' import type { FlowType } from '@/types/common' import type { @@ -16,19 +9,11 @@ import type { VarInInspect, } from '@/types/workflow' import { get, post } from './base' +import { consoleClient } from './client' import { getFlowPrefix } from './utils' import { sanitizeWorkflowDraftPayload } from './workflow-payload' -export type WorkflowDraftFeaturesPayload = { - opening_statement: string - suggested_questions: string[] - suggested_questions_after_answer?: SuggestedQuestionsAfterAnswer - text_to_speech?: TextToSpeech - speech_to_text?: SpeechToText - retriever_resource?: RetrieverResource - sensitive_word_avoidance?: SensitiveWordAvoidance - file_upload?: FileUpload -} +export type { WorkflowDraftFeaturesPayload } from '@/contract/console/workflow' export const fetchWorkflowDraft = (url: string) => { return get(url, {}, { silent: true }) as Promise @@ -118,15 +103,18 @@ export const fetchNodeInspectVars = async (flowType: FlowType, flowId: string, n // Environment Variables API export const fetchEnvironmentVariables = async (appId: string): Promise => { - const { items } = (await get(`apps/${appId}/workflows/draft/environment-variables`)) as { items: EnvironmentVariable[] } - return items + const response = await consoleClient.workflowDraft.environmentVariables({ + params: { appId }, + }) + return response.items } export const updateEnvironmentVariables = ({ appId, environmentVariables }: { appId: string environmentVariables: EnvironmentVariable[] }) => { - return post(`apps/${appId}/workflows/draft/environment-variables`, { + return consoleClient.workflowDraft.updateEnvironmentVariables({ + params: { appId }, body: { environment_variables: environmentVariables }, }) } @@ -135,7 +123,8 @@ export const updateConversationVariables = ({ appId, conversationVariables }: { appId: string conversationVariables: ConversationVariable[] }) => { - return post(`apps/${appId}/workflows/draft/conversation-variables`, { + return consoleClient.workflowDraft.updateConversationVariables({ + params: { appId }, body: { conversation_variables: conversationVariables }, }) } @@ -144,7 +133,8 @@ export const updateFeatures = ({ appId, features }: { appId: string features: WorkflowDraftFeaturesPayload }) => { - return post(`apps/${appId}/workflows/draft/features`, { + return consoleClient.workflowDraft.updateFeatures({ + params: { appId }, body: { features }, }) }