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()