Phase 1 (Critical): - 매출관리 계정과목 일괄변경 함수 추가 (bulkUpdateAccountCode) - 근태관리 사유 등록 페이지 생성 (/hr/documents/new) Phase 2 (High): - 근태 등록 서버 에러 수정 (json_details 유효성 검증) - 직원 등록 서버 에러 수정 (snake_case 필드명 변환) - 근태관리 엑셀 다운로드 구현 (exportAttendanceExcel) Phase 3 (Medium): - 급여관리 엑셀 다운로드 구현 (exportSalaryExcel) - 급여관리 지급항목 인라인 수정 기능 구현
108 lines
3.0 KiB
TypeScript
108 lines
3.0 KiB
TypeScript
/**
|
|
* 엑셀 내보내기 유틸리티
|
|
*
|
|
* 여러 모듈에서 공통으로 사용:
|
|
* - 근태관리 (AttendanceManagement)
|
|
* - 급여관리 (SalaryManagement)
|
|
* - 기타 데이터 내보내기가 필요한 모듈
|
|
*/
|
|
|
|
/**
|
|
* 엑셀 파일 다운로드 처리
|
|
*
|
|
* API 응답(Blob)을 받아 파일 다운로드를 트리거합니다.
|
|
*
|
|
* @param response - fetch Response 객체 (Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet)
|
|
* @param filename - 저장할 파일명 (확장자 포함)
|
|
*/
|
|
export async function downloadExcelFromResponse(
|
|
response: Response,
|
|
filename: string
|
|
): Promise<void> {
|
|
if (!response.ok) {
|
|
throw new Error(`엑셀 다운로드 실패: ${response.status}`);
|
|
}
|
|
|
|
const blob = await response.blob();
|
|
downloadBlob(blob, filename);
|
|
}
|
|
|
|
/**
|
|
* Blob을 파일로 다운로드
|
|
*
|
|
* @param blob - 다운로드할 Blob 데이터
|
|
* @param filename - 저장할 파일명
|
|
*/
|
|
export function downloadBlob(blob: Blob, filename: string): void {
|
|
const url = URL.createObjectURL(blob);
|
|
const link = document.createElement('a');
|
|
link.href = url;
|
|
link.download = filename;
|
|
document.body.appendChild(link);
|
|
link.click();
|
|
document.body.removeChild(link);
|
|
URL.revokeObjectURL(url);
|
|
}
|
|
|
|
/**
|
|
* 현재 날짜/시간을 포함한 파일명 생성
|
|
*
|
|
* @param prefix - 파일명 접두사 (예: '근태현황', '급여명세')
|
|
* @param extension - 파일 확장자 (기본값: 'xlsx')
|
|
* @returns 생성된 파일명 (예: '근태현황_20250115_143052.xlsx')
|
|
*/
|
|
export function generateExportFilename(
|
|
prefix: string,
|
|
extension: string = 'xlsx'
|
|
): string {
|
|
const now = new Date();
|
|
const dateStr = now.toISOString().slice(0, 10).replace(/-/g, '');
|
|
const timeStr = now.toTimeString().slice(0, 8).replace(/:/g, '');
|
|
return `${prefix}_${dateStr}_${timeStr}.${extension}`;
|
|
}
|
|
|
|
/**
|
|
* 엑셀 내보내기 API 호출을 위한 fetch 옵션 생성
|
|
*
|
|
* @param token - 인증 토큰
|
|
* @param params - 쿼리 파라미터 (선택)
|
|
* @returns fetch 옵션 객체
|
|
*/
|
|
export function createExportFetchOptions(
|
|
token: string,
|
|
params?: Record<string, string | number | boolean | undefined>
|
|
): RequestInit {
|
|
return {
|
|
method: 'GET',
|
|
headers: {
|
|
Authorization: `Bearer ${token}`,
|
|
Accept: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
|
|
'X-API-KEY': process.env.NEXT_PUBLIC_API_KEY || '',
|
|
},
|
|
cache: 'no-store',
|
|
};
|
|
}
|
|
|
|
/**
|
|
* 쿼리 파라미터 문자열 생성
|
|
*
|
|
* @param params - 쿼리 파라미터 객체
|
|
* @returns URL 쿼리 문자열 (예: '?year=2025&month=1')
|
|
*/
|
|
export function buildExportQueryString(
|
|
params?: Record<string, string | number | boolean | undefined>
|
|
): string {
|
|
if (!params) return '';
|
|
|
|
const searchParams = new URLSearchParams();
|
|
|
|
Object.entries(params).forEach(([key, value]) => {
|
|
if (value !== undefined && value !== null && value !== '') {
|
|
searchParams.set(key, String(value));
|
|
}
|
|
});
|
|
|
|
const queryString = searchParams.toString();
|
|
return queryString ? `?${queryString}` : '';
|
|
}
|