feat: 숏폼 복사 시 작업 완료 처리
This commit is contained in:
parent
80e462acbf
commit
ea08b6d6b7
@ -50,6 +50,11 @@ public class ShortformController {
|
||||
return ApiResponse.ok(shortformService.reset(id));
|
||||
}
|
||||
|
||||
@PostMapping("/jobs/{id}/complete")
|
||||
public ApiResponse<JobDetail> complete(@PathVariable Long id) {
|
||||
return ApiResponse.ok(shortformService.completeCopyWorkflow(id));
|
||||
}
|
||||
|
||||
@PostMapping("/jobs/{id}/subtitles/retry")
|
||||
public ApiResponse<Long> retrySubtitles(@PathVariable Long id) {
|
||||
shortformService.retrySubtitle(id);
|
||||
|
||||
@ -154,6 +154,14 @@ public class ShortformJob {
|
||||
this.completedAt = LocalDateTime.now();
|
||||
}
|
||||
|
||||
/** URL 또는 자막을 외부 작업 도구로 복사한 큐 작업을 완료 처리한다. */
|
||||
public void completeCopyWorkflow() {
|
||||
this.status = ShortformJobStatus.DONE;
|
||||
if (this.completedAt == null) {
|
||||
this.completedAt = LocalDateTime.now();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 결과를 비우고 다시 대기 상태로 되돌린다. 등록 정보(URL·videoId·등록시각)는 유지하므로
|
||||
* 삭제 후 재등록할 필요가 없고, 큐 스킬이 PENDING 만 집어가므로 그대로 다시 실행된다.
|
||||
|
||||
@ -133,6 +133,14 @@ public class ShortformService {
|
||||
.orElseThrow(() -> new IllegalArgumentException("작업이 없습니다: " + jobId));
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public JobDetail completeCopyWorkflow(Long jobId) {
|
||||
ShortformJob job = jobRepository.findById(jobId)
|
||||
.orElseThrow(() -> new IllegalArgumentException("작업이 없습니다: " + jobId));
|
||||
job.completeCopyWorkflow();
|
||||
return JobDetail.from(job);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void delete(Long jobId) {
|
||||
jobRepository.deleteById(jobId);
|
||||
|
||||
@ -182,8 +182,7 @@
|
||||
e.stopPropagation();
|
||||
await navigator.clipboard.writeText(decodeURIComponent(btn.dataset.copy));
|
||||
if (btn.hasAttribute('data-complete-on-copy')) {
|
||||
btn.textContent = '완료';
|
||||
btn.disabled = true;
|
||||
await completeCopiedJob(id, el, btn);
|
||||
} else {
|
||||
btn.textContent = '복사됨!';
|
||||
setTimeout(() => btn.textContent = label, 1200);
|
||||
@ -195,8 +194,7 @@
|
||||
subtitleButton.onclick = async (e) => {
|
||||
e.stopPropagation();
|
||||
await navigator.clipboard.writeText(detail.subtitleVtt);
|
||||
subtitleButton.textContent = '완료';
|
||||
subtitleButton.disabled = true;
|
||||
await completeCopiedJob(id, el, subtitleButton);
|
||||
};
|
||||
}
|
||||
}
|
||||
@ -205,6 +203,17 @@
|
||||
return (s || '').replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>');
|
||||
}
|
||||
|
||||
async function completeCopiedJob(id, card, button) {
|
||||
await api('/api/shortform/jobs/' + id + '/complete', { method: 'POST' });
|
||||
button.textContent = '완료';
|
||||
button.disabled = true;
|
||||
const badge = card.querySelector('.sf-badge');
|
||||
if (badge) {
|
||||
badge.className = 'sf-badge DONE';
|
||||
badge.textContent = 'DONE';
|
||||
}
|
||||
}
|
||||
|
||||
function clipHtml(c) {
|
||||
return `<div class="sf-clip">
|
||||
<div class="sf-clip-head">
|
||||
@ -301,8 +310,7 @@
|
||||
button.onclick = async (e) => {
|
||||
e.stopPropagation();
|
||||
await navigator.clipboard.writeText(detail.subtitleVtt);
|
||||
button.textContent = '완료';
|
||||
button.disabled = true;
|
||||
await completeCopiedJob(id, card, button);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -69,4 +69,14 @@ class ShortformJobResetTest {
|
||||
assertThat(job.getTitle()).isEqualTo("새 클립");
|
||||
assertThat(job.getRawOutput()).isEqualTo("새 Output");
|
||||
}
|
||||
|
||||
@Test
|
||||
void 복사_워크플로를_완료하면_DONE으로_변경된다() {
|
||||
ShortformJob job = ShortformJob.create("https://youtu.be/abc12345678", "abc12345678");
|
||||
|
||||
job.completeCopyWorkflow();
|
||||
|
||||
assertThat(job.getStatus()).isEqualTo(ShortformJobStatus.DONE);
|
||||
assertThat(job.getCompletedAt()).isNotNull();
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user