From 265d790ea64a88923ec092c7430a97e9958149e6 Mon Sep 17 00:00:00 2001 From: zlwu <704541015@qq.com> Date: Wed, 15 Jul 2026 14:38:39 +0800 Subject: [PATCH] feat(oa): render instance detail progress from API projection Co-authored-by: Cursor --- web-admin/src/api/oaApproval.ts | 279 +++++++++++ .../views/oa-approval/instances/detail.vue | 468 ++++++++++++++++++ 2 files changed, 747 insertions(+) create mode 100644 web-admin/src/api/oaApproval.ts create mode 100644 web-admin/src/views/oa-approval/instances/detail.vue diff --git a/web-admin/src/api/oaApproval.ts b/web-admin/src/api/oaApproval.ts new file mode 100644 index 00000000..0d937641 --- /dev/null +++ b/web-admin/src/api/oaApproval.ts @@ -0,0 +1,279 @@ +import request from '@/utils/http' + +const BASE = '/web/admin/oa-approval' + +// --------------------------------------------------------------------------- +// 工作流角色 +// --------------------------------------------------------------------------- + +export function fetchOaRoleList(params?: { keyword?: string; status?: string }) { + return request.get<{ list: any[] }>({ + url: `${BASE}/roles`, + params + }) +} + +export function fetchEnsureOaRolePresets() { + return request.post<{ createdCount: number }>({ + url: `${BASE}/roles/ensure-presets`, + showSuccessMessage: true + }) +} + +export function fetchCreateOaRole(data: { + roleName: string + roleCode: string + status?: string + orderNum?: number + remark?: string +}) { + return request.post({ + url: `${BASE}/roles`, + data, + showSuccessMessage: true + }) +} + +export function fetchUpdateOaRole( + id: string, + data: Partial<{ + roleName: string + status: string + orderNum: number + remark: string + }> +) { + return request.put({ + url: `${BASE}/roles/${id}`, + data, + showSuccessMessage: true + }) +} + +export function fetchDeleteOaRole(id: string) { + return request.del({ + url: `${BASE}/roles/${id}`, + showSuccessMessage: true + }) +} + +export function fetchOaRoleUsers(roleId: string) { + return request.get<{ list: any[] }>({ + url: `${BASE}/roles/${roleId}/users` + }) +} + +export function fetchReplaceOaRoleUsers(roleId: string, userIds: string[]) { + return request.put<{ list: any[] }>({ + url: `${BASE}/roles/${roleId}/users`, + data: { userIds }, + showSuccessMessage: true + }) +} + +// --------------------------------------------------------------------------- +// 分组 / 应用 / 草稿 / 发布 +// --------------------------------------------------------------------------- + +export function fetchOaGroupList() { + return request.get<{ list: any[] }>({ url: `${BASE}/groups` }) +} + +export function fetchCreateOaGroup(data: { + groupName: string + orderNum?: number + remark?: string +}) { + return request.post({ + url: `${BASE}/groups`, + data, + showSuccessMessage: true + }) +} + +export function fetchUpdateOaGroup( + id: string, + data: Partial<{ groupName: string; orderNum: number; remark: string }> +) { + return request.put({ + url: `${BASE}/groups/${id}`, + data, + showSuccessMessage: true + }) +} + +export function fetchDeleteOaGroup(id: string) { + return request.del({ + url: `${BASE}/groups/${id}`, + showSuccessMessage: true + }) +} + +export function fetchOaAppList(params?: { + groupId?: string + keyword?: string + status?: string +}) { + return request.get<{ list: any[] }>({ + url: `${BASE}/apps`, + params + }) +} + +export function fetchCreateOaApp(data: Record) { + return request.post({ + url: `${BASE}/apps`, + data, + showSuccessMessage: true + }) +} + +export function fetchUpdateOaApp(id: string, data: Record) { + return request.put({ + url: `${BASE}/apps/${id}`, + data, + showSuccessMessage: true + }) +} + +export function fetchDeleteOaApp(id: string) { + return request.del({ + url: `${BASE}/apps/${id}`, + showSuccessMessage: true + }) +} + +export function fetchOaAppDraft(appId: string) { + return request.get({ url: `${BASE}/apps/${appId}/draft` }) +} + +export function fetchSaveOaAppDraft( + appId: string, + data: { + basic?: Record + formSchemaJson?: any + flowTreeJson?: any + advancedSettingsJson?: any + } +) { + return request.put({ + url: `${BASE}/apps/${appId}/draft`, + data, + showSuccessMessage: true + }) +} + +export function fetchPublishOaApp(appId: string) { + return request.post({ + url: `${BASE}/apps/${appId}/publish`, + showSuccessMessage: true + }) +} + +// --------------------------------------------------------------------------- +// 运行时 +// --------------------------------------------------------------------------- + +export function fetchOaTemplates() { + return request.get<{ list: any[] }>({ url: `${BASE}/templates` }) +} + +export function fetchOaTemplateDetail(appId: string) { + return request.get({ url: `${BASE}/templates/${appId}` }) +} + +/** 发起前审批流预览(按当前登录人解析审批人) */ +export function fetchOaFlowPreview(appId: string, initiatorSelectUserIds?: string[]) { + return request.get<{ steps: OaFlowPreviewStep[] }>({ + url: `${BASE}/templates/${appId}/flow-preview`, + params: initiatorSelectUserIds?.length + ? { initiatorSelectUserIds: initiatorSelectUserIds.join(',') } + : undefined + }) +} + +export type OaFlowPreviewStep = { + id: string + type: 'start' | 'approval' | 'cc' | 'branch' | 'end' | string + name: string + signMode?: string + assigneeType?: string + meta?: string + people?: Array<{ id: string; nickName: string }> + resolveError?: string +} + +export function fetchStartOaInstance(data: { + appId: string + formData?: Record + title?: string + initiatorDeptId?: string + initiatorSelectUserIds?: string[] + relatedInstanceIds?: string[] +}) { + return request.post({ + url: `${BASE}/instances`, + data, + showSuccessMessage: true + }) +} + +/** 详情审批进度投影项(后端 build_progress_items) */ +export interface OaProgressItem { + kind: 'submit' | 'task' | 'pending_node' | 'terminal' | string + roundNo?: number + title?: string + status?: string + assigneeUserId?: string + assigneeUserName?: string + timestamp?: string + commentText?: string + nodeKey?: string + taskType?: string + resolveSource?: string + taskId?: string +} + +export function fetchOaInstanceDetail(id: string) { + return request.get<{ progress?: OaProgressItem[]; tasks?: any[] } & Record>({ + url: `${BASE}/instances/${id}` + }) +} + +export function fetchOaTasks(kind: 'pending' | 'done' | 'mine' | 'cc') { + return request.get<{ list: any[] }>({ url: `${BASE}/tasks/${kind}` }) +} + +export function fetchApproveOaTask(taskId: string, comment?: string) { + return request.post({ + url: `${BASE}/tasks/${taskId}/approve`, + data: { comment }, + showSuccessMessage: true + }) +} + +export function fetchRejectOaTask(taskId: string, comment?: string) { + return request.post({ + url: `${BASE}/tasks/${taskId}/reject`, + data: { comment }, + showSuccessMessage: true + }) +} + +export function fetchAddSignOaTask( + taskId: string, + data: { userIds: string[]; comment?: string } +) { + return request.post({ + url: `${BASE}/tasks/${taskId}/add-sign`, + data, + showSuccessMessage: true + }) +} + +export function fetchWithdrawOaInstance(instanceId: string) { + return request.post({ + url: `${BASE}/instances/${instanceId}/withdraw`, + showSuccessMessage: true + }) +} diff --git a/web-admin/src/views/oa-approval/instances/detail.vue b/web-admin/src/views/oa-approval/instances/detail.vue new file mode 100644 index 00000000..cc7256d0 --- /dev/null +++ b/web-admin/src/views/oa-approval/instances/detail.vue @@ -0,0 +1,468 @@ + + + + + +