import { WEB_SERVICE_PREFIX } from '@/constants/service'; import { request } from '../request'; import { type ProjectLocalDateValue, normalizeProjectLocalDate } from './project-shared'; import { type ServiceRequestResult, mapServiceResult, normalizeStringId, safeJsonRequestConfig } from './shared'; const OVERTIME_APPLICATION_PREFIX = `${WEB_SERVICE_PREFIX}/project/overtime-applications`; type StringIdResponse = string | number; type OvertimeApplicationResponse = Omit< Api.OvertimeApplication.OvertimeApplication, 'id' | 'applicantId' | 'approverId' | 'overtimeDate' | 'allowEdit' | 'terminal' > & { id: StringIdResponse; applicantId: StringIdResponse; approverId: StringIdResponse; overtimeDate: ProjectLocalDateValue; allowEdit?: boolean | number | string | null; terminal?: boolean | number | string | null; }; type OvertimeApplicationPageResponse = Omit & { total: number | string; list: OvertimeApplicationResponse[]; }; type OvertimeApplicationApprovalRecordResponse = Omit< Api.OvertimeApplication.OvertimeApplicationApprovalRecord, 'id' | 'overtimeApplicationId' | 'statusLogId' | 'auditorUserId' > & { id: StringIdResponse; overtimeApplicationId: StringIdResponse; statusLogId: StringIdResponse; auditorUserId: StringIdResponse; }; function normalizeBooleanFlag(value: boolean | number | string | null | undefined) { if (typeof value === 'boolean') { return value; } if (typeof value === 'number') { return value === 1; } if (typeof value === 'string') { const normalized = value.trim().toLowerCase(); return !['', '0', 'false', 'n', 'no'].includes(normalized); } return false; } function normalizeTotal(total: number | string) { const value = Number(total); return Number.isFinite(value) ? Math.max(0, value) : 0; } function normalizeOvertimeApplication( response: OvertimeApplicationResponse ): Api.OvertimeApplication.OvertimeApplication { return { ...response, id: normalizeStringId(response.id), applicantId: normalizeStringId(response.applicantId), approverId: normalizeStringId(response.approverId), overtimeDate: normalizeProjectLocalDate(response.overtimeDate) ?? '', statusName: response.statusName || response.statusCode, allowEdit: normalizeBooleanFlag(response.allowEdit), terminal: normalizeBooleanFlag(response.terminal), approvalComment: response.approvalComment ?? null, approvalTime: response.approvalTime ?? null }; } function normalizeApprovalRecord( response: OvertimeApplicationApprovalRecordResponse ): Api.OvertimeApplication.OvertimeApplicationApprovalRecord { return { ...response, id: normalizeStringId(response.id), overtimeApplicationId: normalizeStringId(response.overtimeApplicationId), statusLogId: normalizeStringId(response.statusLogId), auditorUserId: normalizeStringId(response.auditorUserId), opinion: response.opinion ?? null }; } function createPageQuery(params: Api.OvertimeApplication.OvertimeApplicationSearchParams = {}) { const query = new URLSearchParams(); query.append('pageNo', String(params.pageNo ?? 1)); query.append('pageSize', String(params.pageSize ?? 10)); if (params.keyword) { query.append('keyword', params.keyword); } if (params.applicantName) { query.append('applicantName', params.applicantName); } if (params.approverId) { query.append('approverId', params.approverId); } if (params.approverName) { query.append('approverName', params.approverName); } if (params.statusCode) { query.append('statusCode', params.statusCode); } params.overtimeDate?.forEach(item => { if (item) { query.append('overtimeDate', item); } }); params.createTime?.forEach(item => { if (item) { query.append('createTime', item); } }); return query.toString(); } function toSaveRequest(data: Api.OvertimeApplication.SaveOvertimeApplicationParams) { return { overtimeDate: data.overtimeDate, overtimeDuration: data.overtimeDuration, overtimeReason: data.overtimeReason.trim(), overtimeContent: data.overtimeContent.trim(), approverId: data.approverId }; } function toStatusActionRequest(data: Api.OvertimeApplication.StatusActionParams = {}) { return { reason: data.reason?.trim() || undefined }; } export async function fetchGetOvertimeApplicationPage( params: Api.OvertimeApplication.OvertimeApplicationSearchParams = {} ) { const query = createPageQuery(params); const result = await request({ ...safeJsonRequestConfig, url: query ? `${OVERTIME_APPLICATION_PREFIX}/page?${query}` : `${OVERTIME_APPLICATION_PREFIX}/page`, method: 'get' }); return mapServiceResult(result as ServiceRequestResult, data => ({ total: normalizeTotal(data.total), list: data.list.map(normalizeOvertimeApplication) })); } export async function fetchGetOvertimeApplicationApprovalPage( params: Api.OvertimeApplication.OvertimeApplicationSearchParams = {} ) { const query = createPageQuery(params); const result = await request({ ...safeJsonRequestConfig, url: query ? `${OVERTIME_APPLICATION_PREFIX}/approval-page?${query}` : `${OVERTIME_APPLICATION_PREFIX}/approval-page`, method: 'get' }); return mapServiceResult(result as ServiceRequestResult, data => ({ total: normalizeTotal(data.total), list: data.list.map(normalizeOvertimeApplication) })); } export async function fetchGetOvertimeApplicationDetail(id: string) { const result = await request({ ...safeJsonRequestConfig, url: `${OVERTIME_APPLICATION_PREFIX}/${id}`, method: 'get' }); return mapServiceResult(result as ServiceRequestResult, normalizeOvertimeApplication); } export async function fetchCreateOvertimeApplication(data: Api.OvertimeApplication.SaveOvertimeApplicationParams) { const result = await request({ ...safeJsonRequestConfig, url: OVERTIME_APPLICATION_PREFIX, method: 'post', data: toSaveRequest(data) }); return mapServiceResult(result as ServiceRequestResult, normalizeStringId); } export function fetchUpdateRejectedOvertimeApplication( id: string, data: Api.OvertimeApplication.SaveOvertimeApplicationParams ) { return request({ ...safeJsonRequestConfig, url: `${OVERTIME_APPLICATION_PREFIX}/${id}`, method: 'put', data: toSaveRequest(data) }); } export function fetchApproveOvertimeApplication(id: string, data: Api.OvertimeApplication.StatusActionParams = {}) { return request({ ...safeJsonRequestConfig, url: `${OVERTIME_APPLICATION_PREFIX}/${id}/approve`, method: 'post', data: toStatusActionRequest(data) }); } export function fetchRejectOvertimeApplication(id: string, data: Api.OvertimeApplication.StatusActionParams) { return request({ ...safeJsonRequestConfig, url: `${OVERTIME_APPLICATION_PREFIX}/${id}/reject`, method: 'post', data: toStatusActionRequest(data) }); } export function fetchBatchApproveOvertimeApplication( data: Api.OvertimeApplication.OvertimeApplicationBatchActionParams ) { return request({ ...safeJsonRequestConfig, url: `${OVERTIME_APPLICATION_PREFIX}/batch-approve`, method: 'post', data }); } export function fetchBatchRejectOvertimeApplication( data: Api.OvertimeApplication.OvertimeApplicationBatchActionParams ) { return request({ ...safeJsonRequestConfig, url: `${OVERTIME_APPLICATION_PREFIX}/batch-reject`, method: 'post', data }); } export function fetchDeleteOvertimeApplication(id: string) { return request({ ...safeJsonRequestConfig, url: `${OVERTIME_APPLICATION_PREFIX}/${id}`, method: 'delete' }); } export async function fetchGetOvertimeApplicationApprovalRecords(id: string) { const result = await request({ ...safeJsonRequestConfig, url: `${OVERTIME_APPLICATION_PREFIX}/${id}/approval-records`, method: 'get' }); return mapServiceResult(result as ServiceRequestResult, data => data.map(normalizeApprovalRecord) ); } export async function fetchGetOvertimeApplicationStatusDict() { const result = await request({ ...safeJsonRequestConfig, url: `${OVERTIME_APPLICATION_PREFIX}/status/dict`, method: 'get' }); return mapServiceResult( result as ServiceRequestResult, data => data ); } export function fetchExportOvertimeApplications(params: Api.OvertimeApplication.OvertimeApplicationSearchParams = {}) { const query = createPageQuery(params); return request({ url: query ? `${OVERTIME_APPLICATION_PREFIX}/export?${query}` : `${OVERTIME_APPLICATION_PREFIX}/export`, method: 'get', responseType: 'blob' }); }