[api] 스케줄 관리 작업
This commit is contained in:
@@ -0,0 +1,143 @@
|
|||||||
|
package com.alist.api.modules.admin.schedule;
|
||||||
|
|
||||||
|
import com.alist.api.common.response.ApiResponse;
|
||||||
|
import com.alist.api.common.response.ApiResponseCode;
|
||||||
|
import com.alist.api.modules.admin.schedule.form.*;
|
||||||
|
import com.alist.api.modules.admin.schedule.service.AdminScheduleService;
|
||||||
|
import com.alist.api.modules.admin.schedule.vo.*;
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
import jakarta.validation.Valid;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
@Tag(name = "504. 스케줄 관리", description = "관리자 스케줄 작업 관리 API")
|
||||||
|
@Slf4j
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/admin/schedule")
|
||||||
|
public class AdminScheduleController {
|
||||||
|
private final AdminScheduleService adminScheduleService;
|
||||||
|
|
||||||
|
public AdminScheduleController(AdminScheduleService adminScheduleService) {
|
||||||
|
this.adminScheduleService = adminScheduleService;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Operation(
|
||||||
|
summary = "스케줄 작업 목록 조회"
|
||||||
|
, description = "관리자가 스케줄 작업 목록을 검색 조건과 페이징으로 조회합니다."
|
||||||
|
)
|
||||||
|
@GetMapping("/list")
|
||||||
|
public ResponseEntity<ApiResponse<AdminScheduleListVo>> adminScheduleList(
|
||||||
|
@ModelAttribute AdminScheduleListForm adminScheduleListForm
|
||||||
|
) {
|
||||||
|
AdminScheduleListVo adminScheduleListVo = adminScheduleService.selectAdminScheduleList(adminScheduleListForm.toDto());
|
||||||
|
|
||||||
|
if (adminScheduleListVo.getScheduleList() == null || adminScheduleListVo.getScheduleList().isEmpty()) {
|
||||||
|
return ApiResponse.entity(adminScheduleListVo, ApiResponseCode.CODE_2003);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ApiResponse.entity(adminScheduleListVo, ApiResponseCode.CODE_2001, "스케줄 작업");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Operation(
|
||||||
|
summary = "스케줄 작업 상세 조회"
|
||||||
|
, description = "관리자가 스케줄 작업 PK 기준으로 상세 정보를 조회합니다."
|
||||||
|
)
|
||||||
|
@GetMapping("/view")
|
||||||
|
public ResponseEntity<ApiResponse<AdminScheduleViewVo>> adminScheduleView(
|
||||||
|
@RequestParam Long scheduleJobIdx
|
||||||
|
) {
|
||||||
|
AdminScheduleViewVo adminScheduleViewVo = adminScheduleService.selectAdminScheduleView(scheduleJobIdx);
|
||||||
|
|
||||||
|
if (adminScheduleViewVo == null) {
|
||||||
|
return ApiResponse.entity((AdminScheduleViewVo) null, ApiResponseCode.CODE_2003);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ApiResponse.entity(adminScheduleViewVo, ApiResponseCode.CODE_2001, "스케줄 작업");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Operation(
|
||||||
|
summary = "스케줄 작업 등록"
|
||||||
|
, description = "관리자가 스케줄 작업을 등록합니다. JOB_NAME과 JOB_GROUP이 중복되면 등록하지 않습니다."
|
||||||
|
)
|
||||||
|
@PostMapping("/add")
|
||||||
|
public ResponseEntity<ApiResponse<AdminScheduleAddVo>> adminScheduleAdd(
|
||||||
|
@Valid @RequestBody AdminScheduleAddForm adminScheduleAddForm
|
||||||
|
) {
|
||||||
|
AdminScheduleAddVo adminScheduleAddVo = adminScheduleService.insertAdminScheduleAdd(adminScheduleAddForm.toDto());
|
||||||
|
|
||||||
|
if (adminScheduleAddVo.getResultCode() == 401) {
|
||||||
|
return ApiResponse.entity(adminScheduleAddVo, ApiResponseCode.CODE_401);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!adminScheduleAddVo.isProcessed()) {
|
||||||
|
return ApiResponse.entity(adminScheduleAddVo, ApiResponseCode.CODE_2004, "스케줄 작업");
|
||||||
|
}
|
||||||
|
|
||||||
|
return ApiResponse.entity(adminScheduleAddVo, ApiResponseCode.CODE_2002, "스케줄 작업");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Operation(
|
||||||
|
summary = "스케줄 작업 수정"
|
||||||
|
, description = "관리자가 스케줄 작업 PK 기준으로 작업 코드, 크론식, 사용 여부 등 기본 정보를 수정합니다."
|
||||||
|
)
|
||||||
|
@PutMapping("/modify")
|
||||||
|
public ResponseEntity<ApiResponse<AdminScheduleModifyVo>> adminScheduleModify(
|
||||||
|
@Valid @RequestBody AdminScheduleModifyForm adminScheduleModifyForm
|
||||||
|
) {
|
||||||
|
AdminScheduleModifyVo adminScheduleModifyVo = adminScheduleService.updateAdminScheduleModify(adminScheduleModifyForm.toDto());
|
||||||
|
|
||||||
|
if (adminScheduleModifyVo.getResultCode() == 401) {
|
||||||
|
return ApiResponse.entity(adminScheduleModifyVo, ApiResponseCode.CODE_401);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (adminScheduleModifyVo.getResultCode() == 2004) {
|
||||||
|
return ApiResponse.entity(adminScheduleModifyVo, ApiResponseCode.CODE_2004, "스케줄 작업");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!adminScheduleModifyVo.isProcessed()) {
|
||||||
|
return ApiResponse.entity(adminScheduleModifyVo, ApiResponseCode.CODE_2003);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ApiResponse.entity(adminScheduleModifyVo, ApiResponseCode.CODE_2005, "스케줄 작업 수정");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Operation(
|
||||||
|
summary = "스케줄 작업 삭제"
|
||||||
|
, description = "관리자가 스케줄 작업 PK 기준으로 삭제 처리합니다. 실제 삭제가 아닌 DEL_YN 변경 방식입니다."
|
||||||
|
)
|
||||||
|
@PatchMapping("/delete")
|
||||||
|
public ResponseEntity<ApiResponse<AdminScheduleDeleteVo>> adminScheduleDelete(
|
||||||
|
@Valid @RequestBody AdminScheduleDeleteForm adminScheduleDeleteForm
|
||||||
|
) {
|
||||||
|
AdminScheduleDeleteVo adminScheduleDeleteVo = adminScheduleService.updateAdminScheduleDelete(adminScheduleDeleteForm.toDto());
|
||||||
|
|
||||||
|
if (adminScheduleDeleteVo.getResultCode() == 401) {
|
||||||
|
return ApiResponse.entity(adminScheduleDeleteVo, ApiResponseCode.CODE_401);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!adminScheduleDeleteVo.isProcessed()) {
|
||||||
|
return ApiResponse.entity(adminScheduleDeleteVo, ApiResponseCode.CODE_2003);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ApiResponse.entity(adminScheduleDeleteVo, ApiResponseCode.CODE_2005, "스케줄 작업 삭제");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Operation(
|
||||||
|
summary = "스케줄 작업 실행 로그 목록 조회"
|
||||||
|
, description = "관리자가 스케줄 작업 실행 로그를 검색 조건과 페이징으로 조회합니다."
|
||||||
|
)
|
||||||
|
@GetMapping("/log/list")
|
||||||
|
public ResponseEntity<ApiResponse<AdminScheduleLogListVo>> adminScheduleLogList(
|
||||||
|
@ModelAttribute AdminScheduleLogListForm adminScheduleLogListForm
|
||||||
|
) {
|
||||||
|
AdminScheduleLogListVo adminScheduleLogListVo = adminScheduleService.selectAdminScheduleLogList(adminScheduleLogListForm.toDto());
|
||||||
|
|
||||||
|
if (adminScheduleLogListVo.getScheduleLogList() == null || adminScheduleLogListVo.getScheduleLogList().isEmpty()) {
|
||||||
|
return ApiResponse.entity(adminScheduleLogListVo, ApiResponseCode.CODE_2003);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ApiResponse.entity(adminScheduleLogListVo, ApiResponseCode.CODE_2001, "스케줄 작업 실행 로그");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
package com.alist.api.modules.admin.schedule.dto;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
public class AdminScheduleAddDto {
|
||||||
|
private Long scheduleJobIdx;
|
||||||
|
private String jobName;
|
||||||
|
private String jobGroup;
|
||||||
|
private String jobDescription;
|
||||||
|
private String cronExpr;
|
||||||
|
private String timezoneId;
|
||||||
|
private Integer maxRunningSeconds;
|
||||||
|
private String useYn;
|
||||||
|
private Integer createMember;
|
||||||
|
private Integer updateMember;
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
package com.alist.api.modules.admin.schedule.dto;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
public class AdminScheduleDeleteDto {
|
||||||
|
private Long scheduleJobIdx;
|
||||||
|
private Integer updateMember;
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
package com.alist.api.modules.admin.schedule.dto;
|
||||||
|
|
||||||
|
import com.alist.api.common.paging.PageRequest;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
public class AdminScheduleListDto extends PageRequest {
|
||||||
|
private String keyword;
|
||||||
|
private String jobGroup;
|
||||||
|
private Integer lastStatus;
|
||||||
|
private String useYn;
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
package com.alist.api.modules.admin.schedule.dto;
|
||||||
|
|
||||||
|
import com.alist.api.common.paging.PageRequest;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
public class AdminScheduleLogListDto extends PageRequest {
|
||||||
|
private Long scheduleJobIdx;
|
||||||
|
private Integer status;
|
||||||
|
private String startDateFrom;
|
||||||
|
private String startDateTo;
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
package com.alist.api.modules.admin.schedule.dto;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
public class AdminScheduleModifyDto {
|
||||||
|
private Long scheduleJobIdx;
|
||||||
|
private String jobName;
|
||||||
|
private String jobGroup;
|
||||||
|
private String jobDescription;
|
||||||
|
private String cronExpr;
|
||||||
|
private String timezoneId;
|
||||||
|
private Integer maxRunningSeconds;
|
||||||
|
private String useYn;
|
||||||
|
private Integer updateMember;
|
||||||
|
}
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
package com.alist.api.modules.admin.schedule.form;
|
||||||
|
|
||||||
|
import com.alist.api.modules.admin.schedule.dto.AdminScheduleAddDto;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import jakarta.validation.constraints.Min;
|
||||||
|
import jakarta.validation.constraints.NotBlank;
|
||||||
|
import jakarta.validation.constraints.Pattern;
|
||||||
|
import jakarta.validation.constraints.Size;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
@Schema(description = "관리자 스케줄 작업 등록 요청")
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
public class AdminScheduleAddForm {
|
||||||
|
@NotBlank
|
||||||
|
@Size(max = 100)
|
||||||
|
@Schema(description = "작업 코드", example = "DAILY_LEARNING_SUMMARY", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
|
private String jobName;
|
||||||
|
|
||||||
|
@Size(max = 50)
|
||||||
|
@Schema(description = "작업 그룹. 미입력 시 DEFAULT", example = "DEFAULT")
|
||||||
|
private String jobGroup;
|
||||||
|
|
||||||
|
@Size(max = 255)
|
||||||
|
@Schema(description = "작업 설명", example = "일별 학습 통계 집계")
|
||||||
|
private String jobDescription;
|
||||||
|
|
||||||
|
@NotBlank
|
||||||
|
@Size(max = 100)
|
||||||
|
@Schema(description = "크론식", example = "0 0 2 * * *", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
|
private String cronExpr;
|
||||||
|
|
||||||
|
@Size(max = 50)
|
||||||
|
@Schema(description = "타임존. 미입력 시 Asia/Seoul", example = "Asia/Seoul")
|
||||||
|
private String timezoneId;
|
||||||
|
|
||||||
|
@Min(1)
|
||||||
|
@Schema(description = "최대 실행 허용 시간(초). 미입력 시 1800", example = "1800")
|
||||||
|
private Integer maxRunningSeconds;
|
||||||
|
|
||||||
|
@Pattern(regexp = "Y|N")
|
||||||
|
@Schema(description = "사용 여부. Y: 사용, N: 미사용. 미입력 시 Y", example = "Y")
|
||||||
|
private String useYn;
|
||||||
|
|
||||||
|
public AdminScheduleAddDto toDto() {
|
||||||
|
AdminScheduleAddDto adminScheduleAddDto = new AdminScheduleAddDto();
|
||||||
|
adminScheduleAddDto.setJobName(jobName.trim());
|
||||||
|
adminScheduleAddDto.setJobGroup(jobGroup == null || jobGroup.trim().isEmpty() ? "DEFAULT" : jobGroup.trim());
|
||||||
|
adminScheduleAddDto.setJobDescription(jobDescription == null ? null : jobDescription.trim());
|
||||||
|
adminScheduleAddDto.setCronExpr(cronExpr.trim());
|
||||||
|
adminScheduleAddDto.setTimezoneId(timezoneId == null || timezoneId.trim().isEmpty() ? "Asia/Seoul" : timezoneId.trim());
|
||||||
|
adminScheduleAddDto.setMaxRunningSeconds(maxRunningSeconds == null ? 1800 : maxRunningSeconds);
|
||||||
|
adminScheduleAddDto.setUseYn(useYn == null || useYn.trim().isEmpty() ? "Y" : useYn.trim());
|
||||||
|
return adminScheduleAddDto;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
package com.alist.api.modules.admin.schedule.form;
|
||||||
|
|
||||||
|
import com.alist.api.modules.admin.schedule.dto.AdminScheduleDeleteDto;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import jakarta.validation.constraints.NotNull;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
@Schema(description = "관리자 스케줄 작업 삭제 요청")
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
public class AdminScheduleDeleteForm {
|
||||||
|
@NotNull
|
||||||
|
@Schema(description = "스케줄 작업 PK", example = "9", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
|
private Long scheduleJobIdx;
|
||||||
|
|
||||||
|
public AdminScheduleDeleteDto toDto() {
|
||||||
|
AdminScheduleDeleteDto adminScheduleDeleteDto = new AdminScheduleDeleteDto();
|
||||||
|
adminScheduleDeleteDto.setScheduleJobIdx(scheduleJobIdx);
|
||||||
|
return adminScheduleDeleteDto;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
package com.alist.api.modules.admin.schedule.form;
|
||||||
|
|
||||||
|
import com.alist.api.common.paging.PageRequest;
|
||||||
|
import com.alist.api.modules.admin.schedule.dto.AdminScheduleListDto;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
@Schema(description = "관리자 스케줄 작업 목록 검색 조건")
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
public class AdminScheduleListForm extends PageRequest {
|
||||||
|
@Schema(description = "검색어. 작업 코드, 작업 설명을 대상으로 검색합니다.", example = "DAILY")
|
||||||
|
private String keyword;
|
||||||
|
|
||||||
|
@Schema(description = "작업 그룹", example = "DEFAULT")
|
||||||
|
private String jobGroup;
|
||||||
|
|
||||||
|
@Schema(description = "마지막 실행 상태. 0: IDLE, 1: RUNNING, 2: SUCCESS, 3: SKIP, 4: FAIL", example = "2")
|
||||||
|
private Integer lastStatus;
|
||||||
|
|
||||||
|
@Schema(description = "사용 여부. Y: 사용, N: 미사용", example = "Y")
|
||||||
|
private String useYn;
|
||||||
|
|
||||||
|
public AdminScheduleListDto toDto() {
|
||||||
|
AdminScheduleListDto adminScheduleListDto = new AdminScheduleListDto();
|
||||||
|
adminScheduleListDto.setPage(getPage());
|
||||||
|
adminScheduleListDto.setSize(getSize());
|
||||||
|
adminScheduleListDto.setKeyword(keyword == null ? null : keyword.trim());
|
||||||
|
adminScheduleListDto.setJobGroup(jobGroup == null ? null : jobGroup.trim());
|
||||||
|
adminScheduleListDto.setLastStatus(lastStatus);
|
||||||
|
adminScheduleListDto.setUseYn(useYn == null ? null : useYn.trim());
|
||||||
|
return adminScheduleListDto;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
package com.alist.api.modules.admin.schedule.form;
|
||||||
|
|
||||||
|
import com.alist.api.common.paging.PageRequest;
|
||||||
|
import com.alist.api.modules.admin.schedule.dto.AdminScheduleLogListDto;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import jakarta.validation.constraints.NotNull;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
@Schema(description = "관리자 스케줄 작업 실행 로그 목록 검색 조건")
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
public class AdminScheduleLogListForm extends PageRequest {
|
||||||
|
@Schema(description = "스케줄 작업 PK", example = "9", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
|
private Long scheduleJobIdx;
|
||||||
|
|
||||||
|
@Schema(description = "실행 상태. 1: RUNNING, 2: SUCCESS, 3: SKIP, 4: FAIL", example = "2")
|
||||||
|
private Integer status;
|
||||||
|
|
||||||
|
@Schema(description = "실행 시작일 검색 시작값. yyyy-MM-dd 또는 yyyy-MM-dd HH:mm:ss", example = "2026-05-01")
|
||||||
|
private String startDateFrom;
|
||||||
|
|
||||||
|
@Schema(description = "실행 시작일 검색 종료값. yyyy-MM-dd 또는 yyyy-MM-dd HH:mm:ss", example = "2026-05-28")
|
||||||
|
private String startDateTo;
|
||||||
|
|
||||||
|
public AdminScheduleLogListDto toDto() {
|
||||||
|
AdminScheduleLogListDto adminScheduleLogListDto = new AdminScheduleLogListDto();
|
||||||
|
adminScheduleLogListDto.setPage(getPage());
|
||||||
|
adminScheduleLogListDto.setSize(getSize());
|
||||||
|
adminScheduleLogListDto.setScheduleJobIdx(scheduleJobIdx);
|
||||||
|
adminScheduleLogListDto.setStatus(status);
|
||||||
|
adminScheduleLogListDto.setStartDateFrom(startDateFrom == null ? null : startDateFrom.trim());
|
||||||
|
adminScheduleLogListDto.setStartDateTo(startDateTo == null ? null : startDateTo.trim());
|
||||||
|
return adminScheduleLogListDto;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,59 @@
|
|||||||
|
package com.alist.api.modules.admin.schedule.form;
|
||||||
|
|
||||||
|
import com.alist.api.modules.admin.schedule.dto.AdminScheduleModifyDto;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import jakarta.validation.constraints.*;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
@Schema(description = "관리자 스케줄 작업 수정 요청")
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
public class AdminScheduleModifyForm {
|
||||||
|
@NotNull
|
||||||
|
@Schema(description = "스케줄 작업 PK", example = "9", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
|
private Long scheduleJobIdx;
|
||||||
|
|
||||||
|
@NotBlank
|
||||||
|
@Size(max = 100)
|
||||||
|
@Schema(description = "작업 코드", example = "DAILY_LEARNING_SUMMARY", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
|
private String jobName;
|
||||||
|
|
||||||
|
@Size(max = 50)
|
||||||
|
@Schema(description = "작업 그룹. 미입력 시 DEFAULT", example = "DEFAULT")
|
||||||
|
private String jobGroup;
|
||||||
|
|
||||||
|
@Size(max = 255)
|
||||||
|
@Schema(description = "작업 설명", example = "일별 학습 통계 집계")
|
||||||
|
private String jobDescription;
|
||||||
|
|
||||||
|
@NotBlank
|
||||||
|
@Size(max = 100)
|
||||||
|
@Schema(description = "크론식", example = "0 0 2 * * *", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
|
private String cronExpr;
|
||||||
|
|
||||||
|
@Size(max = 50)
|
||||||
|
@Schema(description = "타임존. 미입력 시 Asia/Seoul", example = "Asia/Seoul")
|
||||||
|
private String timezoneId;
|
||||||
|
|
||||||
|
@Min(1)
|
||||||
|
@Schema(description = "최대 실행 허용 시간(초). 미입력 시 1800", example = "1800")
|
||||||
|
private Integer maxRunningSeconds;
|
||||||
|
|
||||||
|
@Pattern(regexp = "Y|N")
|
||||||
|
@Schema(description = "사용 여부. Y: 사용, N: 미사용. 미입력 시 Y", example = "Y")
|
||||||
|
private String useYn;
|
||||||
|
|
||||||
|
public AdminScheduleModifyDto toDto() {
|
||||||
|
AdminScheduleModifyDto adminScheduleModifyDto = new AdminScheduleModifyDto();
|
||||||
|
adminScheduleModifyDto.setScheduleJobIdx(scheduleJobIdx);
|
||||||
|
adminScheduleModifyDto.setJobName(jobName.trim());
|
||||||
|
adminScheduleModifyDto.setJobGroup(jobGroup == null || jobGroup.trim().isEmpty() ? "DEFAULT" : jobGroup.trim());
|
||||||
|
adminScheduleModifyDto.setJobDescription(jobDescription == null ? null : jobDescription.trim());
|
||||||
|
adminScheduleModifyDto.setCronExpr(cronExpr.trim());
|
||||||
|
adminScheduleModifyDto.setTimezoneId(timezoneId == null || timezoneId.trim().isEmpty() ? "Asia/Seoul" : timezoneId.trim());
|
||||||
|
adminScheduleModifyDto.setMaxRunningSeconds(maxRunningSeconds == null ? 1800 : maxRunningSeconds);
|
||||||
|
adminScheduleModifyDto.setUseYn(useYn == null || useYn.trim().isEmpty() ? "Y" : useYn.trim());
|
||||||
|
return adminScheduleModifyDto;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
package com.alist.api.modules.admin.schedule.mapper;
|
||||||
|
|
||||||
|
import com.alist.api.modules.admin.schedule.dto.*;
|
||||||
|
import com.alist.api.modules.admin.schedule.vo.AdminScheduleLogVo;
|
||||||
|
import com.alist.api.modules.admin.schedule.vo.AdminScheduleViewVo;
|
||||||
|
import com.alist.api.modules.admin.schedule.vo.AdminScheduleVo;
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Mapper
|
||||||
|
public interface AdminScheduleMapper {
|
||||||
|
int selectAdminScheduleDuplicateCount(AdminScheduleAddDto adminScheduleAddDto);
|
||||||
|
|
||||||
|
int insertAdminScheduleAdd(AdminScheduleAddDto adminScheduleAddDto);
|
||||||
|
|
||||||
|
int selectAdminScheduleCount(AdminScheduleListDto adminScheduleListDto);
|
||||||
|
|
||||||
|
List<AdminScheduleVo> selectAdminScheduleList(AdminScheduleListDto adminScheduleListDto);
|
||||||
|
|
||||||
|
AdminScheduleViewVo selectAdminScheduleView(Long scheduleJobIdx);
|
||||||
|
|
||||||
|
int selectAdminScheduleModifyDuplicateCount(AdminScheduleModifyDto adminScheduleModifyDto);
|
||||||
|
|
||||||
|
int updateAdminScheduleModify(AdminScheduleModifyDto adminScheduleModifyDto);
|
||||||
|
|
||||||
|
int updateAdminScheduleDelete(AdminScheduleDeleteDto adminScheduleDeleteDto);
|
||||||
|
|
||||||
|
int selectAdminScheduleLogCount(AdminScheduleLogListDto adminScheduleLogListDto);
|
||||||
|
|
||||||
|
List<AdminScheduleLogVo> selectAdminScheduleLogList(AdminScheduleLogListDto adminScheduleLogListDto);
|
||||||
|
}
|
||||||
@@ -0,0 +1,160 @@
|
|||||||
|
package com.alist.api.modules.admin.schedule.service;
|
||||||
|
|
||||||
|
import com.alist.api.common.utils.SecurityUtil;
|
||||||
|
import com.alist.api.modules.admin.auth.mapper.AdminAuthMapper;
|
||||||
|
import com.alist.api.modules.admin.auth.vo.AdminAuthLoginVo;
|
||||||
|
import com.alist.api.modules.admin.schedule.dto.*;
|
||||||
|
import com.alist.api.modules.admin.schedule.mapper.AdminScheduleMapper;
|
||||||
|
import com.alist.api.modules.admin.schedule.vo.*;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class AdminScheduleService {
|
||||||
|
private final AdminScheduleMapper adminScheduleMapper;
|
||||||
|
private final AdminAuthMapper adminAuthMapper;
|
||||||
|
|
||||||
|
public AdminScheduleService(AdminScheduleMapper adminScheduleMapper, AdminAuthMapper adminAuthMapper) {
|
||||||
|
this.adminScheduleMapper = adminScheduleMapper;
|
||||||
|
this.adminAuthMapper = adminAuthMapper;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional(readOnly = true)
|
||||||
|
public AdminScheduleListVo selectAdminScheduleList(AdminScheduleListDto adminScheduleListDto) {
|
||||||
|
int totalCount = adminScheduleMapper.selectAdminScheduleCount(adminScheduleListDto);
|
||||||
|
List<AdminScheduleVo> scheduleList = adminScheduleMapper.selectAdminScheduleList(adminScheduleListDto);
|
||||||
|
|
||||||
|
AdminScheduleListVo adminScheduleListVo = new AdminScheduleListVo();
|
||||||
|
adminScheduleListVo.setScheduleList(scheduleList);
|
||||||
|
adminScheduleListVo.setPaging(adminScheduleListDto, totalCount);
|
||||||
|
|
||||||
|
return adminScheduleListVo;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional(readOnly = true)
|
||||||
|
public AdminScheduleViewVo selectAdminScheduleView(Long scheduleJobIdx) {
|
||||||
|
return adminScheduleMapper.selectAdminScheduleView(scheduleJobIdx);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
public AdminScheduleAddVo insertAdminScheduleAdd(AdminScheduleAddDto adminScheduleAddDto) {
|
||||||
|
AdminScheduleAddVo adminScheduleAddVo = new AdminScheduleAddVo();
|
||||||
|
|
||||||
|
Integer loginUserTokenIdx = SecurityUtil.getLoginUserTokenIdx();
|
||||||
|
|
||||||
|
if (loginUserTokenIdx == null) {
|
||||||
|
adminScheduleAddVo.setResultCode(401);
|
||||||
|
adminScheduleAddVo.setProcessed(false);
|
||||||
|
return adminScheduleAddVo;
|
||||||
|
}
|
||||||
|
|
||||||
|
AdminAuthLoginVo adminAuthLoginVo = adminAuthMapper.selectAdminTokenByUserTokenIdx(loginUserTokenIdx);
|
||||||
|
|
||||||
|
if (adminAuthLoginVo == null || adminAuthLoginVo.getUserIdx() == null) {
|
||||||
|
adminScheduleAddVo.setResultCode(401);
|
||||||
|
adminScheduleAddVo.setProcessed(false);
|
||||||
|
return adminScheduleAddVo;
|
||||||
|
}
|
||||||
|
|
||||||
|
adminScheduleAddDto.setCreateMember(adminAuthLoginVo.getUserIdx());
|
||||||
|
adminScheduleAddDto.setUpdateMember(adminAuthLoginVo.getUserIdx());
|
||||||
|
|
||||||
|
int duplicateCount = adminScheduleMapper.selectAdminScheduleDuplicateCount(adminScheduleAddDto);
|
||||||
|
|
||||||
|
if (duplicateCount > 0) {
|
||||||
|
adminScheduleAddVo.setResultCode(2004);
|
||||||
|
adminScheduleAddVo.setProcessed(false);
|
||||||
|
return adminScheduleAddVo;
|
||||||
|
}
|
||||||
|
|
||||||
|
int insertCount = adminScheduleMapper.insertAdminScheduleAdd(adminScheduleAddDto);
|
||||||
|
|
||||||
|
adminScheduleAddVo.setResultCode(2002);
|
||||||
|
adminScheduleAddVo.setProcessed(insertCount > 0);
|
||||||
|
adminScheduleAddVo.setScheduleJobIdx(adminScheduleAddDto.getScheduleJobIdx());
|
||||||
|
|
||||||
|
return adminScheduleAddVo;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
public AdminScheduleModifyVo updateAdminScheduleModify(AdminScheduleModifyDto adminScheduleModifyDto) {
|
||||||
|
AdminScheduleModifyVo adminScheduleModifyVo = new AdminScheduleModifyVo();
|
||||||
|
|
||||||
|
Integer loginUserTokenIdx = SecurityUtil.getLoginUserTokenIdx();
|
||||||
|
|
||||||
|
if (loginUserTokenIdx == null) {
|
||||||
|
adminScheduleModifyVo.setResultCode(401);
|
||||||
|
adminScheduleModifyVo.setProcessed(false);
|
||||||
|
return adminScheduleModifyVo;
|
||||||
|
}
|
||||||
|
|
||||||
|
AdminAuthLoginVo adminAuthLoginVo = adminAuthMapper.selectAdminTokenByUserTokenIdx(loginUserTokenIdx);
|
||||||
|
|
||||||
|
if (adminAuthLoginVo == null || adminAuthLoginVo.getUserIdx() == null) {
|
||||||
|
adminScheduleModifyVo.setResultCode(401);
|
||||||
|
adminScheduleModifyVo.setProcessed(false);
|
||||||
|
return adminScheduleModifyVo;
|
||||||
|
}
|
||||||
|
|
||||||
|
adminScheduleModifyDto.setUpdateMember(adminAuthLoginVo.getUserIdx());
|
||||||
|
|
||||||
|
int duplicateCount = adminScheduleMapper.selectAdminScheduleModifyDuplicateCount(adminScheduleModifyDto);
|
||||||
|
|
||||||
|
if (duplicateCount > 0) {
|
||||||
|
adminScheduleModifyVo.setResultCode(2004);
|
||||||
|
adminScheduleModifyVo.setProcessed(false);
|
||||||
|
return adminScheduleModifyVo;
|
||||||
|
}
|
||||||
|
|
||||||
|
int updateCount = adminScheduleMapper.updateAdminScheduleModify(adminScheduleModifyDto);
|
||||||
|
|
||||||
|
adminScheduleModifyVo.setResultCode(2005);
|
||||||
|
adminScheduleModifyVo.setProcessed(updateCount > 0);
|
||||||
|
|
||||||
|
return adminScheduleModifyVo;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
public AdminScheduleDeleteVo updateAdminScheduleDelete(AdminScheduleDeleteDto adminScheduleDeleteDto) {
|
||||||
|
AdminScheduleDeleteVo adminScheduleDeleteVo = new AdminScheduleDeleteVo();
|
||||||
|
|
||||||
|
Integer loginUserTokenIdx = SecurityUtil.getLoginUserTokenIdx();
|
||||||
|
|
||||||
|
if (loginUserTokenIdx == null) {
|
||||||
|
adminScheduleDeleteVo.setResultCode(401);
|
||||||
|
adminScheduleDeleteVo.setProcessed(false);
|
||||||
|
return adminScheduleDeleteVo;
|
||||||
|
}
|
||||||
|
|
||||||
|
AdminAuthLoginVo adminAuthLoginVo = adminAuthMapper.selectAdminTokenByUserTokenIdx(loginUserTokenIdx);
|
||||||
|
|
||||||
|
if (adminAuthLoginVo == null || adminAuthLoginVo.getUserIdx() == null) {
|
||||||
|
adminScheduleDeleteVo.setResultCode(401);
|
||||||
|
adminScheduleDeleteVo.setProcessed(false);
|
||||||
|
return adminScheduleDeleteVo;
|
||||||
|
}
|
||||||
|
|
||||||
|
adminScheduleDeleteDto.setUpdateMember(adminAuthLoginVo.getUserIdx());
|
||||||
|
|
||||||
|
int updateCount = adminScheduleMapper.updateAdminScheduleDelete(adminScheduleDeleteDto);
|
||||||
|
|
||||||
|
adminScheduleDeleteVo.setResultCode(2005);
|
||||||
|
adminScheduleDeleteVo.setProcessed(updateCount > 0);
|
||||||
|
|
||||||
|
return adminScheduleDeleteVo;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional(readOnly = true)
|
||||||
|
public AdminScheduleLogListVo selectAdminScheduleLogList(AdminScheduleLogListDto adminScheduleLogListDto) {
|
||||||
|
int totalCount = adminScheduleMapper.selectAdminScheduleLogCount(adminScheduleLogListDto);
|
||||||
|
List<AdminScheduleLogVo> scheduleLogList = adminScheduleMapper.selectAdminScheduleLogList(adminScheduleLogListDto);
|
||||||
|
|
||||||
|
AdminScheduleLogListVo adminScheduleLogListVo = new AdminScheduleLogListVo();
|
||||||
|
adminScheduleLogListVo.setScheduleLogList(scheduleLogList);
|
||||||
|
adminScheduleLogListVo.setPaging(adminScheduleLogListDto, totalCount);
|
||||||
|
|
||||||
|
return adminScheduleLogListVo;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
package com.alist.api.modules.admin.schedule.vo;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
@Schema(description = "관리자 스케줄 작업 등록 응답")
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
public class AdminScheduleAddVo {
|
||||||
|
@Schema(description = "스케줄 작업 등록 여부", example = "true")
|
||||||
|
private boolean processed;
|
||||||
|
|
||||||
|
@Schema(description = "등록된 스케줄 작업 PK", example = "9")
|
||||||
|
private Long scheduleJobIdx;
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
|
@Schema(hidden = true)
|
||||||
|
private int resultCode;
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
package com.alist.api.modules.admin.schedule.vo;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
@Schema(description = "관리자 스케줄 작업 삭제 응답")
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
public class AdminScheduleDeleteVo {
|
||||||
|
@Schema(description = "스케줄 작업 삭제 처리 여부", example = "true")
|
||||||
|
private boolean processed;
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
|
@Schema(hidden = true)
|
||||||
|
private int resultCode;
|
||||||
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
package com.alist.api.modules.admin.schedule.vo;
|
||||||
|
|
||||||
|
import com.alist.api.common.paging.PageResponse;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Schema(description = "관리자 스케줄 작업 목록 조회 응답")
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
public class AdminScheduleListVo extends PageResponse {
|
||||||
|
@Schema(description = "스케줄 작업 목록")
|
||||||
|
private List<AdminScheduleVo> scheduleList;
|
||||||
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
package com.alist.api.modules.admin.schedule.vo;
|
||||||
|
|
||||||
|
import com.alist.api.common.paging.PageResponse;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Schema(description = "관리자 스케줄 작업 실행 로그 목록 조회 응답")
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
public class AdminScheduleLogListVo extends PageResponse {
|
||||||
|
@Schema(description = "스케줄 작업 실행 로그 목록")
|
||||||
|
private List<AdminScheduleLogVo> scheduleLogList;
|
||||||
|
}
|
||||||
@@ -0,0 +1,54 @@
|
|||||||
|
package com.alist.api.modules.admin.schedule.vo;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
@Schema(description = "관리자 스케줄 작업 실행 로그 목록 항목")
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
public class AdminScheduleLogVo {
|
||||||
|
@Schema(description = "스케줄 작업 로그 PK", example = "20185")
|
||||||
|
private Long scheduleJobLogIdx;
|
||||||
|
|
||||||
|
@Schema(description = "스케줄 작업 PK", example = "9")
|
||||||
|
private Long scheduleJobIdx;
|
||||||
|
|
||||||
|
@Schema(description = "1회 실행 식별자", example = "20260528093000-abc123")
|
||||||
|
private String runId;
|
||||||
|
|
||||||
|
@Schema(description = "작업 코드", example = "DAILY_LEARNING_SUMMARY")
|
||||||
|
private String jobName;
|
||||||
|
|
||||||
|
@Schema(description = "실행 시작 시각", example = "2026-05-28 09:30:00")
|
||||||
|
private LocalDateTime startDate;
|
||||||
|
|
||||||
|
@Schema(description = "실행 종료 시각", example = "2026-05-28 09:30:12")
|
||||||
|
private LocalDateTime endDate;
|
||||||
|
|
||||||
|
@Schema(description = "대상 건수", example = "100")
|
||||||
|
private Integer targetCount;
|
||||||
|
|
||||||
|
@Schema(description = "성공 건수", example = "98")
|
||||||
|
private Integer successCount;
|
||||||
|
|
||||||
|
@Schema(description = "실패 건수", example = "2")
|
||||||
|
private Integer failCount;
|
||||||
|
|
||||||
|
@Schema(description = "요약 메시지", example = "일별 학습 통계 집계 완료")
|
||||||
|
private String message;
|
||||||
|
|
||||||
|
@Schema(description = "오류 메시지", example = "timeout")
|
||||||
|
private String errorMessage;
|
||||||
|
|
||||||
|
@Schema(description = "실행 서버", example = "api-01")
|
||||||
|
private String lockOwner;
|
||||||
|
|
||||||
|
@Schema(description = "실행 상태. 1: RUNNING, 2: SUCCESS, 3: SKIP, 4: FAIL", example = "2")
|
||||||
|
private Integer status;
|
||||||
|
|
||||||
|
@Schema(description = "기록 시각", example = "2026-05-28 09:30:00")
|
||||||
|
private LocalDateTime createDate;
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
package com.alist.api.modules.admin.schedule.vo;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
@Schema(description = "관리자 스케줄 작업 수정 응답")
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
public class AdminScheduleModifyVo {
|
||||||
|
@Schema(description = "스케줄 작업 수정 여부", example = "true")
|
||||||
|
private boolean processed;
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
|
@Schema(hidden = true)
|
||||||
|
private int resultCode;
|
||||||
|
}
|
||||||
@@ -0,0 +1,72 @@
|
|||||||
|
package com.alist.api.modules.admin.schedule.vo;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
@Schema(description = "관리자 스케줄 작업 상세 조회 응답")
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
public class AdminScheduleViewVo {
|
||||||
|
@Schema(description = "스케줄 작업 PK", example = "9")
|
||||||
|
private Long scheduleJobIdx;
|
||||||
|
|
||||||
|
@Schema(description = "작업 코드", example = "DAILY_LEARNING_SUMMARY")
|
||||||
|
private String jobName;
|
||||||
|
|
||||||
|
@Schema(description = "작업 그룹", example = "DEFAULT")
|
||||||
|
private String jobGroup;
|
||||||
|
|
||||||
|
@Schema(description = "작업 설명", example = "일별 학습 통계 집계")
|
||||||
|
private String jobDescription;
|
||||||
|
|
||||||
|
@Schema(description = "크론식", example = "0 0 2 * * *")
|
||||||
|
private String cronExpr;
|
||||||
|
|
||||||
|
@Schema(description = "타임존", example = "Asia/Seoul")
|
||||||
|
private String timezoneId;
|
||||||
|
|
||||||
|
@Schema(description = "최대 실행 허용 시간(초)", example = "1800")
|
||||||
|
private Integer maxRunningSeconds;
|
||||||
|
|
||||||
|
@Schema(description = "마지막 실행 시작 시각", example = "2026-05-27 02:00:00")
|
||||||
|
private LocalDateTime lastRunDate;
|
||||||
|
|
||||||
|
@Schema(description = "마지막 실행 종료 시각", example = "2026-05-27 02:00:10")
|
||||||
|
private LocalDateTime lastEndDate;
|
||||||
|
|
||||||
|
@Schema(description = "마지막 성공 시각", example = "2026-05-27 02:00:10")
|
||||||
|
private LocalDateTime lastSuccessDate;
|
||||||
|
|
||||||
|
@Schema(description = "마지막 실행 상태. 0: IDLE, 1: RUNNING, 2: SUCCESS, 3: SKIP, 4: FAIL", example = "2")
|
||||||
|
private Integer lastStatus;
|
||||||
|
|
||||||
|
@Schema(description = "마지막 실행 메시지", example = "정상 처리")
|
||||||
|
private String lastMessage;
|
||||||
|
|
||||||
|
@Schema(description = "실행 락 시각", example = "2026-05-27 02:00:00")
|
||||||
|
private LocalDateTime runLockDate;
|
||||||
|
|
||||||
|
@Schema(description = "실행 락 소유자", example = "api-01")
|
||||||
|
private String runLockOwner;
|
||||||
|
|
||||||
|
@Schema(description = "사용 여부. Y: 사용, N: 미사용", example = "Y")
|
||||||
|
private String useYn;
|
||||||
|
|
||||||
|
@Schema(description = "삭제 여부. Y: 삭제, N: 정상", example = "N")
|
||||||
|
private String delYn;
|
||||||
|
|
||||||
|
@Schema(description = "최초 생성일", example = "2026-05-27 10:00:00")
|
||||||
|
private LocalDateTime createDate;
|
||||||
|
|
||||||
|
@Schema(description = "최초 생성자 회원 PK", example = "1")
|
||||||
|
private Integer createMember;
|
||||||
|
|
||||||
|
@Schema(description = "마지막 수정일", example = "2026-05-27 10:00:00")
|
||||||
|
private LocalDateTime updateDate;
|
||||||
|
|
||||||
|
@Schema(description = "마지막 수정자 회원 PK", example = "1")
|
||||||
|
private Integer updateMember;
|
||||||
|
}
|
||||||
@@ -0,0 +1,63 @@
|
|||||||
|
package com.alist.api.modules.admin.schedule.vo;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
@Schema(description = "관리자 스케줄 작업 목록 항목")
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
public class AdminScheduleVo {
|
||||||
|
@Schema(description = "스케줄 작업 PK", example = "9")
|
||||||
|
private Long scheduleJobIdx;
|
||||||
|
|
||||||
|
@Schema(description = "작업 코드", example = "DAILY_LEARNING_SUMMARY")
|
||||||
|
private String jobName;
|
||||||
|
|
||||||
|
@Schema(description = "작업 그룹", example = "DEFAULT")
|
||||||
|
private String jobGroup;
|
||||||
|
|
||||||
|
@Schema(description = "작업 설명", example = "일별 학습 통계 집계")
|
||||||
|
private String jobDescription;
|
||||||
|
|
||||||
|
@Schema(description = "크론식", example = "0 0 2 * * *")
|
||||||
|
private String cronExpr;
|
||||||
|
|
||||||
|
@Schema(description = "타임존", example = "Asia/Seoul")
|
||||||
|
private String timezoneId;
|
||||||
|
|
||||||
|
@Schema(description = "최대 실행 허용 시간(초)", example = "1800")
|
||||||
|
private Integer maxRunningSeconds;
|
||||||
|
|
||||||
|
@Schema(description = "마지막 실행 시작 시각", example = "2026-05-27 02:00:00")
|
||||||
|
private LocalDateTime lastRunDate;
|
||||||
|
|
||||||
|
@Schema(description = "마지막 실행 종료 시각", example = "2026-05-27 02:00:10")
|
||||||
|
private LocalDateTime lastEndDate;
|
||||||
|
|
||||||
|
@Schema(description = "마지막 성공 시각", example = "2026-05-27 02:00:10")
|
||||||
|
private LocalDateTime lastSuccessDate;
|
||||||
|
|
||||||
|
@Schema(description = "마지막 실행 상태. 0: IDLE, 1: RUNNING, 2: SUCCESS, 3: SKIP, 4: FAIL", example = "2")
|
||||||
|
private Integer lastStatus;
|
||||||
|
|
||||||
|
@Schema(description = "마지막 실행 메시지", example = "정상 처리")
|
||||||
|
private String lastMessage;
|
||||||
|
|
||||||
|
@Schema(description = "실행 락 시각", example = "2026-05-27 02:00:00")
|
||||||
|
private LocalDateTime runLockDate;
|
||||||
|
|
||||||
|
@Schema(description = "실행 락 소유자", example = "api-01")
|
||||||
|
private String runLockOwner;
|
||||||
|
|
||||||
|
@Schema(description = "사용 여부", example = "Y")
|
||||||
|
private String useYn;
|
||||||
|
|
||||||
|
@Schema(description = "생성일", example = "2026-05-27 10:00:00")
|
||||||
|
private LocalDateTime createDate;
|
||||||
|
|
||||||
|
@Schema(description = "수정일", example = "2026-05-27 10:00:00")
|
||||||
|
private LocalDateTime updateDate;
|
||||||
|
}
|
||||||
@@ -0,0 +1,196 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
|
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||||
|
|
||||||
|
<mapper namespace="com.alist.api.modules.admin.schedule.mapper.AdminScheduleMapper">
|
||||||
|
<sql id="adminScheduleWhere">
|
||||||
|
FROM ALISTLMS.SCHEDULE_JOB ASJ
|
||||||
|
WHERE ASJ.DEL_YN = 'N'
|
||||||
|
<if test="keyword != null and keyword != ''">
|
||||||
|
AND (
|
||||||
|
ASJ.JOB_NAME LIKE CONCAT('%', #{keyword}, '%')
|
||||||
|
OR ASJ.JOB_DESCRIPTION LIKE CONCAT('%', #{keyword}, '%')
|
||||||
|
)
|
||||||
|
</if>
|
||||||
|
<if test="jobGroup != null and jobGroup != ''">
|
||||||
|
AND ASJ.JOB_GROUP = #{jobGroup}
|
||||||
|
</if>
|
||||||
|
<if test="lastStatus != null">
|
||||||
|
AND ASJ.LAST_STATUS = #{lastStatus}
|
||||||
|
</if>
|
||||||
|
<if test="useYn != null and useYn != ''">
|
||||||
|
AND ASJ.USE_YN = #{useYn}
|
||||||
|
</if>
|
||||||
|
</sql>
|
||||||
|
|
||||||
|
<select id="selectAdminScheduleCount" resultType="int">
|
||||||
|
/*AdminScheduleMapper.selectAdminScheduleCount*/
|
||||||
|
SELECT COUNT(*)
|
||||||
|
<include refid="adminScheduleWhere"/>
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<select id="selectAdminScheduleList" resultType="com.alist.api.modules.admin.schedule.vo.AdminScheduleVo">
|
||||||
|
/*AdminScheduleMapper.selectAdminScheduleList*/
|
||||||
|
SELECT ASJ.SCHEDULE_JOB_IDX
|
||||||
|
, ASJ.JOB_NAME
|
||||||
|
, ASJ.JOB_GROUP
|
||||||
|
, ASJ.JOB_DESCRIPTION
|
||||||
|
, ASJ.CRON_EXPR
|
||||||
|
, ASJ.TIMEZONE_ID
|
||||||
|
, ASJ.MAX_RUNNING_SECONDS
|
||||||
|
, ASJ.LAST_RUN_DATE
|
||||||
|
, ASJ.LAST_END_DATE
|
||||||
|
, ASJ.LAST_SUCCESS_DATE
|
||||||
|
, ASJ.LAST_STATUS
|
||||||
|
, ASJ.LAST_MESSAGE
|
||||||
|
, ASJ.RUN_LOCK_DATE
|
||||||
|
, ASJ.RUN_LOCK_OWNER
|
||||||
|
, ASJ.USE_YN
|
||||||
|
, ASJ.CREATE_DATE
|
||||||
|
, ASJ.UPDATE_DATE
|
||||||
|
<include refid="adminScheduleWhere"/>
|
||||||
|
ORDER BY ASJ.SCHEDULE_JOB_IDX DESC
|
||||||
|
LIMIT #{limit}
|
||||||
|
OFFSET #{offset}
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<select id="selectAdminScheduleView" resultType="com.alist.api.modules.admin.schedule.vo.AdminScheduleViewVo">
|
||||||
|
/*AdminScheduleMapper.selectAdminScheduleView*/
|
||||||
|
SELECT ASJ.SCHEDULE_JOB_IDX
|
||||||
|
, ASJ.JOB_NAME
|
||||||
|
, ASJ.JOB_GROUP
|
||||||
|
, ASJ.JOB_DESCRIPTION
|
||||||
|
, ASJ.CRON_EXPR
|
||||||
|
, ASJ.TIMEZONE_ID
|
||||||
|
, ASJ.MAX_RUNNING_SECONDS
|
||||||
|
, ASJ.LAST_RUN_DATE
|
||||||
|
, ASJ.LAST_END_DATE
|
||||||
|
, ASJ.LAST_SUCCESS_DATE
|
||||||
|
, ASJ.LAST_STATUS
|
||||||
|
, ASJ.LAST_MESSAGE
|
||||||
|
, ASJ.RUN_LOCK_DATE
|
||||||
|
, ASJ.RUN_LOCK_OWNER
|
||||||
|
, ASJ.USE_YN
|
||||||
|
, ASJ.DEL_YN
|
||||||
|
, ASJ.CREATE_DATE
|
||||||
|
, ASJ.CREATE_MEMBER
|
||||||
|
, ASJ.UPDATE_DATE
|
||||||
|
, ASJ.UPDATE_MEMBER
|
||||||
|
FROM ALISTLMS.SCHEDULE_JOB ASJ
|
||||||
|
WHERE ASJ.SCHEDULE_JOB_IDX = #{scheduleJobIdx}
|
||||||
|
AND ASJ.DEL_YN = 'N'
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<select id="selectAdminScheduleDuplicateCount" resultType="int">
|
||||||
|
/*AdminScheduleMapper.selectAdminScheduleDuplicateCount*/
|
||||||
|
SELECT COUNT(*)
|
||||||
|
FROM ALISTLMS.SCHEDULE_JOB ASJ
|
||||||
|
WHERE ASJ.DEL_YN = 'N'
|
||||||
|
AND ASJ.JOB_NAME = #{jobName}
|
||||||
|
AND ASJ.JOB_GROUP = #{jobGroup}
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<select id="selectAdminScheduleModifyDuplicateCount" resultType="int">
|
||||||
|
/*AdminScheduleMapper.selectAdminScheduleModifyDuplicateCount*/
|
||||||
|
SELECT COUNT(*)
|
||||||
|
FROM ALISTLMS.SCHEDULE_JOB ASJ
|
||||||
|
WHERE ASJ.DEL_YN = 'N'
|
||||||
|
AND ASJ.JOB_NAME = #{jobName}
|
||||||
|
AND ASJ.JOB_GROUP = #{jobGroup}
|
||||||
|
AND ASJ.SCHEDULE_JOB_IDX != #{scheduleJobIdx}
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<sql id="adminScheduleLogWhere">
|
||||||
|
FROM ALISTLMS.SCHEDULE_JOB_LOG ASJL
|
||||||
|
WHERE ASJL.SCHEDULE_JOB_IDX = #{scheduleJobIdx}
|
||||||
|
<if test="status != null">
|
||||||
|
AND ASJL.STATUS = #{status}
|
||||||
|
</if>
|
||||||
|
<if test="startDateFrom != null and startDateFrom != ''">
|
||||||
|
AND ASJL.START_DATE <![CDATA[>=]]> #{startDateFrom}
|
||||||
|
</if>
|
||||||
|
<if test="startDateTo != null and startDateTo != ''">
|
||||||
|
AND ASJL.START_DATE <![CDATA[<=]]> #{startDateTo}
|
||||||
|
</if>
|
||||||
|
</sql>
|
||||||
|
|
||||||
|
<select id="selectAdminScheduleLogCount" resultType="int">
|
||||||
|
/*AdminScheduleMapper.selectAdminScheduleLogCount*/
|
||||||
|
SELECT COUNT(*)
|
||||||
|
<include refid="adminScheduleLogWhere"/>
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<select id="selectAdminScheduleLogList" resultType="com.alist.api.modules.admin.schedule.vo.AdminScheduleLogVo">
|
||||||
|
/*AdminScheduleMapper.selectAdminScheduleLogList*/
|
||||||
|
SELECT ASJL.SCHEDULE_JOB_LOG_IDX
|
||||||
|
, ASJL.SCHEDULE_JOB_IDX
|
||||||
|
, ASJL.RUN_ID
|
||||||
|
, ASJL.JOB_NAME
|
||||||
|
, ASJL.START_DATE
|
||||||
|
, ASJL.END_DATE
|
||||||
|
, ASJL.TARGET_COUNT
|
||||||
|
, ASJL.SUCCESS_COUNT
|
||||||
|
, ASJL.FAIL_COUNT
|
||||||
|
, ASJL.MESSAGE
|
||||||
|
, ASJL.ERROR_MESSAGE
|
||||||
|
, ASJL.LOCK_OWNER
|
||||||
|
, ASJL.STATUS
|
||||||
|
, ASJL.CREATE_DATE
|
||||||
|
<include refid="adminScheduleLogWhere"/>
|
||||||
|
ORDER BY ASJL.SCHEDULE_JOB_LOG_IDX DESC
|
||||||
|
LIMIT #{limit}
|
||||||
|
OFFSET #{offset}
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<insert id="insertAdminScheduleAdd" parameterType="com.alist.api.modules.admin.schedule.dto.AdminScheduleAddDto" useGeneratedKeys="true" keyProperty="scheduleJobIdx">
|
||||||
|
/*AdminScheduleMapper.insertAdminScheduleAdd*/
|
||||||
|
INSERT INTO ALISTLMS.SCHEDULE_JOB (
|
||||||
|
JOB_NAME
|
||||||
|
, JOB_GROUP
|
||||||
|
, JOB_DESCRIPTION
|
||||||
|
, CRON_EXPR
|
||||||
|
, TIMEZONE_ID
|
||||||
|
, MAX_RUNNING_SECONDS
|
||||||
|
, LAST_STATUS
|
||||||
|
, USE_YN
|
||||||
|
, DEL_YN
|
||||||
|
, CREATE_MEMBER
|
||||||
|
, UPDATE_MEMBER
|
||||||
|
) VALUES (
|
||||||
|
#{jobName}
|
||||||
|
, #{jobGroup}
|
||||||
|
, #{jobDescription}
|
||||||
|
, #{cronExpr}
|
||||||
|
, #{timezoneId}
|
||||||
|
, #{maxRunningSeconds}
|
||||||
|
, 0
|
||||||
|
, #{useYn}
|
||||||
|
, 'N'
|
||||||
|
, #{createMember}
|
||||||
|
, #{updateMember}
|
||||||
|
)
|
||||||
|
</insert>
|
||||||
|
|
||||||
|
<update id="updateAdminScheduleModify" parameterType="com.alist.api.modules.admin.schedule.dto.AdminScheduleModifyDto">
|
||||||
|
/*AdminScheduleMapper.updateAdminScheduleModify*/
|
||||||
|
UPDATE ALISTLMS.SCHEDULE_JOB
|
||||||
|
SET JOB_NAME = #{jobName}
|
||||||
|
, JOB_GROUP = #{jobGroup}
|
||||||
|
, JOB_DESCRIPTION = #{jobDescription}
|
||||||
|
, CRON_EXPR = #{cronExpr}
|
||||||
|
, TIMEZONE_ID = #{timezoneId}
|
||||||
|
, MAX_RUNNING_SECONDS = #{maxRunningSeconds}
|
||||||
|
, USE_YN = #{useYn}
|
||||||
|
, UPDATE_MEMBER = #{updateMember}
|
||||||
|
WHERE SCHEDULE_JOB_IDX = #{scheduleJobIdx}
|
||||||
|
AND DEL_YN = 'N'
|
||||||
|
</update>
|
||||||
|
|
||||||
|
<update id="updateAdminScheduleDelete" parameterType="com.alist.api.modules.admin.schedule.dto.AdminScheduleDeleteDto">
|
||||||
|
/*AdminScheduleMapper.updateAdminScheduleDelete*/
|
||||||
|
UPDATE ALISTLMS.SCHEDULE_JOB
|
||||||
|
SET DEL_YN = 'Y'
|
||||||
|
, UPDATE_MEMBER = #{updateMember}
|
||||||
|
WHERE SCHEDULE_JOB_IDX = #{scheduleJobIdx}
|
||||||
|
AND DEL_YN = 'N'
|
||||||
|
</update>
|
||||||
|
</mapper>
|
||||||
Reference in New Issue
Block a user