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: 2px 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.3); | |
border-color: #3a7bd5; | |
transform: scale(1.05); | |
box-shadow: 0 5px 20px rgba(58, 123, 213, 0.3); | |
} | |
.option-card.selected::after { | |
content: '✓'; | |
position: absolute; | |
top: 0.5rem; | |
right: 0.5rem; | |
background: #3a7bd5; | |
color: white; | |
width: 25px; | |
height: 25px; | |
border-radius: 50%; | |
display: flex; | |
align-items: center; | |
justify-content: center; | |
font-weight: bold; | |
} | |
.option-card:hover { | |
border-color: #00d2ff; | |
background: rgba(255, 255, 255, 0.1); | |
transform: translateY(-2px); | |
} | |
.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; | |
} | |
.result-header { | |
text-align: center; | |
margin-bottom: 2rem; | |
} | |
.result-header h3 { | |
font-size: 1.8rem; | |
margin-bottom: 0.5rem; | |
color: #00d2ff; | |
} | |
.period-tabs { | |
display: flex; | |
justify-content: center; | |
gap: 1rem; | |
margin-bottom: 2rem; | |
} | |
.period-tab { | |
padding: 0.5rem 1.5rem; | |
background: rgba(255, 255, 255, 0.1); | |
border: 1px solid rgba(255, 255, 255, 0.2); | |
border-radius: 20px; | |
cursor: pointer; | |
transition: all 0.3s ease; | |
} | |
.period-tab.active { | |
background: linear-gradient(45deg, #00d2ff, #3a7bd5); | |
border-color: transparent; | |
} | |
.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; | |
margin-bottom: 1.5rem; | |
} | |
.selected-components h4 { | |
margin-bottom: 1rem; | |
font-size: 1.2rem; | |
} | |
.component-list { | |
display: grid; | |
gap: 0.5rem; | |
} | |
.component-list-item { | |
display: flex; | |
justify-content: space-between; | |
padding: 0.75rem; | |
border-bottom: 1px solid rgba(255, 255, 255, 0.1); | |
background: rgba(255, 255, 255, 0.02); | |
border-radius: 5px; | |
} | |
.component-list-item:last-child { | |
border-bottom: none; | |
} | |
.timeline-section { | |
background: rgba(255, 255, 255, 0.05); | |
border-radius: 10px; | |
padding: 1.5rem; | |
margin-top: 1.5rem; | |
} | |
.timeline-section h4 { | |
margin-bottom: 1rem; | |
font-size: 1.2rem; | |
} | |
.timeline-bar { | |
position: relative; | |
height: 40px; | |
background: rgba(255, 255, 255, 0.1); | |
border-radius: 20px; | |
overflow: hidden; | |
margin-bottom: 1rem; | |
} | |
.timeline-progress { | |
height: 100%; | |
background: linear-gradient(90deg, #00d2ff, #3a7bd5); | |
border-radius: 20px; | |
display: flex; | |
align-items: center; | |
justify-content: center; | |
color: white; | |
font-weight: 600; | |
transition: width 0.5s ease; | |
} | |
.monthly-breakdown { | |
display: grid; | |
grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); | |
gap: 1rem; | |
margin-top: 1rem; | |
} | |
.monthly-item { | |
background: rgba(255, 255, 255, 0.05); | |
padding: 1rem; | |
border-radius: 10px; | |
text-align: center; | |
} | |
.monthly-label { | |
font-size: 0.9rem; | |
color: #a8a8b3; | |
margin-bottom: 0.5rem; | |
} | |
.monthly-value { | |
font-size: 1.2rem; | |
font-weight: 600; | |
color: #00d2ff; | |
} | |
@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" data-category="service" data-id="image-gen" data-cost="30" data-time="2"> | |
<div class="option-name">이미지 생성</div> | |
<div class="option-details"> | |
<span>₩30M</span> | |
<span>2개월</span> | |
</div> | |
</div> | |
<div class="option-card" data-category="service" data-id="image-edit" data-cost="35" data-time="2.5"> | |
<div class="option-name">이미지 편집/합성</div> | |
<div class="option-details"> | |
<span>₩35M</span> | |
<span>2.5개월</span> | |
</div> | |
</div> | |
<div class="option-card" data-category="service" data-id="video-gen" data-cost="50" data-time="3"> | |
<div class="option-name">비디오 생성</div> | |
<div class="option-details"> | |
<span>₩50M</span> | |
<span>3개월</span> | |
</div> | |
</div> | |
<div class="option-card" data-category="service" data-id="music-gen" data-cost="40" data-time="2.5"> | |
<div class="option-name">음악 및 음향 생성</div> | |
<div class="option-details"> | |
<span>₩40M</span> | |
<span>2.5개월</span> | |
</div> | |
</div> | |
<div class="option-card" data-category="service" data-id="text-chat" data-cost="20" data-time="1.5"> | |
<div class="option-name">텍스트 생성(챗봇)</div> | |
<div class="option-details"> | |
<span>₩20M</span> | |
<span>1.5개월</span> | |
</div> | |
</div> | |
<div class="option-card" data-category="service" data-id="text-expert" data-cost="25" data-time="2"> | |
<div class="option-name">텍스트 생성(전문가)</div> | |
<div class="option-details"> | |
<span>₩25M</span> | |
<span>2개월</span> | |
</div> | |
</div> | |
<div class="option-card" data-category="service" data-id="voice-clone" data-cost="45" data-time="2.5"> | |
<div class="option-name">음성 복제/생성</div> | |
<div class="option-details"> | |
<span>₩45M</span> | |
<span>2.5개월</span> | |
</div> | |
</div> | |
<div class="option-card" data-category="service" data-id="vision-ai" data-cost="35" data-time="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" data-category="db" data-id="basic-db" data-cost="5" data-time="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" data-category="db" data-id="advanced-db" data-cost="15" data-time="1"> | |
<div class="option-name">고급 DB + 백업</div> | |
<div class="option-details"> | |
<span>₩15M</span> | |
<span>1개월</span> | |
</div> | |
</div> | |
<div class="option-card" data-category="db" data-id="enterprise-db" data-cost="25" data-time="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" data-category="auth" data-id="gmail-only" data-cost="3" data-time="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" data-category="auth" data-id="multi-auth" data-cost="8" data-time="0.5"> | |
<div class="option-name">다중 소셜 로그인</div> | |
<div class="option-details"> | |
<span>₩8M</span> | |
<span>0.5개월</span> | |
</div> | |
</div> | |
<div class="option-card" data-category="auth" data-id="custom-auth" data-cost="12" data-time="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" data-category="credit" data-id="basic-credit" data-cost="5" data-time="0.5"> | |
<div class="option-name">기본 크레딧 시스템</div> | |
<div class="option-details"> | |
<span>₩5M</span> | |
<span>0.5개월</span> | |
</div> | |
</div> | |
<div class="option-card" data-category="credit" data-id="advanced-credit" data-cost="12" data-time="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" data-category="payment" data-id="basic-payment" data-cost="8" data-time="0.5"> | |
<div class="option-name">기본 결제 (카드)</div> | |
<div class="option-details"> | |
<span>₩8M</span> | |
<span>0.5개월</span> | |
</div> | |
</div> | |
<div class="option-card" data-category="payment" data-id="multi-payment" data-cost="15" data-time="1"> | |
<div class="option-name">다중 결제 수단</div> | |
<div class="option-details"> | |
<span>₩15M</span> | |
<span>1개월</span> | |
</div> | |
</div> | |
<div class="option-card" data-category="payment" data-id="global-payment" data-cost="20" data-time="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" data-category="marketing" data-id="basic-marketing" data-cost="10" data-time="1"> | |
<div class="option-name">기본 마케팅 도구</div> | |
<div class="option-details"> | |
<span>₩10M</span> | |
<span>1개월</span> | |
</div> | |
</div> | |
<div class="option-card" data-category="marketing" data-id="advanced-marketing" data-cost="20" data-time="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" data-category="support" data-id="basic-support" data-cost="5" data-time="0"> | |
<div class="option-name">기본 기술 지원</div> | |
<div class="option-details"> | |
<span>월 ₩5M</span> | |
<span>즉시</span> | |
</div> | |
</div> | |
<div class="option-card" data-category="support" data-id="dedicated-support" data-cost="15" data-time="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" data-category="monitoring" data-id="basic-monitor" data-cost="3" data-time="0.3"> | |
<div class="option-name">기본 모니터링</div> | |
<div class="option-details"> | |
<span>₩3M</span> | |
<span>0.3개월</span> | |
</div> | |
</div> | |
<div class="option-card" data-category="monitoring" data-id="advanced-monitor" data-cost="8" data-time="0.5"> | |
<div class="option-name">고급 분석 + 알림</div> | |
<div class="option-details"> | |
<span>₩8M</span> | |
<span>0.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" data-category="additional" data-id="admin-panel" data-cost="10" data-time="0.5"> | |
<div class="option-name">관리자 대시보드</div> | |
<div class="option-details"> | |
<span>₩10M</span> | |
<span>0.5개월</span> | |
</div> | |
</div> | |
<div class="option-card" data-category="additional" data-id="api-system" data-cost="15" data-time="1"> | |
<div class="option-name">API 시스템</div> | |
<div class="option-details"> | |
<span>₩15M</span> | |
<span>1개월</span> | |
</div> | |
</div> | |
<div class="option-card" data-category="additional" data-id="analytics" data-cost="12" data-time="0.5"> | |
<div class="option-name">분석 도구</div> | |
<div class="option-details"> | |
<span>₩12M</span> | |
<span>0.5개월</span> | |
</div> | |
</div> | |
<div class="option-card" data-category="additional" data-id="multi-language" data-cost="8" data-time="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="result-header"> | |
<h3>맞춤 AI SaaS 견적서</h3> | |
<p>선택하신 구성으로 산출된 상세 견적입니다</p> | |
</div> | |
<div class="period-tabs"> | |
<div class="period-tab active" onclick="switchPeriod(3)">3개월</div> | |
<div class="period-tab" onclick="switchPeriod(6)">6개월</div> | |
<div class="period-tab" onclick="switchPeriod(12)">12개월</div> | |
</div> | |
<div class="custom-summary"> | |
<div class="summary-item"> | |
<div class="summary-label">초기 개발 비용</div> | |
<div class="summary-value" id="initialCost">₩0</div> | |
</div> | |
<div class="summary-item"> | |
<div class="summary-label">예상 개발 기간</div> | |
<div class="summary-value" id="devTime">0개월</div> | |
</div> | |
<div class="summary-item"> | |
<div class="summary-label">총 비용 (<span id="periodText">3</span>개월)</div> | |
<div class="summary-value" id="totalCost">₩0</div> | |
</div> | |
</div> | |
<div class="selected-components"> | |
<h4>선택한 구성 요소 상세</h4> | |
<div class="component-list" id="componentList"></div> | |
</div> | |
<div class="timeline-section"> | |
<h4>개발 일정 및 진행률</h4> | |
<div class="timeline-bar"> | |
<div class="timeline-progress" id="timelineProgress" style="width: 0%"> | |
<span id="progressText">0%</span> | |
</div> | |
</div> | |
<p style="text-align: center; color: #a8a8b3; margin-top: 0.5rem;"> | |
예상 개발 기간: <span id="timelineText">0개월</span> | |
</p> | |
</div> | |
<div class="monthly-breakdown"> | |
<div class="monthly-item"> | |
<div class="monthly-label">월 서버 비용</div> | |
<div class="monthly-value" id="serverCost">₩0</div> | |
</div> | |
<div class="monthly-item"> | |
<div class="monthly-label">월 API 비용</div> | |
<div class="monthly-value" id="apiCost">₩0</div> | |
</div> | |
<div class="monthly-item"> | |
<div class="monthly-label">월 유지보수</div> | |
<div class="monthly-value" id="maintenanceCost">₩0</div> | |
</div> | |
<div class="monthly-item"> | |
<div class="monthly-label">월 총 운영비</div> | |
<div class="monthly-value" id="totalMonthlyCost">₩0</div> | |
</div> | |
</div> | |
</div> | |
</div> | |
</div> | |
</div> | |
<script> | |
let costChart = null; | |
let selectedComponents = {}; | |
let currentPeriod = 3; | |
// 탭 전환 함수 | |
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'); | |
} | |
// 맞춤 설계 옵션 선택 함수 | |
document.addEventListener('DOMContentLoaded', function() { | |
// 모든 option-card에 클릭 이벤트 추가 | |
document.querySelectorAll('.option-card').forEach(card => { | |
card.addEventListener('click', function() { | |
const category = this.dataset.category; | |
const id = this.dataset.id; | |
const cost = parseFloat(this.dataset.cost); | |
const time = parseFloat(this.dataset.time); | |
const name = this.querySelector('.option-name').textContent; | |
// 복수 선택 가능한 카테고리 | |
const multiSelectCategories = ['service', 'additional']; | |
if (multiSelectCategories.includes(category)) { | |
// 복수 선택 처리 | |
if (!selectedComponents[category]) { | |
selectedComponents[category] = {}; | |
} | |
if (this.classList.contains('selected')) { | |
// 이미 선택된 경우 해제 | |
this.classList.remove('selected'); | |
delete selectedComponents[category][id]; | |
// 카테고리에 선택된 항목이 없으면 카테고리 삭제 | |
if (Object.keys(selectedComponents[category]).length === 0) { | |
delete selectedComponents[category]; | |
} | |
} else { | |
// 선택 추가 | |
this.classList.add('selected'); | |
selectedComponents[category][id] = { | |
id: id, | |
name: name, | |
cost: cost, | |
time: time, | |
category: category | |
}; | |
} | |
} else { | |
// 단일 선택 처리 (기존 로직) | |
document.querySelectorAll(`.option-card[data-category="${category}"]`).forEach(c => { | |
c.classList.remove('selected'); | |
}); | |
this.classList.add('selected'); | |
selectedComponents[category] = { | |
id: id, | |
name: name, | |
cost: cost, | |
time: time, | |
category: category | |
}; | |
} | |
}); | |
}); | |
}); | |
// 기간 전환 함수 | |
function switchPeriod(period) { | |
currentPeriod = period; | |
document.querySelectorAll('.period-tab').forEach(tab => { | |
tab.classList.remove('active'); | |
}); | |
event.target.classList.add('active'); | |
if (Object.keys(selectedComponents).length > 0) { | |
displayCustomResults(); | |
} | |
} | |
// 맞춤 비용 계산 함수 | |
function calculateCustomCost() { | |
// 필수 항목 체크 (타깃 서비스 최소 1개) | |
if (!selectedComponents.service || Object.keys(selectedComponents.service).length === 0) { | |
alert('타깃 서비스 유형을 최소 1개 이상 선택해주세요.'); | |
return; | |
} | |
displayCustomResults(); | |
document.getElementById('customResult').style.display = 'block'; | |
document.getElementById('customResult').scrollIntoView({ behavior: 'smooth' }); | |
} | |
// 결과 표시 함수 | |
function displayCustomResults() { | |
let initialCost = 0; | |
let maxTime = 0; | |
let componentListHTML = ''; | |
let monthlySupport = 0; | |
// 카테고리별 이름 | |
const categoryNames = { | |
'service': '타깃 서비스', | |
'db': 'DB 관리', | |
'auth': '인증 시스템', | |
'credit': '크레딧 관리', | |
'payment': '결제 시스템', | |
'marketing': '마케팅 도구', | |
'support': '기술 지원', | |
'monitoring': '모니터링', | |
'additional': '추가 기능' | |
}; | |
// 초기 비용 계산 및 구성 요소 목록 생성 | |
Object.entries(selectedComponents).forEach(([category, value]) => { | |
if (typeof value === 'object' && value.id) { | |
// 단일 선택 항목 | |
if (category === 'support') { | |
monthlySupport += value.cost; | |
} else { | |
initialCost += value.cost; | |
} | |
maxTime = Math.max(maxTime, value.time); | |
componentListHTML += ` | |
<div class="component-list-item"> | |
<span><strong>${categoryNames[category]}</strong>: ${value.name}</span> | |
<span>${category === 'support' ? '월 ' : ''}₩${value.cost}M</span> | |
</div> | |
`; | |
} else { | |
// 복수 선택 항목 | |
Object.values(value).forEach(item => { | |
initialCost += item.cost; | |
maxTime = Math.max(maxTime, item.time); | |
componentListHTML += ` | |
<div class="component-list-item"> | |
<span><strong>${categoryNames[category]}</strong>: ${item.name}</span> | |
<span>₩${item.cost}M</span> | |
</div> | |
`; | |
}); | |
} | |
}); | |
// 월별 운영 비용 계산 | |
const serverCost = Math.round(initialCost * 0.02); // 초기 비용의 2% | |
const apiCost = Math.round(initialCost * 0.03); // 초기 비용의 3% | |
const maintenanceCost = Math.round(initialCost * 0.01); // 초기 비용의 1% | |
const totalMonthly = serverCost + apiCost + maintenanceCost + monthlySupport; | |
// 총 비용 계산 (기간별) | |
const totalCost = initialCost + (totalMonthly * currentPeriod); | |
// 개발 기간 조정 (최소 3개월) | |
const adjustedTime = Math.max(3, Math.ceil(maxTime)); | |
// 결과 표시 | |
document.getElementById('initialCost').textContent = `₩${initialCost}M`; | |
document.getElementById('devTime').textContent = `${adjustedTime}개월`; | |
document.getElementById('totalCost').textContent = `₩${totalCost}M`; | |
document.getElementById('periodText').textContent = currentPeriod; | |
document.getElementById('componentList').innerHTML = componentListHTML; | |
// 타임라인 업데이트 | |
const progressPercent = Math.min(100, (adjustedTime / 12) * 100); | |
document.getElementById('timelineProgress').style.width = `${progressPercent}%`; | |
document.getElementById('progressText').textContent = `${Math.round(progressPercent)}%`; | |
document.getElementById('timelineText').textContent = `${adjustedTime}개월`; | |
// 월별 비용 표시 | |
document.getElementById('serverCost').textContent = `₩${serverCost}M`; | |
document.getElementById('apiCost').textContent = `₩${apiCost}M`; | |
document.getElementById('maintenanceCost').textContent = `₩${maintenanceCost}M`; | |
document.getElementById('totalMonthlyCost').textContent = `₩${totalMonthly}M`; | |
} | |
// 기존 비용 계산 함수 | |
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> |