From 9dc266774181641ea3e1abe521f531545a6c7587 Mon Sep 17 00:00:00 2001 From: caadiq Date: Mon, 8 Jun 2026 21:34:46 +0900 Subject: [PATCH] =?UTF-8?q?feat(youtube-bot):=20=EC=98=88=EC=A0=95=20?= =?UTF-8?q?=EC=9D=BC=EC=A0=95=20=EC=83=9D=EC=84=B1=20=EC=A3=BC=EA=B8=B0(?= =?UTF-8?q?=EB=AA=87=20=EC=A3=BC=20=EB=92=A4)=20=EC=98=B5=EC=85=98=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 기존엔 '다음 주 요일'만 가능해 격주 콘텐츠(한화 이단장 등)에 못 썼는데, weeksAhead(1~4주)를 추가해 N주 뒤 날짜로 예정 일정을 생성. getNextWeekday에 weeksAhead 반영, auto_schedule_config JSON에 필드 추가, 다이얼로그에 생성 주기 드롭다운 추가. DB/라우트 변경 없음. Co-Authored-By: Claude Opus 4.7 --- backend/src/services/youtube/index.js | 7 +++-- .../pc/admin/bot/YouTubeBotDialog.jsx | 26 +++++++++++++++++++ 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/backend/src/services/youtube/index.js b/backend/src/services/youtube/index.js index 489cda7..389f813 100644 --- a/backend/src/services/youtube/index.js +++ b/backend/src/services/youtube/index.js @@ -11,15 +11,18 @@ async function youtubeBotPlugin(fastify) { /** * 다음 특정 요일 날짜 계산 (KST 기준) * @param {number} targetDay - 목표 요일 (0=일, 4=목) + * @param {number} weeksAhead - 몇 주 뒤 (1=다음 주, 2=2주 뒤, 격주 콘텐츠 대응) * @param {Date} fromDate - 기준 날짜 (기본: 오늘) * @returns {string} YYYY-MM-DD 형식 */ - function getNextWeekday(targetDay, fromDate = new Date()) { + function getNextWeekday(targetDay, weeksAhead = 1, fromDate = new Date()) { const kst = new Date(fromDate.toLocaleString('en-US', { timeZone: 'Asia/Seoul' })); const currentDay = kst.getDay(); // 다음 주 같은 요일까지 일수 계산 let daysUntil = targetDay - currentDay + 7; if (daysUntil <= 0) daysUntil += 7; + // weeksAhead가 2 이상이면 그만큼 주를 더 더함 + daysUntil += (Math.max(1, weeksAhead) - 1) * 7; const nextDate = new Date(kst); nextDate.setDate(kst.getDate() + daysUntil); @@ -81,7 +84,7 @@ async function youtubeBotPlugin(fastify) { const { autoScheduleNext } = bot; if (!autoScheduleNext) return null; - const nextDate = getNextWeekday(autoScheduleNext.dayOfWeek); + const nextDate = getNextWeekday(autoScheduleNext.dayOfWeek, autoScheduleNext.weeksAhead || 1); // 이미 존재하는지 확인 (같은 채널, 같은 날짜, is_temp = 1) const [existing] = await fastify.db.query( diff --git a/frontend/src/components/pc/admin/bot/YouTubeBotDialog.jsx b/frontend/src/components/pc/admin/bot/YouTubeBotDialog.jsx index 588a07a..5288f17 100644 --- a/frontend/src/components/pc/admin/bot/YouTubeBotDialog.jsx +++ b/frontend/src/components/pc/admin/bot/YouTubeBotDialog.jsx @@ -47,6 +47,14 @@ const DAY_OPTIONS = [ { value: 0, label: '일요일' }, ]; +// 주기 옵션 (몇 주 뒤에 예정 일정 생성 — 격주/3주 콘텐츠 대응) +const WEEKS_OPTIONS = [ + { value: 1, label: '다음 주 (매주)' }, + { value: 2, label: '2주 뒤 (격주)' }, + { value: 3, label: '3주 뒤' }, + { value: 4, label: '4주 뒤' }, +]; + // 시간 옵션 (00:00 ~ 23:00) const TIME_OPTIONS = Array.from({ length: 24 }, (_, i) => ({ value: `${String(i).padStart(2, '0')}:00`, @@ -290,6 +298,7 @@ function YouTubeBotDialog({ isOpen, onClose, botId = null, onSuccess }) { // 예정 일정 설정 const [autoScheduleEnabled, setAutoScheduleEnabled] = useState(false); const [scheduleDayOfWeek, setScheduleDayOfWeek] = useState(4); + const [weeksAhead, setWeeksAhead] = useState(1); const [scheduleTime, setScheduleTime] = useState('18:00'); const [titleTemplate, setTitleTemplate] = useState('{channelName} {episode}화'); const [deadlineDayOfWeek, setDeadlineDayOfWeek] = useState(5); @@ -369,6 +378,7 @@ function YouTubeBotDialog({ isOpen, onClose, botId = null, onSuccess }) { if (config && config.dayOfWeek !== undefined) { setAutoScheduleEnabled(true); setScheduleDayOfWeek(config.dayOfWeek); + setWeeksAhead(config.weeksAhead ?? 1); setScheduleTime(config.time?.slice(0, 5) || '18:00'); setTitleTemplate(config.titleTemplate || '{channelName} {episode}화'); setDeadlineDayOfWeek(config.deadlineDayOfWeek ?? 5); @@ -376,6 +386,7 @@ function YouTubeBotDialog({ isOpen, onClose, botId = null, onSuccess }) { } else { setAutoScheduleEnabled(false); setScheduleDayOfWeek(4); + setWeeksAhead(1); setScheduleTime('18:00'); setTitleTemplate('{channelName} {episode}화'); setDeadlineDayOfWeek(5); @@ -458,6 +469,7 @@ function YouTubeBotDialog({ isOpen, onClose, botId = null, onSuccess }) { auto_schedule_config: autoScheduleEnabled ? { dayOfWeek: scheduleDayOfWeek, + weeksAhead, time: `${scheduleTime}:00`, titleTemplate, deadlineDayOfWeek, @@ -732,6 +744,20 @@ function YouTubeBotDialog({ isOpen, onClose, botId = null, onSuccess }) { + {/* 생성 주기 (몇 주 뒤) */} +
+ + +

+ 예정 일정을 몇 주 뒤 날짜로 생성할지 (격주 콘텐츠는 2주 뒤) +

+
+ {/* 제목 템플릿 */}