feat: 대시보드 모달에 관심상품 탭 추가
- /admin/user/<id> API에 interests 필드 추가
- ai_recommendations 테이블에서 status='interested' 조회
- 모달에 💝 관심 탭 추가
- 트리거 상품, 추천 이유 표시
This commit is contained in:
parent
3fc9bbaf8e
commit
8c366cc4db
@ -1448,7 +1448,27 @@ def admin_user_detail(user_id):
|
|||||||
except Exception as rx_error:
|
except Exception as rx_error:
|
||||||
logging.warning(f"조제 이력 조회 실패 (user {user_id}): {rx_error}")
|
logging.warning(f"조제 이력 조회 실패 (user {user_id}): {rx_error}")
|
||||||
|
|
||||||
# 7. 응답 생성
|
# 7. 관심상품 조회 (AI 추천에서 '관심있어요' 누른 상품)
|
||||||
|
interests = []
|
||||||
|
try:
|
||||||
|
cursor.execute("""
|
||||||
|
SELECT recommended_product, recommendation_reason, trigger_products, created_at
|
||||||
|
FROM ai_recommendations
|
||||||
|
WHERE user_id = ? AND status = 'interested'
|
||||||
|
ORDER BY created_at DESC
|
||||||
|
LIMIT 20
|
||||||
|
""", (user_id,))
|
||||||
|
for row in cursor.fetchall():
|
||||||
|
interests.append({
|
||||||
|
'product': row['recommended_product'],
|
||||||
|
'reason': row['recommendation_reason'],
|
||||||
|
'trigger_products': row['trigger_products'],
|
||||||
|
'created_at': utc_to_kst_str(row['created_at'])
|
||||||
|
})
|
||||||
|
except Exception as interest_error:
|
||||||
|
logging.warning(f"관심상품 조회 실패 (user {user_id}): {interest_error}")
|
||||||
|
|
||||||
|
# 8. 응답 생성
|
||||||
return jsonify({
|
return jsonify({
|
||||||
'success': True,
|
'success': True,
|
||||||
'user': {
|
'user': {
|
||||||
@ -1472,7 +1492,8 @@ def admin_user_detail(user_id):
|
|||||||
],
|
],
|
||||||
'purchases': purchases,
|
'purchases': purchases,
|
||||||
'prescriptions': prescriptions,
|
'prescriptions': prescriptions,
|
||||||
'pos_customer': pos_customer
|
'pos_customer': pos_customer,
|
||||||
|
'interests': interests
|
||||||
})
|
})
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
|||||||
@ -904,6 +904,9 @@
|
|||||||
<button onclick="switchTab('prescriptions')" id="tab-prescriptions" class="tab-btn" style="padding: 12px 20px; border: none; background: none; font-size: 15px; font-weight: 600; cursor: pointer; border-bottom: 3px solid transparent; color: #868e96;">
|
<button onclick="switchTab('prescriptions')" id="tab-prescriptions" class="tab-btn" style="padding: 12px 20px; border: none; background: none; font-size: 15px; font-weight: 600; cursor: pointer; border-bottom: 3px solid transparent; color: #868e96;">
|
||||||
💊 조제 (${data.prescriptions ? data.prescriptions.length : 0})
|
💊 조제 (${data.prescriptions ? data.prescriptions.length : 0})
|
||||||
</button>
|
</button>
|
||||||
|
<button onclick="switchTab('interests')" id="tab-interests" class="tab-btn" style="padding: 12px 20px; border: none; background: none; font-size: 15px; font-weight: 600; cursor: pointer; border-bottom: 3px solid transparent; color: #868e96;">
|
||||||
|
💝 관심 (${data.interests ? data.interests.length : 0})
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 정렬 버튼 (구매 이력용) -->
|
<!-- 정렬 버튼 (구매 이력용) -->
|
||||||
@ -1009,6 +1012,46 @@
|
|||||||
html += '<p style="text-align: center; padding: 40px; color: #868e96;">📭 조제 이력이 없습니다</p>';
|
html += '<p style="text-align: center; padding: 40px; color: #868e96;">📭 조제 이력이 없습니다</p>';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
html += `
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 관심상품 탭 -->
|
||||||
|
<div id="tab-content-interests" class="tab-content" style="display: none;">
|
||||||
|
`;
|
||||||
|
|
||||||
|
// 관심상품 렌더링
|
||||||
|
const interests = data.interests || [];
|
||||||
|
if (interests.length > 0) {
|
||||||
|
interests.forEach(item => {
|
||||||
|
// 날짜 포맷
|
||||||
|
const date = item.created_at || '';
|
||||||
|
|
||||||
|
// 트리거 상품 파싱
|
||||||
|
let triggerText = '';
|
||||||
|
try {
|
||||||
|
const triggers = JSON.parse(item.trigger_products || '[]');
|
||||||
|
if (triggers.length > 0) {
|
||||||
|
triggerText = triggers.join(', ');
|
||||||
|
}
|
||||||
|
} catch(e) {}
|
||||||
|
|
||||||
|
html += `
|
||||||
|
<div style="border: 1px solid #e9ecef; border-radius: 12px; margin-bottom: 12px; padding: 16px; border-left: 4px solid #ec4899;">
|
||||||
|
<div style="display: flex; justify-content: space-between; margin-bottom: 8px;">
|
||||||
|
<span style="font-size: 15px; font-weight: 700; color: #ec4899;">💝 ${item.product}</span>
|
||||||
|
<span style="font-size: 12px; color: #868e96;">${date}</span>
|
||||||
|
</div>
|
||||||
|
<div style="font-size: 13px; color: #64748b; margin-bottom: 8px;">
|
||||||
|
${item.reason || ''}
|
||||||
|
</div>
|
||||||
|
${triggerText ? `<div style="font-size: 12px; color: #94a3b8; background: #f8f9fa; padding: 8px 12px; border-radius: 6px;">🛒 구매: ${triggerText}</div>` : ''}
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
html += '<p style="text-align: center; padding: 40px; color: #868e96;">💝 관심 상품이 없습니다<br><small>마일리지 적립 시 AI 추천에서 "관심있어요"를 누르면 여기에 표시됩니다</small></p>';
|
||||||
|
}
|
||||||
|
|
||||||
html += `
|
html += `
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user