Spaces:
Running
Running
<html lang="ko"> | |
<head> | |
<meta charset="UTF-8"> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
<title>AI SAAS Build Calculator</title> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.9.1/chart.min.js"></script> | |
<style> | |
* { | |
margin: 0; | |
padding: 0; | |
box-sizing: border-box; | |
} | |
body { | |
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; | |
background: linear-gradient(135deg, #0f0c29 0%, #302b63 50%, #24243e 100%); | |
color: #ffffff; | |
min-height: 100vh; | |
overflow-x: hidden; | |
} | |
.container { | |
max-width: 1400px; | |
margin: 0 auto; | |
padding: 2rem; | |
} | |
header { | |
text-align: center; | |
margin-bottom: 3rem; | |
animation: fadeInDown 0.8s ease-out; | |
} | |
h1 { | |
font-size: 3rem; | |
margin-bottom: 1rem; | |
background: linear-gradient(45deg, #00d2ff, #3a7bd5, #00d2ff); | |
background-size: 200% auto; | |
-webkit-background-clip: text; | |
-webkit-text-fill-color: transparent; | |
animation: gradient 3s ease infinite; | |
} | |
@keyframes gradient { | |
0% { background-position: 0% 50%; } | |
50% { background-position: 100% 50%; } | |
100% { background-position: 0% 50%; } | |
} | |
.subtitle { | |
font-size: 1.2rem; | |
color: #a8a8b3; | |
} | |
.tabs { | |
display: flex; | |
justify-content: center; | |
margin-bottom: 3rem; | |
background: rgba(255, 255, 255, 0.05); | |
backdrop-filter: blur(10px); | |
border-radius: 15px; | |
padding: 0.5rem; | |
gap: 0.5rem; | |
} | |
.tab { | |
padding: 1rem 2rem; | |
background: transparent; | |
border: none; | |
color: #a8a8b3; | |
cursor: pointer; | |
border-radius: 10px; | |
transition: all 0.3s ease; | |
font-size: 1.1rem; | |
font-weight: 500; | |
} | |
.tab.active { | |
background: linear-gradient(45deg, #00d2ff, #3a7bd5); | |
color: #ffffff; | |
transform: scale(1.05); | |
} | |
.tab:hover:not(.active) { | |
background: rgba(255, 255, 255, 0.1); | |
color: #ffffff; | |
} | |
.tab-content { | |
display: none; | |
} | |
.tab-content.active { | |
display: block; | |
animation: fadeIn 0.5s ease; | |
} | |
@keyframes fadeIn { | |
from { opacity: 0; } | |
to { opacity: 1; } | |
} | |
.methods-grid { | |
display: grid; | |
grid-template-columns: repeat(auto-fit, minmax(350px, 1fr)); | |
gap: 2rem; | |
margin-bottom: 3rem; | |
} | |
.method-card { | |
background: rgba(255, 255, 255, 0.05); | |
backdrop-filter: blur(10px); | |
border: 1px solid rgba(255, 255, 255, 0.1); | |
border-radius: 20px; | |
padding: 2rem; | |
transition: all 0.3s ease; | |
animation: fadeInUp 0.8s ease-out; | |
position: relative; | |
overflow: hidden; | |
} | |
.method-card::before { | |
content: ''; | |
position: absolute; | |
top: -50%; | |
left: -50%; | |
width: 200%; | |
height: 200%; | |
background: radial-gradient(circle, rgba(58, 123, 213, 0.1) 0%, transparent 70%); | |
opacity: 0; | |
transition: opacity 0.3s ease; | |
} | |
.method-card:hover::before { | |
opacity: 1; | |
} | |
.method-card:hover { | |
transform: translateY(-10px); | |
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.3); | |
border-color: rgba(58, 123, 213, 0.5); | |
} | |
.method-header { | |
display: flex; | |
align-items: center; | |
margin-bottom: 1.5rem; | |
} | |
.method-icon { | |
width: 60px; | |
height: 60px; | |
margin-right: 1rem; | |
display: flex; | |
align-items: center; | |
justify-content: center; | |
border-radius: 15px; | |
font-size: 2rem; | |
} | |
.outsource-icon { background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); } | |
.inhouse-icon { background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%); } | |
.platform-icon { background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%); } | |
.method-title { | |
font-size: 1.5rem; | |
font-weight: 700; | |
} | |
.method-description { | |
color: #a8a8b3; | |
margin-bottom: 1.5rem; | |
line-height: 1.6; | |
} | |
.cost-breakdown { | |
background: rgba(0, 0, 0, 0.2); | |
border-radius: 10px; | |
padding: 1rem; | |
margin-bottom: 1.5rem; | |
} | |
.cost-item { | |
display: flex; | |
justify-content: space-between; | |
margin-bottom: 0.5rem; | |
padding: 0.5rem 0; | |
border-bottom: 1px solid rgba(255, 255, 255, 0.05); | |
} | |
.cost-item:last-child { | |
border-bottom: none; | |
} | |
.pros-cons { | |
display: grid; | |
grid-template-columns: 1fr 1fr; | |
gap: 1rem; | |
margin-top: 1.5rem; | |
} | |
.pros, .cons { | |
padding: 1rem; | |
border-radius: 10px; | |
font-size: 0.9rem; | |
} | |
.pros { | |
background: rgba(46, 213, 115, 0.1); | |
border: 1px solid rgba(46, 213, 115, 0.3); | |
} | |
.cons { | |
background: rgba(255, 71, 87, 0.1); | |
border: 1px solid rgba(255, 71, 87, 0.3); | |
} | |
.pros h4, .cons h4 { | |
margin-bottom: 0.5rem; | |
font-size: 1rem; | |
} | |
.pros ul, .cons ul { | |
list-style: none; | |
padding-left: 0; | |
} | |
.pros li::before { | |
content: "✓ "; | |
color: #2ed573; | |
font-weight: bold; | |
} | |
.cons li::before { | |
content: "✗ "; | |
color: #ff4757; | |
font-weight: bold; | |
} | |
.calculator-section { | |
background: rgba(255, 255, 255, 0.05); | |
backdrop-filter: blur(10px); | |
border: 1px solid rgba(255, 255, 255, 0.1); | |
border-radius: 20px; | |
padding: 2rem; | |
margin-bottom: 3rem; | |
animation: fadeInUp 1s ease-out; | |
} | |
.calculator-title { | |
font-size: 2rem; | |
margin-bottom: 2rem; | |
text-align: center; | |
} | |
.input-group { | |
display: grid; | |
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); | |
gap: 1.5rem; | |
margin-bottom: 2rem; | |
} | |
.input-field { | |
display: flex; | |
flex-direction: column; | |
} | |
.input-field label { | |
margin-bottom: 0.5rem; | |
color: #a8a8b3; | |
font-size: 0.9rem; | |
} | |
.input-field input, .input-field select { | |
background: rgba(255, 255, 255, 0.1); | |
border: 1px solid rgba(255, 255, 255, 0.2); | |
border-radius: 10px; | |
padding: 0.75rem 1rem; | |
color: #ffffff; | |
font-size: 1rem; | |
transition: all 0.3s ease; | |
} | |
.input-field input:focus, .input-field select:focus { | |
outline: none; | |
border-color: #3a7bd5; | |
background: rgba(255, 255, 255, 0.15); | |
} | |
.input-field select option { | |
background: #24243e; | |
} | |
.calculate-btn { | |
background: linear-gradient(45deg, #00d2ff, #3a7bd5); | |
border: none; | |
border-radius: 10px; | |
padding: 1rem 2rem; | |
font-size: 1.1rem; | |
font-weight: 600; | |
color: #ffffff; | |
cursor: pointer; | |
transition: all 0.3s ease; | |
display: block; | |
margin: 0 auto; | |
} | |
.calculate-btn:hover { | |
transform: translateY(-2px); | |
box-shadow: 0 10px 20px rgba(58, 123, 213, 0.3); | |
} | |
.results-section { | |
margin-top: 3rem; | |
display: none; | |
} | |
.results-grid { | |
display: grid; | |
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); | |
gap: 2rem; | |
margin-bottom: 2rem; | |
} | |
.result-card { | |
background: rgba(0, 0, 0, 0.3); | |
border-radius: 15px; | |
padding: 1.5rem; | |
text-align: center; | |
} | |
.result-value { | |
font-size: 2.5rem; | |
font-weight: 700; | |
margin: 1rem 0; | |
background: linear-gradient(45deg, #00d2ff, #3a7bd5); | |
-webkit-background-clip: text; | |
-webkit-text-fill-color: transparent; | |
} | |
.chart-container { | |
position: relative; | |
height: 400px; | |
background: rgba(0, 0, 0, 0.3); | |
border-radius: 15px; | |
padding: 1.5rem; | |
margin-top: 2rem; | |
} | |
/* 맞춤 설계 스타일 */ | |
.custom-design-container { | |
background: rgba(255, 255, 255, 0.05); | |
backdrop-filter: blur(10px); | |
border: 1px solid rgba(255, 255, 255, 0.1); | |
border-radius: 20px; | |
padding: 2rem; | |
} | |
.component-section { | |
margin-bottom: 2.5rem; | |
} | |
.component-title { | |
font-size: 1.3rem; | |
margin-bottom: 1rem; | |
display: flex; | |
align-items: center; | |
gap: 0.5rem; | |
} | |
.component-icon { | |
width: 30px; | |
height: 30px; | |
background: linear-gradient(45deg, #00d2ff, #3a7bd5); | |
border-radius: 8px; | |
display: flex; | |
align-items: center; | |
justify-content: center; | |
font-size: 1.2rem; | |
} | |
.component-options { | |
display: grid; | |
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); | |
gap: 1rem; | |
} | |
.option-card { | |
background: rgba(255, 255, 255, 0.05); | |
border: 1px solid rgba(255, 255, 255, 0.2); | |
border-radius: 10px; | |
padding: 1rem; | |
cursor: pointer; | |
transition: all 0.3s ease; | |
position: relative; | |
overflow: hidden; | |
} | |
.option-card.selected { | |
background: rgba(58, 123, 213, 0.2); | |
border-color: #3a7bd5; | |
transform: scale(1.05); | |
} | |
.option-card:hover { | |
border-color: #00d2ff; | |
background: rgba(255, 255, 255, 0.1); | |
} | |
.option-name { | |
font-weight: 600; | |
margin-bottom: 0.5rem; | |
} | |
.option-details { | |
display: flex; | |
justify-content: space-between; | |
font-size: 0.9rem; | |
color: #a8a8b3; | |
} | |
.custom-result { | |
background: rgba(0, 0, 0, 0.3); | |
border-radius: 15px; | |
padding: 2rem; | |
margin-top: 2rem; | |
display: none; | |
} | |
.custom-summary { | |
display: grid; | |
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); | |
gap: 2rem; | |
margin-bottom: 2rem; | |
} | |
.summary-item { | |
text-align: center; | |
} | |
.summary-label { | |
color: #a8a8b3; | |
margin-bottom: 0.5rem; | |
} | |
.summary-value { | |
font-size: 2rem; | |
font-weight: 700; | |
background: linear-gradient(45deg, #00d2ff, #3a7bd5); | |
-webkit-background-clip: text; | |
-webkit-text-fill-color: transparent; | |
} | |
.selected-components { | |
background: rgba(255, 255, 255, 0.05); | |
border-radius: 10px; | |
padding: 1.5rem; | |
} | |
.selected-components h4 { | |
margin-bottom: 1rem; | |
} | |
.component-list { | |
display: grid; | |
gap: 0.5rem; | |
} | |
.component-list-item { | |
display: flex; | |
justify-content: space-between; | |
padding: 0.5rem 0; | |
border-bottom: 1px solid rgba(255, 255, 255, 0.1); | |
} | |
@keyframes fadeInDown { | |
from { | |
opacity: 0; | |
transform: translateY(-30px); | |
} | |
to { | |
opacity: 1; | |
transform: translateY(0); | |
} | |
} | |
@keyframes fadeInUp { | |
from { | |
opacity: 0; | |
transform: translateY(30px); | |
} | |
to { | |
opacity: 1; | |
transform: translateY(0); | |
} | |
} | |
@media (max-width: 768px) { | |
h1 { | |
font-size: 2rem; | |
} | |
.methods-grid { | |
grid-template-columns: 1fr; | |
} | |
.pros-cons { | |
grid-template-columns: 1fr; | |
} | |
.tabs { | |
flex-direction: column; | |
} | |
.tab { | |
width: 100%; | |
} | |
} | |
</style> | |
</head> | |
<body> | |
<div class="container"> | |
<header> | |
<h1>AI SAAS Build Calculator</h1> | |
<p class="subtitle">최적의 AI 서비스 구축 방식을 찾아드립니다</p> | |
</header> | |
<div class="tabs"> | |
<button class="tab active" onclick="switchTab('comparison')">구축 방식 비교</button> | |
<button class="tab" onclick="switchTab('custom')">나만의 맞춤 설계</button> | |
</div> | |
<!-- 구축 방식 비교 탭 --> | |
<div id="comparison" class="tab-content active"> | |
<div class="methods-grid"> | |
<!-- 외주 용역 개발 방식 --> | |
<div class="method-card"> | |
<div class="method-header"> | |
<div class="method-icon outsource-icon">🤝</div> | |
<h2 class="method-title">외주 용역 개발</h2> | |
</div> | |
<p class="method-description"> | |
전문 개발사에 프로젝트를 위탁하여 AI SaaS를 구축하는 방식 | |
</p> | |
<div class="cost-breakdown"> | |
<div class="cost-item"> | |
<span>초기 비용</span> | |
<span>₩50M - ₩200M</span> | |
</div> | |
<div class="cost-item"> | |
<span>개발 기간</span> | |
<span>3 - 6개월</span> | |
</div> | |
<div class="cost-item"> | |
<span>유지보수</span> | |
<span>월 ₩5M - ₩15M</span> | |
</div> | |
</div> | |
<div class="pros-cons"> | |
<div class="pros"> | |
<h4>장점</h4> | |
<ul> | |
<li>빠른 개발 착수</li> | |
<li>전문성 활용</li> | |
<li>인력 관리 부담 없음</li> | |
</ul> | |
</div> | |
<div class="cons"> | |
<h4>단점</h4> | |
<ul> | |
<li>높은 비용</li> | |
<li>커스터마이징 제한</li> | |
<li>의존성 문제</li> | |
</ul> | |
</div> | |
</div> | |
</div> | |
<!-- 자체 인력 개발 방식 --> | |
<div class="method-card"> | |
<div class="method-header"> | |
<div class="method-icon inhouse-icon">👥</div> | |
<h2 class="method-title">자체 인력 개발</h2> | |
</div> | |
<p class="method-description"> | |
내부 개발팀을 구성하여 직접 AI SaaS를 개발하는 방식 | |
</p> | |
<div class="cost-breakdown"> | |
<div class="cost-item"> | |
<span>초기 비용</span> | |
<span>₩30M - ₩100M</span> | |
</div> | |
<div class="cost-item"> | |
<span>개발 기간</span> | |
<span>6 - 12개월</span> | |
</div> | |
<div class="cost-item"> | |
<span>운영 비용</span> | |
<span>월 ₩20M - ₩50M</span> | |
</div> | |
</div> | |
<div class="pros-cons"> | |
<div class="pros"> | |
<h4>장점</h4> | |
<ul> | |
<li>완전한 통제권</li> | |
<li>장기적 비용 효율</li> | |
<li>기술 내재화</li> | |
</ul> | |
</div> | |
<div class="cons"> | |
<h4>단점</h4> | |
<ul> | |
<li>채용 어려움</li> | |
<li>긴 개발 기간</li> | |
<li>높은 운영 비용</li> | |
</ul> | |
</div> | |
</div> | |
</div> | |
<!-- 플랫폼 대여 방식 --> | |
<div class="method-card"> | |
<div class="method-header"> | |
<div class="method-icon platform-icon">🚀</div> | |
<h2 class="method-title">플랫폼 대여</h2> | |
</div> | |
<p class="method-description"> | |
기존 플랫폼을 대여하여 빠르게 AI SaaS를 구축하는 방식 | |
</p> | |
<div class="cost-breakdown"> | |
<div class="cost-item"> | |
<span>초기 비용</span> | |
<span>₩10M - ₩50M</span> | |
</div> | |
<div class="cost-item"> | |
<span>개발 기간</span> | |
<span>1 - 3개월</span> | |
</div> | |
<div class="cost-item"> | |
<span>구독료</span> | |
<span>월 ₩2M - ₩10M</span> | |
</div> | |
</div> | |
<div class="pros-cons"> | |
<div class="pros"> | |
<h4>장점</h4> | |
<ul> | |
<li>빠른 시장 진입</li> | |
<li>낮은 초기 비용</li> | |
<li>검증된 기술</li> | |
</ul> | |
</div> | |
<div class="cons"> | |
<h4>단점</h4> | |
<ul> | |
<li>제한된 커스터마이징</li> | |
<li>플랫폼 종속성</li> | |
<li>차별화 어려움</li> | |
</ul> | |
</div> | |
</div> | |
</div> | |
</div> | |
<!-- 비용 계산기 섹션 --> | |
<div class="calculator-section"> | |
<h2 class="calculator-title">비용 시뮬레이터</h2> | |
<div class="input-group"> | |
<div class="input-field"> | |
<label for="projectScale">프로젝트 규모</label> | |
<select id="projectScale"> | |
<option value="small">소규모 (MVP)</option> | |
<option value="medium">중규모</option> | |
<option value="large">대규모</option> | |
</select> | |
</div> | |
<div class="input-field"> | |
<label for="duration">운영 기간 (개월)</label> | |
<input type="number" id="duration" value="12" min="1" max="60"> | |
</div> | |
<div class="input-field"> | |
<label for="users">예상 사용자 수</label> | |
<input type="number" id="users" value="1000" min="100" max="1000000"> | |
</div> | |
<div class="input-field"> | |
<label for="features">AI 기능 복잡도</label> | |
<select id="features"> | |
<option value="basic">기본 (챗봇, 번역)</option> | |
<option value="advanced">고급 (이미지 생성, 분석)</option> | |
<option value="enterprise">엔터프라이즈 (맞춤형 모델)</option> | |
</select> | |
</div> | |
</div> | |
<button class="calculate-btn" onclick="calculateCosts()">비용 계산하기</button> | |
<div class="results-section" id="results"> | |
<div class="results-grid"> | |
<div class="result-card"> | |
<h3>외주 용역 총 비용</h3> | |
<div class="result-value" id="outsourceCost">₩0</div> | |
<p>초기 + 운영 비용</p> | |
</div> | |
<div class="result-card"> | |
<h3>자체 인력 총 비용</h3> | |
<div class="result-value" id="inhouseCost">₩0</div> | |
<p>인건비 + 인프라</p> | |
</div> | |
<div class="result-card"> | |
<h3>플랫폼 대여 총 비용</h3> | |
<div class="result-value" id="platformCost">₩0</div> | |
<p>라이선스 + API</p> | |
</div> | |
</div> | |
<div class="chart-container"> | |
<canvas id="costChart"></canvas> | |
</div> | |
</div> | |
</div> | |
</div> | |
<!-- 나만의 맞춤 설계 탭 --> | |
<div id="custom" class="tab-content"> | |
<div class="custom-design-container"> | |
<h2 class="calculator-title">나만의 AI SaaS 맞춤 설계</h2> | |
<!-- 타깃 서비스 유형 --> | |
<div class="component-section"> | |
<div class="component-title"> | |
<div class="component-icon">🎯</div> | |
<span>타깃 서비스 유형</span> | |
</div> | |
<div class="component-options"> | |
<div class="option-card" onclick="selectOption('service', 'image-gen', 30, 2)"> | |
<div class="option-name">이미지 생성</div> | |
<div class="option-details"> | |
<span>₩30M</span> | |
<span>2개월</span> | |
</div> | |
</div> | |
<div class="option-card" onclick="selectOption('service', 'image-edit', 35, 2.5)"> | |
<div class="option-name">이미지 편집/합성</div> | |
<div class="option-details"> | |
<span>₩35M</span> | |
<span>2.5개월</span> | |
</div> | |
</div> | |
<div class="option-card" onclick="selectOption('service', 'video-gen', 50, 3)"> | |
<div class="option-name">비디오 생성</div> | |
<div class="option-details"> | |
<span>₩50M</span> | |
<span>3개월</span> | |
</div> | |
</div> | |
<div class="option-card" onclick="selectOption('service', 'music-gen', 40, 2.5)"> | |
<div class="option-name">음악 및 음향 생성</div> | |
<div class="option-details"> | |
<span>₩40M</span> | |
<span>2.5개월</span> | |
</div> | |
</div> | |
<div class="option-card" onclick="selectOption('service', 'text-chat', 20, 1.5)"> | |
<div class="option-name">텍스트 생성(챗봇)</div> | |
<div class="option-details"> | |
<span>₩20M</span> | |
<span>1.5개월</span> | |
</div> | |
</div> | |
<div class="option-card" onclick="selectOption('service', 'text-expert', 25, 2)"> | |
<div class="option-name">텍스트 생성(전문가)</div> | |
<div class="option-details"> | |
<span>₩25M</span> | |
<span>2개월</span> | |
</div> | |
</div> | |
<div class="option-card" onclick="selectOption('service', 'voice-clone', 45, 2.5)"> | |
<div class="option-name">음성 복제/생성</div> | |
<div class="option-details"> | |
<span>₩45M</span> | |
<span>2.5개월</span> | |
</div> | |
</div> | |
<div class="option-card" onclick="selectOption('service', 'vision-ai', 35, 2)"> | |
<div class="option-name">비전 인식</div> | |
<div class="option-details"> | |
<span>₩35M</span> | |
<span>2개월</span> | |
</div> | |
</div> | |
</div> | |
</div> | |
<!-- DB 관리 --> | |
<div class="component-section"> | |
<div class="component-title"> | |
<div class="component-icon">💾</div> | |
<span>DB 관리</span> | |
</div> | |
<div class="component-options"> | |
<div class="option-card" onclick="selectOption('db', 'basic-db', 5, 0.5)"> | |
<div class="option-name">기본 DB</div> | |
<div class="option-details"> | |
<span>₩5M</span> | |
<span>0.5개월</span> | |
</div> | |
</div> | |
<div class="option-card" onclick="selectOption('db', 'advanced-db', 15, 1)"> | |
<div class="option-name">고급 DB + 백업</div> | |
<div class="option-details"> | |
<span>₩15M</span> | |
<span>1개월</span> | |
</div> | |
</div> | |
<div class="option-card" onclick="selectOption('db', 'enterprise-db', 25, 1.5)"> | |
<div class="option-name">엔터프라이즈 DB</div> | |
<div class="option-details"> | |
<span>₩25M</span> | |
<span>1.5개월</span> | |
</div> | |
</div> | |
</div> | |
</div> | |
<!-- 회원가입 및 로그인 --> | |
<div class="component-section"> | |
<div class="component-title"> | |
<div class="component-icon">🔐</div> | |
<span>회원가입 및 로그인</span> | |
</div> | |
<div class="component-options"> | |
<div class="option-card" onclick="selectOption('auth', 'gmail-only', 3, 0.3)"> | |
<div class="option-name">Gmail 연동</div> | |
<div class="option-details"> | |
<span>₩3M</span> | |
<span>0.3개월</span> | |
</div> | |
</div> | |
<div class="option-card" onclick="selectOption('auth', 'multi-auth', 8, 0.5)"> | |
<div class="option-name">다중 소셜 로그인</div> | |
<div class="option-details"> | |
<span>₩8M</span> | |
<span>0.5개월</span> | |
</div> | |
</div> | |
<div class="option-card" onclick="selectOption('auth', 'custom-auth', 12, 1)"> | |
<div class="option-name">커스텀 인증 시스템</div> | |
<div class="option-details"> | |
<span>₩12M</span> | |
<span>1개월</span> | |
</div> | |
</div> | |
</div> | |
</div> | |
<!-- 크레딧 관리 --> | |
<div class="component-section"> | |
<div class="component-title"> | |
<div class="component-icon">💰</div> | |
<span>크레딧 관리</span> | |
</div> | |
<div class="component-options"> | |
<div class="option-card" onclick="selectOption('credit', 'basic-credit', 5, 0.5)"> | |
<div class="option-name">기본 크레딧 시스템</div> | |
<div class="option-details"> | |
<span>₩5M</span> | |
<span>0.5개월</span> | |
</div> | |
</div> | |
<div class="option-card" onclick="selectOption('credit', 'advanced-credit', 12, 1)"> | |
<div class="option-name">고급 크레딧 + 구독</div> | |
<div class="option-details"> | |
<span>₩12M</span> | |
<span>1개월</span> | |
</div> | |
</div> | |
</div> | |
</div> | |
<!-- 페이먼트 지원 --> | |
<div class="component-section"> | |
<div class="component-title"> | |
<div class="component-icon">💳</div> | |
<span>페이먼트 지원</span> | |
</div> | |
<div class="component-options"> | |
<div class="option-card" onclick="selectOption('payment', 'basic-payment', 8, 0.5)"> | |
<div class="option-name">기본 결제 (카드)</div> | |
<div class="option-details"> | |
<span>₩8M</span> | |
<span>0.5개월</span> | |
</div> | |
</div> | |
<div class="option-card" onclick="selectOption('payment', 'multi-payment', 15, 1)"> | |
<div class="option-name">다중 결제 수단</div> | |
<div class="option-details"> | |
<span>₩15M</span> | |
<span>1개월</span> | |
</div> | |
</div> | |
<div class="option-card" onclick="selectOption('payment', 'global-payment', 20, 1.5)"> | |
<div class="option-name">글로벌 결제 시스템</div> | |
<div class="option-details"> | |
<span>₩20M</span> | |
<span>1.5개월</span> | |
</div> | |
</div> | |
</div> | |
</div> | |
<!-- 마케팅 지원 --> | |
<div class="component-section"> | |
<div class="component-title"> | |
<div class="component-icon">📢</div> | |
<span>마케팅 지원</span> | |
</div> | |
<div class="component-options"> | |
<div class="option-card" onclick="selectOption('marketing', 'basic-marketing', 10, 1)"> | |
<div class="option-name">기본 마케팅 도구</div> | |
<div class="option-details"> | |
<span>₩10M</span> | |
<span>1개월</span> | |
</div> | |
</div> | |
<div class="option-card" onclick="selectOption('marketing', 'advanced-marketing', 20, 1.5)"> | |
<div class="option-name">고급 마케팅 자동화</div> | |
<div class="option-details"> | |
<span>₩20M</span> | |
<span>1.5개월</span> | |
</div> | |
</div> | |
</div> | |
</div> | |
<!-- 개발 및 기술 인력 지원 --> | |
<div class="component-section"> | |
<div class="component-title"> | |
<div class="component-icon">👨💻</div> | |
<span>개발 및 기술 인력 지원</span> | |
</div> | |
<div class="component-options"> | |
<div class="option-card" onclick="selectOption('support', 'basic-support', 5, 0)"> | |
<div class="option-name">기본 기술 지원</div> | |
<div class="option-details"> | |
<span>월 ₩5M</span> | |
<span>즉시</span> | |
</div> | |
</div> | |
<div class="option-card" onclick="selectOption('support', 'dedicated-support', 15, 0)"> | |
<div class="option-name">전담 개발자 지원</div> | |
<div class="option-details"> | |
<span>월 ₩15M</span> | |
<span>즉시</span> | |
</div> | |
</div> | |
</div> | |
</div> | |
<!-- 원격 모니터링 지원 --> | |
<div class="component-section"> | |
<div class="component-title"> | |
<div class="component-icon">📊</div> | |
<span>원격 모니터링 지원</span> | |
</div> | |
<div class="component-options"> | |
<div class="option-card" onclick="selectOption('monitoring', 'basic-monitor', 3, 0.3)"> | |
<div class="option-name">기본 모니터링</div> | |
<div class="option-details"> | |
<span>₩3M</span> | |
<span>0.3개월</span> | |
</div> | |
</div> | |
<div class="option-card" onclick="selectOption('monitoring', 'advanced-monitor', 8, 0.5)"> | |
<div class="option-name">고급 분석 + 알림</div> | |
<div class="option-details"> | |
<span>₩8M</span> | |
<span>0.5개월</span> | |
</div> | |
</div> | |
</div> | |
</div> | |
<button class="calculate-btn" onclick="calculateCustomCost()">맞춤 견적 계산하기</button> | |
<div class="custom-result" id="customResult"> | |
<div class="custom-summary"> | |
<div class="summary-item"> | |
<div class="summary-label">총 개발 비용</div> | |
<div class="summary-value" id="totalCost">₩0</div> | |
</div> | |
<div class="summary-item"> | |
<div class="summary-label">예상 개발 기간</div> | |
<div class="summary-value" id="totalTime">0개월</div> | |
</div> | |
<div class="summary-item"> | |
<div class="summary-label">월 운영 비용</div> | |
<div class="summary-value" id="monthlyCost">₩0</div> | |
</div> | |
</div> | |
<div class="selected-components"> | |
<h4>선택한 구성 요소</h4> | |
<div class="component-list" id="componentList"></div> | |
</div> | |
</div> | |
</div> | |
</div> | |
</div> | |
<script> | |
let costChart = null; | |
let selectedComponents = {}; | |
function switchTab(tabName) { | |
// 모든 탭 내용 숨기기 | |
document.querySelectorAll('.tab-content').forEach(content => { | |
content.classList.remove('active'); | |
}); | |
// 모든 탭 버튼 비활성화 | |
document.querySelectorAll('.tab').forEach(tab => { | |
tab.classList.remove('active'); | |
}); | |
// 선택한 탭 활성화 | |
document.getElementById(tabName).classList.add('active'); | |
event.target.classList.add('active'); | |
} | |
function selectOption(category, optionId, cost, time) { | |
// 이전 선택 제거 | |
document.querySelectorAll(`.component-section:has(.component-title:has(.component-icon:contains('${getCategoryIcon(category)}'))) .option-card`).forEach(card => { | |
card.classList.remove('selected'); | |
}); | |
// 새 선택 추가 | |
event.currentTarget.classList.add('selected'); | |
// 선택 정보 저장 | |
selectedComponents[category] = { | |
id: optionId, | |
name: event.currentTarget.querySelector('.option-name').textContent, | |
cost: cost, | |
time: time | |
}; | |
} | |
function getCategoryIcon(category) { | |
const icons = { | |
'service': '🎯', | |
'db': '💾', | |
'auth': '🔐', | |
'credit': '💰', | |
'payment': '💳', | |
'marketing': '📢', | |
'support': '👨💻', | |
'monitoring': '📊' | |
}; | |
return icons[category]; | |
} | |
function calculateCustomCost() { | |
if (Object.keys(selectedComponents).length === 0) { | |
alert('구성 요소를 선택해주세요.'); | |
return; | |
} | |
let totalCost = 0; | |
let totalTime = 0; | |
let monthlyCost = 0; | |
let componentListHTML = ''; | |
Object.values(selectedComponents).forEach(component => { | |
totalCost += component.cost; | |
totalTime = Math.max(totalTime, component.time); | |
// 월 운영 비용 계산 (support는 월 비용) | |
if (component.id.includes('support')) { | |
monthlyCost += component.cost; | |
} | |
componentListHTML += ` | |
<div class="component-list-item"> | |
<span>${component.name}</span> | |
<span>₩${component.cost}M</span> | |
</div> | |
`; | |
}); | |
// 기본 월 운영 비용 추가 (서버, API 등) | |
monthlyCost += totalCost * 0.05; // 초기 비용의 5%를 월 운영비로 가정 | |
document.getElementById('totalCost').textContent = `₩${totalCost}M`; | |
document.getElementById('totalTime').textContent = `${totalTime}개월`; | |
document.getElementById('monthlyCost').textContent = `₩${monthlyCost.toFixed(1)}M`; | |
document.getElementById('componentList').innerHTML = componentListHTML; | |
document.getElementById('customResult').style.display = 'block'; | |
// 스크롤 다운 | |
document.getElementById('customResult').scrollIntoView({ behavior: 'smooth' }); | |
} | |
function calculateCosts() { | |
const scale = document.getElementById('projectScale').value; | |
const duration = parseInt(document.getElementById('duration').value); | |
const users = parseInt(document.getElementById('users').value); | |
const features = document.getElementById('features').value; | |
// 기본 비용 설정 | |
const baseCosts = { | |
outsource: { | |
small: { initial: 50, monthly: 5 }, | |
medium: { initial: 100, monthly: 10 }, | |
large: { initial: 200, monthly: 15 } | |
}, | |
inhouse: { | |
small: { initial: 30, monthly: 20 }, | |
medium: { initial: 60, monthly: 35 }, | |
large: { initial: 100, monthly: 50 } | |
}, | |
platform: { | |
small: { initial: 10, monthly: 2 }, | |
medium: { initial: 30, monthly: 5 }, | |
large: { initial: 50, monthly: 10 } | |
} | |
}; | |
// 복잡도에 따른 가중치 | |
const complexityMultiplier = { | |
basic: 1, | |
advanced: 1.5, | |
enterprise: 2 | |
}; | |
// 사용자 수에 따른 추가 비용 | |
const userCostFactor = Math.log10(users) / 3; | |
// 비용 계산 | |
const multiplier = complexityMultiplier[features] * userCostFactor; | |
const outsourceCost = baseCosts.outsource[scale].initial + | |
(baseCosts.outsource[scale].monthly * duration * multiplier); | |
const inhouseCost = baseCosts.inhouse[scale].initial + | |
(baseCosts.inhouse[scale].monthly * duration * multiplier); | |
const platformCost = baseCosts.platform[scale].initial + | |
(baseCosts.platform[scale].monthly * duration * multiplier); | |
// 결과 표시 | |
document.getElementById('outsourceCost').textContent = `₩${Math.round(outsourceCost)}M`; | |
document.getElementById('inhouseCost').textContent = `₩${Math.round(inhouseCost)}M`; | |
document.getElementById('platformCost').textContent = `₩${Math.round(platformCost)}M`; | |
document.getElementById('results').style.display = 'block'; | |
// 차트 그리기 | |
drawChart(duration, baseCosts[scale], multiplier); | |
} | |
function drawChart(duration, costs, multiplier) { | |
const ctx = document.getElementById('costChart').getContext('2d'); | |
if (costChart) { | |
costChart.destroy(); | |
} | |
const months = Array.from({length: duration}, (_, i) => i + 1); | |
costChart = new Chart(ctx, { | |
type: 'line', | |
data: { | |
labels: months.map(m => `${m}개월`), | |
datasets: [ | |
{ | |
label: '외주 용역', | |
data: months.map(m => costs.outsource.initial + (costs.outsource.monthly * m * multiplier)), | |
borderColor: '#764ba2', | |
backgroundColor: 'rgba(118, 75, 162, 0.1)', | |
tension: 0.4 | |
}, | |
{ | |
label: '자체 인력', | |
data: months.map(m => costs.inhouse.initial + (costs.inhouse.monthly * m * multiplier)), | |
borderColor: '#f5576c', | |
backgroundColor: 'rgba(245, 87, 108, 0.1)', | |
tension: 0.4 | |
}, | |
{ | |
label: '플랫폼 대여', | |
data: months.map(m => costs.platform.initial + (costs.platform.monthly * m * multiplier)), | |
borderColor: '#00f2fe', | |
backgroundColor: 'rgba(0, 242, 254, 0.1)', | |
tension: 0.4 | |
} | |
] | |
}, | |
options: { | |
responsive: true, | |
maintainAspectRatio: false, | |
plugins: { | |
title: { | |
display: true, | |
text: '시간에 따른 누적 비용 추이', | |
color: '#ffffff', | |
font: { | |
size: 16 | |
} | |
}, | |
legend: { | |
labels: { | |
color: '#ffffff' | |
} | |
} | |
}, | |
scales: { | |
x: { | |
grid: { | |
color: 'rgba(255, 255, 255, 0.1)' | |
}, | |
ticks: { | |
color: '#ffffff' | |
} | |
}, | |
y: { | |
grid: { | |
color: 'rgba(255, 255, 255, 0.1)' | |
}, | |
ticks: { | |
color: '#ffffff', | |
callback: function(value) { | |
return '₩' + value + 'M'; | |
} | |
} | |
} | |
} | |
} | |
}); | |
} | |
// 애니메이션 효과를 위한 Intersection Observer | |
const observer = new IntersectionObserver((entries) => { | |
entries.forEach(entry => { | |
if (entry.isIntersecting) { | |
entry.target.style.animation = 'fadeInUp 0.8s ease-out forwards'; | |
} | |
}); | |
}); | |
document.querySelectorAll('.method-card').forEach(card => { | |
observer.observe(card); | |
}); | |
</script> | |
</body> | |
</html> |