chore(report): 下线「系统管理 → 报表分析」菜单及其接口与开关

This commit is contained in:
yelan
2026-09-30 09:42:34 +08:00
parent fe8cb01d4d
commit e7a7c1f01b
21 changed files with 48 additions and 2988 deletions
-122
View File
@@ -1,122 +0,0 @@
import { unwrapApiResponse } from '@/utils/api-response'
import { mockFlags } from '@/utils/mock-flags'
import { request } from '@/utils/request'
import type { ApiResponse } from '@/types/common'
import type {
ReportExportJobResponseDto,
ReportExportRequestDto,
ReportFilterDto,
ReportOptionsResponseDto,
ReportOverviewResponseDto,
ReportPageResponseDto,
ReportTaskResponseDto,
ReportTasksQueryDto,
} from './types'
export const isReportsMockEnabled = mockFlags.reports
function compactQuery(values: object) {
return Object.fromEntries(
Object.entries(values).filter(
([, value]) => value !== undefined && value !== null && value !== '',
),
)
}
function normalizeReportOptions(data: ReportOptionsResponseDto): ReportOptionsResponseDto {
return {
campuses: data.campuses ?? [],
departments: data.departments ?? [],
templateCategories: data.templateCategories ?? [],
}
}
function normalizeReportOverview(data: ReportOverviewResponseDto): ReportOverviewResponseDto {
return {
timezone: data.timezone ?? 'Asia/Shanghai',
generatedAt: data.generatedAt ?? '',
snapshotAt: data.snapshotAt ?? '',
metrics: {
initiatedCount: data.metrics?.initiatedCount ?? 0,
signedCount: data.metrics?.signedCount ?? 0,
onTimeSignedCount: data.metrics?.onTimeSignedCount ?? 0,
onTimeSampleCount: data.metrics?.onTimeSampleCount ?? 0,
onTimeRate: data.metrics?.onTimeRate ?? null,
averageSignDurationSeconds: data.metrics?.averageSignDurationSeconds ?? null,
durationSampleCount: data.metrics?.durationSampleCount ?? 0,
},
trend: data.trend ?? [],
departments: data.departments ?? [],
}
}
/**
* ReportFilter/ReportTasksQuery are object query parameters in OpenAPI's default
* form/explode representation, so fields are sent flat (createdFrom=..., etc.).
*/
export async function getReportOptions(
filter: ReportFilterDto = {},
): Promise<ReportOptionsResponseDto> {
const response = await request.get<ApiResponse<ReportOptionsResponseDto>>(
'/v1/reports/signing/options',
{ params: compactQuery(filter) },
)
return normalizeReportOptions(unwrapApiResponse(response))
}
export async function getReportOverview(
filter: ReportFilterDto,
): Promise<ReportOverviewResponseDto> {
const response = await request.get<ApiResponse<ReportOverviewResponseDto>>(
'/v1/reports/signing/overview',
{ params: compactQuery(filter) },
)
return normalizeReportOverview(unwrapApiResponse(response))
}
export async function getReportTasks(
query: ReportTasksQueryDto,
): Promise<ReportPageResponseDto<ReportTaskResponseDto>> {
const response = await request.get<ApiResponse<ReportPageResponseDto<ReportTaskResponseDto>>>(
'/v1/reports/signing/tasks',
{ params: compactQuery(query) },
)
const page = unwrapApiResponse(response)
return {
records: page.records ?? [],
page: page.page,
size: page.size,
total: page.total,
pages: page.pages,
}
}
export async function createReportExportJob(
payload: ReportExportRequestDto,
): Promise<ReportExportJobResponseDto> {
const response = await request.post<ApiResponse<ReportExportJobResponseDto>>(
'/v1/reports/signing/export-jobs',
payload,
)
return unwrapApiResponse(response)
}
export async function getReportExportJob(jobId: string): Promise<ReportExportJobResponseDto> {
const response = await request.get<ApiResponse<ReportExportJobResponseDto>>(
`/v1/reports/signing/export-jobs/${encodeURIComponent(jobId)}`,
)
return unwrapApiResponse(response)
}
export async function downloadReportExportFile(jobId: string): Promise<Blob> {
return request.get<Blob>(
`/v1/reports/signing/export-jobs/${encodeURIComponent(jobId)}/download`,
{ responseType: 'blob' },
)
}
-140
View File
@@ -341,146 +341,6 @@ export interface OrganizationResponseDto {
departmentName?: string | null
}
export type ReportBackendTaskStatus =
| 'CREATED'
| 'WAITING_SIGN'
| 'SIGNED'
| 'EXPIRED'
| 'VOIDED'
| 'GENERATING'
| 'FAILED'
/** 患者已签、等科室复核签章(与 workbench 的 WAITING_CONFIRM 同口径) */
| 'WAITING_CONFIRM'
/** 与 workbench 的 BackendSigningMethod 同口径:四种方式平铺,无通道归并 */
export type ReportBackendSignMethod = 'PAD' | 'SMS' | 'IPAD' | 'WX'
export type ReportTimeDimension = 'CREATED' | 'SIGNED' | 'EXPIRED'
export type ReportSortDirection = 'asc' | 'desc'
export type ReportExportFormat = 'CSV' | 'XLSX'
/** /api/v1/reports/signing 的公共过滤 DTO;时间区间为左闭右开。 */
export interface ReportFilterDto {
createdFrom?: string
createdTo?: string
signedFrom?: string
signedTo?: string
expiredFrom?: string
expiredTo?: string
campusId?: string
departmentId?: string
templateVersionId?: string
templateCategory?: string
signMethod?: ReportBackendSignMethod
keyword?: string
timezone?: string
}
export interface ReportTasksQueryDto extends ReportFilterDto {
page?: number
size?: number
timeDimension?: ReportTimeDimension
sort?: string
direction?: ReportSortDirection
}
export interface ReportExportRequestDto extends ReportTasksQueryDto {
format: ReportExportFormat
columns?: string[]
}
export interface ReportMetricsDto {
initiatedCount: number
signedCount: number
onTimeSignedCount: number
onTimeSampleCount: number
onTimeRate: number | null
averageSignDurationSeconds: number | null
durationSampleCount: number
}
export interface ReportTrendPointDto {
date: string
label: string
signedCount: number
}
export interface ReportDepartmentBreakdownDto {
departmentId?: string | null
departmentName?: string | null
initiatedCount?: number | null
signedCount?: number | null
onTimeSignedCount?: number | null
onTimeSampleCount?: number | null
onTimeRate?: number | null
}
export interface ReportOverviewResponseDto {
timezone: string
generatedAt: string
snapshotAt: string
metrics: ReportMetricsDto
trend: ReportTrendPointDto[]
departments: ReportDepartmentBreakdownDto[]
}
export interface ReportTaskResponseDto {
taskId: string
patientDisplayId: string
patientNameMasked: string
patientMobileMasked?: string | null
status: ReportBackendTaskStatus
signMethod: ReportBackendSignMethod
createdAt: string
deadlineAt?: string | null
signStartedAt?: string | null
signedAt?: string | null
expiredAt?: string | null
voidedAt?: string | null
signDurationSeconds?: number | null
onTime?: boolean | null
templateVersionId: string
templateVersionNumber?: number | null
templateName: string
templateCategory: string
campusId: string
campusName: string
departmentId?: string | null
departmentName: string
}
export interface ReportOptionsResponseDto {
campuses: Array<{ id: string; name: string }>
departments: Array<{ id: string; campusId: string; name: string }>
templateCategories: string[]
}
export interface ReportPageResponseDto<T> {
records: T[]
page: number
size: number
total: number
pages: number
}
export type ReportExportJobStatus = 'PENDING' | 'RUNNING' | 'SUCCEEDED' | 'FAILED' | 'EXPIRED'
export interface ReportExportJobResponseDto {
jobId: string
status: ReportExportJobStatus
format?: ReportExportFormat | string | null
requestedAt?: string | null
startedAt?: string | null
completedAt?: string | null
expiresAt?: string | null
resultCount?: number | null
errorCode?: string | null
errorMessage?: string | null
downloadPath?: string | null
}
export type UserStatus = 'enabled' | 'disabled' | 'locked'
export interface UserQuery extends PageQuery {