feat(management): align reports with signing APIs
This commit is contained in:
@@ -1,38 +1,76 @@
|
||||
import { request } from '@/utils/request'
|
||||
import { getCampuses, getDepartments } from './organization'
|
||||
import { getSigningTasks, getSigningTemplates, isSigningMockEnabled } from '@/api/workbench/signing'
|
||||
import type { WorkbenchCampus } from '@/api/workbench/types'
|
||||
|
||||
import type { ReportOverviewResponse, ReportQuery } from './types'
|
||||
import type { ReportTaskData } from './types'
|
||||
|
||||
const useMockData = import.meta.env.VITE_USE_MOCK !== 'false'
|
||||
const REPORT_PAGE_SIZE = 200
|
||||
|
||||
const mockOverview: ReportOverviewResponse = {
|
||||
metrics: [
|
||||
{ key: 'total', label: '签署总量', value: 1268, unit: '份', trend: 12.8 },
|
||||
{ key: 'signed', label: '已完成', value: 1142, unit: '份', trend: 8.6 },
|
||||
{ key: 'rate', label: '完成率', value: 90.1, unit: '%', trend: 3.2 },
|
||||
{ key: 'average', label: '平均耗时', value: 6.4, unit: '分钟', trend: -4.5 },
|
||||
],
|
||||
trend: [
|
||||
{ date: '08-21', signed: 146, rejected: 5, pending: 12 },
|
||||
{ date: '08-22', signed: 158, rejected: 4, pending: 10 },
|
||||
{ date: '08-23', signed: 132, rejected: 7, pending: 15 },
|
||||
{ date: '08-24', signed: 176, rejected: 3, pending: 9 },
|
||||
{ date: '08-25', signed: 188, rejected: 6, pending: 13 },
|
||||
{ date: '08-26', signed: 172, rejected: 5, pending: 11 },
|
||||
{ date: '08-27', signed: 170, rejected: 4, pending: 8 },
|
||||
],
|
||||
departments: [
|
||||
{ department: '消化内科', total: 328, signed: 305, completionRate: 93.0 },
|
||||
{ department: '儿科急诊', total: 286, signed: 249, completionRate: 87.1 },
|
||||
{ department: '普外科', total: 264, signed: 243, completionRate: 92.0 },
|
||||
],
|
||||
export const isReportsMockEnabled = isSigningMockEnabled
|
||||
|
||||
function isWorkbenchCampus(value: string): value is WorkbenchCampus {
|
||||
return value === '本部院区' || value === '东院区' || value === '西院区'
|
||||
}
|
||||
|
||||
export function getReportOverview(query: ReportQuery): Promise<ReportOverviewResponse> {
|
||||
if (useMockData) {
|
||||
return Promise.resolve(mockOverview)
|
||||
function buildSigningApiOptions(data: ReportTaskData) {
|
||||
return {
|
||||
templates: data.templates,
|
||||
campusNames: Object.fromEntries(
|
||||
data.campuses
|
||||
.filter((campus) => isWorkbenchCampus(campus.name))
|
||||
.map((campus) => [campus.id, campus.name]),
|
||||
) as Record<string, WorkbenchCampus>,
|
||||
}
|
||||
}
|
||||
|
||||
async function getAllReportTasks(data: ReportTaskData) {
|
||||
const options = buildSigningApiOptions(data)
|
||||
const query = {
|
||||
page: 1,
|
||||
pageSize: REPORT_PAGE_SIZE,
|
||||
status: 'all' as const,
|
||||
dateRange: 'all' as const,
|
||||
campus: 'all' as const,
|
||||
method: 'all' as const,
|
||||
}
|
||||
const firstPage = await getSigningTasks(query, options)
|
||||
const records = [...firstPage.records]
|
||||
const pageSize = Math.max(firstPage.pageSize, 1)
|
||||
const totalPages = Math.ceil(firstPage.total / pageSize)
|
||||
|
||||
for (let page = 2; page <= totalPages; page += 1) {
|
||||
const nextPage = await getSigningTasks({ ...query, page }, options)
|
||||
records.push(...nextPage.records)
|
||||
|
||||
if (!nextPage.records.length) {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return request.get<ReportOverviewResponse>('/management/reports/overview', {
|
||||
params: query,
|
||||
})
|
||||
return records
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询报表所需的全部可见任务。
|
||||
* 当前后端没有聚合报表接口,因此这里按最大页大小读取签署任务;聚合接口上线后只需替换本函数。
|
||||
*/
|
||||
export async function getReportTaskData(): Promise<ReportTaskData> {
|
||||
if (isReportsMockEnabled) {
|
||||
return { tasks: [], templates: [], campuses: [], departments: [] }
|
||||
}
|
||||
|
||||
const [templatesResult, campusesResult, departmentsResult] = await Promise.allSettled([
|
||||
getSigningTemplates(),
|
||||
getCampuses(),
|
||||
getDepartments(),
|
||||
])
|
||||
const data: ReportTaskData = {
|
||||
tasks: [],
|
||||
templates: templatesResult.status === 'fulfilled' ? templatesResult.value : [],
|
||||
campuses: campusesResult.status === 'fulfilled' ? campusesResult.value : [],
|
||||
departments: departmentsResult.status === 'fulfilled' ? departmentsResult.value : [],
|
||||
}
|
||||
|
||||
data.tasks = await getAllReportTasks(data)
|
||||
return data
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import type { PageQuery, PageResult } from '@/types/common'
|
||||
import type { SigningTaskRecord, SigningTemplate } from '@/api/workbench/types'
|
||||
|
||||
export type DocumentStatus = 'draft' | 'published' | 'archived' | 'review'
|
||||
|
||||
@@ -260,39 +261,15 @@ export interface OrganizationResponseDto {
|
||||
departmentName?: string | null
|
||||
}
|
||||
|
||||
export type ReportPeriod = 'today' | 'week' | 'month' | 'year'
|
||||
|
||||
export interface ReportQuery {
|
||||
period: ReportPeriod
|
||||
department?: string
|
||||
}
|
||||
|
||||
export interface ReportMetric {
|
||||
key: string
|
||||
label: string
|
||||
value: number
|
||||
unit: string
|
||||
trend: number
|
||||
}
|
||||
|
||||
export interface ReportTrendPoint {
|
||||
date: string
|
||||
signed: number
|
||||
rejected: number
|
||||
pending: number
|
||||
}
|
||||
|
||||
export interface ReportDepartment {
|
||||
department: string
|
||||
total: number
|
||||
signed: number
|
||||
completionRate: number
|
||||
}
|
||||
|
||||
export interface ReportOverviewResponse {
|
||||
metrics: ReportMetric[]
|
||||
trend: ReportTrendPoint[]
|
||||
departments: ReportDepartment[]
|
||||
/**
|
||||
* 报表当前由签署任务列表、模板和组织字典在前端聚合。
|
||||
* 后端提供聚合报表接口后,可在 reports.ts 的边界替换为对应 DTO,页面无需感知。
|
||||
*/
|
||||
export interface ReportTaskData {
|
||||
tasks: SigningTaskRecord[]
|
||||
templates: SigningTemplate[]
|
||||
campuses: CampusRecord[]
|
||||
departments: DepartmentRecord[]
|
||||
}
|
||||
|
||||
export type UserStatus = 'enabled' | 'disabled'
|
||||
|
||||
Reference in New Issue
Block a user