Spaces:
Sleeping
Sleeping
import gradio as gr | |
import datetime | |
import calendar | |
class EventManager: | |
def __init__(self): | |
# 월별 기본 컨셉 정의 | |
self.monthly_concepts = { | |
1: {"theme": "신년/설날", "colors": ["#FF6B6B", "#FFE66D"], "mood": "희망찬, 따뜻한", "symbol": "🎊"}, | |
2: {"theme": "발렌타인데이", "colors": ["#FF69B4", "#FFB6C1"], "mood": "로맨틱, 달콤한", "symbol": "💕"}, | |
3: {"theme": "화이트데이/봄", "colors": ["#FFFFFF", "#F0F8FF"], "mood": "순수한, 상쾌한", "symbol": "🤍"}, | |
4: {"theme": "벚꽃/봄나들이", "colors": ["#FFB7C5", "#98FB98"], "mood": "생기발랄, 활기찬", "symbol": "🌸"}, | |
5: {"theme": "로즈데이/가정의달", "colors": ["#FF1493", "#FF69B4"], "mood": "감사한, 사랑스러운", "symbol": "🌹"}, | |
6: {"theme": "결혼시즌/초여름", "colors": ["#87CEEB", "#F0E68C"], "mood": "청량한, 행복한", "symbol": "💒"}, | |
7: {"theme": "여름휴가", "colors": ["#00CED1", "#FFE4B5"], "mood": "시원한, 자유로운", "symbol": "🏖️"}, | |
8: {"theme": "무더위극복", "colors": ["#20B2AA", "#F0FFFF"], "mood": "시원한, 에너지 넘치는", "symbol": "❄️"}, | |
9: {"theme": "가을시작", "colors": ["#DEB887", "#CD853F"], "mood": "따뜻한, 아늑한", "symbol": "🍂"}, | |
10: {"theme": "할로윈", "colors": ["#FF4500", "#8B0000"], "mood": "신비로운, 재미있는", "symbol": "🎃"}, | |
11: {"theme": "단풍/감사", "colors": ["#DAA520", "#B22222"], "mood": "감사한, 따뜻한", "symbol": "🍁"}, | |
12: {"theme": "크리스마스/연말", "colors": ["#DC143C", "#228B22"], "mood": "축제같은, 따뜻한", "symbol": "🎄"} | |
} | |
# 상품 종류 옵션 | |
self.reward_types = [ | |
"네이버페이 금액권", | |
"배달의민족 상품권", | |
"스타벅스 기프트카드", | |
"CGV 영화관람권", | |
"올리브영 상품권", | |
"컬쳐랜드 문화상품권", | |
"해피머니 상품권" | |
] | |
def calculate_event_duration(self, start_date, end_date): | |
"""이벤트 기간 계산""" | |
try: | |
start = datetime.datetime.strptime(start_date, "%Y-%m-%d") | |
end = datetime.datetime.strptime(end_date, "%Y-%m-%d") | |
duration = (end - start).days + 1 | |
month = start.month | |
# 요일 정보 추가 | |
start_weekday = start.strftime("(%a)") | |
end_weekday = end.strftime("(%a)") | |
return duration, month, start_weekday, end_weekday, start, end | |
except: | |
return 0, 0, "", "", None, None | |
def generate_monthly_concept(self, month): | |
"""월별 컨셉 생성""" | |
if month in self.monthly_concepts: | |
concept = self.monthly_concepts[month] | |
return { | |
"theme": concept["theme"], | |
"colors": concept["colors"], | |
"mood": concept["mood"], | |
"symbol": concept["symbol"], | |
"month_name": calendar.month_name[month] | |
} | |
return {} | |
def parse_rewards(self, reward_structure): | |
"""상품 구조 파싱""" | |
if not reward_structure.strip(): | |
return "네이버페이 금액권 20,000원\n1시간마다 1명씩 하루 24명" | |
return reward_structure | |
def generate_detailed_comment_event(self, start_date, end_date, concept, duration, | |
reward_structure, kakao_id, phone_number, custom_details=""): | |
"""참고자료 구조를 완전히 반영한 댓글 이벤트 템플릿""" | |
if not concept: | |
return "먼저 이벤트 기간을 설정해주세요." | |
theme = concept.get("theme", "특별한") | |
symbol = concept.get("symbol", "🎉") | |
mood = concept.get("mood", "즐거운") | |
# 날짜 포맷팅 | |
duration_info, month, start_weekday, end_weekday, start_dt, end_dt = self.calculate_event_duration(start_date, end_date) | |
if duration_info == 0: | |
return "날짜 형식을 확인해주세요." | |
formatted_start = f"{start_dt.year}년 {start_dt.month}월 {start_dt.day}일 {start_weekday} 00:00" | |
formatted_end = f"{end_dt.year}년 {end_dt.month}월 {end_dt.day}일 {end_weekday} 23:59" | |
# 상품 정보 파싱 | |
reward_text = self.parse_rewards(reward_structure) | |
# 메인 제목 생성 | |
if "로즈" in theme: | |
main_title = f"댓글 남기면 1시간마다 선물이!\n{symbol}같은 {month}월 {theme} 이벤트" | |
else: | |
main_title = f"댓글 남기면 1시간마다 선물이!\n{symbol} {mood} {theme} 이벤트" | |
template = f"""{main_title} | |
{formatted_start} - {formatted_end} ({duration}일간) | |
======================== | |
EVENT | |
<커뮤니티>에 작성된 글에 유익하고 착한 댓글을 남기면 | |
1시간마다 1명씩! 하루 24명에게 선물을드려요! | |
{formatted_start} - {formatted_end} ({duration}일간) | |
===================== | |
STEP 1 | |
회사명 <커뮤니티>에 작성된 글에 | |
유익하고 착한 댓글 작성 | |
* 이쁘고 좋은 말 많이 해주는 회원님들이 되길 부탁드려요 | |
STEP 2 | |
댓글 작성 후 선물 당첨 팝업이 나타나면 | |
화면캡쳐 또는 사진촬영하기! | |
*당첨팝업은 이벤트 기간동안 1시간마다 1명씩! | |
하루 24명에게 나타나요! | |
STEP 3 | |
당첨팝업 캡쳐 & 촬영했으면 | |
카카오톡 또는 고객센터로 연락하기! | |
================= | |
당첨혜택 | |
{reward_text} | |
======================== | |
이벤트 대상 | |
일반 여성회원이라면 누구나! | |
(*회원, 비회원 모두 참여가능 / 기업회원제외) | |
======================== | |
수령방법 | |
댓글 작성 후 랜덤하게뜨는 이미지를 캡처 or 사진 촬영하기! | |
꼭 캡처후 팝업을 닫아주세요! | |
pc버전 당첨 예시 이미지, 모바일버전 당첨 예시 이미지 | |
1.상단 당첨 날짜와 시간이 함께 나오도록 | |
화면캡쳐 또는 사진촬영 | |
2.카카오톡 ({kakao_id}) 로 캡쳐 사진 보내기 | |
3.카카오톡으로 연락처를 남기거나 | |
고객센터 운영시간에 맞춰 전화하기 | |
4. 고객센터와 여성회원 확인 통화 후 | |
선물 받기! | |
========================= | |
꼭 확인하세요! | |
※본이벤트는 회사명 일반 여성회원만 참여가능합니다. (비회원도 가능) | |
※ pc에서 캡처가 어려운 경우, 카메라로 촬영하여 연락 주셔도 됩니다. | |
※이벤트 팝업 상품 이미지와 상단 당첨 날짜&시간을 함께 | |
화면 캡처 또는 사진 촬영해야 수령 가능합니다. | |
※ 화면 캡처 전에 팝업을 닫을 시, 상품 지급이 어려우니 반드시 캡처 또는 | |
촬영 후 팝업을 닫아주세요! | |
※당첨 시 여성확인절차가 있음으로 고객센터로 연락 주시기 바랍니다. (통화로 여성확인) | |
※ 고객센터와 여성 확인 통화 후 상품 수령가능합니다. | |
※ 상품은 1인 1일 최대 1회까지 수령이 가능합니다. 같은 날 재당첨되어도 | |
지급되지 않습니다. 단, 날짜가 다를 시 중복 수령 가능합니다. | |
※ 상품 수령 가능 기간은 당첨 일로부터 영업일 기준 다음 날까지 가능합니다. | |
ex) 주말 당첨시, 고객센터 영업일(월) 업무 종료시간 19:00시까지 수령가능 | |
※ 단순 이벤트 참여를 위해서 작성된 댓글에는 당첨 팝업이 나오지 않습니다. | |
상품이 나타나지 않은 당첨 팝업 캡처, 사진에는 상품권 지급이 | |
어려운 점 유의해주세요! | |
※ 욕설, 공지사항 위반, 도배, 내용이 없거나 반복된 댓글, 신고 접수 된 댓글 | |
등은 당첨 취소됩니다. | |
※ 당첨된 댓글은 고객센터에서 확인할 수 있어야 하므로 | |
댓글 수정, 비밀댓글 또는 댓글 삭제 등을 하시면 상품 수령이 불가합니다. | |
※당첨자가 상품 수령 요청시, 최초 요청자에게 지급되며 동일 당첨 상품권으로 | |
요청시 이벤트 참여 불가 합니다. | |
※ 다른 상품으로 변경 불가합니다. | |
=========================== | |
{phone_number} | |
※ 대표번호는 문자수신이 불가합니다 | |
고객센터 운영시간 | |
(평일 09:30~19:00 / 점심 12:00~13:30) | |
※ 주말 및 공휴일은 운영하지 않습니다. | |
카카오톡 ID: {kakao_id} | |
""" | |
if custom_details: | |
template += f"\n\n📝 추가 정보\n{custom_details}" | |
return template | |
def generate_design_advice(self, concept): | |
"""디자인 조언 생성""" | |
if not concept: | |
return "컨셉 정보가 필요합니다." | |
colors = concept.get("colors", ["#000000", "#FFFFFF"]) | |
mood = concept.get("mood", "") | |
theme = concept.get("theme", "") | |
symbol = concept.get("symbol", "") | |
advice = f"""🎨 디자인 조언 ({theme} 테마) | |
🎯 컬러 팔레트 | |
- 메인 컬러: {colors[0]} | |
- 서브 컬러: {colors[1]} | |
- 20-40대 여성에게 어필하는 {mood} 느낌 | |
📐 레이아웃 구조 (참고자료 기반) | |
1. **메인 제목**: 임팩트 있는 큰 폰트 + {symbol} 아이콘 | |
2. **날짜 정보**: 박스로 구분하여 명확하게 표시 | |
3. **EVENT 섹션**: 굵은 구분선으로 강조 | |
4. **STEP 가이드**: 숫자와 함께 단계별 명확한 구분 | |
5. **당첨혜택**: 상품 이미지와 함께 시각적으로 강조 | |
6. **주의사항**: 읽기 쉽게 ※ 기호로 구분 | |
👀 가독성 향상 포인트 | |
- 구분선(=====) 활용으로 섹션 명확히 분리 | |
- 중요 정보는 박스 처리 또는 배경색 변경 | |
- 단계별 가이드는 아이콘과 함께 시각화 | |
- 모바일에서도 스크롤하며 읽기 편하게 구성 | |
🔥 핵심 강조 요소 | |
- "1시간마다 1명씩" - 긴급성 강조 | |
- "하루 24명" - 기회의 많음 어필 | |
- 상품 이미지 - 실제 혜택 시각화 | |
- 참여 방법 - 간단함 강조 | |
📱 반응형 고려사항 | |
- PC/모바일 캡처 예시 이미지 별도 제공 | |
- 길어질 수 있는 주의사항은 접기/펼치기 기능 고려 | |
- 중요 정보는 상단 고정 또는 요약 박스 제공""" | |
return advice | |
def create_interface(): | |
event_manager = EventManager() | |
with gr.Blocks(title="이벤트 관리 시스템 v2.1") as demo: | |
gr.Markdown("# 🎉 이벤트 관리 시스템 v2.1") | |
gr.Markdown("**유연한 상품 설정** - 단일상품부터 등급별 상품까지 자유롭게 설정") | |
with gr.Row(): | |
with gr.Column(scale=1): | |
gr.Markdown("## 📅 기본 정보") | |
with gr.Group(): | |
start_date = gr.Textbox( | |
label="시작일", | |
placeholder="YYYY-MM-DD", | |
value="2025-05-15" | |
) | |
end_date = gr.Textbox( | |
label="종료일", | |
placeholder="YYYY-MM-DD", | |
value="2025-05-25" | |
) | |
gr.Markdown("## 🎁 상품 설정") | |
with gr.Group(): | |
reward_type_selector = gr.Radio( | |
choices=[ | |
"단일 상품", | |
"등급별 상품 (1,2,3등)", | |
"선택형 상품 (네이버페이 OR 배달의민족)", | |
"직접 입력" | |
], | |
label="상품 구성 방식", | |
value="단일 상품" | |
) | |
# 단일 상품 설정 | |
with gr.Group(visible=True) as single_reward_group: | |
single_reward_type = gr.Dropdown( | |
choices=event_manager.reward_types, | |
label="상품 종류", | |
value="네이버페이 금액권" | |
) | |
single_reward_amount = gr.Number( | |
label="금액 (원)", | |
value=20000, | |
step=1000 | |
) | |
single_reward_frequency = gr.Textbox( | |
label="당첨 주기", | |
value="1시간마다 1명씩 하루 24명", | |
placeholder="예: 1시간마다 1명씩 하루 24명" | |
) | |
# 등급별 상품 설정 | |
with gr.Group(visible=False) as grade_reward_group: | |
gr.Markdown("### 🥇 1등") | |
grade1_type = gr.Dropdown(choices=event_manager.reward_types, value="네이버페이 금액권") | |
grade1_amount = gr.Number(label="1등 금액", value=50000, step=1000) | |
grade1_count = gr.Number(label="1등 인원", value=5, step=1) | |
gr.Markdown("### 🥈 2등") | |
grade2_type = gr.Dropdown(choices=event_manager.reward_types, value="네이버페이 금액권") | |
grade2_amount = gr.Number(label="2등 금액", value=30000, step=1000) | |
grade2_count = gr.Number(label="2등 인원", value=10, step=1) | |
gr.Markdown("### 🥉 3등") | |
grade3_type = gr.Dropdown(choices=event_manager.reward_types, value="네이버페이 금액권") | |
grade3_amount = gr.Number(label="3등 금액", value=20000, step=1000) | |
grade3_count = gr.Number(label="3등 인원", value=20, step=1) | |
# 선택형 상품 설정 | |
with gr.Group(visible=False) as choice_reward_group: | |
choice_type1 = gr.Dropdown(choices=event_manager.reward_types, value="네이버페이 금액권", label="상품 1") | |
choice_type2 = gr.Dropdown(choices=event_manager.reward_types, value="배달의민족 상품권", label="상품 2") | |
choice_amount = gr.Number(label="금액 (원)", value=20000, step=1000) | |
choice_frequency = gr.Textbox( | |
label="당첨 주기", | |
value="1시간마다 1명씩 하루 24명", | |
placeholder="예: 1시간마다 1명씩 하루 24명" | |
) | |
# 직접 입력 | |
with gr.Group(visible=False) as custom_reward_group: | |
custom_reward_text = gr.Textbox( | |
label="상품 정보 직접 입력", | |
placeholder="예:\n네이버페이 금액권 20,000원 이미지 / 배달의민족 상품권 20,000원 이미지\n네이버페이 or 배달의 민족 상품권 2만원\n1시간마다 1명씩 하루 24명", | |
lines=5 | |
) | |
gr.Markdown("## 📞 연락처 정보") | |
with gr.Group(): | |
phone_number = gr.Textbox( | |
label="고객센터 번호", | |
placeholder="1544-1234", | |
value="1544-1234" | |
) | |
kakao_id = gr.Textbox( | |
label="카카오톡 ID", | |
placeholder="company_kakao", | |
value="company_kakao" | |
) | |
custom_details = gr.Textbox( | |
label="추가 정보", | |
placeholder="추가할 내용이 있다면 입력하세요", | |
lines=2 | |
) | |
generate_btn = gr.Button("✨ 이벤트 생성하기", variant="primary", size="lg") | |
with gr.Column(scale=2): | |
gr.Markdown("## 📊 생성 결과") | |
with gr.Tabs(): | |
with gr.Tab("📋 이벤트 공지사항"): | |
event_template = gr.Textbox( | |
label="완성된 이벤트 공지사항", | |
interactive=False, | |
lines=30, | |
max_lines=50 | |
) | |
with gr.Tab("🎨 디자인 가이드"): | |
design_guide = gr.Textbox( | |
label="디자인 조언 및 가이드", | |
interactive=False, | |
lines=20 | |
) | |
with gr.Tab("📈 이벤트 정보"): | |
event_info = gr.Textbox( | |
label="이벤트 기본 정보 요약", | |
interactive=False, | |
lines=8 | |
) | |
# 상품 구성 방식에 따라 UI 변경 | |
def update_reward_ui(reward_type): | |
return ( | |
gr.update(visible=(reward_type == "단일 상품")), | |
gr.update(visible=(reward_type == "등급별 상품 (1,2,3등)")), | |
gr.update(visible=(reward_type == "선택형 상품 (네이버페이 OR 배달의민족)")), | |
gr.update(visible=(reward_type == "직접 입력")) | |
) | |
reward_type_selector.change( | |
fn=update_reward_ui, | |
inputs=[reward_type_selector], | |
outputs=[single_reward_group, grade_reward_group, choice_reward_group, custom_reward_group] | |
) | |
def generate_reward_structure(reward_type, *args): | |
"""상품 구성에 따라 텍스트 생성""" | |
if reward_type == "단일 상품": | |
single_type, single_amount, single_frequency = args[0], args[1], args[2] | |
return f"{single_type} {int(single_amount):,}원 이미지\n{single_type} {int(single_amount):,}원\n{single_frequency}" | |
elif reward_type == "등급별 상품 (1,2,3등)": | |
g1_type, g1_amount, g1_count, g2_type, g2_amount, g2_count, g3_type, g3_amount, g3_count = args[3:12] | |
return f"""🥇 1등: {g1_type} {int(g1_amount):,}원 ({int(g1_count)}명) | |
🥈 2등: {g2_type} {int(g2_amount):,}원 ({int(g2_count)}명) | |
🥉 3등: {g3_type} {int(g3_amount):,}원 ({int(g3_count)}명) | |
총 {int(g1_count + g2_count + g3_count)}명""" | |
elif reward_type == "선택형 상품 (네이버페이 OR 배달의민족)": | |
c_type1, c_type2, c_amount, c_frequency = args[12], args[13], args[14], args[15] | |
return f"{c_type1} {int(c_amount):,}원 이미지 / {c_type2} {int(c_amount):,}원 이미지\n{c_type1} or {c_type2} {int(c_amount):,}원\n{c_frequency}" | |
elif reward_type == "직접 입력": | |
return args[16] if args[16] else "상품 정보를 입력해주세요" | |
return "상품 정보를 설정해주세요" | |
def generate_complete_event(start_date_val, end_date_val, phone_number_val, kakao_id_val, | |
custom_details_val, reward_type, *reward_args): | |
# 기간 계산 | |
duration, month, start_weekday, end_weekday, start_dt, end_dt = event_manager.calculate_event_duration(start_date_val, end_date_val) | |
if duration == 0: | |
return "날짜 형식을 확인해주세요", "", "" | |
# 월별 컨셉 생성 | |
concept = event_manager.generate_monthly_concept(month) | |
# 상품 구조 생성 | |
reward_structure = generate_reward_structure(reward_type, *reward_args) | |
# 상세 템플릿 생성 | |
template = event_manager.generate_detailed_comment_event( | |
start_date_val, end_date_val, concept, duration, | |
reward_structure, kakao_id_val, phone_number_val, custom_details_val | |
) | |
# 디자인 가이드 생성 | |
design = event_manager.generate_design_advice(concept) | |
# 이벤트 정보 요약 | |
info = f"""📊 이벤트 기본 정보 | |
🗓️ 기간: {duration}일간 ({start_date_val} ~ {end_date_val}) | |
🎯 테마: {concept.get('theme', '')} {concept.get('symbol', '')} | |
🎨 분위기: {concept.get('mood', '')} | |
📞 연락처: {phone_number_val} | |
💬 카톡: {kakao_id_val} | |
🎁 상품 구성: | |
{reward_structure} | |
💡 상품 구성 방식: {reward_type}""" | |
return template, design, info | |
# 모든 입력값을 리스트로 정리 | |
all_inputs = [ | |
start_date, end_date, phone_number, kakao_id, custom_details, reward_type_selector, | |
# 단일 상품 | |
single_reward_type, single_reward_amount, single_reward_frequency, | |
# 등급별 상품 | |
grade1_type, grade1_amount, grade1_count, | |
grade2_type, grade2_amount, grade2_count, | |
grade3_type, grade3_amount, grade3_count, | |
# 선택형 상품 | |
choice_type1, choice_type2, choice_amount, choice_frequency, | |
# 직접 입력 | |
custom_reward_text | |
] | |
generate_btn.click( | |
fn=generate_complete_event, | |
inputs=all_inputs, | |
outputs=[event_template, design_guide, event_info] | |
) | |
with gr.Row(): | |
gr.Markdown(""" | |
## ✅ v2.1 새로운 기능 | |
- **🎁 유연한 상품 설정**: 단일/등급별/선택형/직접입력 모두 지원 | |
- **💰 자동 비용 계산**: 등급별 상품 총 비용 자동 계산 | |
- **🏢 간소화**: 회사 정보 제거로 더 간단한 설정 | |
- **📝 자유도 증가**: 상품 구성의 완전한 자유도 제공 | |
""") | |
gr.Markdown(""" | |
## 🎯 상품 설정 예시 | |
- **단일**: 네이버페이 2만원, 1시간마다 1명 | |
- **등급별**: 1등 5만원(5명), 2등 3만원(10명), 3등 2만원(20명) | |
- **선택형**: 네이버페이 OR 배달의민족 2만원 중 선택 | |
- **직접입력**: 완전히 자유로운 형식 | |
""") | |
return demo | |
if __name__ == "__main__": | |
demo = create_interface() | |
demo.launch() |