money-briefing-analyzer.html•209 kB
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>머니브리핑 타겟팅 분석 서비스</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
min-height: 100vh;
padding: 20px;
}
.container {
max-width: 1400px;
margin: 0 auto;
background: white;
border-radius: 20px;
box-shadow: 0 20px 40px rgba(0,0,0,0.1);
overflow: hidden;
}
.header {
background: linear-gradient(135deg, #4CAF50 0%, #45a049 100%);
color: white;
padding: 30px;
text-align: center;
}
.header h1 {
font-size: 2.5em;
margin-bottom: 10px;
}
.header p {
font-size: 1.2em;
opacity: 0.9;
}
.tab-navigation {
display: flex;
background: #f8f9fa;
border-bottom: 2px solid #e9ecef;
}
.tab-button {
flex: 1;
padding: 20px;
background: none;
border: none;
font-size: 16px;
font-weight: 500;
cursor: pointer;
transition: all 0.3s ease;
color: #6c757d;
}
.tab-button.active {
background: white;
color: #4CAF50;
border-bottom: 3px solid #4CAF50;
}
.tab-button:hover {
background: #e9ecef;
}
.tab-content {
display: none;
padding: 30px;
min-height: 600px;
}
.tab-content.active {
display: block;
}
/* 브리핑 소재 탭 스타일 */
.briefing-stats {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 20px;
margin-bottom: 30px;
}
.stat-card {
background: linear-gradient(135deg, #e3f2fd 0%, #f3e5f5 100%);
padding: 20px;
border-radius: 15px;
text-align: center;
border-left: 5px solid #4CAF50;
}
.stat-number {
font-size: 2em;
font-weight: bold;
color: #2c3e50;
margin-bottom: 5px;
}
.stat-label {
color: #6c757d;
font-size: 14px;
}
.filter-section {
margin-bottom: 30px;
padding: 20px;
background: #f8f9fa;
border-radius: 15px;
}
.filter-buttons {
display: flex;
flex-wrap: wrap;
gap: 10px;
margin-bottom: 15px;
}
.filter-btn {
padding: 8px 16px;
border: 2px solid #e9ecef;
background: white;
border-radius: 20px;
cursor: pointer;
transition: all 0.3s ease;
font-size: 14px;
}
.filter-btn.active {
background: #4CAF50;
color: white;
border-color: #4CAF50;
}
.search-box {
margin-top: 15px;
}
.search-input {
width: 100%;
padding: 12px 20px;
border: 2px solid #e9ecef;
border-radius: 25px;
font-size: 16px;
outline: none;
transition: border-color 0.3s ease;
}
.search-input:focus {
border-color: #4CAF50;
}
.briefing-cards {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(400px, 1fr));
gap: 20px;
}
.briefing-card {
background: white;
border: 2px solid #e9ecef;
border-radius: 15px;
padding: 20px;
transition: all 0.3s ease;
cursor: pointer;
}
.briefing-card:hover {
border-color: #4CAF50;
transform: translateY(-2px);
box-shadow: 0 8px 25px rgba(0,0,0,0.1);
}
.briefing-header {
display: flex;
justify-content: space-between;
align-items: flex-start;
margin-bottom: 15px;
}
.briefing-title {
font-size: 18px;
font-weight: 600;
color: #2c3e50;
flex: 1;
margin-right: 10px;
}
.status-badge {
padding: 4px 12px;
border-radius: 15px;
font-size: 12px;
font-weight: 500;
}
.status-active {
background: #d4edda;
color: #155724;
}
.status-inactive {
background: #f8d7da;
color: #721c24;
}
.briefing-meta {
display: flex;
gap: 15px;
margin-bottom: 10px;
font-size: 14px;
color: #6c757d;
}
.briefing-category {
background: #e9ecef;
padding: 4px 8px;
border-radius: 10px;
font-size: 12px;
}
.briefing-details {
display: none;
margin-top: 20px;
padding-top: 20px;
border-top: 2px solid #f8f9fa;
}
.briefing-details.show {
display: block;
}
.detail-section {
margin-bottom: 15px;
}
.detail-label {
font-weight: 600;
color: #495057;
margin-bottom: 5px;
}
.detail-content {
color: #6c757d;
line-height: 1.5;
}
/* CDP 탭 스타일 */
.cdp-search {
margin-bottom: 30px;
}
.query-input-container {
display: flex;
gap: 15px;
margin-bottom: 20px;
}
.query-input {
flex: 1;
padding: 15px 20px;
border: 2px solid #e9ecef;
border-radius: 25px;
font-size: 16px;
outline: none;
transition: border-color 0.3s ease;
}
.query-input:focus {
border-color: #4CAF50;
}
.query-button {
padding: 15px 30px;
background: #4CAF50;
color: white;
border: none;
border-radius: 25px;
font-size: 16px;
font-weight: 500;
cursor: pointer;
transition: background 0.3s ease;
}
.query-button:hover {
background: #45a049;
}
.example-queries {
display: flex;
flex-wrap: wrap;
gap: 10px;
}
.example-tag {
padding: 8px 15px;
background: #f8f9fa;
border: 2px solid #e9ecef;
border-radius: 20px;
cursor: pointer;
font-size: 14px;
transition: all 0.3s ease;
}
.example-tag:hover {
background: #4CAF50;
color: white;
border-color: #4CAF50;
}
.cdp-columns {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
gap: 20px;
}
.column-card {
background: white;
border: 2px solid #e9ecef;
border-radius: 15px;
padding: 15px;
transition: all 0.3s ease;
}
.column-card:hover {
border-color: #4CAF50;
transform: translateY(-2px);
}
.column-name {
font-weight: 600;
color: #2c3e50;
margin-bottom: 8px;
font-size: 14px;
}
.column-description {
color: #6c757d;
font-size: 13px;
line-height: 1.4;
}
.column-category {
display: inline-block;
padding: 2px 8px;
background: #e9ecef;
border-radius: 10px;
font-size: 11px;
margin-bottom: 8px;
}
.loading {
text-align: center;
padding: 40px;
display: none;
}
.spinner {
border: 4px solid #f3f3f3;
border-top: 4px solid #4CAF50;
border-radius: 50%;
width: 50px;
height: 50px;
animation: spin 1s linear infinite;
margin: 0 auto 20px;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
.results-container {
margin-top: 30px;
padding: 20px;
background: #f8f9fa;
border-radius: 15px;
display: none;
}
.results-container.show {
display: block;
}
.recommendation-card {
background: white;
border-left: 5px solid #4CAF50;
padding: 20px;
margin-bottom: 15px;
border-radius: 10px;
}
.recommendation-title {
font-weight: 600;
color: #2c3e50;
margin-bottom: 10px;
}
.recommendation-content {
color: #6c757d;
}
/* 추가 UI 개선 스타일 */
.copy-button {
background: #4CAF50;
color: white;
border: none;
padding: 5px 10px;
border-radius: 5px;
cursor: pointer;
font-size: 12px;
margin-left: 10px;
transition: background 0.3s ease;
}
.copy-button:hover {
background: #45a049;
}
.tooltip {
position: relative;
display: inline-block;
}
.tooltip .tooltiptext {
visibility: hidden;
width: 140px;
background-color: #555;
color: #fff;
text-align: center;
border-radius: 6px;
padding: 5px;
position: absolute;
z-index: 1;
bottom: 125%;
left: 50%;
margin-left: -70px;
opacity: 0;
transition: opacity 0.3s;
font-size: 12px;
}
.tooltip:hover .tooltiptext {
visibility: visible;
opacity: 1;
}
.highlight {
background-color: #fff3cd;
padding: 2px 4px;
border-radius: 3px;
font-weight: 500;
}
.quick-stats {
display: flex;
gap: 15px;
margin-bottom: 20px;
font-size: 14px;
color: #6c757d;
}
.quick-stat {
display: flex;
align-items: center;
gap: 5px;
}
.export-button {
background: #17a2b8;
color: white;
border: none;
padding: 10px 20px;
border-radius: 20px;
cursor: pointer;
font-size: 14px;
margin-left: 15px;
transition: background 0.3s ease;
}
.export-button:hover {
background: #138496;
}
/* 분석 모드 선택 스타일 */
.analysis-mode-container {
display: flex;
align-items: center;
gap: 15px;
margin: 20px 0;
padding: 15px;
background: #f8f9fa;
border-radius: 10px;
}
.analysis-mode-label {
font-weight: 600;
color: #495057;
font-size: 14px;
}
.analysis-mode-buttons {
display: flex;
gap: 10px;
}
.mode-btn {
padding: 12px 20px;
border: 2px solid #e9ecef;
background: white;
border-radius: 10px;
cursor: pointer;
transition: all 0.3s ease;
font-size: 14px;
font-weight: 500;
display: flex;
flex-direction: column;
align-items: center;
gap: 5px;
min-width: 140px;
}
.mode-btn:hover {
border-color: #4CAF50;
background: #f8fff8;
}
.mode-btn.active {
border-color: #4CAF50;
background: #4CAF50;
color: white;
}
.mode-desc {
font-size: 12px;
opacity: 0.8;
font-weight: 400;
}
/* 반응형 디자인 */
@media (max-width: 768px) {
.container {
margin: 10px;
border-radius: 15px;
}
.header {
padding: 20px;
}
.header h1 {
font-size: 1.8em;
}
.tab-content {
padding: 20px;
}
.briefing-cards {
grid-template-columns: 1fr;
}
.cdp-columns {
grid-template-columns: 1fr;
}
.query-input-container {
flex-direction: column;
}
}
/* 브리핑 생성 탭 스타일 */
.generator-header {
text-align: center;
margin-bottom: 30px;
}
.generator-header h2 {
color: #4CAF50;
margin-bottom: 10px;
}
.generator-header p {
color: #6c757d;
font-size: 16px;
}
.generator-input-section {
background: #f8f9fa;
border-radius: 15px;
padding: 30px;
margin-bottom: 30px;
}
.generator-input-container {
display: flex;
gap: 15px;
margin-bottom: 20px;
}
.generator-input {
flex: 1;
padding: 15px;
border: 2px solid #e9ecef;
border-radius: 10px;
font-size: 16px;
font-family: inherit;
resize: vertical;
min-height: 80px;
}
.generator-input:focus {
outline: none;
border-color: #4CAF50;
box-shadow: 0 0 0 3px rgba(76, 175, 80, 0.1);
}
.generator-button {
background: linear-gradient(135deg, #4CAF50 0%, #45a049 100%);
color: white;
border: none;
padding: 15px 25px;
border-radius: 10px;
font-size: 16px;
font-weight: 600;
cursor: pointer;
transition: all 0.3s ease;
white-space: nowrap;
}
.generator-button:hover {
background: linear-gradient(135deg, #45a049 0%, #3d8b40 100%);
transform: translateY(-2px);
box-shadow: 0 5px 15px rgba(76, 175, 80, 0.3);
}
.generator-examples {
border-top: 1px solid #e9ecef;
padding-top: 20px;
}
.example-category {
margin-bottom: 15px;
}
.example-category strong {
color: #495057;
margin-right: 10px;
}
.generator-results {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(450px, 1fr));
gap: 20px;
margin-top: 20px;
}
.generated-briefing-card {
background: white;
border-radius: 15px;
padding: 25px;
box-shadow: 0 5px 15px rgba(0,0,0,0.1);
border-left: 5px solid #4CAF50;
transition: all 0.3s ease;
}
.generated-briefing-card:hover {
transform: translateY(-5px);
box-shadow: 0 10px 25px rgba(0,0,0,0.15);
}
.generated-briefing-header {
display: flex;
justify-content: space-between;
align-items: flex-start;
margin-bottom: 15px;
}
.generated-briefing-title {
font-size: 18px;
font-weight: 600;
color: #2c3e50;
flex: 1;
}
.generated-briefing-category {
background: linear-gradient(135deg, #e3f2fd 0%, #f3e5f5 100%);
color: #4CAF50;
padding: 5px 12px;
border-radius: 20px;
font-size: 12px;
font-weight: 500;
margin-left: 10px;
}
.generated-briefing-content {
background: #f8f9fa;
padding: 15px;
border-radius: 10px;
margin-bottom: 15px;
line-height: 1.6;
}
.generated-briefing-meta {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 15px;
margin-bottom: 15px;
}
.generated-briefing-field {
background: #f8f9fa;
padding: 10px;
border-radius: 8px;
}
.generated-briefing-label {
font-size: 12px;
font-weight: 600;
color: #6c757d;
margin-bottom: 5px;
}
.generated-briefing-value {
font-size: 14px;
color: #2c3e50;
}
.generated-briefing-reason {
background: #e8f5e8;
padding: 15px;
border-radius: 10px;
border-left: 4px solid #4CAF50;
}
.generated-briefing-reason-title {
font-size: 14px;
font-weight: 600;
color: #2c3e50;
margin-bottom: 8px;
}
.generated-briefing-reason-content {
font-size: 13px;
color: #495057;
line-height: 1.5;
}
.loading-progress {
width: 100%;
background: #e9ecef;
border-radius: 10px;
overflow: hidden;
margin-top: 20px;
}
.progress-bar {
height: 6px;
background: #e9ecef;
border-radius: 3px;
overflow: hidden;
position: relative;
}
.progress-fill {
height: 100%;
background: linear-gradient(90deg, #4CAF50, #45a049);
width: 0%;
border-radius: 3px;
animation: progressAnimation 3s ease-in-out infinite;
}
@keyframes progressAnimation {
0% { width: 0%; }
50% { width: 70%; }
100% { width: 100%; }
}
/* 자산 변동 브리핑 탭 스타일 */
.asset-header {
text-align: center;
margin-bottom: 30px;
}
.asset-header h2 {
color: #4CAF50;
margin-bottom: 10px;
}
.asset-header p {
color: #6c757d;
font-size: 16px;
}
.asset-input-section {
background: #f8f9fa;
border-radius: 15px;
padding: 30px;
margin-bottom: 30px;
}
.asset-input-section h3 {
color: #2c3e50;
margin-bottom: 20px;
text-align: center;
}
.asset-form-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 30px;
margin-bottom: 30px;
}
.asset-category {
background: white;
border-radius: 15px;
padding: 20px;
border: 2px solid #e9ecef;
transition: all 0.3s ease;
}
.asset-category:hover {
border-color: #4CAF50;
transform: translateY(-2px);
box-shadow: 0 8px 25px rgba(0,0,0,0.1);
}
.asset-category h4 {
color: #4CAF50;
margin-bottom: 15px;
text-align: center;
font-size: 16px;
}
.input-group {
margin-bottom: 15px;
}
.input-group label {
display: block;
margin-bottom: 5px;
color: #495057;
font-weight: 500;
font-size: 14px;
}
.input-group input {
width: 100%;
padding: 12px;
border: 2px solid #e9ecef;
border-radius: 8px;
font-size: 16px;
transition: border-color 0.3s ease;
}
.input-group input:focus {
outline: none;
border-color: #4CAF50;
}
.asset-actions {
display: flex;
gap: 20px;
justify-content: center;
flex-wrap: wrap;
}
.asset-calculate-btn, .asset-generate-btn {
padding: 15px 30px;
border: none;
border-radius: 25px;
font-size: 16px;
font-weight: 500;
cursor: pointer;
transition: all 0.3s ease;
min-width: 200px;
}
.asset-calculate-btn {
background: #17a2b8;
color: white;
}
.asset-calculate-btn:hover {
background: #138496;
transform: translateY(-2px);
}
.asset-generate-btn {
background: #4CAF50;
color: white;
}
.asset-generate-btn:hover {
background: #45a049;
transform: translateY(-2px);
}
.asset-summary {
background: #f8f9fa;
border-radius: 15px;
padding: 30px;
margin-bottom: 30px;
border-left: 5px solid #4CAF50;
}
.asset-summary h3 {
color: #2c3e50;
margin-bottom: 20px;
text-align: center;
}
.summary-cards {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 20px;
}
.summary-card {
background: white;
border-radius: 15px;
padding: 20px;
text-align: center;
border: 2px solid #e9ecef;
transition: all 0.3s ease;
}
.summary-card:hover {
transform: translateY(-2px);
box-shadow: 0 8px 25px rgba(0,0,0,0.1);
}
.summary-card.total {
border-color: #4CAF50;
}
.summary-card.positive {
border-color: #28a745;
}
.summary-card.negative {
border-color: #dc3545;
}
.summary-title {
font-size: 14px;
color: #6c757d;
margin-bottom: 10px;
font-weight: 500;
}
.summary-value {
font-size: 18px;
font-weight: bold;
color: #2c3e50;
margin-bottom: 5px;
}
.summary-rate {
font-size: 16px;
font-weight: 600;
}
.summary-card.total .summary-rate {
color: #4CAF50;
}
.summary-card.positive .summary-rate {
color: #28a745;
}
.summary-card.negative .summary-rate {
color: #dc3545;
}
.asset-briefings-results {
margin-top: 30px;
}
.asset-briefing-card {
border-left: 5px solid #4CAF50;
}
.landing-page-btn {
background: #4CAF50;
color: white;
border: none;
padding: 8px 16px;
border-radius: 20px;
cursor: pointer;
font-size: 14px;
transition: all 0.3s ease;
}
.landing-page-btn:hover {
background: #45a049;
transform: translateY(-1px);
}
.landing-page-info {
background: #e3f2fd;
border-radius: 10px;
padding: 15px;
margin-top: 15px;
}
.landing-page-label {
font-weight: 600;
color: #1976d2;
margin-bottom: 8px;
font-size: 14px;
}
.landing-page-details {
font-size: 13px;
color: #495057;
}
.landing-page-details div {
margin-bottom: 5px;
}
/* 반응형 디자인 - 자산 탭 */
@media (max-width: 768px) {
.asset-form-grid {
grid-template-columns: 1fr;
gap: 20px;
}
.asset-actions {
flex-direction: column;
align-items: center;
}
.asset-calculate-btn, .asset-generate-btn {
min-width: 250px;
}
.summary-cards {
grid-template-columns: 1fr;
}
}
/* 랜딩 페이지 모달 스타일 */
.modal {
position: fixed;
z-index: 1000;
left: 0;
top: 0;
width: 100%;
height: 100%;
background-color: rgba(0,0,0,0.5);
backdrop-filter: blur(5px);
}
.modal-content {
background-color: white;
margin: 5% auto;
padding: 0;
border-radius: 20px;
width: 90%;
max-width: 900px;
max-height: 80vh;
overflow-y: auto;
box-shadow: 0 20px 40px rgba(0,0,0,0.2);
animation: modalSlideIn 0.3s ease-out;
}
@keyframes modalSlideIn {
from {
opacity: 0;
transform: translateY(-50px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.modal-header {
background: linear-gradient(135deg, #4CAF50 0%, #45a049 100%);
color: white;
padding: 20px 30px;
border-radius: 20px 20px 0 0;
display: flex;
justify-content: space-between;
align-items: center;
}
.modal-header h2 {
margin: 0;
font-size: 1.5em;
}
.close {
color: white;
font-size: 28px;
font-weight: bold;
cursor: pointer;
transition: color 0.3s ease;
}
.close:hover {
color: #f0f0f0;
}
.modal-body {
padding: 30px;
}
.chart-container {
background: #f8f9fa;
border-radius: 15px;
padding: 20px;
margin: 20px 0;
text-align: center;
border: 2px solid #e9ecef;
}
.chart-placeholder {
width: 100%;
height: 200px;
background: linear-gradient(45deg, #e3f2fd, #f3e5f5);
border-radius: 10px;
display: flex;
align-items: center;
justify-content: center;
color: #6c757d;
font-size: 16px;
margin-bottom: 10px;
}
.insight-card {
background: white;
border: 2px solid #e9ecef;
border-radius: 15px;
padding: 20px;
margin: 15px 0;
border-left: 5px solid #4CAF50;
}
.insight-title {
font-weight: 600;
color: #4CAF50;
margin-bottom: 10px;
}
.insight-content {
color: #495057;
line-height: 1.5;
}
.modal-stats {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 20px;
margin: 20px 0;
}
.modal-stat-card {
background: linear-gradient(135deg, #e3f2fd, #f3e5f5);
border-radius: 15px;
padding: 20px;
text-align: center;
}
.modal-stat-value {
font-size: 24px;
font-weight: bold;
color: #4CAF50;
margin-bottom: 5px;
}
.modal-stat-label {
color: #6c757d;
font-size: 14px;
}
/* 모달 반응형 */
@media (max-width: 768px) {
.modal-content {
width: 95%;
margin: 10% auto;
max-height: 85vh;
}
.modal-header {
padding: 15px 20px;
}
.modal-body {
padding: 20px;
}
.modal-stats {
grid-template-columns: 1fr;
}
}
/* AI 브리핑 아이디어 섹션 스타일 */
.ai-ideas-section {
background: #f8f9fa;
border-radius: 15px;
padding: 30px;
margin-top: 30px;
border-left: 5px solid #ff6b35;
}
.ai-ideas-header {
text-align: center;
margin-bottom: 30px;
}
.ai-ideas-header h2 {
color: #ff6b35;
margin-bottom: 10px;
}
.ai-ideas-header p {
color: #6c757d;
font-size: 16px;
}
.user-profile-section {
background: white;
border-radius: 15px;
padding: 25px;
margin-bottom: 30px;
border: 2px solid #e9ecef;
}
.user-profile-section h3 {
color: #2c3e50;
margin-bottom: 20px;
text-align: center;
}
.profile-form {
margin-bottom: 25px;
}
.profile-row {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 20px;
margin-bottom: 20px;
}
.profile-group {
display: flex;
flex-direction: column;
}
.profile-group label {
margin-bottom: 8px;
font-weight: 600;
color: #495057;
font-size: 14px;
}
.profile-group select {
padding: 12px;
border: 2px solid #e9ecef;
border-radius: 8px;
font-size: 14px;
transition: border-color 0.3s ease;
background: white;
}
.profile-group select:focus {
outline: none;
border-color: #ff6b35;
}
.profile-actions {
text-align: center;
}
.generate-ideas-btn {
background: linear-gradient(135deg, #ff6b35, #f7931e);
color: white;
border: none;
padding: 15px 30px;
border-radius: 25px;
font-size: 16px;
font-weight: 500;
cursor: pointer;
transition: all 0.3s ease;
min-width: 250px;
}
.generate-ideas-btn:hover {
transform: translateY(-2px);
box-shadow: 0 8px 25px rgba(255, 107, 53, 0.3);
}
.ideas-results {
margin-top: 30px;
}
.idea-card {
background: white;
border-radius: 15px;
padding: 25px;
margin-bottom: 20px;
border: 2px solid #e9ecef;
border-left: 5px solid #ff6b35;
transition: all 0.3s ease;
}
.idea-card:hover {
transform: translateY(-2px);
box-shadow: 0 8px 25px rgba(0,0,0,0.1);
border-color: #ff6b35;
}
.idea-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 15px;
}
.idea-title {
font-size: 18px;
font-weight: 600;
color: #2c3e50;
}
.idea-category {
background: linear-gradient(135deg, #ff6b35, #f7931e);
color: white;
padding: 4px 12px;
border-radius: 15px;
font-size: 12px;
font-weight: 500;
}
.idea-description {
color: #495057;
line-height: 1.6;
margin-bottom: 15px;
}
.idea-features {
background: #f8f9fa;
border-radius: 10px;
padding: 15px;
margin-bottom: 15px;
}
.idea-features h4 {
color: #ff6b35;
margin-bottom: 10px;
font-size: 14px;
}
.idea-features ul {
list-style: none;
padding: 0;
margin: 0;
}
.idea-features li {
padding: 3px 0;
color: #6c757d;
font-size: 13px;
}
.idea-features li:before {
content: "▪ ";
color: #ff6b35;
font-weight: bold;
}
.idea-actions {
display: flex;
gap: 10px;
justify-content: flex-end;
}
.implement-idea-btn {
background: #ff6b35;
color: white;
border: none;
padding: 8px 16px;
border-radius: 20px;
font-size: 13px;
cursor: pointer;
transition: all 0.3s ease;
}
.implement-idea-btn:hover {
background: #e55a2b;
transform: translateY(-1px);
}
.rate-idea-btn {
background: transparent;
color: #6c757d;
border: 2px solid #e9ecef;
padding: 8px 16px;
border-radius: 20px;
font-size: 13px;
cursor: pointer;
transition: all 0.3s ease;
}
.rate-idea-btn:hover {
border-color: #ff6b35;
color: #ff6b35;
}
.ai-ideas-toggle {
text-align: center;
margin: 30px 0;
}
/* 프로필 폼 반응형 */
@media (max-width: 768px) {
.profile-row {
grid-template-columns: 1fr;
gap: 15px;
}
.generate-ideas-btn {
min-width: 100%;
}
.idea-header {
flex-direction: column;
align-items: flex-start;
gap: 10px;
}
.idea-actions {
flex-direction: column;
gap: 8px;
}
.implement-idea-btn,
.rate-idea-btn {
width: 100%;
}
}
</style>
</head>
<body>
<div class="container">
<div class="header">
<div style="display: flex; justify-content: space-between; align-items: center;">
<div>
<h1>💰 머니브리핑 타겟팅 분석 서비스</h1>
<p>네이버페이 머니브리핑 소재별 고객 타겟팅 최적화를 위한 분석 도구</p>
</div>
<button class="export-button" onclick="exportBriefingData()">
📊 데이터 내보내기
</button>
</div>
</div>
<div class="tab-navigation">
<button class="tab-button active" onclick="switchTab('briefings')">
📋 브리핑 소재 분석
</button>
<button class="tab-button" onclick="switchTab('cdp')">
🎯 CDP 기반 타겟팅
</button>
<button class="tab-button" onclick="switchTab('generator')">
✨ 브리핑 생성
</button>
<button class="tab-button" onclick="switchTab('asset')">
💰 자산 변동 브리핑
</button>
</div>
<!-- 브리핑 소재 분석 탭 -->
<div class="tab-content active" id="briefings-tab">
<div class="briefing-stats">
<div class="stat-card">
<div class="stat-number" id="totalBriefings">67</div>
<div class="stat-label">총 브리핑 소재</div>
</div>
<div class="stat-card">
<div class="stat-number" id="activeBriefings">45</div>
<div class="stat-label">현재 노출 중</div>
</div>
<div class="stat-card">
<div class="stat-number" id="inactiveBriefings">22</div>
<div class="stat-label">노출 예정</div>
</div>
<div class="stat-card">
<div class="stat-number" id="completedBriefings">57</div>
<div class="stat-label">개발 완료</div>
</div>
</div>
<div class="filter-section">
<div class="filter-buttons">
<button class="filter-btn active" onclick="filterBriefings('all')">전체</button>
<button class="filter-btn" onclick="filterBriefings('생활과 연관된 돈')">생활과 연관된 돈</button>
<button class="filter-btn" onclick="filterBriefings('불린 돈')">불린 돈</button>
<button class="filter-btn" onclick="filterBriefings('빌린 돈')">빌린 돈</button>
<button class="filter-btn" onclick="filterBriefings('나간 돈')">나간 돈</button>
<button class="filter-btn" onclick="filterBriefings('들어오는 돈')">들어오는 돈</button>
<button class="filter-btn" onclick="filterBriefings('미래를 위한 돈')">미래를 위한 돈</button>
<button class="filter-btn" onclick="filterBriefings('경제/자산컨텐츠')">경제/자산컨텐츠</button>
</div>
<div class="search-box">
<input type="text" class="search-input" placeholder="브리핑 제목이나 내용으로 검색..." onkeyup="searchBriefings(this.value)">
</div>
</div>
<div class="briefing-cards" id="briefingCards">
<!-- 브리핑 카드들이 여기에 동적으로 생성됩니다 -->
</div>
</div>
<!-- CDP 기반 타겟팅 탭 -->
<div class="tab-content" id="cdp-tab">
<div class="cdp-search">
<div class="query-input-container">
<input type="text" class="query-input" id="queryInput"
placeholder="예: 대출 니즈가 높은 20-30대 여성 고객을 찾아주세요">
<button class="query-button" onclick="analyzeQuery()">🔍 분석</button>
</div>
<!-- 분석 모드 선택 -->
<div class="analysis-mode-container">
<div class="analysis-mode-label">분석 모드:</div>
<div class="analysis-mode-buttons">
<button class="mode-btn active" id="keywordMode" onclick="setAnalysisMode('keyword')">
🔤 키워드 기반
<span class="mode-desc">빠르고 간단한 분석</span>
</button>
<button class="mode-btn" id="llmMode" onclick="setAnalysisMode('llm')">
🤖 LLM 기반
<span class="mode-desc">정확하고 상세한 분석</span>
</button>
</div>
</div>
<div class="example-queries">
<div class="example-tag" onclick="setExampleQuery('대출 니즈가 높은 고객군')">💰 대출 니즈 고객</div>
<div class="example-tag" onclick="setExampleQuery('20-30대 여성 중 뷰티에 관심이 많은 고객')">💄 뷰티 관심 여성</div>
<div class="example-tag" onclick="setExampleQuery('고소득층 중 투자 상품에 관심있는 고객')">📈 투자 관심 고객</div>
<div class="example-tag" onclick="setExampleQuery('해외여행을 자주 가는 고객')">✈️ 해외여행 고객</div>
<div class="example-tag" onclick="setExampleQuery('1인 가구 중 배달음식을 자주 시키는 고객')">🏠 1인가구 배달족</div>
<div class="example-tag" onclick="setExampleQuery('골프를 치는 프리미엄 고객')">⛳ 골프 VIP</div>
</div>
</div>
<div class="loading" id="loadingSection">
<div class="spinner"></div>
<p>🤖 CDP 데이터를 분석하여 최적의 고객 세그먼트를 찾고 있습니다...</p>
</div>
<div class="results-container" id="resultsContainer">
<div id="analysisResults"></div>
</div>
<div class="filter-section">
<h3>📊 CDP 컬럼 브라우저</h3>
<div class="filter-buttons">
<button class="filter-btn active" onclick="filterColumns('all')">전체</button>
<button class="filter-btn" onclick="filterColumns('interests')">관심사 지표</button>
<button class="filter-btn" onclick="filterColumns('industries')">업종별 지표</button>
<button class="filter-btn" onclick="filterColumns('scores')">예측 스코어</button>
<button class="filter-btn" onclick="filterColumns('flags')">플래그 지표</button>
</div>
<div class="search-box">
<input type="text" class="search-input" placeholder="컬럼명이나 설명으로 검색..." onkeyup="searchColumns(this.value)">
</div>
</div>
<div class="cdp-columns" id="cdpColumns">
<!-- CDP 컬럼들이 여기에 동적으로 생성됩니다 -->
</div>
</div>
<!-- 브리핑 생성 탭 -->
<div class="tab-content" id="generator-tab">
<div class="generator-header">
<h2>✨ 새로운 브리핑 소재 생성</h2>
<p>아이디어나 키워드를 입력하면 AI가 6개의 새로운 머니브리핑 소재를 생성해드립니다.</p>
</div>
<div class="generator-input-section">
<div class="generator-input-container">
<textarea class="generator-input" id="generatorInput" rows="3"
placeholder="예: 겨울철 난방비 절약을 위한 브리핑 소재를 만들어주세요 혹은: 20-30대 직장인을 위한 연말정산 관련 브리핑"></textarea>
<button class="generator-button" onclick="generateBriefings()">
🚀 브리핑 생성하기
</button>
</div>
<div class="generator-examples">
<div class="example-category">
<strong>💡 예시 아이디어:</strong>
<div class="example-tag" onclick="setGeneratorExample('20-30대 직장인을 위한 연말정산 관련 브리핑')">📊 연말정산</div>
<div class="example-tag" onclick="setGeneratorExample('겨울철 난방비 절약을 위한 브리핑')">🔥 난방비 절약</div>
<div class="example-tag" onclick="setGeneratorExample('신혼부부를 위한 주택 관련 브리핑')">🏠 신혼부부 주택</div>
<div class="example-tag" onclick="setGeneratorExample('대학생을 위한 용돈 관리 브리핑')">🎓 대학생 용돈</div>
<div class="example-tag" onclick="setGeneratorExample('중년층을 위한 노후 준비 브리핑')">👴 노후 준비</div>
<div class="example-tag" onclick="setGeneratorExample('1인 가구를 위한 절약 브리핑')">🏠 1인가구 절약</div>
</div>
</div>
</div>
<!-- 로딩 섹션 -->
<div class="loading-section" id="generatorLoadingSection" style="display: none;">
<div class="loading-spinner">🤖</div>
<p>AI가 새로운 브리핑 소재를 생성하고 있습니다...</p>
<div class="loading-progress">
<div class="progress-bar">
<div class="progress-fill"></div>
</div>
</div>
</div>
<!-- 생성 결과 -->
<div class="generator-results" id="generatorResults">
<!-- 생성된 브리핑들이 여기에 표시됩니다 -->
</div>
</div>
<!-- 자산 변동 브리핑 탭 -->
<div class="tab-content" id="asset-tab">
<div class="asset-header">
<h2>💰 자산 변동 브리핑</h2>
<p>개인 자산 데이터를 입력하고 AI가 맞춤형 자산 변동 브리핑을 생성해드립니다.</p>
</div>
<!-- 자산 데이터 입력 섹션 -->
<div class="asset-input-section">
<h3>자산 데이터 입력</h3>
<div class="asset-form-grid">
<div class="asset-category">
<h4>💳 은행 자산</h4>
<div class="input-group">
<label>현재 은행 잔액 (만원)</label>
<input type="number" id="currBankValue" placeholder="5,000" value="5000">
</div>
<div class="input-group">
<label>전일 은행 잔액 (만원)</label>
<input type="number" id="prevBankValue" placeholder="4,800" value="4800">
</div>
</div>
<div class="asset-category">
<h4>📈 증권 자산</h4>
<div class="input-group">
<label>현재 증권 평가액 (만원)</label>
<input type="number" id="currStockValue" placeholder="8,000" value="8000">
</div>
<div class="input-group">
<label>전일 증권 평가액 (만원)</label>
<input type="number" id="prevStockValue" placeholder="7,500" value="7500">
</div>
</div>
<div class="asset-category">
<h4>🏠 부동산 자산</h4>
<div class="input-group">
<label>현재 부동산 시세 (만원)</label>
<input type="number" id="currRealestateValue" placeholder="50,000" value="50000">
</div>
<div class="input-group">
<label>전일 부동산 시세 (만원)</label>
<input type="number" id="prevRealestateValue" placeholder="49,500" value="49500">
</div>
</div>
<div class="asset-category">
<h4>🎯 연금/IRP</h4>
<div class="input-group">
<label>현재 연금 평가액 (만원)</label>
<input type="number" id="currPensionValue" placeholder="3,000" value="3000">
</div>
<div class="input-group">
<label>전일 연금 평가액 (만원)</label>
<input type="number" id="prevPensionValue" placeholder="2,950" value="2950">
</div>
</div>
<div class="asset-category">
<h4>💸 대출/카드</h4>
<div class="input-group">
<label>현재 대출 잔액 (만원)</label>
<input type="number" id="currLoanBalance" placeholder="15,000" value="15000">
</div>
<div class="input-group">
<label>전일 대출 잔액 (만원)</label>
<input type="number" id="prevLoanBalance" placeholder="15,100" value="15100">
</div>
<div class="input-group">
<label>현재 카드 청구액 (만원)</label>
<input type="number" id="currCardPaymentDue" placeholder="150" value="150">
</div>
<div class="input-group">
<label>전일 카드 청구액 (만원)</label>
<input type="number" id="prevCardPaymentDue" placeholder="200" value="200">
</div>
</div>
<div class="asset-category">
<h4>🚗 기타 자산</h4>
<div class="input-group">
<label>현재 자동차 시세 (만원)</label>
<input type="number" id="currCarValue" placeholder="2,500" value="2500">
</div>
<div class="input-group">
<label>전일 자동차 시세 (만원)</label>
<input type="number" id="prevCarValue" placeholder="2,500" value="2500">
</div>
<div class="input-group">
<label>현재 포인트/머니 (만원)</label>
<input type="number" id="currPointmoneyValue" placeholder="50" value="50">
</div>
<div class="input-group">
<label>전일 포인트/머니 (만원)</label>
<input type="number" id="prevPointmoneyValue" placeholder="45" value="45">
</div>
</div>
</div>
<div class="asset-actions">
<button class="asset-calculate-btn" onclick="calculateAssetChanges()">
📊 자산 변동 계산하기
</button>
<button class="asset-generate-btn" onclick="generateAssetBriefings()">
🤖 AI 브리핑 생성하기
</button>
</div>
</div>
<!-- 자산 변동 요약 대시보드 -->
<div class="asset-summary" id="assetSummary" style="display: none;">
<h3>자산 변동 요약</h3>
<div class="summary-cards">
<div class="summary-card total">
<div class="summary-title">총 자산 변동</div>
<div class="summary-value" id="totalAssetChange">+1,205만원</div>
<div class="summary-rate" id="totalAssetChangeRate">+2.3%</div>
</div>
<div class="summary-card positive">
<div class="summary-title">가장 큰 증가</div>
<div class="summary-value" id="biggestIncrease">주식 +500만원</div>
<div class="summary-rate" id="biggestIncreaseRate">+6.7%</div>
</div>
<div class="summary-card negative">
<div class="summary-title">가장 큰 감소</div>
<div class="summary-value" id="biggestDecrease">카드청구 -50만원</div>
<div class="summary-rate" id="biggestDecreaseRate">-25%</div>
</div>
</div>
</div>
<!-- 로딩 섹션 -->
<div class="loading-section" id="assetLoadingSection" style="display: none;">
<div class="loading-spinner">💰</div>
<p>AI가 자산 변동을 분석하고 맞춤형 브리핑을 생성하고 있습니다...</p>
<div class="loading-progress">
<div class="progress-bar">
<div class="progress-fill"></div>
</div>
</div>
</div>
<!-- 생성된 자산 브리핑 결과 -->
<div class="asset-briefings-results" id="assetBriefingsResults">
<!-- 생성된 자산 브리핑들이 여기에 표시됩니다 -->
</div>
<!-- AI 브리핑 아이디어 섹션 -->
<div class="ai-ideas-section" id="aiIdeasSection" style="display: none;">
<div class="ai-ideas-header">
<h2>💡 AI 브리핑 아이디어</h2>
<p>당신의 자산 프로필을 분석하여 창의적이고 개인화된 브리핑 아이디어를 제안합니다.</p>
</div>
<!-- 사용자 프로필 입력 -->
<div class="user-profile-section">
<h3>👤 사용자 프로필 설정</h3>
<div class="profile-form">
<div class="profile-row">
<div class="profile-group">
<label>연령대</label>
<select id="userAge">
<option value="20s">20대</option>
<option value="30s" selected>30대</option>
<option value="40s">40대</option>
<option value="50s">50대</option>
<option value="60s+">60대 이상</option>
</select>
</div>
<div class="profile-group">
<label>직업군</label>
<select id="userJob">
<option value="office_worker" selected>직장인</option>
<option value="business_owner">사업자</option>
<option value="freelancer">프리랜서</option>
<option value="student">학생</option>
<option value="housewife">주부</option>
<option value="retiree">은퇴자</option>
</select>
</div>
<div class="profile-group">
<label>투자 성향</label>
<select id="investmentStyle">
<option value="conservative">안정형</option>
<option value="moderate" selected>중간형</option>
<option value="aggressive">적극형</option>
<option value="speculative">투기형</option>
</select>
</div>
</div>
<div class="profile-row">
<div class="profile-group">
<label>라이프스타일</label>
<select id="lifestyle">
<option value="frugal">절약형</option>
<option value="balanced" selected>균형형</option>
<option value="luxury">소비형</option>
<option value="minimalist">미니멀형</option>
</select>
</div>
<div class="profile-group">
<label>관심 분야</label>
<select id="interests">
<option value="tech" selected>IT/기술</option>
<option value="real_estate">부동산</option>
<option value="stocks">주식투자</option>
<option value="travel">여행</option>
<option value="education">교육</option>
<option value="health">건강</option>
</select>
</div>
<div class="profile-group">
<label>금융 목표</label>
<select id="financialGoal">
<option value="emergency_fund">비상자금 마련</option>
<option value="house_purchase">내집마련</option>
<option value="retirement" selected>노후준비</option>
<option value="wealth_building">자산증대</option>
<option value="debt_reduction">부채상환</option>
</select>
</div>
</div>
</div>
<div class="profile-actions">
<button class="generate-ideas-btn" onclick="generateCreativeIdeas()">
🧠 창의적 브리핑 아이디어 생성
</button>
</div>
</div>
<!-- 로딩 섹션 -->
<div class="loading-section" id="ideasLoadingSection" style="display: none;">
<div class="loading-spinner">🧠</div>
<p>AI가 당신만의 특별한 브리핑 아이디어를 고민하고 있습니다...</p>
<div class="loading-progress">
<div class="progress-bar">
<div class="progress-fill"></div>
</div>
</div>
</div>
<!-- 생성된 아이디어 결과 -->
<div class="ideas-results" id="ideasResults">
<!-- 생성된 아이디어들이 여기에 표시됩니다 -->
</div>
</div>
<!-- AI 아이디어 표시 버튼 -->
<div class="ai-ideas-toggle" style="text-align: center; margin: 30px 0;">
<button class="asset-generate-btn" onclick="toggleAiIdeasSection()">
💡 AI 브리핑 아이디어 보기
</button>
</div>
</div>
</div>
<!-- 랜딩 페이지 모달 -->
<div id="landingPageModal" class="modal" style="display: none;">
<div class="modal-content">
<div class="modal-header">
<h2 id="modalTitle">랜딩 페이지</h2>
<span class="close" onclick="closeLandingPage()">×</span>
</div>
<div class="modal-body" id="modalBody">
<!-- 동적으로 생성되는 랜딩 페이지 콘텐츠 -->
</div>
</div>
</div>
<script>
// 머니브리핑 데이터 (전체 67개)
const MONEY_BRIEFINGS = [
{"no": 1, "exposed": "O", "status": "완료", "type": "생활과 연관된 돈", "service": "내자산", "templateId": "expire_20250604150738", "title": "만기 연장 안내", "content": "28일전 : 00일 뒤에 자산연결이 종료돼요! 연장하지 않으면 자산확인이 어려워요.\n당일 : 오늘, 자산연결이 종료돼요! 연장하지 않으면 자산확인이 어려워요.", "button": "다시 연결하기", "target": "만기연장 자산이 있는 경우 15일 전에 브리핑 노출"},
{"no": 2, "exposed": "O", "status": "완료", "type": "생활과 연관된 돈", "service": "내자산", "templateId": "CARD_20250602123538", "title": "새 카드 발견", "content": "{카드명} 발급 완료! 내자산에 연결하고 이용내역 확인하세요.", "button": "새 카드 연결하기", "target": "새로운 카드 자산 발견 시"},
{"no": 3, "exposed": "O", "status": "완료", "type": "나간 돈", "service": "내자산", "templateId": "CARD_20250602124028", "title": "카드 청구서 도착", "content": "{청구월}월에 내야할 {금융사명} 결제금액은 {청구금액}원이에요.", "button": "청구서 확인하기", "target": "새로운 청구서 발행 시"},
{"no": 4, "exposed": "O", "status": "완료", "type": "나간 돈", "service": "내자산", "templateId": "CARD_20250602124341", "title": "카드 결제일", "content": "{청구금액}원이 오늘 내 계좌에서 빠져나갈 예정이에요.", "button": "청구서 확인하기", "target": "청구서의 결제일이 오늘일 경우"},
{"no": 5, "exposed": "O", "status": "완료", "type": "생활과 연관된 돈", "service": "내자산", "templateId": "POINT_20250604162215", "title": "포인트 사용 안내", "content": "Npay로 전환 가능한 포인트가 {금액} 있어요", "button": "전환가능 포인트 확인하기", "target": "전환 가능한 포인트가 500원 이상 있는 사용자"},
{"no": 6, "exposed": "X", "status": "완료", "type": "생활과 연관된 돈", "service": "내자산", "templateId": "POINT_20250604162405", "title": "포인트 사용 안내", "content": "소멸 예정인 포인트가 있어요!", "button": "내 포인트 확인하기", "target": "소멸 예정 포인트가 있는 사용자"},
{"no": 7, "exposed": "O", "status": "완료", "type": "불린 돈", "service": "내자산", "templateId": "BANK_20250602121139", "title": "예적금 만기 알림", "content": "{금융상품명} 만기일 7일전이에요. 만기 전에 가입 상품 확인해보세요.", "button": "내 상품 만기 확인하기", "target": "예적금 상품만기 7일전, 만기 당일"},
{"no": 8, "exposed": "O", "status": "완료", "type": "미래를 위한 돈", "service": "내자산", "templateId": "BANK_20250602122931", "title": "예적금 신규 가입", "content": "{금융상품명} 개설 완료! 내자산에 연결하고 한번에 확인하세요.", "button": "가입한 상품 확인하기", "target": "예적금 상품 가입 당일"},
{"no": 9, "exposed": "X", "status": "완료", "type": "나간 돈", "service": "내자산", "templateId": "BANK_20250602122729", "title": "거액 출금 발생", "content": "거액 출금이 발생했어요! 거래내역이 맞는지 확인해보세요.", "button": "출금 계좌 확인하기", "target": "300만원 이상 출금 발생 직후"},
{"no": 10, "exposed": "X", "status": "삭제", "type": "미래를 위한 돈", "service": "내자산", "templateId": "BANK_20250602115930", "title": "예상 이자 확인", "content": "제외", "button": "예상이자 확인하기", "target": "예적금 가입자 대상 월 1회"},
{"no": 11, "exposed": "X", "status": "완료", "type": "생활과 연관된 돈", "service": "내자산", "templateId": "BANK_20250602120924", "title": "숨은 돈 찾기", "content": "잊고 있던 내 계좌에서 숨은 돈을 찾아보세요!", "button": "계좌내역 확인하기", "target": "미사용 계좌가 있는 가입자 월 1회"},
{"no": 12, "exposed": "X", "status": "완료", "type": "미래를 위한 돈", "service": "내자산", "templateId": "PENSION_20250602125726", "title": "연금 개시 예정", "content": "{금융상품명} 연금 개시일이 {n}일전으로 다가 왔어요!", "button": "내 연금 확인하기", "target": "연금 개시일 도래 3개월 전, 7일 전"},
{"no": 13, "exposed": "X", "status": "삭제", "type": "미래를 위한 돈", "service": "내자산", "templateId": "PENSION_20250602125914", "title": "연금 미납 알림", "content": "제외", "button": "내 연금 확인하기", "target": "연금 미납 2개월 이상"},
{"no": 14, "exposed": "O", "status": "완료", "type": "불린 돈", "service": "내자산", "templateId": "STOCK_20250602130143", "title": "배당금 입금", "content": "{종목명}의 배당금이 계좌에 입금되었어요.", "button": "배당금 확인하기", "target": "마데 거래내역에서 배당금 텍스트 있는 사용자"},
{"no": 15, "exposed": "X", "status": "완료", "type": "불린 돈", "service": "내자산", "templateId": "STOCK_20250602130349", "title": "평가금액 변동", "content": "주식 평가금액이 3일전과 비교하여 변동되었네요.", "button": "내 종목내역 확인하기", "target": "계좌에서 주식 평가금액이 5% 이상 늘어난 사용자"},
{"no": 16, "exposed": "X", "status": "완료", "type": "미래를 위한 돈", "service": "내자산", "templateId": "STOCK_20250604151823", "title": "예수금 발견", "content": "내 주식 계좌에 {예수금금액} 원이 쌓여있어요!", "button": "미리 관리하러가기!", "target": "100만원 이상 예수금이 쌓여 있는 계좌가 있는 사용자"},
{"no": 17, "exposed": "O", "status": "완료", "type": "불린 돈", "service": "내자산", "templateId": "STOCK_20250602133502", "title": "새 증권계좌 발견", "content": "{금융기관명}의 신규 증권계좌 추가! 내 자산의 포트폴리오를 구성해보세요!", "button": "주식 계좌 확인하기", "target": "증권 서비스의 새로운 계좌가 있는 사용자"},
{"no": 18, "exposed": "O", "status": "완료", "type": "불린 돈", "service": "내자산", "templateId": "STOCK_20250604153239", "title": "청약일정 확인해보세요!", "content": "이번 주 청약 예정 종목 모아봤어요. 어떤 종목이 있는지 확인해보세요.", "button": "", "target": ""},
{"no": 19, "exposed": "O", "status": "완료", "type": "생활과 연관된 돈", "service": "내자산", "templateId": "PFMS_20250604131606", "title": "이번달 지출분석", "content": "이번달 지출이 가장 많은 곳을 알려드려요.", "button": "이번달 지출분석보기", "target": "월말 1회 타겟팅하여 머니브리핑 제공"},
{"no": 20, "exposed": "X", "status": "완료", "type": "생활과 연관된 돈", "service": "내자산", "templateId": "PFMS_20250604131446", "title": "수입지출 관련 소식", "content": "오늘의 행운글자 확인하고 포인트 받으세요!", "button": "포인트 받으러 가기", "target": "방문이 많지 않은 사용자 대상으로 행운글자 이벤트"},
{"no": 21, "exposed": "O", "status": "완료", "type": "생활과 연관된 돈", "service": "신용점수", "templateId": "CREDIT_20250602145632", "title": "신용점수 변동", "content": "신용점수가 최근에 바뀌었어요. 어떻게 변했는지 확인해보세요.", "button": "내 점수변동 📊 확인하기", "target": "신용점수 변동된 대상자"},
{"no": 22, "exposed": "O", "status": "완료", "type": "경제/자산컨텐츠", "service": "신용점수", "templateId": "CREDIT_20250602145426", "title": "대출리포트 발행", "content": "이번 달 대출리포트가 발행되었어요! 상세한 내용을 확인해보세요.", "button": "대출리포트 🧾 자세히보기", "target": "대출리포트 발행된 대상자"},
{"no": 23, "exposed": "O", "status": "완료", "type": "경제/자산컨텐츠", "service": "신용점수", "templateId": "CREDIT_20250602152021", "title": "최저금리 변동", "content": "이번 달 예상 대출 최저금리가 달라졌어요! 얼마나 변동됐는지 확인해보세요.", "button": "정확한 조건 🧾 비교하기", "target": "대출리포트 내 예상금리 변동 대상자"},
{"no": 24, "exposed": "O", "status": "완료", "type": "생활과 연관된 돈", "service": "신용점수", "templateId": "CREDIT_20250602152325", "title": "놓친 신용조회", "content": "{이름}님이 확인을 놓친 신용조회가 있어요!", "button": "놓친 조회 🔍 확인하기", "target": "신용조회 발생 후 확인하지 않은 대상자"},
{"no": 25, "exposed": "X", "status": "완료", "type": "생활과 연관된 돈", "service": "신용점수", "templateId": "CREDIT_20250602152449", "title": "놓친 신용변동", "content": "{이름}님이 확인을 놓친 신용변동이 있어요!", "button": "놓친 변동 🔍 확인하기", "target": "신용변동 내역 발생 후 확인하지 않은 대상자"},
{"no": 26, "exposed": "O", "status": "삭제", "type": "생활과 연관된 돈", "service": "신용점수", "templateId": "CREDIT_20250602152626", "title": "신용변동 발생", "content": "(개발x)", "button": "내 정보변동 확인", "target": "신용정보 변동내역 확인하지 않은 대상자"},
{"no": 27, "exposed": "O", "status": "완료", "type": "생활과 연관된 돈", "service": "신용점수", "templateId": "CREDIT_20250602152731", "title": "신용점수 올리기", "content": "{이름}님이 신용점수를 올릴 수 있는 기회가 생겼어요!", "button": "지금 📈 점수 올리기", "target": "신용점수 서비스 가입자 전체"},
{"no": 28, "exposed": "O", "status": "완료", "type": "빌린 돈", "service": "대출", "templateId": "LOAN_20250602152842", "title": "새로 추가된 대출 계좌", "content": "{금융사명}에서 새로 추가된 대출을 내자산에서 관리해보세요.", "button": "내 대출 확인하기", "target": "전일 기준 새로운 대출계좌가 개설이 된 사용자"},
{"no": 29, "exposed": "X", "status": "완료", "type": "경제/자산컨텐츠", "service": "대출", "templateId": "LOAN_20250602153132", "title": "대출 관련 소식", "content": "개발 진행 중", "button": "정부의 한도 축소 정책 알아보기", "target": "대출비교 서비스 이용자 전체"},
{"no": 30, "exposed": "X", "status": "완료", "type": "경제/자산컨텐츠", "service": "대출", "templateId": "LOAN_20250602153238", "title": "대출 관련 소식", "content": "개발 진행 중", "button": "정부의 한도 확대 소식 알아보기", "target": "대출비교 서비스 이용자 전체"},
{"no": 31, "exposed": "X", "status": "완료", "type": "경제/자산컨텐츠", "service": "대출", "templateId": "LOAN_20250602153617", "title": "대출 관련 소식", "content": "개발 진행 중", "button": "정부 지원 대출 알아보기", "target": "대출비교 서비스 이용자 전체"},
{"no": 32, "exposed": "X", "status": "완료", "type": "경제/자산컨텐츠", "service": "대출", "templateId": "LOAN_20250602154218", "title": "대출 관련 소식", "content": "개발 진행 중", "button": "변동 사항 확인하기", "target": "대출비교 서비스 이용자 전체"},
{"no": 33, "exposed": "O", "status": "완료", "type": "빌린 돈", "service": "대출", "templateId": "LOAN_20250602194218", "title": "대출 심사 결과", "content": "{이름}님의 신용대출 심사 결과, 최대한도 {n,nnn}만원, 최저금리 {nn.nn%} 상품을 확인하세요!", "button": "심사 결과 보기", "target": "신용대출비교 서비스 이용자"},
{"no": 34, "exposed": "O", "status": "완료", "type": "빌린 돈", "service": "대출", "templateId": "LOAN_20250602195616", "title": "신청 중인 대출", "content": "{이름}님 신청 중인 신용대출이 있습니다. 오늘이 지나면 조건이 달라질 수 있어요", "button": "신청 이어하기", "target": "신용대출비교 서비스 이용자"},
{"no": 35, "exposed": "X", "status": "완료", "type": "빌린 돈", "service": "대출", "templateId": "LOAN_20250602193623", "title": "대출 심사 결과", "content": "개발 진행 중", "button": "신청하러 가기", "target": "신용대출비교 서비스 이용자"},
{"no": 36, "exposed": "X", "status": "완료", "type": "빌린 돈", "service": "대출", "templateId": "LOAN_20250602200339", "title": "대출 관련 소식", "content": "개발 진행 중", "button": "단독 혜택 확인하기", "target": "대출비교 서비스 이용자 (직전 3개월)"},
{"no": 37, "exposed": "O", "status": "완료", "type": "빌린 돈", "service": "대출", "templateId": "LOAN_20250602200847", "title": "이자 납입일", "content": "{금융기관명}의 대출 이자 납입일 3일전이에요.", "button": "이번 달 이자 확인하기", "target": "마이데이터 내에서 대출 연동한 이용자"},
{"no": 38, "exposed": "O", "status": "완료", "type": "빌린 돈", "service": "대출", "templateId": "LOAN_20250602201013", "title": "대출 만기 예정", "content": "이용하고 있는 {금융기관}의 대출상품 만기가 00일 남았어여!", "button": "내 대출 보기", "target": "마이데이터 내에서 대출 연동한 이용자"},
{"no": 39, "exposed": "O", "status": "완료", "type": "빌린 돈", "service": "대출", "templateId": "rentloan_20250604095636", "title": "대출 심사 결과", "content": "{이름}님의 주택담보대출 심사 결과, 최대한도 {n,nnn}만원, 최저금리 {nn.nn%} 상품을 확인하세요!", "button": "비교 결과 확인하기", "target": "주택담보대출(신규/대환) 대출 비교 서비스 이용자"},
{"no": 40, "exposed": "X", "status": "완료", "type": "빌린 돈", "service": "대출", "templateId": "rentloan_20250602202229", "title": "대출 심사 결과", "content": "{이름}님의 전월세대출 심사 결과, 최대한도 {n,nnn}만원, 최저금리 {nn.nn%} 상품을 확인하세요!", "button": "비교 결과 확인하기", "target": "전월세대출(신규/대환) 대출 비교 서비스 이용자"},
{"no": 41, "exposed": "O", "status": "완료", "type": "빌린 돈", "service": "대출", "templateId": "houseloan_20250602202355", "title": "대출 심사 결과", "content": "오늘이 지나면 주택담보대출 조건이 달라질 수 있어요! 결과가 만료되기 전 다시 확인해 볼까요?", "button": "비교 결과 확인하기", "target": "주택담보대출(신규/대환) 대출 조회 결과 승인 1건 이상"},
{"no": 42, "exposed": "O", "status": "완료", "type": "빌린 돈", "service": "대출", "templateId": "rentloan_20250603114240", "title": "대출 심사 결과", "content": "오늘이 지나면 전월세대출 조건이 달라질 수 있어요! 결과가 만료되기 전 다시 확인해 볼까요?", "button": "비교 결과 확인하기", "target": "전월세대출(신규/대환) 대출 조회 결과 승인 1건 이상"},
{"no": 43, "exposed": "X", "status": "삭제", "type": "빌린 돈", "service": "대출", "templateId": "houseloan_20250603114345", "title": "대출 관련 소식", "content": "", "button": "주택담보대출 금리 확인하기", "target": "주택담보대출 대출 비교 서비스 이용 약관 동의 이후 90일"},
{"no": 44, "exposed": "X", "status": "삭제", "type": "빌린 돈", "service": "대출", "templateId": "houseloan_20250604092521", "title": "대출 관련 소식", "content": "", "button": "대출 갈아타고 이자 아끼기", "target": "마이데이터 내 주택담보대출 연동한 사용자"},
{"no": 45, "exposed": "O", "status": "삭제", "type": "빌린 돈", "service": "대출", "templateId": "houseloan_20250602201221", "title": "대출 관련 소식", "content": "", "button": "대출 갈아타고 이자 아끼기", "target": "마이데이터 내 전월세대출 연동한 사용자"},
{"no": 46, "exposed": "X", "status": "삭제", "type": "빌린 돈", "service": "대출", "templateId": "houseloan_20250604100424", "title": "대출 관련 소식", "content": "", "button": "주택담보대출 비교하기", "target": "주택담보대출(신규/대환) 신규 금융사 라이브"},
{"no": 47, "exposed": "X", "status": "삭제", "type": "빌린 돈", "service": "대출", "templateId": "rentloan_20250604121056", "title": "대출 관련 소식", "content": "", "button": "전월세대출 비교하기", "target": "전월세대출(신규/대환) 신규 금융사 라이브"},
{"no": 48, "exposed": "X", "status": "삭제", "type": "빌린 돈", "service": "대출", "templateId": "houseloan_20250604121211", "title": "대출 관련 소식", "content": "", "button": "내 대출 한도 확인하기", "target": "시세가 없는 관심부동산에 시세가 생성된 경우"},
{"no": 49, "exposed": "O", "status": "완료", "type": "경제/자산컨텐츠", "service": "대출", "templateId": "LOAN_20250627142856", "title": "대출 관련 소식", "content": "머니스토리 컨텐츠 (내용 그때 그때 달라짐)", "button": "대출규제 내용 확인하기", "target": "머니브리핑 게시물 발행"},
{"no": 50, "exposed": "X", "status": "완료", "type": "경제/자산컨텐츠", "service": "대출", "templateId": "LOAN_20250604155931", "title": "대출 관련 소식", "content": "머니스토리 대체", "button": "대출규제 내용 확인하기", "target": "머니브리핑 게시물 발행"},
{"no": 51, "exposed": "X", "status": "삭제", "type": "경제/자산컨텐츠", "service": "대출", "templateId": "rentloan_20250604125234", "title": "대출 관련 소식", "content": "", "button": "전월세대출 금리 확인하기", "target": "전월세대출 대출 비교 서비스 이용 약관 동의 이후 30일"},
{"no": 52, "exposed": "X", "status": "완료", "type": "나간 돈", "service": "보험", "templateId": "INSURANCE_20250604133400", "title": "보험 납입일", "content": "개발 진행 중", "button": "오늘 나갈 보험료💰 확인해보기", "target": "마이데이터 > 보험가입자"},
{"no": 53, "exposed": "X", "status": "완료", "type": "생활과 연관된 돈", "service": "보험", "templateId": "INSURANCE_20250604133732", "title": "자동차보험 만기 예정 / 만기일", "content": "30일 뒤에 {보험상품명} 보장이 끝나요. 갱신을 놓쳐서 과태료 내지 않도록 내 보험에서 관리해보세요.", "button": "보험 계약 갱신하기", "target": "자동차보험 갱신 이력 존재하는 경우"},
{"no": 54, "exposed": "O", "status": "완료", "type": "생활과 연관된 돈", "service": "보험", "templateId": "travelinsu_20250709111335", "title": "해외여행 준비", "content": "아직 준비 안했다면, [페이회원명]님 해외여행 [4박5일]동안 사고에 대비하세요.", "button": "안전여행 준비하기", "target": "해외여행보험 비교서비스 비교완료 후 이탈한 사용자"},
{"no": 55, "exposed": "X", "status": "완료", "type": "나간 돈", "service": "보험", "templateId": "INSURANCE_20250604134608", "title": "보험 납입 종료 예정", "content": "개발 진행 중", "button": "내 보험 확인해보기", "target": "보험 갱신 이력 존재하는 경우"},
{"no": 56, "exposed": "X", "status": "완료", "type": "생활과 연관된 돈", "service": "보험", "templateId": "INSURANCE_20250604135005", "title": "보험 만기 예정", "content": "개발 진행 중", "button": "만기된 내 보험 살펴보기", "target": "보험 갱신 이력 존재하는 경우"},
{"no": 57, "exposed": "X", "status": "완료", "type": "생활과 연관된 돈", "service": "보험", "templateId": "INSURANCE_20250604135244", "title": "보험 관련 소식", "content": "개발 진행중", "button": "내 보험 관리하기", "target": "같은 종류의 보험이 2개 이상인 고객"},
{"no": 58, "exposed": "O", "status": "완료", "type": "들어오는 돈", "service": "페이머니", "templateId": "payment_20250616172151", "title": "페이머니 충전 완료", "content": "예약하신 페이머니 {금액}원이 충전되었어요", "button": "예약 충전 확인하기", "target": "예약 충전된 금액이 충전된 사용자"},
{"no": 59, "exposed": "X", "status": "완료", "type": "들어오는 돈", "service": "페이머니", "templateId": "NPAY_20250604132751", "title": "머니통장 관련 소식", "content": "머니 통장-하나 {N}월 이자가 {금액}원 입금되었어요!", "button": "내 통장 이자 확인하기", "target": "머니 통장의 이자가 입금된 사용자"},
{"no": 60, "exposed": "X", "status": "완료", "type": "들어오는 돈", "service": "페이머니", "templateId": "NPAY_20250604133027", "title": "페이머니 관련 소식", "content": "0월 김페이님은 {포인트적립금액}원을 적립했어요!", "button": "Npay포인트 확인하기", "target": "매월 말일에 포인트 적립을 10,000원이상 쌓은 고객"},
{"no": 61, "exposed": "O", "status": "완료", "type": "들어오는 돈", "service": "송금", "templateId": "REMIT_20250604135509", "title": "송금 도착", "content": "{김페이}님이 {송금금액}원을 보냈어요. 돈을 받아주세요.", "button": "받을 송금 확인하러 가기", "target": ""},
{"no": 62, "exposed": "O", "status": "완료", "type": "나간 돈", "service": "송금", "templateId": "REMIT_20250604140006", "title": "예약송금 예정", "content": "내일 예약송금 {건수}건이 실행 예정입니다.", "button": "예약송금 확인하러 가기", "target": ""},
{"no": 63, "exposed": "O", "status": "완료", "type": "나간 돈", "service": "후불결제", "templateId": "PAYLATER_20250604140217", "title": "후불결제 납부", "content": "{**월 **일} 후불결제 납부금액은 {납부금액}원입니다. 납부 내역을 확인해 보세요.", "button": "후불결제 납부액 확인", "target": ""},
{"no": 64, "exposed": "O", "status": "완료", "type": "나간 돈", "service": "후불결제", "templateId": "PAYLATER_20250604140520", "title": "후불결제 연체", "content": "후불결제로 {연체금액}원 연체 중이에요. 이용에 어려움이 없도록 빠르게 납부하세요.", "button": "후불결제 연체액 확인", "target": ""},
{"no": 65, "exposed": "O", "status": "완료", "type": "미래를 위한 돈", "service": "우리집", "templateId": "MYHOUSE_20250604141759", "title": "신규 실거래가 알림", "content": "{단지명} {면적}㎡ {거래유형} 실거래가가 등록됐어요.", "button": "실거래가 보기", "target": "실거래가 등록 되었을때 발송"},
{"no": 66, "exposed": "O", "status": "완료", "type": "미래를 위한 돈", "service": "우리집", "templateId": "MYHOUSE_20250604142912", "title": "신규 시세 알림", "content": "{단지명} {면적}㎡ {거래유형} {데이터 수급처} 최신 시세가 등록됐어요.", "button": "시세 확인하기", "target": "최근 시세가 등록되었을 때 발송"},
{"no": 67, "exposed": "O", "status": "완료", "type": "경제/자산컨텐츠", "service": "머니스토리", "templateId": "mstory_20250604143012", "title": "머니스토리 컨텐츠", "content": "머니스토리 컨텐츠로 매일 다르게 발송 중", "button": "콘텐츠 더보기", "target": "현재 내자산 등록자 대상으로 발송 중"}
];
// CDP 컬럼 데이터
const CDP_COLUMNS = {
basic: {
'mbr_id_no': '네이버 IDNO'
},
interests: {
'fa_int_householdsingle': '최근 1개월 1인 가구 관련 상품 결제 또는 오피스텔/원룸 거주 추정 고객',
'fa_int_householdpet': '최근 1개월 동물용품/동물병원 결제 고객',
'fa_int_householdchild': '최근 1개월 어린이 관련 상품 결제 고객',
'fa_int_householdbaby': '최근 1개월 영유아 관련 상품 결제 또는 출산 정책지원금 수령 고객',
'fa_int_householdyouth': '최근 1개월 중고등학생 관련 상품 결제 고객',
'fa_int_publictransport': '최근 1개월 Npay 교통카드 이용 또는 교통비 결제 고객',
'fa_int_motorcycle': '최근 1개월 오토바이 관련 상품 결제 고객',
'fa_int_loan1stfinancial': '최근 1개월 1금융권에서 신용 대출 실행 고객',
'fa_int_loan2ndfinancial': '최근 1개월 저축은행, 카드사, 보험사, 증권사 등에서 신용 대출을 실행 고객',
'fa_int_loanpersonal': '최근 1개월 신용대출을 실행 고객',
'fa_int_saving': '최근 1개월 예적금 개설 고객',
'fa_int_jeonsemonthlyrent': '최근 24개월 계좌 및 대출이력을 통한 전월세 거주 추정 고객',
'fa_int_homeappliance': '최근 1개월 가전 상품 결제 고객',
'fa_int_luxury': '최근 1개월 100만원 이상 명품관련 결제 고객',
'fa_int_delivery': '최근 1개월 식비 목적의배달 결제 고객',
'fa_int_mutualaidservice': '최근 1개월 상조서비스 관련 결제 고객',
'fa_int_interior': '최근 1개월 인테리어 관련 상품 결제 고객',
'fa_int_carinsurance': '향후 1개월 자동차 보험 결제 예정으로 추정되는 고객(과거 동월 포함)',
'fa_int_carpurchase': '최근 1개월 마이카 및 오토론을 통한 차량 구매 추정 고객',
'fa_int_overseasshopping': '최근 1개월 해외직구 결제 고객',
'fa_int_traveldomestic': '최근 1개월 국내여행 관련 상품 결제 고객',
'fa_int_travelpackage': '최근 1개월 여행사 패키지 상품 결제 고객',
'fa_int_traveloverseas': '향후 1개월 내 해외 여행 목적의 출국 예정 추정 고객',
'fa_int_travelasia': '향후 1개월 내 아시아 지역으로 해외여행 목적의 출국 예정 추정 고객',
'fa_int_golf': '최근 1개월 골프용품/골프장 관련 상품 결제 고객',
'fa_int_running': '최근 1개월 러닝/마라톤 관련 상품 결제 고객',
'fa_int_swimming': '최근 1개월 수영 관련 상품 결제 고객',
'fa_int_pilatesyoga': '최근 1개월 필라테스/요가 관련 상품 결제 고객',
'fa_int_gym': '최근 1개월 피트니스/헬스장 가맹점 결제 고객',
'fa_int_wedding': '최근 1개월 결혼 준비 관련 상품 결제 및 활동 발생 고객',
'fa_int_retirement': '향후 24개월 내 은퇴 예정으로 추정되는 고객',
'fa_int_move': '최근 1개월 주소지 변경이력 존재 또는 이사 관련 상품 결제 고객',
'fa_int_childbirth': '최근 1개월 임신/출산 관련 상품 결제 고객',
'fa_int_highincome': '최근 12개월 Nice 추정소득 1억이상 고객',
'fa_int_homeowner': '최근 12개월 주택 소유 추정 고객',
'fa_int_business': '대출 등을 통한 사업자 추정 고객',
'fa_int_youngprofessional': '최근 1개월 급여입금을 통해 취직 추정 고객',
'fa_int_pharmaceutical': '최근 1개월 제약 B2B 가맹점 고객',
'fa_int_worker': '최근 2개월 정기적으로 급여 받는 고객',
'fa_int_fishing': '최근 1개월 낚시 관련 상품 결제 고객',
'fa_int_diet': '최근 1개월 다이어트 목적의 상품 결제 고객',
'fa_int_alcohol': '최근 1개월 주류 관련 상품 결제 고객',
'fa_int_ott': '최근 1개월 OTT 관련 결제 고객'
},
industries: {
'fa_ind_education': '최근 1개월 업종>교육 결제 고객',
'fa_ind_academy': '최근 1개월 업종>교육>학원 결제 고객',
'fa_ind_technicacademy': '최근 1개월 업종>교육>학원>기능학원 결제 고객',
'fa_ind_languageacademy': '최근 1개월 업종>교육>학원>외국어학원 결제 고객',
'fa_ind_drivingacademy': '최근 1개월 업종>교육>학원>운전면허학원 결제 고객',
'fa_ind_codingacademy': '최근 1개월 업종>교육>학원>프로그래밍/코딩 결제 고객',
'fa_ind_transportation': '최근 1개월 업종>교통 결제 고객',
'fa_ind_rentcar': '최근 1개월 업종>교통>렌터카 결제 고객',
'fa_ind_taxi': '최근 1개월 업종>교통>택시 결제 고객',
'fa_ind_airsevice': '최근 1개월 업종>교통>항공 결제 고객',
'fa_ind_finance': '최근 1개월 업종>금융 결제 고객',
'fa_ind_insurance': '최근 1개월 업종>금융>보험 결제 고객',
'fa_ind_card': '최근 1개월 업종>금융>카드 결제 고객',
'fa_ind_mobility': '최근 1개월 업종>모빌리티 결제 고객',
'fa_ind_carwash': '최근 1개월 업종>모빌리티>모빌리티 서비스>세차장 결제 고객',
'fa_ind_parkinglot': '최근 1개월 업종>모빌리티>모빌리티 서비스>주차장 결제 고객',
'fa_ind_culturehobby': '최근 1개월 업종>문화/취미 결제 고객',
'fa_ind_golfcourse': '최근 1개월 업종>문화/취미>레포츠시설>골프장 결제 고객',
'fa_ind_fitness': '최근 1개월 업종>문화/취미>레포츠시설>피트니스 결제 고객',
'fa_ind_cinema': '최근 1개월 업종>문화/취미>영화/엔터>영화 결제 고객',
'fa_ind_game': '최근 1개월 업종>문화/취미>컨텐츠 서비스>게임 결제 고객',
'fa_ind_ott': '최근 1개월 업종>문화/취미>영상/음악>OTT/영상 결제 고객',
'fa_ind_beauty': '최근 1개월 업종>미용 결제 고객',
'fa_ind_beautysalon': '최근 1개월 업종>미용>미용실 결제 고객',
'fa_ind_massage': '최근 1개월 업종>미용>안마/스포츠마사지 결제 고객',
'fa_ind_medical': '최근 1개월 업종>의료 결제 고객',
'fa_ind_pharmacy': '최근 1개월 업종>의료>약국 결제 고객',
'fa_ind_specialtymall': '최근 1개월 업종>전문판매 결제 고객',
'fa_ind_cosmetic': '최근 1개월 업종>전문판매>뷰티 결제 고객',
'fa_ind_food': '최근 1개월 업종>전문판매>식품 결제 고객',
'fa_ind_golfequipmnt': '최근 1개월 업종>전문판매>아웃도어>골프 결제 고객',
'fa_ind_fashion': '최근 1개월 업종>전문판매>패션의류>패션의류 결제 고객',
'fa_ind_generalmall': '최근 1개월 업종>종합판매 결제 고객',
'fa_ind_departmentstr': '최근 1개월 업종>종합판매>백화점 결제 고객',
'fa_ind_conveniencestr': '최근 1개월 업종>종합판매>편의점 결제 고객',
'fa_ind_foodbeverage': '최근 1개월 업종>F&B 결제 고객',
'fa_ind_restaurant': '최근 1개월 업종>F&B>음식점 결제 고객',
'fa_ind_fastfood': '최근 1개월 업종>F&B>음식점>패스트푸드 결제 고객',
'fa_ind_cafe': '최근 1개월 업종>F&B>카페 결제 고객',
'fa_ind_koreancuisine': '최근 1개월 업종>F&B>음식점>한식 결제 고객'
},
scores: {
'sc_int_householdsingle': '최근 1개월 1인 가구 관련 상품 결제 또는 오피스텔/원룸 거주 추정 고객 (예측스코어)',
'sc_int_householdpet': '최근 1개월 동물용품/동물병원 결제 고객 (예측스코어)',
'sc_int_loan1stfinancial': '최근 1개월 1금융권에서 신용 대출 실행 고객 (예측스코어)',
'sc_int_loanpersonal': '최근 1개월 신용대출 실행 고객 (예측스코어)',
'sc_int_saving': '최근 1개월 예적금 개설 고객 (예측스코어)',
'sc_int_luxury': '최근 1개월 100만원 이상 명품관련 결제 고객 (예측스코어)',
'sc_int_delivery': '최근 1개월 식비 목적의 배달 결제 고객 (예측스코어)',
'sc_int_traveloverseas': '향후 1개월 내 해외 여행 목적의 출국 예정 추정 고객 (예측스코어)',
'sc_int_golf': '최근 1개월 골프용품/골프장 관련 상품 결제 고객 (예측스코어)',
'sc_int_gym': '최근 1개월 피트니스/헬스장 가맹점 결제 고객 (예측스코어)',
'sc_int_wedding': '최근 1개월 결혼 준비 관련 상품 결제 및 활동 발생한 고객 (예측스코어)',
'sc_int_highincome': '최근 12개월 nice 추정소득 1억이상 고객 (예측스코어)',
'sc_int_homeowner': '최근 12개월 주택 소유 추정 고객 (예측스코어)',
'sc_int_business': '대출 등을 통한 사업자 추정 고객 (예측스코어)',
'sc_ind_beauty': '최근 1개월 업종>미용 결제 고객 (예측스코어)',
'sc_ind_golfcourse': '최근 1개월 업종>문화/취미>레포츠시설>골프장 결제 고객 (예측스코어)',
'sc_ind_cosmetic': '최근 1개월 업종>전문판매>뷰티 결제 고객 (예측스코어)',
'sc_ind_cafe': '최근 1개월 업종>F&B>카페 결제 고객 (예측스코어)',
'sc_ind_restaurant': '최근 1개월 업종>F&B>음식점 결제 고객 (예측스코어)'
},
flags: {
'flag_young_adult': '20-35세 연령대 플래그',
'flag_middle_age': '36-50세 연령대 플래그',
'flag_senior': '51세 이상 연령대 플래그',
'flag_high_spender': '월 100만원 이상 고액 결제자 플래그',
'flag_frequent_user': '주 3회 이상 Npay 이용자 플래그',
'flag_new_user': '최근 3개월 내 신규 가입자 플래그',
'flag_dormant_user': '3개월 이상 미이용자 플래그',
'flag_premium_service': '프리미엄 서비스 이용자 플래그'
}
};
// 자산 데이터 구조 (만원 단위)
let MOCK_ASSET_DATA = {
current: {
CURR_BANK_VALUE: 5000, // 5천만원 -> 5000만원
CURR_CAR_VALUE: 2500, // 2천5백만원 -> 2500만원
CURR_CARD_PAYMENT_DUE: 150, // 150만원 -> 150만원
CURR_LOAN_BALANCE: 15000, // 1억5천만원 -> 15000만원
CURR_PENSION_VALUE: 3000, // 3천만원 -> 3000만원
CURR_POINTMONEY_VALUE: 50, // 50만원 -> 50만원
CURR_REALESTATE_VALUE: 50000, // 5억원 -> 50000만원
CURR_STOCK_VALUE: 8000, // 8천만원 -> 8000만원
CURRENT_DATE: "2025-01-21",
CURRENT_TOTAL_ASSET_VALUE: 0 // 계산으로 업데이트
},
previous: {
PREV_BANK_VALUE: 4800, // 4천8백만원 -> 4800만원
PREV_CAR_VALUE: 2500, // 2천5백만원 -> 2500만원
PREV_CARD_PAYMENT_DUE: 200, // 200만원 -> 200만원
PREV_LOAN_BALANCE: 15100, // 1억5천1백만원 -> 15100만원
PREV_PENSION_VALUE: 2950, // 2천9백50만원 -> 2950만원
PREV_POINTMONEY_VALUE: 45, // 45만원 -> 45만원
PREV_REALESTATE_VALUE: 49500, // 4억9천5백만원 -> 49500만원
PREV_STOCK_VALUE: 7500, // 7천5백만원 -> 7500만원
PREVIOUS_DATE: "2025-01-20",
PREVIOUS_TOTAL_ASSET_VALUE: 0 // 계산으로 업데이트
}
};
let currentBriefings = MONEY_BRIEFINGS;
let currentColumns = {};
let currentAnalysisMode = 'keyword'; // 기본값은 키워드 기반
let assetData = MOCK_ASSET_DATA; // 자산 데이터 상태 관리
// 탭 전환 함수
function switchTab(tabName) {
// 모든 탭 버튼과 컨텐츠 비활성화
document.querySelectorAll('.tab-button').forEach(btn => btn.classList.remove('active'));
document.querySelectorAll('.tab-content').forEach(content => content.classList.remove('active'));
// 선택된 탭 활성화
document.querySelector(`[onclick="switchTab('${tabName}')"]`).classList.add('active');
document.getElementById(`${tabName}-tab`).classList.add('active');
if (tabName === 'briefings') {
renderBriefingCards();
} else if (tabName === 'cdp') {
renderCDPColumns();
} else if (tabName === 'generator') {
// 브리핑 생성 탭 초기화
initializeGeneratorTab();
} else if (tabName === 'asset') {
// 자산 변동 브리핑 탭 초기화
initializeAssetTab();
}
}
// 브리핑 카드 렌더링
function renderBriefingCards() {
const container = document.getElementById('briefingCards');
container.innerHTML = '';
currentBriefings.forEach(briefing => {
const card = document.createElement('div');
card.className = 'briefing-card';
card.innerHTML = `
<div class="briefing-header">
<div class="briefing-title">${briefing.title}</div>
<div style="display: flex; align-items: center; gap: 10px;">
<div class="status-badge ${briefing.exposed === 'O' ? 'status-active' : 'status-inactive'}">
${briefing.exposed === 'O' ? '노출 중' : '비노출'}
</div>
<button class="copy-button tooltip" onclick="copyBriefingInfo(${briefing.no})">
📋
<span class="tooltiptext">브리핑 정보 복사</span>
</button>
</div>
</div>
<div class="briefing-meta">
<span>No. ${briefing.no}</span>
<span>${briefing.service}</span>
<span>${briefing.status}</span>
</div>
<div class="briefing-category">${briefing.type}</div>
<div class="briefing-details" id="details-${briefing.no}">
<div class="detail-section">
<div class="detail-label">📝 브리핑 내용</div>
<div class="detail-content">${briefing.content}</div>
</div>
<div class="detail-section">
<div class="detail-label">🎯 타겟 고객</div>
<div class="detail-content">${briefing.target}</div>
</div>
<div class="detail-section">
<div class="detail-label">🔗 버튼 액션</div>
<div class="detail-content">${briefing.button}</div>
</div>
<div class="detail-section">
<div class="detail-label">🏷️ 템플릿 ID</div>
<div class="detail-content">${briefing.templateId}</div>
</div>
</div>
`;
card.addEventListener('click', () => {
const details = document.getElementById(`details-${briefing.no}`);
details.classList.toggle('show');
});
container.appendChild(card);
});
}
// 브리핑 필터링
function filterBriefings(type) {
// 필터 버튼 활성화 상태 변경
document.querySelectorAll('.filter-btn').forEach(btn => btn.classList.remove('active'));
event.target.classList.add('active');
if (type === 'all') {
currentBriefings = MONEY_BRIEFINGS;
} else {
currentBriefings = MONEY_BRIEFINGS.filter(briefing => briefing.type === type);
}
renderBriefingCards();
}
// 필터 버튼 텍스트 업데이트 (개수 포함)
function updateFilterButtonCounts() {
const typeCounts = {};
MONEY_BRIEFINGS.forEach(briefing => {
typeCounts[briefing.type] = (typeCounts[briefing.type] || 0) + 1;
});
// 필터 버튼 HTML 업데이트
const filterButtons = document.querySelector('.filter-buttons');
if (filterButtons) {
filterButtons.innerHTML = `
<button class="filter-btn active" onclick="filterBriefings('all')">전체 (${MONEY_BRIEFINGS.length})</button>
<button class="filter-btn" onclick="filterBriefings('생활과 연관된 돈')">생활과 연관된 돈 (${typeCounts['생활과 연관된 돈'] || 0})</button>
<button class="filter-btn" onclick="filterBriefings('불린 돈')">불린 돈 (${typeCounts['불린 돈'] || 0})</button>
<button class="filter-btn" onclick="filterBriefings('빌린 돈')">빌린 돈 (${typeCounts['빌린 돈'] || 0})</button>
<button class="filter-btn" onclick="filterBriefings('나간 돈')">나간 돈 (${typeCounts['나간 돈'] || 0})</button>
<button class="filter-btn" onclick="filterBriefings('들어오는 돈')">들어오는 돈 (${typeCounts['들어오는 돈'] || 0})</button>
<button class="filter-btn" onclick="filterBriefings('미래를 위한 돈')">미래를 위한 돈 (${typeCounts['미래를 위한 돈'] || 0})</button>
<button class="filter-btn" onclick="filterBriefings('경제/자산컨텐츠')">경제/자산컨텐츠 (${typeCounts['경제/자산컨텐츠'] || 0})</button>
`;
}
}
// 브리핑 검색
function searchBriefings(query) {
if (!query) {
currentBriefings = MONEY_BRIEFINGS;
} else {
currentBriefings = MONEY_BRIEFINGS.filter(briefing =>
briefing.title.toLowerCase().includes(query.toLowerCase()) ||
briefing.content.toLowerCase().includes(query.toLowerCase()) ||
briefing.target.toLowerCase().includes(query.toLowerCase())
);
}
renderBriefingCards();
}
// CDP 컬럼 렌더링
function renderCDPColumns() {
const container = document.getElementById('cdpColumns');
container.innerHTML = '';
Object.keys(currentColumns).forEach(category => {
Object.keys(currentColumns[category]).forEach(columnName => {
const card = document.createElement('div');
card.className = 'column-card';
card.innerHTML = `
<div class="column-category">${getCategoryName(category)}</div>
<div class="column-name">${columnName}</div>
<div class="column-description">${currentColumns[category][columnName]}</div>
`;
container.appendChild(card);
});
});
}
function getCategoryName(category) {
const names = {
'basic': '기본 정보',
'interests': '관심사 지표',
'industries': '업종별 지표',
'scores': '예측 스코어',
'flags': '플래그 지표'
};
return names[category] || category;
}
// CDP 컬럼 필터링
function filterColumns(category) {
// 필터 버튼 활성화 상태 변경
document.querySelectorAll('#cdp-tab .filter-btn').forEach(btn => btn.classList.remove('active'));
event.target.classList.add('active');
if (category === 'all') {
currentColumns = CDP_COLUMNS;
} else {
currentColumns = { [category]: CDP_COLUMNS[category] };
}
renderCDPColumns();
}
// CDP 컬럼 검색
function searchColumns(query) {
if (!query) {
currentColumns = CDP_COLUMNS;
} else {
currentColumns = {};
Object.keys(CDP_COLUMNS).forEach(category => {
const filteredColumns = {};
Object.keys(CDP_COLUMNS[category]).forEach(columnName => {
if (columnName.toLowerCase().includes(query.toLowerCase()) ||
CDP_COLUMNS[category][columnName].toLowerCase().includes(query.toLowerCase())) {
filteredColumns[columnName] = CDP_COLUMNS[category][columnName];
}
});
if (Object.keys(filteredColumns).length > 0) {
currentColumns[category] = filteredColumns;
}
});
}
renderCDPColumns();
}
// 예시 쿼리 설정
function setExampleQuery(query) {
document.getElementById('queryInput').value = query;
}
// 분석 모드 설정
function setAnalysisMode(mode) {
currentAnalysisMode = mode;
// 버튼 활성화 상태 변경
document.querySelectorAll('.mode-btn').forEach(btn => btn.classList.remove('active'));
document.getElementById(mode + 'Mode').classList.add('active');
// 로딩 텍스트 변경
const loadingText = document.querySelector('#loadingSection p');
if (mode === 'keyword') {
loadingText.textContent = '🔤 키워드 기반으로 CDP 데이터를 분석하고 있습니다...';
} else {
loadingText.textContent = '🤖 LLM이 CDP 데이터를 심층 분석하여 최적의 고객 세그먼트를 찾고 있습니다...';
}
}
// 쿼리 분석
function analyzeQuery() {
const query = document.getElementById('queryInput').value;
if (!query) return;
const loadingSection = document.getElementById('loadingSection');
const resultsContainer = document.getElementById('resultsContainer');
const analysisResults = document.getElementById('analysisResults');
loadingSection.style.display = 'block';
resultsContainer.classList.remove('show');
if (currentAnalysisMode === 'keyword') {
// 키워드 기반 분석 (빠름)
setTimeout(() => {
loadingSection.style.display = 'none';
const recommendations = generateKeywordRecommendations(query);
analysisResults.innerHTML = recommendations;
resultsContainer.classList.add('show');
}, 1000);
} else {
// LLM 기반 분석 (정확함)
generateLLMRecommendations(query).then(recommendations => {
loadingSection.style.display = 'none';
analysisResults.innerHTML = recommendations;
resultsContainer.classList.add('show');
}).catch(error => {
console.error('LLM 분석 실패:', error);
loadingSection.style.display = 'none';
// Fallback to keyword-based analysis
const fallbackRecommendations = `
<div class="recommendation-card">
<div class="recommendation-title">⚠️ LLM 분석 실패 - 키워드 기반으로 분석</div>
<div class="recommendation-content">
LLM 분석에 실패했습니다. 키워드 기반 분석 결과를 제공합니다.
</div>
</div>
${generateKeywordRecommendations(query)}
`;
analysisResults.innerHTML = fallbackRecommendations;
resultsContainer.classList.add('show');
});
}
}
// LLM 기반 추천 생성 (OpenAI GPT-4o)
async function generateLLMRecommendations(query) {
const apiKey = 'YOUR_OPENAI_API_KEY_HERE';
const model = 'gpt-4o-2024-11-20';
// CDP 스키마를 문자열로 변환
const cdpSchema = Object.entries(CDP_COLUMNS).map(([category, columns]) => {
const columnList = Object.entries(columns).map(([key, desc]) => `${key}: ${desc}`).join('\n');
return `${category}:\n${columnList}`;
}).join('\n\n');
// 머니브리핑 소재 요약
const briefingSummary = MONEY_BRIEFINGS.map(b =>
`No.${b.no} ${b.title} (${b.type}) - ${b.target}`
).join('\n');
const systemPrompt = `You are a financial marketing expert specializing in customer segmentation for money management services. You must respond with valid JSON only.
Given a user query about target customer segments, analyze the query and recommend:
1. Relevant CDP (Customer Data Platform) columns to identify the target audience
2. Suitable money briefing materials to engage these customers
CDP Schema Available:
${cdpSchema}
Money Briefing Materials Available:
${briefingSummary}
IMPORTANT: You must respond with ONLY a valid JSON object, no additional text before or after.
Response format (Korean content):
{
"analysis": "Brief analysis of the query in Korean",
"recommended_columns": [
{"column": "column_name", "reason": "why this column is relevant in Korean"},
{"column": "column_name", "reason": "why this column is relevant in Korean"}
],
"recommended_briefings": [
{"no": briefing_number, "title": "briefing_title", "reason": "why this briefing fits in Korean"},
{"no": briefing_number, "title": "briefing_title", "reason": "why this briefing fits in Korean"}
],
"targeting_strategy": "Overall strategy for targeting this segment in Korean"
}`;
const userPrompt = `Target customer query: "${query}"
Please analyze this query and recommend the most relevant CDP columns and money briefing materials for targeting the described customer segment.`;
try {
const response = await fetch('https://api.openai.com/v1/chat/completions', {
method: 'POST',
headers: {
'Authorization': `Bearer ${apiKey}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
model: model,
messages: [
{ role: 'system', content: systemPrompt },
{ role: 'user', content: userPrompt }
],
temperature: 0.7,
max_tokens: 2000,
response_format: { type: "json_object" }
})
});
if (!response.ok) {
throw new Error(`OpenAI API error: ${response.status} ${response.statusText}`);
}
const data = await response.json();
const llmResponse = data.choices[0].message.content;
// JSON 파싱 시도 (더 견고한 처리)
let parsedResponse;
try {
// JSON 블록 추출 시도
const jsonMatch = llmResponse.match(/\{[\s\S]*\}/);
const jsonStr = jsonMatch ? jsonMatch[0] : llmResponse;
parsedResponse = JSON.parse(jsonStr);
} catch (e) {
console.error('JSON 파싱 실패, 원본 응답:', llmResponse);
console.error('파싱 에러:', e.message);
// JSON 파싱 실패 시 텍스트 기반 처리
const textRecommendations = `
<div class="recommendation-card">
<div class="recommendation-title">🤖 LLM 분석 결과: "${query}"</div>
<div class="recommendation-content">
<strong>OpenAI 응답:</strong><br>
${llmResponse.replace(/\n/g, '<br>')}
</div>
</div>
<div class="recommendation-card">
<div class="recommendation-title">⚠️ 디버깅 정보</div>
<div class="recommendation-content">
JSON 파싱 실패: ${e.message}<br>
키워드 기반 분석으로 자동 전환하시거나, 콘솔에서 원본 응답을 확인하세요.
</div>
</div>
`;
return textRecommendations;
}
// HTML 형태로 변환
let recommendations = `
<div class="recommendation-card">
<div class="recommendation-title">🤖 LLM 분석 결과: "${query}"</div>
<div class="recommendation-content">
${parsedResponse.analysis}
</div>
</div>
`;
if (parsedResponse.recommended_columns && parsedResponse.recommended_columns.length > 0) {
recommendations += `
<div class="recommendation-card">
<div class="recommendation-title">📊 추천 CDP 컬럼</div>
<div class="recommendation-content">
${parsedResponse.recommended_columns.map(col =>
`• <strong>${col.column}</strong>: ${col.reason}`
).join('<br>')}
</div>
</div>
`;
}
if (parsedResponse.recommended_briefings && parsedResponse.recommended_briefings.length > 0) {
recommendations += `
<div class="recommendation-card">
<div class="recommendation-title">💡 추천 브리핑 소재</div>
<div class="recommendation-content">
${parsedResponse.recommended_briefings.map(brief =>
`• <strong>No.${brief.no} ${brief.title}</strong>: ${brief.reason}`
).join('<br>')}
</div>
</div>
`;
}
if (parsedResponse.targeting_strategy) {
recommendations += `
<div class="recommendation-card">
<div class="recommendation-title">🎯 타겟팅 전략</div>
<div class="recommendation-content">
${parsedResponse.targeting_strategy}
</div>
</div>
`;
}
return recommendations;
} catch (error) {
console.error('OpenAI API 호출 실패:', error);
throw error;
}
}
// 키워드 기반 추천 생성 (기존 로직)
function generateKeywordRecommendations(query) {
const lowerQuery = query.toLowerCase();
let recommendations = `
<div class="recommendation-card">
<div class="recommendation-title">🔤 키워드 분석 결과: "${query}"</div>
<div class="recommendation-content">
키워드 매칭을 통해 분석한 결과, 다음과 같은 CDP 컬럼 조합과 브리핑 소재를 추천합니다:
</div>
</div>
`;
const keywordMappings = {
'대출': {
columns: [
'fa_int_loan1stfinancial: 1금융권 신용대출 고객',
'fa_int_loan2ndfinancial: 2금융권 신용대출 고객',
'sc_int_loanpersonal: 신용대출 예측 스코어',
'fa_int_highincome: 고소득층 (대출 승인률 높음)'
],
briefings: [
'신용대출 심사 결과 (No. 33)',
'주택담보대출 심사 결과 (No. 39)',
'대출 이자 납입일 (No. 37)',
'대출 만기 예정 (No. 38)',
'새로 추가된 대출 계좌 (No. 28)'
]
},
'뷰티': {
columns: [
'fa_ind_beauty: 미용 업종 결제 고객',
'fa_ind_cosmetic: 화장품 전문판매 고객',
'fa_ind_beautysalon: 미용실 결제 고객',
'sc_ind_cosmetic: 뷰티 관련 예측 스코어'
],
briefings: [
'카드 청구서 도착 (No. 3) - 뷰티 소비 알림용',
'이번달 지출분석 (No. 19) - 뷰티 지출 분석'
]
},
'골프': {
columns: [
'fa_int_golf: 골프용품/골프장 결제 고객',
'sc_int_golf: 골프 관련 예측 스코어',
'fa_ind_golfcourse: 골프장 업종 결제 고객',
'fa_int_highincome: 고소득층 (골프 고객 특성)'
],
briefings: [
'카드 청구서 도착 (No. 3) - 골프 소비 알림용',
'이번달 지출분석 (No. 19) - 골프 지출 분석',
'신용점수 올리기 (No. 27) - 프리미엄 고객 대상'
]
},
'여행': {
columns: [
'fa_int_traveloverseas: 해외여행 예정 고객',
'fa_int_traveldomestic: 국내여행 관련 결제 고객',
'sc_int_traveloverseas: 해외여행 예측 스코어',
'fa_ind_airsevice: 항공 업종 결제 고객'
],
briefings: [
'해외여행 준비 (No. 54)',
'카드 청구서 도착 (No. 3) - 여행 소비 알림용',
'이번달 지출분석 (No. 19) - 여행 지출 분석'
]
},
'1인가구': {
columns: [
'fa_int_householdsingle: 1인 가구 관련 결제 고객',
'sc_int_householdsingle: 1인 가구 예측 스코어',
'fa_int_delivery: 배달 결제 고객',
'fa_int_jeonsemonthlyrent: 전월세 거주 추정 고객'
],
briefings: [
'이번달 지출분석 (No. 19) - 1인가구 지출 패턴',
'카드 청구서 도착 (No. 3) - 생활비 관리',
'포인트 사용 안내 (No. 5) - 절약형 혜택'
]
},
'투자': {
columns: [
'fa_int_saving: 예적금 개설 고객',
'fa_int_highincome: 고소득층',
'sc_int_saving: 예적금 예측 스코어',
'sc_int_business: 사업자 예측 스코어'
],
briefings: [
'예적금 신규 가입 (No. 8)',
'예적금 만기 알림 (No. 7)',
'배당금 입금 (No. 14)',
'새 증권계좌 발견 (No. 17)',
'청약일정 확인해보세요! (No. 18)'
]
},
'보험': {
columns: [
'fa_ind_insurance: 보험 업종 결제 고객',
'fa_int_carinsurance: 자동차보험 결제 예정 고객',
'fa_int_traveloverseas: 해외여행 예정 고객 (여행자보험)'
],
briefings: [
'해외여행 준비 (No. 54)',
'자동차보험 만기 예정 (No. 53)',
'보험 납입일 (No. 52)'
]
}
};
// 키워드 매칭 및 추천 생성
let foundMappings = [];
for (const [keyword, mapping] of Object.entries(keywordMappings)) {
if (lowerQuery.includes(keyword) || query.includes(keyword)) {
foundMappings.push({ keyword, ...mapping });
}
}
// 연령대 분석
if (lowerQuery.includes('20대') || lowerQuery.includes('30대') || lowerQuery.includes('젊은')) {
recommendations += `
<div class="recommendation-card">
<div class="recommendation-title">👥 연령대 분석</div>
<div class="recommendation-content">
• flag_young_adult: 20-35세 연령대 플래그<br>
• fa_int_youngprofessional: 취직 추정 고객<br>
• fa_int_jeonsemonthlyrent: 전월세 거주 추정 고객
</div>
</div>
`;
}
// 고소득층 분석
if (lowerQuery.includes('고소득') || lowerQuery.includes('프리미엄') || lowerQuery.includes('vip')) {
recommendations += `
<div class="recommendation-card">
<div class="recommendation-title">💰 고소득층 분석</div>
<div class="recommendation-content">
• fa_int_highincome: Nice 추정소득 1억이상 고객<br>
• sc_int_highincome: 고소득층 예측 스코어<br>
• fa_int_luxury: 명품 관련 결제 고객<br>
• flag_high_spender: 월 100만원 이상 고액 결제자
</div>
</div>
`;
}
// 매핑된 추천 결과 추가
foundMappings.forEach(mapping => {
recommendations += `
<div class="recommendation-card">
<div class="recommendation-title">📊 ${mapping.keyword} 관련 추천 컬럼</div>
<div class="recommendation-content">
${mapping.columns.map(col => `• ${col}`).join('<br>')}
</div>
</div>
<div class="recommendation-card">
<div class="recommendation-title">💡 추천 브리핑 소재</div>
<div class="recommendation-content">
${mapping.briefings.map(brief => `• ${brief}`).join('<br>')}
</div>
</div>
`;
});
// 매핑이 없는 경우 일반적인 추천
if (foundMappings.length === 0) {
recommendations += `
<div class="recommendation-card">
<div class="recommendation-title">💡 일반 추천</div>
<div class="recommendation-content">
질의에 적합한 구체적인 키워드를 포함해보세요:<br>
• 관심사: 대출, 투자, 뷰티, 골프, 여행 등<br>
• 연령대: 20대, 30대, 젊은, 중년 등<br>
• 소득수준: 고소득, 프리미엄, VIP 등<br>
• 생활패턴: 1인가구, 배달, 운동 등
</div>
</div>
`;
}
return recommendations;
}
// 추천 결과 생성 (개선된 분석 로직)
function generateRecommendations(query) {
const lowerQuery = query.toLowerCase();
let recommendations = `
<div class="recommendation-card">
<div class="recommendation-title">🎯 분석 결과: "${query}"</div>
<div class="recommendation-content">
질의를 분석한 결과, 다음과 같은 CDP 컬럼 조합과 브리핑 소재를 추천합니다:
</div>
</div>
`;
const keywordMappings = {
'대출': {
columns: [
'fa_int_loan1stfinancial: 1금융권 신용대출 고객',
'fa_int_loan2ndfinancial: 2금융권 신용대출 고객',
'sc_int_loanpersonal: 신용대출 예측 스코어',
'fa_int_highincome: 고소득층 (대출 승인률 높음)'
],
briefings: [
'신용대출 심사 결과 (No. 33)',
'주택담보대출 심사 결과 (No. 39)',
'대출 이자 납입일 (No. 37)',
'대출 만기 예정 (No. 38)',
'새로 추가된 대출 계좌 (No. 28)'
]
},
'뷰티': {
columns: [
'fa_ind_beauty: 미용 업종 결제 고객',
'fa_ind_cosmetic: 화장품 전문판매 고객',
'fa_ind_beautysalon: 미용실 결제 고객',
'sc_ind_cosmetic: 뷰티 관련 예측 스코어'
],
briefings: [
'카드 청구서 도착 (No. 3) - 뷰티 소비 알림용',
'이번달 지출분석 (No. 19) - 뷰티 지출 분석'
]
},
'골프': {
columns: [
'fa_int_golf: 골프용품/골프장 결제 고객',
'sc_int_golf: 골프 관련 예측 스코어',
'fa_ind_golfcourse: 골프장 업종 결제 고객',
'fa_int_highincome: 고소득층 (골프 고객 특성)'
],
briefings: [
'카드 청구서 도착 (No. 3) - 골프 소비 알림용',
'이번달 지출분석 (No. 19) - 골프 지출 분석',
'신용점수 올리기 (No. 27) - 프리미엄 고객 대상'
]
},
'여행': {
columns: [
'fa_int_traveloverseas: 해외여행 예정 고객',
'fa_int_traveldomestic: 국내여행 관련 결제 고객',
'sc_int_traveloverseas: 해외여행 예측 스코어',
'fa_ind_airsevice: 항공 업종 결제 고객'
],
briefings: [
'해외여행 준비 (No. 54)',
'카드 청구서 도착 (No. 3) - 여행 소비 알림용',
'이번달 지출분석 (No. 19) - 여행 지출 분석'
]
},
'1인가구': {
columns: [
'fa_int_householdsingle: 1인 가구 관련 결제 고객',
'sc_int_householdsingle: 1인 가구 예측 스코어',
'fa_int_delivery: 배달 결제 고객',
'fa_int_jeonsemonthlyrent: 전월세 거주 추정 고객'
],
briefings: [
'이번달 지출분석 (No. 19) - 1인가구 지출 패턴',
'카드 청구서 도착 (No. 3) - 생활비 관리',
'포인트 사용 안내 (No. 5) - 절약형 혜택'
]
},
'투자': {
columns: [
'fa_int_saving: 예적금 개설 고객',
'fa_int_highincome: 고소득층',
'sc_int_saving: 예적금 예측 스코어',
'sc_int_business: 사업자 예측 스코어'
],
briefings: [
'예적금 신규 가입 (No. 8)',
'예적금 만기 알림 (No. 7)',
'배당금 입금 (No. 14)',
'새 증권계좌 발견 (No. 17)',
'청약일정 확인해보세요! (No. 18)'
]
},
'보험': {
columns: [
'fa_ind_insurance: 보험 업종 결제 고객',
'fa_int_carinsurance: 자동차보험 결제 예정 고객',
'fa_int_traveloverseas: 해외여행 예정 고객 (여행자보험)'
],
briefings: [
'해외여행 준비 (No. 54)',
'자동차보험 만기 예정 (No. 53)',
'보험 납입일 (No. 52)'
]
}
};
// 키워드 매칭 및 추천 생성
let foundMappings = [];
for (const [keyword, mapping] of Object.entries(keywordMappings)) {
if (lowerQuery.includes(keyword) || query.includes(keyword)) {
foundMappings.push({ keyword, ...mapping });
}
}
// 연령대 분석
if (lowerQuery.includes('20대') || lowerQuery.includes('30대') || lowerQuery.includes('젊은')) {
recommendations += `
<div class="recommendation-card">
<div class="recommendation-title">👥 연령대 분석</div>
<div class="recommendation-content">
• flag_young_adult: 20-35세 연령대 플래그<br>
• fa_int_youngprofessional: 취직 추정 고객<br>
• fa_int_jeonsemonthlyrent: 전월세 거주 추정 고객
</div>
</div>
`;
}
// 고소득층 분석
if (lowerQuery.includes('고소득') || lowerQuery.includes('프리미엄') || lowerQuery.includes('vip')) {
recommendations += `
<div class="recommendation-card">
<div class="recommendation-title">💰 고소득층 분석</div>
<div class="recommendation-content">
• fa_int_highincome: Nice 추정소득 1억이상 고객<br>
• sc_int_highincome: 고소득층 예측 스코어<br>
• fa_int_luxury: 명품 관련 결제 고객<br>
• flag_high_spender: 월 100만원 이상 고액 결제자
</div>
</div>
`;
}
// 매핑된 추천 결과 추가
foundMappings.forEach(mapping => {
recommendations += `
<div class="recommendation-card">
<div class="recommendation-title">📊 ${mapping.keyword} 관련 추천 컬럼</div>
<div class="recommendation-content">
${mapping.columns.map(col => `• ${col}`).join('<br>')}
</div>
</div>
<div class="recommendation-card">
<div class="recommendation-title">💡 추천 브리핑 소재</div>
<div class="recommendation-content">
${mapping.briefings.map(brief => `• ${brief}`).join('<br>')}
</div>
</div>
`;
});
// 매핑이 없는 경우 일반적인 추천
if (foundMappings.length === 0) {
recommendations += `
<div class="recommendation-card">
<div class="recommendation-title">💡 일반 추천</div>
<div class="recommendation-content">
질의에 적합한 구체적인 키워드를 포함해보세요:<br>
• 관심사: 대출, 투자, 뷰티, 골프, 여행 등<br>
• 연령대: 20대, 30대, 젊은, 중년 등<br>
• 소득수준: 고소득, 프리미엄, VIP 등<br>
• 생활패턴: 1인가구, 배달, 운동 등
</div>
</div>
`;
}
return recommendations;
}
// 통계 계산 및 업데이트
function updateBriefingStats() {
const total = MONEY_BRIEFINGS.length;
const active = MONEY_BRIEFINGS.filter(b => b.exposed === 'O').length;
const inactive = MONEY_BRIEFINGS.filter(b => b.exposed === 'X').length;
const completed = MONEY_BRIEFINGS.filter(b => b.status === '완료').length;
document.getElementById('totalBriefings').textContent = total;
document.getElementById('activeBriefings').textContent = active;
document.getElementById('inactiveBriefings').textContent = inactive;
document.getElementById('completedBriefings').textContent = completed;
}
// 브리핑 정보 복사 기능
function copyBriefingInfo(briefingNo) {
const briefing = MONEY_BRIEFINGS.find(b => b.no === briefingNo);
if (!briefing) return;
const info = `
📋 머니브리핑 소재 정보
• 제목: ${briefing.title}
• 번호: No. ${briefing.no}
• 유형: ${briefing.type}
• 서비스: ${briefing.service}
• 노출상태: ${briefing.exposed === 'O' ? '노출 중' : '비노출'}
• 상태: ${briefing.status}
• 타겟: ${briefing.target}
• 버튼: ${briefing.button}
• 내용: ${briefing.content}
• 템플릿ID: ${briefing.templateId}
`;
navigator.clipboard.writeText(info.trim()).then(() => {
showNotification('브리핑 정보가 복사되었습니다.');
}).catch(() => {
showNotification('복사에 실패했습니다.');
});
}
// 알림 표시 기능
function showNotification(message) {
const notification = document.createElement('div');
notification.style.cssText = `
position: fixed;
top: 20px;
right: 20px;
background: #4CAF50;
color: white;
padding: 15px 20px;
border-radius: 5px;
z-index: 1000;
box-shadow: 0 4px 12px rgba(0,0,0,0.15);
transform: translateX(100%);
transition: transform 0.3s ease;
`;
notification.textContent = message;
document.body.appendChild(notification);
setTimeout(() => notification.style.transform = 'translateX(0)', 100);
setTimeout(() => {
notification.style.transform = 'translateX(100%)';
setTimeout(() => document.body.removeChild(notification), 300);
}, 3000);
}
// 데이터 내보내기 기능
function exportBriefingData() {
const data = {
summary: {
total: MONEY_BRIEFINGS.length,
active: MONEY_BRIEFINGS.filter(b => b.exposed === 'O').length,
inactive: MONEY_BRIEFINGS.filter(b => b.exposed === 'X').length,
completed: MONEY_BRIEFINGS.filter(b => b.status === '완료').length
},
briefings: currentBriefings,
exportDate: new Date().toISOString()
};
const blob = new Blob([JSON.stringify(data, null, 2)], { type: 'application/json' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = `money-briefing-analysis-${new Date().toISOString().split('T')[0]}.json`;
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
URL.revokeObjectURL(url);
showNotification('데이터가 내보내졌습니다.');
}
// 키보드 단축키
document.addEventListener('keydown', function(e) {
// Ctrl+1: 첫 번째 탭
if (e.ctrlKey && e.key === '1') {
e.preventDefault();
switchTab('briefings');
}
// Ctrl+2: 두 번째 탭
if (e.ctrlKey && e.key === '2') {
e.preventDefault();
switchTab('cdp');
}
// Ctrl+3: 세 번째 탭
if (e.ctrlKey && e.key === '3') {
e.preventDefault();
switchTab('generator');
}
// Ctrl+4: 네 번째 탭 (자산 변동 브리핑)
if (e.ctrlKey && e.key === '4') {
e.preventDefault();
switchTab('asset');
}
// Ctrl+Enter: 쿼리 분석 (CDP 탭에서)
if (e.ctrlKey && e.key === 'Enter' && document.getElementById('cdp-tab').classList.contains('active')) {
e.preventDefault();
analyzeQuery();
}
});
// 검색 입력 시 Enter 키 처리
function handleKeyPress(event) {
if (event.key === 'Enter') {
analyzeQuery();
}
}
// 통계 정보 표시
function getQuickStats() {
const totalColumns = Object.values(CDP_COLUMNS).reduce((acc, category) => acc + Object.keys(category).length, 0);
const activeFilters = document.querySelectorAll('.filter-btn.active').length;
return {
totalColumns,
activeFilters,
currentResults: Object.values(currentColumns).reduce((acc, category) => acc + Object.keys(category).length, 0)
};
}
// 브리핑 생성 관련 함수들
function initializeGeneratorTab() {
// 브리핑 생성 탭 초기화 로직
document.getElementById('generatorInput').value = '';
document.getElementById('generatorResults').innerHTML = '';
document.getElementById('generatorLoadingSection').style.display = 'none';
}
function setGeneratorExample(example) {
document.getElementById('generatorInput').value = example;
}
// 브리핑 생성 메인 함수
async function generateBriefings() {
const input = document.getElementById('generatorInput').value.trim();
if (!input) {
showNotification('아이디어나 키워드를 입력해주세요.');
return;
}
const loadingSection = document.getElementById('generatorLoadingSection');
const resultsContainer = document.getElementById('generatorResults');
// 로딩 시작
loadingSection.style.display = 'block';
resultsContainer.innerHTML = '';
try {
const briefings = await generateBriefingsWithLLM(input);
loadingSection.style.display = 'none';
displayGeneratedBriefings(briefings);
} catch (error) {
console.error('브리핑 생성 실패:', error);
loadingSection.style.display = 'none';
showNotification('브리핑 생성에 실패했습니다. 다시 시도해주세요.');
}
}
// LLM을 사용한 브리핑 생성
async function generateBriefingsWithLLM(input) {
const apiKey = 'YOUR_OPENAI_API_KEY_HERE';
const model = 'gpt-4o-2024-11-20';
// 기존 브리핑 패턴 분석
const briefingExamples = MONEY_BRIEFINGS.slice(0, 10).map(b =>
`제목: ${b.title}\n분류: ${b.type}\n내용: ${b.content}\n타겟: ${b.target}\n버튼: ${b.button}`
).join('\n\n');
// CDP 컬럼 요약
const cdpSummary = Object.entries(CDP_COLUMNS).map(([category, columns]) => {
const sampleColumns = Object.entries(columns).slice(0, 5).map(([key, desc]) => `${key}: ${desc}`).join('\n');
return `${category}:\n${sampleColumns}`;
}).join('\n\n');
const systemPrompt = `당신은 네이버페이 머니브리핑 소재를 전문으로 만드는 마케터입니다. 사용자가 제공한 아이디어를 바탕으로 6개의 새로운 브리핑 소재를 생성해야 합니다.
기존 브리핑 패턴 (참고용):
${briefingExamples}
브리핑 분류 (7가지 중 선택):
1. 생활과 연관된 돈 - 일상생활과 관련된 금전 관리
2. 불린 돈 - 투자, 수익, 자산 증가 관련
3. 나간 돈 - 지출, 결제, 소비 관련
4. 들어오는 돈 - 수입, 송금, 적립 관련
5. 미래를 위한 돈 - 저축, 투자, 노후 준비 관련
6. 빌린 돈 - 대출, 신용, 금융 관련
7. 경제/자산컨텐츠 - 경제 동향, 금융 정보 관련
CDP 컬럼 (타겟팅용):
${cdpSummary}
반드시 JSON 형식으로 응답하세요:
{
"briefings": [
{
"title": "브리핑 제목",
"category": "분류 (위 7가지 중 선택)",
"content": "브리핑 내용 (구체적이고 개인화된 메시지)",
"target": "타겟 고객 (CDP 컬럼 기반으로 구체적으로)",
"button": "버튼 텍스트",
"reason": "이 브리핑이 적절한 이유와 기대 효과"
}
]
}`;
const userPrompt = `아이디어: "${input}"
이 아이디어를 바탕으로 6개의 다양한 머니브리핑 소재를 생성해주세요. 각 브리핑은 서로 다른 관점과 타겟을 가져야 합니다.`;
try {
const response = await fetch('https://api.openai.com/v1/chat/completions', {
method: 'POST',
headers: {
'Authorization': `Bearer ${apiKey}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
model: model,
messages: [
{ role: 'system', content: systemPrompt },
{ role: 'user', content: userPrompt }
],
temperature: 0.8,
max_tokens: 3000,
response_format: { type: "json_object" }
})
});
if (!response.ok) {
throw new Error(`OpenAI API error: ${response.status} ${response.statusText}`);
}
const data = await response.json();
const llmResponse = data.choices[0].message.content;
try {
const parsedResponse = JSON.parse(llmResponse);
return parsedResponse.briefings || [];
} catch (e) {
console.error('JSON 파싱 실패:', e);
throw new Error('LLM 응답을 파싱할 수 없습니다.');
}
} catch (error) {
console.error('OpenAI API 호출 실패:', error);
throw error;
}
}
// 생성된 브리핑 표시
function displayGeneratedBriefings(briefings) {
const container = document.getElementById('generatorResults');
if (!briefings || briefings.length === 0) {
container.innerHTML = '<p>브리핑을 생성하지 못했습니다.</p>';
return;
}
container.innerHTML = briefings.map(briefing => `
<div class="generated-briefing-card">
<div class="generated-briefing-header">
<div class="generated-briefing-title">${briefing.title}</div>
<div class="generated-briefing-category">${briefing.category}</div>
</div>
<div class="generated-briefing-content">
${briefing.content}
</div>
<div class="generated-briefing-meta">
<div class="generated-briefing-field">
<div class="generated-briefing-label">🎯 타겟 고객</div>
<div class="generated-briefing-value">${briefing.target}</div>
</div>
<div class="generated-briefing-field">
<div class="generated-briefing-label">🔗 버튼 액션</div>
<div class="generated-briefing-value">${briefing.button}</div>
</div>
</div>
<div class="generated-briefing-reason">
<div class="generated-briefing-reason-title">💡 제안 이유</div>
<div class="generated-briefing-reason-content">${briefing.reason}</div>
</div>
</div>
`).join('');
}
// ===== 자산 변동 브리핑 관련 함수들 =====
// 만원 단위 포맷팅 함수
function formatWonUnit(value) {
if (value === 0) return '0만원';
return `${value.toLocaleString()}만원`;
}
// 변동 포맷팅 함수 (+ 또는 - 표시 포함)
function formatChangeWonUnit(value) {
if (value === 0) return '0만원';
const sign = value >= 0 ? '+' : '';
return `${sign}${value.toLocaleString()}만원`;
}
// 자산 탭 초기화
function initializeAssetTab() {
updateAssetFormFromData();
}
// 자산 폼 데이터 업데이트
function updateAssetFormFromData() {
document.getElementById('currBankValue').value = assetData.current.CURR_BANK_VALUE;
document.getElementById('prevBankValue').value = assetData.previous.PREV_BANK_VALUE;
document.getElementById('currStockValue').value = assetData.current.CURR_STOCK_VALUE;
document.getElementById('prevStockValue').value = assetData.previous.PREV_STOCK_VALUE;
document.getElementById('currRealestateValue').value = assetData.current.CURR_REALESTATE_VALUE;
document.getElementById('prevRealestateValue').value = assetData.previous.PREV_REALESTATE_VALUE;
document.getElementById('currPensionValue').value = assetData.current.CURR_PENSION_VALUE;
document.getElementById('prevPensionValue').value = assetData.previous.PREV_PENSION_VALUE;
document.getElementById('currLoanBalance').value = assetData.current.CURR_LOAN_BALANCE;
document.getElementById('prevLoanBalance').value = assetData.previous.PREV_LOAN_BALANCE;
document.getElementById('currCardPaymentDue').value = assetData.current.CURR_CARD_PAYMENT_DUE;
document.getElementById('prevCardPaymentDue').value = assetData.previous.PREV_CARD_PAYMENT_DUE;
document.getElementById('currCarValue').value = assetData.current.CURR_CAR_VALUE;
document.getElementById('prevCarValue').value = assetData.previous.PREV_CAR_VALUE;
document.getElementById('currPointmoneyValue').value = assetData.current.CURR_POINTMONEY_VALUE;
document.getElementById('prevPointmoneyValue').value = assetData.previous.PREV_POINTMONEY_VALUE;
}
// 폼에서 자산 데이터 읽기
function readAssetDataFromForm() {
assetData.current.CURR_BANK_VALUE = parseInt(document.getElementById('currBankValue').value) || 0;
assetData.previous.PREV_BANK_VALUE = parseInt(document.getElementById('prevBankValue').value) || 0;
assetData.current.CURR_STOCK_VALUE = parseInt(document.getElementById('currStockValue').value) || 0;
assetData.previous.PREV_STOCK_VALUE = parseInt(document.getElementById('prevStockValue').value) || 0;
assetData.current.CURR_REALESTATE_VALUE = parseInt(document.getElementById('currRealestateValue').value) || 0;
assetData.previous.PREV_REALESTATE_VALUE = parseInt(document.getElementById('prevRealestateValue').value) || 0;
assetData.current.CURR_PENSION_VALUE = parseInt(document.getElementById('currPensionValue').value) || 0;
assetData.previous.PREV_PENSION_VALUE = parseInt(document.getElementById('prevPensionValue').value) || 0;
assetData.current.CURR_LOAN_BALANCE = parseInt(document.getElementById('currLoanBalance').value) || 0;
assetData.previous.PREV_LOAN_BALANCE = parseInt(document.getElementById('prevLoanBalance').value) || 0;
assetData.current.CURR_CARD_PAYMENT_DUE = parseInt(document.getElementById('currCardPaymentDue').value) || 0;
assetData.previous.PREV_CARD_PAYMENT_DUE = parseInt(document.getElementById('prevCardPaymentDue').value) || 0;
assetData.current.CURR_CAR_VALUE = parseInt(document.getElementById('currCarValue').value) || 0;
assetData.previous.PREV_CAR_VALUE = parseInt(document.getElementById('prevCarValue').value) || 0;
assetData.current.CURR_POINTMONEY_VALUE = parseInt(document.getElementById('currPointmoneyValue').value) || 0;
assetData.previous.PREV_POINTMONEY_VALUE = parseInt(document.getElementById('prevPointmoneyValue').value) || 0;
}
// 자산 변동 계산
function calculateAssetChanges() {
readAssetDataFromForm();
// 총자산 계산 (부채 제외)
const currentAssets = assetData.current.CURR_BANK_VALUE +
assetData.current.CURR_STOCK_VALUE +
assetData.current.CURR_REALESTATE_VALUE +
assetData.current.CURR_PENSION_VALUE +
assetData.current.CURR_CAR_VALUE +
assetData.current.CURR_POINTMONEY_VALUE;
const previousAssets = assetData.previous.PREV_BANK_VALUE +
assetData.previous.PREV_STOCK_VALUE +
assetData.previous.PREV_REALESTATE_VALUE +
assetData.previous.PREV_PENSION_VALUE +
assetData.previous.PREV_CAR_VALUE +
assetData.previous.PREV_POINTMONEY_VALUE;
// 순자산 계산 (부채 차감)
const currentNetAssets = currentAssets - assetData.current.CURR_LOAN_BALANCE - assetData.current.CURR_CARD_PAYMENT_DUE;
const previousNetAssets = previousAssets - assetData.previous.PREV_LOAN_BALANCE - assetData.previous.PREV_CARD_PAYMENT_DUE;
assetData.current.CURRENT_TOTAL_ASSET_VALUE = currentNetAssets;
assetData.previous.PREVIOUS_TOTAL_ASSET_VALUE = previousNetAssets;
const totalChange = currentNetAssets - previousNetAssets;
const totalChangeRate = previousNetAssets !== 0 ? (totalChange / previousNetAssets * 100) : 0;
// 개별 항목 변동 계산
const changes = [
{
name: '은행',
change: assetData.current.CURR_BANK_VALUE - assetData.previous.PREV_BANK_VALUE,
rate: assetData.previous.PREV_BANK_VALUE !== 0 ?
((assetData.current.CURR_BANK_VALUE - assetData.previous.PREV_BANK_VALUE) / assetData.previous.PREV_BANK_VALUE * 100) : 0
},
{
name: '증권',
change: assetData.current.CURR_STOCK_VALUE - assetData.previous.PREV_STOCK_VALUE,
rate: assetData.previous.PREV_STOCK_VALUE !== 0 ?
((assetData.current.CURR_STOCK_VALUE - assetData.previous.PREV_STOCK_VALUE) / assetData.previous.PREV_STOCK_VALUE * 100) : 0
},
{
name: '부동산',
change: assetData.current.CURR_REALESTATE_VALUE - assetData.previous.PREV_REALESTATE_VALUE,
rate: assetData.previous.PREV_REALESTATE_VALUE !== 0 ?
((assetData.current.CURR_REALESTATE_VALUE - assetData.previous.PREV_REALESTATE_VALUE) / assetData.previous.PREV_REALESTATE_VALUE * 100) : 0
},
{
name: '연금',
change: assetData.current.CURR_PENSION_VALUE - assetData.previous.PREV_PENSION_VALUE,
rate: assetData.previous.PREV_PENSION_VALUE !== 0 ?
((assetData.current.CURR_PENSION_VALUE - assetData.previous.PREV_PENSION_VALUE) / assetData.previous.PREV_PENSION_VALUE * 100) : 0
},
{
name: '대출',
change: assetData.previous.PREV_LOAN_BALANCE - assetData.current.CURR_LOAN_BALANCE, // 대출은 감소가 좋음
rate: assetData.previous.PREV_LOAN_BALANCE !== 0 ?
((assetData.previous.PREV_LOAN_BALANCE - assetData.current.CURR_LOAN_BALANCE) / assetData.previous.PREV_LOAN_BALANCE * 100) : 0
},
{
name: '카드청구',
change: assetData.previous.PREV_CARD_PAYMENT_DUE - assetData.current.CURR_CARD_PAYMENT_DUE, // 청구액 감소가 좋음
rate: assetData.previous.PREV_CARD_PAYMENT_DUE !== 0 ?
((assetData.previous.PREV_CARD_PAYMENT_DUE - assetData.current.CURR_CARD_PAYMENT_DUE) / assetData.previous.PREV_CARD_PAYMENT_DUE * 100) : 0
}
];
// 가장 큰 증가/감소 찾기
const positiveChanges = changes.filter(c => c.change > 0).sort((a, b) => b.change - a.change);
const negativeChanges = changes.filter(c => c.change < 0).sort((a, b) => a.change - b.change);
const biggestIncrease = positiveChanges[0] || { name: '없음', change: 0, rate: 0 };
const biggestDecrease = negativeChanges[0] || { name: '없음', change: 0, rate: 0 };
// UI 업데이트
document.getElementById('totalAssetChange').textContent = formatChangeWonUnit(totalChange);
document.getElementById('totalAssetChangeRate').textContent =
`${totalChangeRate >= 0 ? '+' : ''}${totalChangeRate.toFixed(1)}%`;
document.getElementById('biggestIncrease').textContent =
`${biggestIncrease.name} ${formatChangeWonUnit(biggestIncrease.change)}`;
document.getElementById('biggestIncreaseRate').textContent =
`+${biggestIncrease.rate.toFixed(1)}%`;
document.getElementById('biggestDecrease').textContent =
`${biggestDecrease.name} ${formatChangeWonUnit(biggestDecrease.change)}`;
document.getElementById('biggestDecreaseRate').textContent =
`${biggestDecrease.rate.toFixed(1)}%`;
// 요약 섹션 표시
document.getElementById('assetSummary').style.display = 'block';
showNotification('💰 자산 변동이 계산되었습니다!');
}
// 자산 브리핑 생성
async function generateAssetBriefings() {
readAssetDataFromForm();
// 로딩 시작
document.getElementById('assetLoadingSection').style.display = 'block';
document.getElementById('assetBriefingsResults').innerHTML = '';
try {
// 자산 변동 계산
calculateAssetChanges();
const briefings = await generateAssetBriefingsWithLLM();
displayAssetBriefings(briefings);
} catch (error) {
console.error('자산 브리핑 생성 오류:', error);
showNotification('❌ 자산 브리핑 생성 중 오류가 발생했습니다.');
} finally {
document.getElementById('assetLoadingSection').style.display = 'none';
}
}
// 추천용 자산 변동 계산
function calculateAssetChangesForRecommendation() {
readAssetDataFromForm();
return {
'은행': {
change: assetData.current.CURR_BANK_VALUE - assetData.previous.PREV_BANK_VALUE,
rate: assetData.previous.PREV_BANK_VALUE !== 0 ?
((assetData.current.CURR_BANK_VALUE - assetData.previous.PREV_BANK_VALUE) / assetData.previous.PREV_BANK_VALUE * 100) : 0
},
'증권': {
change: assetData.current.CURR_STOCK_VALUE - assetData.previous.PREV_STOCK_VALUE,
rate: assetData.previous.PREV_STOCK_VALUE !== 0 ?
((assetData.current.CURR_STOCK_VALUE - assetData.previous.PREV_STOCK_VALUE) / assetData.previous.PREV_STOCK_VALUE * 100) : 0
},
'부동산': {
change: assetData.current.CURR_REALESTATE_VALUE - assetData.previous.PREV_REALESTATE_VALUE,
rate: assetData.previous.PREV_REALESTATE_VALUE !== 0 ?
((assetData.current.CURR_REALESTATE_VALUE - assetData.previous.PREV_REALESTATE_VALUE) / assetData.previous.PREV_REALESTATE_VALUE * 100) : 0
},
'연금': {
change: assetData.current.CURR_PENSION_VALUE - assetData.previous.PREV_PENSION_VALUE,
rate: assetData.previous.PREV_PENSION_VALUE !== 0 ?
((assetData.current.CURR_PENSION_VALUE - assetData.previous.PREV_PENSION_VALUE) / assetData.previous.PREV_PENSION_VALUE * 100) : 0
},
'대출': {
change: assetData.previous.PREV_LOAN_BALANCE - assetData.current.CURR_LOAN_BALANCE, // 대출은 감소가 좋음
rate: assetData.previous.PREV_LOAN_BALANCE !== 0 ?
((assetData.previous.PREV_LOAN_BALANCE - assetData.current.CURR_LOAN_BALANCE) / assetData.previous.PREV_LOAN_BALANCE * 100) : 0
},
'카드청구': {
change: assetData.previous.PREV_CARD_PAYMENT_DUE - assetData.current.CURR_CARD_PAYMENT_DUE, // 청구액 감소가 좋음
rate: assetData.previous.PREV_CARD_PAYMENT_DUE !== 0 ?
((assetData.previous.PREV_CARD_PAYMENT_DUE - assetData.current.CURR_CARD_PAYMENT_DUE) / assetData.previous.PREV_CARD_PAYMENT_DUE * 100) : 0
}
};
}
// 기존 브리핑 추천 알고리즘
function getRelatedBriefings(assetChanges) {
const relatedBriefings = [];
// 자산 변동에 따른 기존 브리핑 매핑
const assetMapping = {
bank_increase: [1, 11, 19], // 은행 증가 -> 만기연장, 숨은돈찾기, 지출분석
stock_increase: [14, 15, 17, 18], // 증권 증가 -> 배당금, 평가금액변동, 신규계좌, 청약일정
stock_decrease: [16], // 증권 감소 -> 예수금 발견
realestate_increase: [65, 66], // 부동산 증가 -> 실거래가, 시세알림
pension_increase: [12, 13], // 연금 증가 -> 연금개시, 연금미납
loan_decrease: [28, 37, 38], // 대출 감소 -> 신규대출계좌, 이자납입일, 대출만기
card_decrease: [3, 4], // 카드 감소 -> 청구서도착, 카드결제일
general_asset: [19, 49, 67] // 종합 자산 -> 지출분석, 대출소식, 머니스토리
};
// 변동이 큰 항목에 따른 브리핑 추천
Object.keys(assetChanges).forEach(key => {
const change = assetChanges[key];
if (Math.abs(change.change) > 100) { // 100만원 이상 변동
switch (key) {
case '은행':
if (change.change > 0) relatedBriefings.push(...assetMapping.bank_increase);
break;
case '증권':
if (change.change > 0) relatedBriefings.push(...assetMapping.stock_increase);
else relatedBriefings.push(...assetMapping.stock_decrease);
break;
case '부동산':
if (change.change > 0) relatedBriefings.push(...assetMapping.realestate_increase);
break;
case '연금':
if (change.change > 0) relatedBriefings.push(...assetMapping.pension_increase);
break;
case '대출':
if (change.change > 0) relatedBriefings.push(...assetMapping.loan_decrease); // 대출 감소가 좋음
break;
case '카드청구':
if (change.change > 0) relatedBriefings.push(...assetMapping.card_decrease); // 청구액 감소가 좋음
break;
}
}
});
// 기본 추천 브리핑 (항상 포함)
relatedBriefings.push(...assetMapping.general_asset);
// 중복 제거 및 실제 브리핑 데이터 반환
const uniqueBriefingNos = [...new Set(relatedBriefings)];
return MONEY_BRIEFINGS.filter(briefing => uniqueBriefingNos.includes(briefing.no)).slice(0, 5);
}
// GPT-4를 활용한 자산 브리핑 생성
async function generateAssetBriefingsWithLLM() {
const apiKey = 'YOUR_OPENAI_API_KEY_HERE';
// 자산 변동 요약 생성
const assetSummary = generateAssetSummary();
// 관련 기존 브리핑 찾기
const assetChanges = calculateAssetChangesForRecommendation();
const relatedBriefings = getRelatedBriefings(assetChanges);
const briefingSummary = relatedBriefings.map(b => `- ${b.title}: ${b.content.substring(0, 100)}...`).join('\n');
const prompt = `당신은 네이버페이 개인 자산 변동 브리핑을 전문으로 만드는 AI 어시스턴트입니다.
사용자의 자산 변동 데이터:
${assetSummary}
관련 기존 브리핑 (참고용):
${briefingSummary}
위 자산 변동 데이터와 기존 브리핑을 참고하여 6-8개의 맞춤형 자산 변동 브리핑을 생성해주세요.
기존 브리핑의 패턴과 톤을 참고하되, 사용자의 실제 자산 변동에 맞게 개인화해주세요.
각 브리핑은 다음 7가지 분류 중 하나여야 합니다:
1. 생활과 연관된 돈 - 일상생활과 관련된 금전 관리
2. 불린 돈 - 투자, 수익, 자산 증가 관련
3. 나간 돈 - 지출, 결제, 소비 관련
4. 들어오는 돈 - 수입, 송금, 적립 관련
5. 미래를 위한 돈 - 저축, 투자, 노후 준비 관련
6. 빌린 돈 - 대출, 신용, 금융 관련
7. 경제/자산컨텐츠 - 경제 동향, 금융 정보 관련
응답은 반드시 다음 JSON 형식으로 해주세요:
{
"briefings": [
{
"title": "브리핑 제목 (감정적, 개인화된 메시지)",
"category": "분류 (위 7가지 중 선택)",
"content": "브리핑 내용 (구체적인 금액과 개인화된 메시지, 2-3문장)",
"target": "타겟 고객 (자산 변동 패턴 기반으로 구체적으로)",
"button": "버튼 텍스트 (액션 유도)",
"landing_page": {
"type": "페이지 타입 (예: stock_performance, loan_tracker, asset_report 등)",
"charts": ["차트1", "차트2", "차트3"],
"insights": ["인사이트1", "인사이트2"]
},
"reason": "이 브리핑이 적절한 이유와 기대 효과"
}
]
}`;
try {
const response = await fetch('https://api.openai.com/v1/chat/completions', {
method: 'POST',
headers: {
'Authorization': `Bearer ${apiKey}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
model: 'gpt-4o-2024-11-20',
messages: [
{
role: 'system',
content: '당신은 네이버페이 개인 자산 변동 브리핑을 전문으로 만드는 AI 어시스턴트입니다. 사용자의 자산 변동을 분석하여 맞춤형 브리핑을 생성합니다.'
},
{
role: 'user',
content: prompt
}
],
temperature: 0.8,
max_tokens: 3000,
response_format: { type: "json_object" }
})
});
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const data = await response.json();
const content = data.choices[0].message.content;
try {
const parsed = JSON.parse(content);
return parsed.briefings || [];
} catch (parseError) {
console.error('JSON 파싱 오류:', parseError);
return [];
}
} catch (error) {
console.error('API 호출 오류:', error);
throw error;
}
}
// 자산 변동 요약 생성
function generateAssetSummary() {
const currentTotal = assetData.current.CURRENT_TOTAL_ASSET_VALUE || 0;
const previousTotal = assetData.previous.PREVIOUS_TOTAL_ASSET_VALUE || 0;
const totalChange = currentTotal - previousTotal;
const totalChangeRate = previousTotal !== 0 ? (totalChange / previousTotal * 100) : 0;
return `
- 총자산: ${formatWonUnit(previousTotal)} → ${formatWonUnit(currentTotal)} (${totalChangeRate >= 0 ? '+' : ''}${totalChangeRate.toFixed(1)}%, ${formatChangeWonUnit(totalChange)})
- 은행: ${formatWonUnit(assetData.previous.PREV_BANK_VALUE)} → ${formatWonUnit(assetData.current.CURR_BANK_VALUE)}
- 증권: ${formatWonUnit(assetData.previous.PREV_STOCK_VALUE)} → ${formatWonUnit(assetData.current.CURR_STOCK_VALUE)}
- 부동산: ${formatWonUnit(assetData.previous.PREV_REALESTATE_VALUE)} → ${formatWonUnit(assetData.current.CURR_REALESTATE_VALUE)}
- 연금: ${formatWonUnit(assetData.previous.PREV_PENSION_VALUE)} → ${formatWonUnit(assetData.current.CURR_PENSION_VALUE)}
- 대출: ${formatWonUnit(assetData.previous.PREV_LOAN_BALANCE)} → ${formatWonUnit(assetData.current.CURR_LOAN_BALANCE)}
- 카드청구: ${formatWonUnit(assetData.previous.PREV_CARD_PAYMENT_DUE)} → ${formatWonUnit(assetData.current.CURR_CARD_PAYMENT_DUE)}
- 자동차: ${formatWonUnit(assetData.previous.PREV_CAR_VALUE)} → ${formatWonUnit(assetData.current.CURR_CAR_VALUE)}
- 포인트/머니: ${formatWonUnit(assetData.previous.PREV_POINTMONEY_VALUE)} → ${formatWonUnit(assetData.current.CURR_POINTMONEY_VALUE)}
`.trim();
}
// 생성된 자산 브리핑 표시
function displayAssetBriefings(briefings) {
const container = document.getElementById('assetBriefingsResults');
if (!briefings || briefings.length === 0) {
container.innerHTML = '<p>자산 브리핑을 생성하지 못했습니다.</p>';
return;
}
// 관련 기존 브리핑도 같이 표시
const assetChanges = calculateAssetChangesForRecommendation();
const relatedBriefings = getRelatedBriefings(assetChanges);
container.innerHTML = `
<!-- AI 생성 브리핑 -->
<div class="generated-briefings-section">
<h3>🤖 AI 생성 자산 변동 브리핑</h3>
${briefings.map(briefing => `
<div class="generated-briefing-card asset-briefing-card">
<div class="generated-briefing-header">
<div class="generated-briefing-title">${briefing.title}</div>
<div class="generated-briefing-category">${briefing.category}</div>
</div>
<div class="generated-briefing-content">
${briefing.content}
</div>
<div class="generated-briefing-meta">
<div class="generated-briefing-field">
<div class="generated-briefing-label">🎯 타겟 고객</div>
<div class="generated-briefing-value">${briefing.target}</div>
</div>
<div class="generated-briefing-field">
<div class="generated-briefing-label">🔗 버튼 액션</div>
<div class="generated-briefing-value">
<button class="landing-page-btn" onclick="showLandingPage('${briefing.landing_page?.type || 'default'}', '${briefing.title}')">
${briefing.button}
</button>
</div>
</div>
</div>
${briefing.landing_page ? `
<div class="landing-page-info">
<div class="landing-page-label">📊 랜딩 페이지 구성</div>
<div class="landing-page-details">
<div>차트: ${briefing.landing_page.charts?.join(', ') || '없음'}</div>
<div>인사이트: ${briefing.landing_page.insights?.join(', ') || '없음'}</div>
</div>
</div>
` : ''}
<div class="generated-briefing-reason">
<div class="generated-briefing-reason-title">💡 제안 이유</div>
<div class="generated-briefing-reason-content">${briefing.reason}</div>
</div>
</div>
`).join('')}
</div>
<!-- 관련 기존 브리핑 -->
${relatedBriefings.length > 0 ? `
<div class="related-briefings-section" style="margin-top: 40px;">
<h3>📋 자산 변동 관련 기존 브리핑</h3>
<p style="color: #6c757d; margin-bottom: 20px;">현재 자산 상황에 맞는 기존 브리핑들을 추천드립니다.</p>
${relatedBriefings.map(briefing => `
<div class="briefing-card related-briefing" style="margin-bottom: 15px;">
<div class="briefing-header">
<div class="briefing-title">${briefing.title}</div>
<div style="display: flex; align-items: center; gap: 10px;">
<div class="briefing-category">${briefing.type}</div>
<div class="status-badge ${briefing.exposed === 'O' ? 'status-active' : 'status-inactive'}">
${briefing.exposed === 'O' ? '노출 중' : '비노출'}
</div>
</div>
</div>
<div class="briefing-content" style="margin: 10px 0; color: #495057;">
${briefing.content}
</div>
<div class="briefing-meta">
<span style="background: #e9ecef; padding: 4px 8px; border-radius: 10px; font-size: 12px;">
${briefing.button}
</span>
<span style="margin-left: 10px; color: #6c757d; font-size: 12px;">
타겟: ${briefing.target}
</span>
</div>
</div>
`).join('')}
</div>
` : ''}
`;
showNotification('🎉 자산 변동 브리핑이 생성되었습니다!');
}
// 랜딩 페이지 모달 표시
function showLandingPage(pageType, title) {
const modal = document.getElementById('landingPageModal');
const modalTitle = document.getElementById('modalTitle');
const modalBody = document.getElementById('modalBody');
modalTitle.textContent = title;
// 페이지 타입에 따른 콘텐츠 생성
let content = generateLandingPageContent(pageType, title);
modalBody.innerHTML = content;
modal.style.display = 'block';
// 모달 외부 클릭 시 닫기
modal.onclick = function(event) {
if (event.target === modal) {
closeLandingPage();
}
};
}
// 랜딩 페이지 콘텐츠 생성
function generateLandingPageContent(pageType, title) {
const mockData = {
stock_performance: {
stats: [
{ label: '총 수익률', value: '+6.7%' },
{ label: '수익 금액', value: '+500만원' },
{ label: '평가 금액', value: '8,000만원' }
],
charts: ['수익률 추이', '종목별 수익', '포트폴리오 구성'],
insights: [
{ title: '최고 수익 종목', content: '삼성전자가 +15.3%로 가장 높은 수익률을 기록했습니다.' },
{ title: '투자 성과 분석', content: 'IT 섹터의 강세로 전체 포트폴리오가 시장 대비 우수한 성과를 보이고 있습니다.' }
]
},
loan_tracker: {
stats: [
{ label: '상환 진행률', value: '32.5%' },
{ label: '남은 원금', value: '14,900만원' },
{ label: '예상 완납일', value: '2029년 6월' }
],
charts: ['상환 진행률', '예상 완납일', '이자 절감액'],
insights: [
{ title: '월별 상환 추이', content: '꾸준한 원금 상환으로 이자 부담이 점진적으로 감소하고 있습니다.' },
{ title: '추가 상환 시뮬레이션', content: '월 50만원 추가 상환 시 2년 단축, 약 1,200만원 이자 절약 가능합니다.' }
]
},
asset_report: {
stats: [
{ label: '총 자산 증가', value: '+1,205만원' },
{ label: '증가율', value: '+2.3%' },
{ label: '현재 총 자산', value: '53,500만원' }
],
charts: ['자산 구성 파이차트', '월별 변동 추이', '카테고리별 성과'],
insights: [
{ title: '자산 배분 조언', content: '부동산 비중이 높으니 증권 투자를 늘려 포트폴리오를 다양화하는 것을 권장합니다.' },
{ title: '다음 달 전망', content: '현재 추세가 지속될 경우 연말까지 약 5% 추가 성장이 예상됩니다.' }
]
},
expense_analysis: {
stats: [
{ label: '이번 달 지출', value: '150만원' },
{ label: '전월 대비', value: '+50만원' },
{ label: '평균 일일 지출', value: '4.8만원' }
],
charts: ['카테고리별 지출', '일별 지출 패턴', '전월 비교'],
insights: [
{ title: '주요 지출 항목', content: '식비와 쇼핑 지출이 전월 대비 크게 증가했습니다.' },
{ title: '절약 가능 영역', content: '구독 서비스와 배달음식 지출을 줄이면 월 20만원 절약 가능합니다.' }
]
},
real_estate_value: {
stats: [
{ label: '현재 시세', value: '50,050만원' },
{ label: '전일 대비', value: '+500만원' },
{ label: '수익률', value: '+1.0%' }
],
charts: ['시세 변동 추이', '지역 평균 비교', '매매/전세 동향'],
insights: [
{ title: '투자 수익률', content: '최근 3개월간 꾸준한 상승세로 연 12% 수익률을 기록 중입니다.' },
{ title: '시장 전망', content: '해당 지역의 재개발 소식으로 향후 6개월간 추가 상승이 예상됩니다.' }
]
}
};
const data = mockData[pageType] || mockData.asset_report;
return `
<div class="modal-stats">
${data.stats.map(stat => `
<div class="modal-stat-card">
<div class="modal-stat-value">${stat.value}</div>
<div class="modal-stat-label">${stat.label}</div>
</div>
`).join('')}
</div>
<div class="chart-container">
<h3>📊 차트 분석</h3>
${data.charts.map(chart => `
<div class="chart-placeholder">
${chart} (실제 차트는 Chart.js로 구현 예정)
</div>
`).join('')}
</div>
<div class="insights-section">
<h3>💡 AI 인사이트</h3>
${data.insights.map(insight => `
<div class="insight-card">
<div class="insight-title">${insight.title}</div>
<div class="insight-content">${insight.content}</div>
</div>
`).join('')}
</div>
<div class="chart-container">
<h4>🔗 관련 액션</h4>
<button class="asset-generate-btn" onclick="showNotification('관련 서비스로 이동합니다.')">
서비스 바로가기
</button>
</div>
`;
}
// AI 아이디어 섹션 토글 함수
function toggleAiIdeasSection() {
const section = document.getElementById('aiIdeasSection');
if (section.style.display === 'none' || section.style.display === '') {
section.style.display = 'block';
// 부드러운 스크롤 효과
section.scrollIntoView({ behavior: 'smooth' });
} else {
section.style.display = 'none';
}
}
// 창의적 브리핑 아이디어 생성 함수
async function generateCreativeIdeas() {
// 사용자 프로필 데이터 수집
const userProfile = {
age: document.getElementById('userAge').value,
job: document.getElementById('userJob').value,
investmentStyle: document.getElementById('investmentStyle').value,
lifestyle: document.getElementById('lifestyle').value,
interests: document.getElementById('interests').value,
financialGoal: document.getElementById('financialGoal').value
};
// 현재 자산 데이터 수집
const currentAssets = collectCurrentAssetData();
// 로딩 섹션 표시
const loadingSection = document.getElementById('ideasLoadingSection');
const resultsSection = document.getElementById('ideasResults');
loadingSection.style.display = 'block';
resultsSection.innerHTML = '';
try {
// AI 아이디어 생성 (실제 API 호출 시뮬레이션)
const ideas = await generatePersonalizedIdeas(userProfile, currentAssets);
// 결과 표시
displayCreativeIdeas(ideas);
} catch (error) {
console.error('아이디어 생성 중 오류 발생:', error);
showNotification('❌ 아이디어 생성 중 오류가 발생했습니다.');
// 에러 발생 시 모의 데이터로 표시
const mockIdeas = generateMockCreativeIdeas(userProfile);
displayCreativeIdeas(mockIdeas);
} finally {
loadingSection.style.display = 'none';
}
}
// 현재 자산 데이터 수집
function collectCurrentAssetData() {
return {
bankValue: parseInt(document.getElementById('currBankValue').value) || 0,
stockValue: parseInt(document.getElementById('currStockValue').value) || 0,
realEstateValue: parseInt(document.getElementById('currRealEstateValue').value) || 0,
pensionValue: parseInt(document.getElementById('currPensionValue').value) || 0,
savingsValue: parseInt(document.getElementById('currSavingsValue').value) || 0,
insuranceValue: parseInt(document.getElementById('currInsuranceValue').value) || 0,
loanBalance: parseInt(document.getElementById('currLoanBalance').value) || 0,
carValue: parseInt(document.getElementById('currCarValue').value) || 0,
totalAssets: 0
};
}
// 개인화된 아이디어 생성 (AI API 시뮬레이션)
async function generatePersonalizedIdeas(userProfile, assetData) {
// 실제 구현에서는 OpenAI API 호출
return new Promise((resolve) => {
setTimeout(() => {
const ideas = generateMockCreativeIdeas(userProfile, assetData);
resolve(ideas);
}, 2000);
});
}
// 모의 창의적 아이디어 생성
function generateMockCreativeIdeas(userProfile, assetData = {}) {
const personalizedIdeas = [];
// 연령대별 맞춤 아이디어
const ageIdeas = {
'20s': [
{
title: "첫 직장인을 위한 '월급관리 마스터' 브리핑",
content: "매월 급여일에 자동으로 생활비, 저축, 투자 비율을 분석해주는 개인화된 가이드",
category: "생활과 연관된 돈",
target: "20-30대 신입 직장인",
button: "월급관리 시작하기",
uniqueness: "연령대 특화",
reason: "20대는 첫 경제활동 시작 시기로 올바른 자산관리 습관 형성이 중요"
},
{
title: "청년 투자자를 위한 '작은 돈 큰 수익' 챌린지",
content: "소액으로 시작하는 분산투자 전략과 매주 성과 리포트",
category: "불린 돈",
target: "20-30대 투자 입문자",
button: "투자 챌린지 참여",
uniqueness: "연령대 특화",
reason: "젊은 층의 장기투자 시작을 독려하고 성취감을 제공"
}
],
'30s': [
{
title: "30대 직장인을 위한 '내집마련 로드맵' 브리핑",
content: "현재 자산 기준 주택 구입 가능 시기와 전략을 시뮬레이션",
category: "미래를 위한 돈",
target: "30대 무주택자",
button: "내집마련 계획보기",
uniqueness: "연령대 특화",
reason: "30대는 주택 구입을 본격 검토하는 시기"
}
],
'40s': [
{
title: "40대를 위한 '중년 재테크 리밸런싱' 가이드",
content: "자녀 교육비와 노후자금을 동시에 준비하는 포트폴리오 전략",
category: "미래를 위한 돈",
target: "40대 가장",
button: "재테크 전략보기",
uniqueness: "연령대 특화",
reason: "교육비 부담과 노후준비를 병행해야 하는 시기"
}
]
};
// 직업군별 맞춤 아이디어
const jobIdeas = {
'office_worker': {
title: "직장인 전용 '보너스 활용법' 브리핑",
content: "상여금, 성과급 등 불규칙한 수입을 효율적으로 활용하는 전략",
category: "들어오는 돈",
target: "직장인",
button: "보너스 활용전략보기",
uniqueness: "직업 특화"
},
'business_owner': {
title: "사업자를 위한 '세금 최적화' 브리핑",
content: "사업 소득과 개인 자산을 분리한 효율적인 세무 전략",
category: "나간 돈",
target: "개인사업자/법인사업자",
button: "세무전략 확인하기",
uniqueness: "직업 특화"
},
'freelancer': {
title: "프리랜서를 위한 '불규칙 소득 관리법'",
content: "월마다 다른 수입에 맞춘 유연한 가계부 시스템",
category: "생활과 연관된 돈",
target: "프리랜서",
button: "소득관리 시작하기",
uniqueness: "직업 특화"
}
};
// 투자성향별 아이디어
const investmentIdeas = {
'conservative': {
title: "안정형 투자자를 위한 '리스크 제로 수익 창출법'",
content: "예금금리보다 높으면서도 원금보장이 되는 상품들의 조합 전략",
category: "불린 돈",
target: "보수적 투자자",
button: "안정투자 상품보기",
uniqueness: "투자성향 특화"
},
'aggressive': {
title: "적극형 투자자를 위한 '하이리스크 하이리턴' 포트폴리오",
content: "새로운 투자 기회와 위험 관리 전략을 결합한 공격적 투자법",
category: "불린 돈",
target: "적극적 투자자",
button: "고수익 전략보기",
uniqueness: "투자성향 특화"
}
};
// 라이프스타일별 아이디어
const lifestyleIdeas = {
'frugal': {
title: "절약왕을 위한 '숨은 지출 찾기' 브리핑",
content: "생활 속 불필요한 지출을 찾아내는 AI 분석과 절약 팁",
category: "나간 돈",
target: "절약 지향 고객",
button: "숨은지출 분석하기",
uniqueness: "라이프스타일 특화"
},
'luxury': {
title: "프리미엄 라이프를 위한 '럭셔리 투자' 가이드",
content: "고가 소비와 투자를 균형있게 관리하는 방법",
category: "생활과 연관된 돈",
target: "고소비층",
button: "프리미엄 전략보기",
uniqueness: "라이프스타일 특화"
}
};
// 관심분야별 아이디어
const interestIdeas = {
'tech': {
title: "테크 전문가를 위한 'IT 주식 투자' 인사이트",
content: "기술 트렌드를 활용한 투자 기회 발굴과 포트폴리오 구성",
category: "불린 돈",
target: "IT 관심층",
button: "테크 투자전략보기",
uniqueness: "관심분야 특화"
},
'real_estate': {
title: "부동산 통을 위한 '지역별 투자 기회' 브리핑",
content: "현재 보유 부동산 기준 추가 투자 지역과 타이밍 분석",
category: "불린 돈",
target: "부동산 투자자",
button: "투자지역 분석보기",
uniqueness: "관심분야 특화"
}
};
// 선택된 프로필에 따른 아이디어 선별
if (ageIdeas[userProfile.age]) {
personalizedIdeas.push(...ageIdeas[userProfile.age]);
}
if (jobIdeas[userProfile.job]) {
personalizedIdeas.push(jobIdeas[userProfile.job]);
}
if (investmentIdeas[userProfile.investmentStyle]) {
personalizedIdeas.push(investmentIdeas[userProfile.investmentStyle]);
}
if (lifestyleIdeas[userProfile.lifestyle]) {
personalizedIdeas.push(lifestyleIdeas[userProfile.lifestyle]);
}
if (interestIdeas[userProfile.interests]) {
personalizedIdeas.push(interestIdeas[userProfile.interests]);
}
// 추가 범용 창의적 아이디어
const universalIdeas = [
{
title: "AI 개인비서 '머니메이트' - 24시간 자산 모니터링",
content: "챗봇 형태로 언제든 자산 현황과 투자 조언을 받을 수 있는 개인화 서비스",
category: "경제/자산컨텐츠",
target: "모든 연령층",
button: "AI 비서 체험하기",
uniqueness: "AI 융합",
reason: "개인화된 AI 서비스는 차별화된 고객 경험을 제공"
},
{
title: "가족 자산 공유 '패밀리 월렛' 대시보드",
content: "가족 구성원별 자산 현황을 통합 관리하고 목표 달성을 함께 추진",
category: "생활과 연관된 돈",
target: "가족 단위 고객",
button: "패밀리 대시보드 보기",
uniqueness: "가족 단위 서비스",
reason: "가족 중심의 재테크는 새로운 시장 니즈"
}
];
personalizedIdeas.push(...universalIdeas);
return personalizedIdeas.slice(0, 6); // 최대 6개 아이디어 반환
}
// 창의적 아이디어 결과 표시
function displayCreativeIdeas(ideas) {
const resultsDiv = document.getElementById('ideasResults');
if (ideas.length === 0) {
resultsDiv.innerHTML = `
<div class="no-ideas">
<h3>💡 아이디어를 생성할 수 없습니다</h3>
<p>프로필 정보를 다시 확인해보세요.</p>
</div>
`;
return;
}
resultsDiv.innerHTML = `
<div class="ideas-header">
<h3>🧠 맞춤형 브리핑 아이디어 (${ideas.length}개)</h3>
<p>당신의 프로필을 분석하여 생성된 창의적인 브리핑 아이디어입니다.</p>
</div>
<div class="ideas-grid">
${ideas.map((idea, index) => `
<div class="idea-card" data-idea-index="${index}">
<div class="idea-header">
<div class="idea-title">${idea.title}</div>
<div class="idea-category">${idea.category}</div>
</div>
<div class="idea-content">
${idea.content}
</div>
<div class="idea-meta">
<div class="idea-target">🎯 타겟: ${idea.target}</div>
<div class="idea-button">📱 버튼: ${idea.button}</div>
${idea.uniqueness ? `<div class="idea-uniqueness">✨ ${idea.uniqueness}</div>` : ''}
</div>
${idea.reason ? `
<div class="idea-reason">
<strong>💡 추천 이유:</strong> ${idea.reason}
</div>
` : ''}
<div class="idea-actions">
<button class="rate-idea-btn" onclick="rateIdea(${index}, 'like')">
👍 좋아요
</button>
<button class="implement-idea-btn" onclick="implementIdea(${index})">
🚀 브리핑으로 구현
</button>
</div>
</div>
`).join('')}
</div>
<div class="ideas-summary">
<h4>📊 아이디어 분석 요약</h4>
<div class="summary-stats">
<div class="summary-stat">
<span class="stat-label">가장 많은 카테고리:</span>
<span class="stat-value">${getMostCommonCategory(ideas)}</span>
</div>
<div class="summary-stat">
<span class="stat-label">개인화 레벨:</span>
<span class="stat-value">높음 (프로필 기반 생성)</span>
</div>
</div>
</div>
`;
showNotification('🎉 창의적인 브리핑 아이디어가 생성되었습니다!');
}
// 가장 많은 카테고리 찾기
function getMostCommonCategory(ideas) {
const categories = ideas.map(idea => idea.category);
const counts = {};
categories.forEach(cat => counts[cat] = (counts[cat] || 0) + 1);
return Object.keys(counts).reduce((a, b) => counts[a] > counts[b] ? a : b);
}
// 아이디어 평가 함수
function rateIdea(ideaIndex, rating) {
showNotification(`💝 아이디어 #${ideaIndex + 1}에 ${rating === 'like' ? '좋아요' : '별로'}를 표시했습니다!`);
// 실제 구현에서는 사용자 피드백을 서버로 전송
console.log(`아이디어 평가: Index ${ideaIndex}, Rating: ${rating}`);
}
// 아이디어를 실제 브리핑으로 구현하는 함수
function implementIdea(ideaIndex) {
const ideaCards = document.querySelectorAll('.idea-card');
const selectedCard = ideaCards[ideaIndex];
if (!selectedCard) return;
const ideaTitle = selectedCard.querySelector('.idea-title').textContent;
const ideaContent = selectedCard.querySelector('.idea-content').textContent;
const ideaCategory = selectedCard.querySelector('.idea-category').textContent;
const ideaTarget = selectedCard.querySelector('.idea-target').textContent.replace('🎯 타겟: ', '');
const ideaButton = selectedCard.querySelector('.idea-button').textContent.replace('📱 버튼: ', '');
// 실제 브리핑으로 변환
const newBriefing = {
title: ideaTitle,
content: ideaContent,
category: ideaCategory,
target: ideaTarget,
button: ideaButton,
reason: `사용자 프로필 기반 AI 생성 아이디어를 브리핑으로 구현`,
source: 'AI_CREATIVE_IDEAS'
};
// 자산 브리핑 결과에 추가
addCreatedBriefingToResults(newBriefing);
showNotification(`🚀 "${ideaTitle}"가 브리핑으로 생성되었습니다!`);
// 자산 브리핑 결과 섹션으로 스크롤
document.getElementById('assetBriefingsResults').scrollIntoView({ behavior: 'smooth' });
}
// 생성된 브리핑을 결과 영역에 추가
function addCreatedBriefingToResults(briefing) {
const resultsDiv = document.getElementById('assetBriefingsResults');
// 기존 결과가 있으면 추가, 없으면 새로 생성
const existingContent = resultsDiv.innerHTML;
const newBriefingHTML = `
<div class="briefing-result-section" style="margin-top: 20px;">
<h3>🧠 AI 창의 아이디어로 생성된 브리핑</h3>
<div class="briefing-card created-from-idea">
<div class="briefing-header">
<div class="briefing-title">${briefing.title}</div>
<div class="briefing-category">${briefing.category}</div>
</div>
<div class="briefing-content" style="margin: 10px 0; color: #495057;">
${briefing.content}
</div>
<div class="briefing-meta">
<span style="background: #ff6b35; color: white; padding: 4px 8px; border-radius: 10px; font-size: 12px;">
${briefing.button}
</span>
<span style="margin-left: 10px; color: #6c757d; font-size: 12px;">
타겟: ${briefing.target}
</span>
</div>
<div class="briefing-reason" style="margin-top: 10px; font-size: 13px; color: #6c757d; font-style: italic;">
💡 ${briefing.reason}
</div>
</div>
</div>
`;
if (existingContent.trim()) {
resultsDiv.innerHTML = existingContent + newBriefingHTML;
} else {
resultsDiv.innerHTML = newBriefingHTML;
}
}
// 모달 닫기
function closeLandingPage() {
document.getElementById('landingPageModal').style.display = 'none';
}
// 초기화
document.addEventListener('DOMContentLoaded', function() {
currentColumns = CDP_COLUMNS;
updateBriefingStats();
updateFilterButtonCounts();
renderBriefingCards();
renderCDPColumns();
// 도움말 표시
showNotification('💡 팁: Ctrl+1/2/3/4로 탭 전환, Ctrl+Enter로 분석 실행');
});
</script>
</body>
</html>