- V/R 시스템 완전 전환: WARRANTY/CONTRACT/INSPECTION → V(방문)/R(원격) - 유지보수 대시보드 카드 → StandardDataTable 테이블 형태 전환 - "조회중..." 문제 해결: 백엔드 직접 필드 사용 (equipment_model, company_name) - MaintenanceDto 신규 필드 추가: company_id, company_name, equipment_serial, equipment_model - preloadEquipmentData 비활성화로 불필요한 equipment-history API 호출 제거 - CO-STAR 프레임워크 적용 및 CLAUDE.md v3.0 업데이트 - Flutter Analyze ERROR: 0 유지, 100% shadcn_ui 컴플라이언스 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
186 lines
5.7 KiB
Dart
186 lines
5.7 KiB
Dart
import 'package:injectable/injectable.dart';
|
|
import 'package:superport/data/models/maintenance_dto.dart';
|
|
import 'package:superport/data/repositories/maintenance_repository.dart';
|
|
|
|
@lazySingleton
|
|
class MaintenanceUseCase {
|
|
final MaintenanceRepository _repository;
|
|
|
|
MaintenanceUseCase({required MaintenanceRepository repository})
|
|
: _repository = repository;
|
|
|
|
// 유지보수 목록 조회
|
|
Future<MaintenanceListResponse> getMaintenances({
|
|
int page = 1,
|
|
int perPage = 20,
|
|
int? equipmentId,
|
|
String? maintenanceType,
|
|
bool? isExpired,
|
|
int? expiringDays,
|
|
bool includeDeleted = false,
|
|
}) async {
|
|
return await _repository.getMaintenances(
|
|
page: page,
|
|
perPage: perPage,
|
|
equipmentId: equipmentId,
|
|
maintenanceType: maintenanceType,
|
|
isExpired: isExpired,
|
|
expiringDays: expiringDays,
|
|
includeDeleted: includeDeleted,
|
|
);
|
|
}
|
|
|
|
// 특정 유지보수 상세 조회
|
|
Future<MaintenanceDto> getMaintenanceDetail(int id) async {
|
|
return await _repository.getMaintenanceDetail(id);
|
|
}
|
|
|
|
// 유지보수 생성
|
|
Future<MaintenanceDto> createMaintenance(MaintenanceRequestDto request) async {
|
|
// 기본 검증
|
|
_validateMaintenanceRequest(request);
|
|
|
|
return await _repository.createMaintenance(request);
|
|
}
|
|
|
|
// 유지보수 수정
|
|
Future<MaintenanceDto> updateMaintenance(
|
|
int id, MaintenanceUpdateRequestDto request) async {
|
|
// 기본 검증
|
|
if (request.periodMonth != null && request.periodMonth! <= 0) {
|
|
throw Exception('유지보수 주기는 1개월 이상이어야 합니다.');
|
|
}
|
|
|
|
// 날짜 검증
|
|
if (request.startedAt != null && request.endedAt != null) {
|
|
if (request.endedAt!.isBefore(request.startedAt!)) {
|
|
throw Exception('종료일은 시작일 이후여야 합니다.');
|
|
}
|
|
}
|
|
|
|
// 유지보수 타입 검증
|
|
if (request.maintenanceType != null &&
|
|
!MaintenanceType.allTypes.contains(request.maintenanceType!)) {
|
|
throw Exception('올바른 유지보수 타입을 선택해주세요.');
|
|
}
|
|
|
|
return await _repository.updateMaintenance(id, request);
|
|
}
|
|
|
|
// 유지보수 삭제 (소프트 삭제)
|
|
Future<void> deleteMaintenance(int id) async {
|
|
return await _repository.deleteMaintenance(id);
|
|
}
|
|
|
|
// 만료 예정 유지보수 조회
|
|
Future<List<MaintenanceDto>> getExpiringMaintenances({int days = 30}) async {
|
|
return await _repository.getExpiringMaintenances(days: days);
|
|
}
|
|
|
|
// 활성 유지보수만 조회 (is_deleted = false)
|
|
Future<MaintenanceListResponse> getActiveMaintenances({
|
|
int page = 1,
|
|
int perPage = 20,
|
|
int? equipmentId,
|
|
String? maintenanceType,
|
|
}) async {
|
|
return await getMaintenances(
|
|
page: page,
|
|
perPage: perPage,
|
|
equipmentId: equipmentId,
|
|
maintenanceType: maintenanceType,
|
|
includeDeleted: false, // 삭제된 항목 제외
|
|
);
|
|
}
|
|
|
|
// 만료된 유지보수 조회
|
|
Future<MaintenanceListResponse> getExpiredMaintenances({
|
|
int page = 1,
|
|
int perPage = 20,
|
|
}) async {
|
|
return await getMaintenances(
|
|
page: page,
|
|
perPage: perPage,
|
|
isExpired: true,
|
|
includeDeleted: false,
|
|
);
|
|
}
|
|
|
|
// 특정 장비의 유지보수 내역 조회
|
|
Future<MaintenanceListResponse> getMaintenancesByEquipment({
|
|
required int equipmentId,
|
|
int page = 1,
|
|
int perPage = 20,
|
|
bool includeDeleted = false,
|
|
}) async {
|
|
return await getMaintenances(
|
|
page: page,
|
|
perPage: perPage,
|
|
equipmentId: equipmentId,
|
|
includeDeleted: includeDeleted,
|
|
);
|
|
}
|
|
|
|
// Private 검증 메서드
|
|
void _validateMaintenanceRequest(MaintenanceRequestDto request) {
|
|
// 유지보수 주기 검증
|
|
if (request.periodMonth <= 0 || request.periodMonth > 120) {
|
|
throw Exception('유지보수 주기는 1-120개월 사이여야 합니다.');
|
|
}
|
|
|
|
// 날짜 검증
|
|
if (request.endedAt.isBefore(request.startedAt)) {
|
|
throw Exception('종료일은 시작일 이후여야 합니다.');
|
|
}
|
|
|
|
// 유지보수 타입 검증 (백엔드와 일치)
|
|
if (!MaintenanceType.allTypes.contains(request.maintenanceType)) {
|
|
throw Exception('유지보수 타입은 ${MaintenanceType.allTypes.join(', ')} 중 하나여야 합니다.');
|
|
}
|
|
}
|
|
|
|
// 유지보수 통계 조회
|
|
Future<MaintenanceStatistics> getMaintenanceStatistics() async {
|
|
// 첫 번째 페이지로 전체 개수 확인
|
|
final response = await getMaintenances(perPage: 1);
|
|
final totalCount = response.totalCount;
|
|
|
|
// 전체 데이터 조회 (페이지 크기를 총 개수로 설정)
|
|
final allDataResponse = await getMaintenances(
|
|
perPage: totalCount > 0 ? totalCount : 1000,
|
|
includeDeleted: false,
|
|
);
|
|
|
|
final maintenances = allDataResponse.items;
|
|
|
|
int activeCount = maintenances.where((m) => m.isActive).length;
|
|
int visitCount = maintenances.where((m) => m.maintenanceType == MaintenanceType.visit).length;
|
|
int remoteCount = maintenances.where((m) => m.maintenanceType == MaintenanceType.remote).length;
|
|
int expiredCount = maintenances.where((m) => m.isExpired).length;
|
|
|
|
return MaintenanceStatistics(
|
|
totalCount: totalCount,
|
|
activeCount: activeCount,
|
|
visitCount: visitCount,
|
|
remoteCount: remoteCount,
|
|
expiredCount: expiredCount,
|
|
);
|
|
}
|
|
}
|
|
|
|
/// 유지보수 통계 모델 (V/R 시스템)
|
|
class MaintenanceStatistics {
|
|
final int totalCount;
|
|
final int activeCount;
|
|
final int visitCount; // 방문 유지보수
|
|
final int remoteCount; // 원격 유지보수
|
|
final int expiredCount; // 만료된 것
|
|
|
|
MaintenanceStatistics({
|
|
required this.totalCount,
|
|
required this.activeCount,
|
|
required this.visitCount,
|
|
required this.remoteCount,
|
|
required this.expiredCount,
|
|
});
|
|
} |