feat: 어드민 집계 페이지에 반려동물 통계 추가
통계 카드: - 등록 반려동물 총 수 - 강아지/고양이 종류별 수 - 노란색 그라데이션 카드 스타일 최근 등록 반려동물 섹션: - 최근 10마리 반려동물 카드 - 사진 + 이름 + 품종 + 보호자 정보 - 보호자 전화번호 마스킹 처리
This commit is contained in:
parent
a7b3d5b7e0
commit
c525632246
@ -2208,6 +2208,35 @@ def admin():
|
||||
FROM claim_tokens
|
||||
""")
|
||||
token_stats = cursor.fetchone()
|
||||
|
||||
# 반려동물 통계
|
||||
cursor.execute("""
|
||||
SELECT
|
||||
COUNT(*) as total_pets,
|
||||
SUM(CASE WHEN species = 'dog' THEN 1 ELSE 0 END) as dog_count,
|
||||
SUM(CASE WHEN species = 'cat' THEN 1 ELSE 0 END) as cat_count,
|
||||
COUNT(DISTINCT user_id) as owners_count
|
||||
FROM pets
|
||||
WHERE is_active = 1
|
||||
""")
|
||||
pet_stats = cursor.fetchone()
|
||||
|
||||
# 최근 등록 반려동물 (10마리)
|
||||
cursor.execute("""
|
||||
SELECT p.id, p.name, p.species, p.breed, p.photo_url, p.created_at,
|
||||
u.nickname as owner_name, u.phone as owner_phone
|
||||
FROM pets p
|
||||
JOIN users u ON p.user_id = u.id
|
||||
WHERE p.is_active = 1
|
||||
ORDER BY p.created_at DESC
|
||||
LIMIT 10
|
||||
""")
|
||||
recent_pets_raw = cursor.fetchall()
|
||||
recent_pets = []
|
||||
for pet in recent_pets_raw:
|
||||
pet_dict = dict(pet)
|
||||
pet_dict['created_at'] = utc_to_kst_str(pet['created_at'])
|
||||
recent_pets.append(pet_dict)
|
||||
|
||||
# 최근 QR 발행 내역 (20건)
|
||||
cursor.execute("""
|
||||
@ -2237,7 +2266,9 @@ def admin():
|
||||
recent_users=recent_users,
|
||||
recent_transactions=recent_transactions,
|
||||
token_stats=token_stats,
|
||||
recent_tokens=recent_tokens)
|
||||
recent_tokens=recent_tokens,
|
||||
pet_stats=pet_stats,
|
||||
recent_pets=recent_pets)
|
||||
|
||||
|
||||
# ============================================================================
|
||||
|
||||
@ -457,8 +457,44 @@
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
<div class="stat-card" style="background: linear-gradient(135deg, #fef3c7, #fde68a);">
|
||||
<div class="stat-label" style="color: #92400e;">🐾 등록 반려동물</div>
|
||||
<div class="stat-value" style="color: #92400e;">
|
||||
{{ pet_stats.total_pets or 0 }}마리
|
||||
<span style="font-size: 14px; font-weight: 500; margin-left: 8px;">
|
||||
(🐕 {{ pet_stats.dog_count or 0 }} / 🐈 {{ pet_stats.cat_count or 0 }})
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 최근 등록 반려동물 -->
|
||||
{% if recent_pets %}
|
||||
<div class="section">
|
||||
<div class="section-title">🐾 최근 등록 반려동물 (10마리)</div>
|
||||
<div style="display: flex; flex-wrap: wrap; gap: 12px;">
|
||||
{% for pet in recent_pets %}
|
||||
<div style="display: flex; align-items: center; gap: 12px; padding: 12px 16px; background: linear-gradient(135deg, #fef3c7, #fde68a); border-radius: 14px; min-width: 220px;">
|
||||
{% if pet.photo_url %}
|
||||
<img src="{{ pet.photo_url }}" style="width: 48px; height: 48px; border-radius: 50%; object-fit: cover; border: 2px solid #fff; box-shadow: 0 2px 6px rgba(0,0,0,0.15);">
|
||||
{% else %}
|
||||
<div style="width: 48px; height: 48px; border-radius: 50%; background: #fff; display: flex; align-items: center; justify-content: center; font-size: 24px; box-shadow: 0 2px 6px rgba(0,0,0,0.1);">
|
||||
{% if pet.species == 'dog' %}🐕{% elif pet.species == 'cat' %}🐈{% else %}🐾{% endif %}
|
||||
</div>
|
||||
{% endif %}
|
||||
<div>
|
||||
<div style="font-weight: 700; font-size: 15px; color: #92400e;">
|
||||
{% if pet.species == 'dog' %}🐕{% elif pet.species == 'cat' %}🐈{% else %}🐾{% endif %} {{ pet.name }}
|
||||
</div>
|
||||
<div style="font-size: 12px; color: #a16207;">{{ pet.breed or '품종 미등록' }}</div>
|
||||
<div style="font-size: 11px; color: #b45309; margin-top: 2px;">{{ pet.owner_name }} ({{ pet.owner_phone[:3] }}-****-{{ pet.owner_phone[-4:] }})</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<!-- 최근 가입 사용자 -->
|
||||
<div class="section">
|
||||
<div class="section-title">최근 가입 사용자 (20명)</div>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user