Files
wenzi/frontend/admin/src/services/approval.ts
Your Name 5f5597ef0f
Some checks failed
CI / build_test_package (push) Has been cancelled
CI / auto_merge (push) Has been cancelled
chore: sync project snapshot for gitea/github upload
2026-03-26 15:59:53 +08:00

448 lines
12 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* 审批流服务 - 与后端审批API交互
*/
import { authFetch, baseUrl } from './authHelper'
import type { AdminRole } from '../auth/roles'
export interface ApprovalFlow {
id: number
flowCode: string
flowName: string
moduleCode: string
description?: string
status: number
createdAt: string
updatedAt?: string
}
export interface ApprovalRecord {
id: number
flowId: number
bizType: string
bizId: string
title: string
applicantId: number
applicantName: string
currentStatus: string
currentNodeId: number
currentNodeName: string
applyReason?: string
applyAttachments?: string
createdAt: string
updatedAt?: string
}
export interface ApprovalNode {
id: number
flowId: number
nodeName: string
nodeType: 'start' | 'approver' | 'condition' | 'cc' | 'end'
approverType: 'user' | 'role' | 'department_leader'
approverIds?: string
approverRoles?: string
condition?: string
timeout: number
action: string
sortOrder: number
}
export interface ApprovalHistory {
id: number
recordId: number
nodeId: number
nodeName: string
action: 'submit' | 'approve' | 'reject' | 'transfer' | 'callback'
operatorId: number
operatorName: string
comment?: string
attachments?: string
createdAt: string
}
export interface CreateFlowRequest {
flowCode: string
flowName: string
moduleCode: string
description?: string
}
export interface UpdateFlowRequest extends Partial<CreateFlowRequest> {
id: number
status?: number
}
export interface ApiResponse<T> {
code: number
data: T
message?: string
}
/**
* 审批流服务类
*/
class ApprovalService {
private baseUrl = baseUrl || '/api/v1'
/**
* 获取所有审批流
*/
async getFlows(): Promise<ApprovalFlow[]> {
const response = await authFetch(`${this.baseUrl}/approval/flows`, {
credentials: undefined
})
const result = await response.json() as ApiResponse<ApprovalFlow[]>
if (result.code !== 200) {
throw new Error(result.message || '获取审批流失败')
}
return result.data
}
/**
* 获取审批流详情
*/
async getFlowById(id: number): Promise<ApprovalFlow | null> {
const response = await authFetch(`${this.baseUrl}/approval/flows/${id}`, {
credentials: undefined
})
const result = await response.json() as ApiResponse<ApprovalFlow>
if (result.code !== 200) {
return null
}
return result.data
}
/**
* 创建审批流
*/
async createFlow(data: CreateFlowRequest): Promise<number> {
const response = await authFetch(`${this.baseUrl}/approval/flows`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
credentials: undefined,
body: JSON.stringify(data)
})
const result = await response.json() as ApiResponse<number>
if (result.code !== 200) {
throw new Error(result.message || '创建审批流失败')
}
return result.data
}
/**
* 更新审批流
*/
async updateFlow(data: UpdateFlowRequest): Promise<void> {
const response = await authFetch(`${this.baseUrl}/approval/flows/${data.id}`, {
method: 'PUT',
headers: { 'Content-Type': 'application/json' },
credentials: undefined,
body: JSON.stringify(data)
})
const result = await response.json() as ApiResponse<void>
if (result.code !== 200) {
throw new Error(result.message || '更新审批流失败')
}
}
/**
* 删除审批流
*/
async deleteFlow(id: number): Promise<void> {
const response = await authFetch(`${this.baseUrl}/approval/flows/${id}`, {
method: 'DELETE',
credentials: undefined
})
const result = await response.json() as ApiResponse<void>
if (result.code !== 200) {
throw new Error(result.message || '删除审批流失败')
}
}
/**
* 获取待审批列表
*/
async getPendingApprovals(): Promise<ApprovalRecord[]> {
const response = await authFetch(`${this.baseUrl}/approval/pending`, {
credentials: undefined
})
const result = await response.json() as ApiResponse<ApprovalRecord[]>
if (result.code !== 200) {
throw new Error(result.message || '获取待审批列表失败')
}
return result.data
}
/**
* 获取已审批列表
*/
async getApprovedList(): Promise<ApprovalRecord[]> {
const response = await authFetch(`${this.baseUrl}/approval/processed`, {
credentials: undefined
})
const result = await response.json() as ApiResponse<ApprovalRecord[]>
if (result.code !== 200) {
throw new Error(result.message || '获取已审批列表失败')
}
return result.data
}
/**
* 获取我发起的审批
*/
async getMyApplications(): Promise<ApprovalRecord[]> {
const response = await authFetch(`${this.baseUrl}/approval/my`, {
credentials: undefined
})
const result = await response.json() as ApiResponse<ApprovalRecord[]>
if (result.code !== 200) {
throw new Error(result.message || '获取我发起的审批失败')
}
return result.data
}
/**
* 审批操作(统一入口)
* @deprecated 请使用 approveRecord, rejectRecord, transferRecord 三个独立方法
*/
async approve(data: {
recordId: number
action: 'APPROVE' | 'REJECT' | 'TRANSFER'
operatorId: number
comment?: string
transferTo?: number // TRANSFER时必填
}): Promise<void> {
// 根据action调用对应的独立接口
switch (data.action) {
case 'APPROVE':
return this.approveRecord({ recordId: data.recordId, comment: data.comment })
case 'REJECT':
return this.rejectRecord({ recordId: data.recordId, comment: data.comment })
case 'TRANSFER':
if (data.transferTo == null) {
throw new Error('TRANSFER操作需要提供transferTo参数')
}
return this.transferRecord({ recordId: data.recordId, transferTo: data.transferTo, comment: data.comment })
default:
throw new Error(`Unknown action: ${data.action}`)
}
}
/**
* 审批通过
*/
async approveRecord(data: {
recordId: number
comment?: string
}): Promise<void> {
const response = await authFetch(`${this.baseUrl}/approval/approve`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
credentials: undefined,
body: JSON.stringify({
recordId: data.recordId,
comment: data.comment || ''
})
})
const result = await response.json() as ApiResponse<void>
if (result.code !== 200) {
throw new Error(result.message || '审批通过失败')
}
}
/**
* 审批拒绝
*/
async rejectRecord(data: {
recordId: number
comment?: string
}): Promise<void> {
const response = await authFetch(`${this.baseUrl}/approval/reject`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
credentials: undefined,
body: JSON.stringify({
recordId: data.recordId,
comment: data.comment || ''
})
})
const result = await response.json() as ApiResponse<void>
if (result.code !== 200) {
throw new Error(result.message || '审批拒绝失败')
}
}
/**
* 审批转交
*/
async transferRecord(data: {
recordId: number
transferTo: number
comment?: string
}): Promise<void> {
const response = await authFetch(`${this.baseUrl}/approval/transfer`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
credentials: undefined,
body: JSON.stringify({
recordId: data.recordId,
transferTo: data.transferTo,
comment: data.comment || ''
})
})
const result = await response.json() as ApiResponse<void>
if (result.code !== 200) {
throw new Error(result.message || '审批转交失败')
}
}
/**
* 审批委托
*/
async delegateRecord(data: {
recordId: number
delegateTo: number
reason?: string
}): Promise<void> {
const response = await authFetch(`${this.baseUrl}/approval/delegate`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
credentials: undefined,
body: JSON.stringify({
recordId: data.recordId,
delegateTo: data.delegateTo,
reason: data.reason || ''
})
})
const result = await response.json() as ApiResponse<void>
if (result.code !== 200) {
throw new Error(result.message || '审批委托失败')
}
}
/**
* 批量审批操作
* 使用新批量接口 POST /api/v1/approval/batch (approval.index.batch.ALL)
* 注意:批量转交使用 POST /api/v1/approval/batch-transfer (approval.index.batch.transfer.ALL)
*/
async batchApprove(data: {
recordIds: number[]
action: 'APPROVE' | 'REJECT' | 'TRANSFER'
comment?: string
}): Promise<{
total: number
successCount: number
failCount: number
results: Array<{ recordId: number; success: boolean; status: string; message: string }>
}> {
// 根据操作类型选择接口TRANSFER使用批量转交接口其他使用批量审批接口
const endpoint = data.action === 'TRANSFER'
? `${this.baseUrl}/api/v1/approval/batch-transfer`
: `${this.baseUrl}/api/v1/approval/batch`;
const response = await authFetch(endpoint, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
credentials: undefined,
body: JSON.stringify(data)
})
const result = await response.json() as ApiResponse<{
total: number
successCount: number
failCount: number
results: Array<{ recordId: number; success: boolean; status: string; message: string }>
}>
if (result.code !== 200) {
throw new Error(result.message || '批量审批操作失败')
}
return result.data
}
/**
* 提交审批申请
*/
async submitApproval(data: {
flowId: number
bizType: string
bizId: number
title: string
applicantId: number
applyReason: string
}): Promise<number> {
const response = await authFetch(`${this.baseUrl}/approval/submit`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
credentials: undefined,
body: JSON.stringify(data)
})
const result = await response.json() as ApiResponse<{ recordId: number }>
if (result.code !== 200) {
throw new Error(result.message || '提交审批失败')
}
return result.data.recordId
}
/**
* 取消审批
*/
async cancelApproval(recordId: number, operatorId: number): Promise<void> {
const response = await authFetch(`${this.baseUrl}/approval/cancel`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
credentials: undefined,
body: JSON.stringify({ recordId, operatorId })
})
const result = await response.json() as ApiResponse<void>
if (result.code !== 200) {
throw new Error(result.message || '取消审批失败')
}
}
/**
* 获取审批记录详情
*/
async getRecordById(id: number): Promise<ApprovalRecord | null> {
const response = await authFetch(`${this.baseUrl}/approval/records/${id}`, {
credentials: undefined
})
const result = await response.json() as ApiResponse<ApprovalRecord>
if (result.code !== 200) {
return null
}
return result.data
}
/**
* 获取审批历史
*/
async getApprovalHistory(recordId: number): Promise<ApprovalHistory[]> {
const response = await authFetch(`${this.baseUrl}/approval/records/${recordId}/history`, {
credentials: undefined
})
const result = await response.json() as ApiResponse<ApprovalHistory[]>
if (result.code !== 200) {
throw new Error(result.message || '获取审批历史失败')
}
return result.data
}
/**
* 添加审批意见(不改变审批状态)
*/
async addComment(recordId: number, comment: string): Promise<void> {
const response = await authFetch(`${this.baseUrl}/approval/records/${recordId}/comment`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
credentials: undefined,
body: JSON.stringify({ comment })
})
const result = await response.json() as ApiResponse<void>
if (result.code !== 200) {
throw new Error(result.message || '添加审批意见失败')
}
}
}
export const approvalService = new ApprovalService()
export default approvalService