feat: 반려동물 정보 표시 기능 추가
API: - /api/admin/pos-live에 pets 배열 추가 - 적립된 회원의 반려동물 정보 조회 (이름, 종류, 품종, 사진) 테이블 (바깥): - 적립 열에 반려동물 아이콘 표시 (🐕🐈) 상세 패널: - 반려동물 카드 섹션 추가 - 사진 + 이름 + 품종 표시 - 노란색 그라데이션 카드 스타일
This commit is contained in:
parent
695c1f707f
commit
a7b3d5b7e0
@ -4933,9 +4933,9 @@ def api_admin_pos_live():
|
||||
qr_record = sqlite_cursor.fetchone()
|
||||
qr_issued = bool(qr_record)
|
||||
|
||||
# SQLite에서 적립 사용자 조회
|
||||
# SQLite에서 적립 사용자 조회 (user_id 포함)
|
||||
sqlite_cursor.execute("""
|
||||
SELECT u.nickname, u.phone, ct.claimable_points
|
||||
SELECT u.id as user_id, u.nickname, u.phone, ct.claimable_points
|
||||
FROM claim_tokens ct
|
||||
LEFT JOIN users u ON ct.claimed_by_user_id = u.id
|
||||
WHERE ct.transaction_id = ? AND ct.claimed_at IS NOT NULL
|
||||
@ -4943,7 +4943,9 @@ def api_admin_pos_live():
|
||||
claimed_user = sqlite_cursor.fetchone()
|
||||
|
||||
# 적립 사용자 정보 분리
|
||||
claimed_user_id = None
|
||||
if claimed_user and claimed_user['nickname'] and claimed_user['phone']:
|
||||
claimed_user_id = claimed_user['user_id']
|
||||
claimed_name = claimed_user['nickname']
|
||||
claimed_phone = claimed_user['phone']
|
||||
claimed_points = claimed_user['claimable_points']
|
||||
@ -4952,6 +4954,23 @@ def api_admin_pos_live():
|
||||
claimed_phone = ""
|
||||
claimed_points = 0
|
||||
|
||||
# 반려동물 정보 조회
|
||||
pets_list = []
|
||||
if claimed_user_id:
|
||||
sqlite_cursor.execute("""
|
||||
SELECT name, species, breed, photo_url
|
||||
FROM pets
|
||||
WHERE user_id = ? AND is_active = 1
|
||||
""", (claimed_user_id,))
|
||||
pets_rows = sqlite_cursor.fetchall()
|
||||
for pet in pets_rows:
|
||||
pets_list.append({
|
||||
'name': pet['name'],
|
||||
'species': pet['species'], # dog, cat
|
||||
'breed': pet['breed'] or '',
|
||||
'photo_url': pet['photo_url'] or ''
|
||||
})
|
||||
|
||||
# 결제수단 판별
|
||||
card_amt = float(card_total) if card_total else 0.0
|
||||
cash_amt = float(cash_total) if cash_total else 0.0
|
||||
@ -4989,7 +5008,8 @@ def api_admin_pos_live():
|
||||
'claimed_name': claimed_name,
|
||||
'claimed_phone': claimed_phone,
|
||||
'claimed_points': claimed_points,
|
||||
'qr_issued': qr_issued
|
||||
'qr_issued': qr_issued,
|
||||
'pets': pets_list # 반려동물 정보
|
||||
})
|
||||
|
||||
return jsonify({
|
||||
|
||||
23
backend/check_pets.py
Normal file
23
backend/check_pets.py
Normal file
@ -0,0 +1,23 @@
|
||||
import sqlite3
|
||||
|
||||
conn = sqlite3.connect('db/mileage.db')
|
||||
c = conn.cursor()
|
||||
|
||||
# 테이블 구조
|
||||
c.execute("SELECT sql FROM sqlite_master WHERE name='pets'")
|
||||
print("=== PETS TABLE SCHEMA ===")
|
||||
print(c.fetchone())
|
||||
|
||||
# 샘플 데이터
|
||||
c.execute("SELECT * FROM pets LIMIT 5")
|
||||
print("\n=== SAMPLE DATA ===")
|
||||
for row in c.fetchall():
|
||||
print(row)
|
||||
|
||||
# 컬럼명
|
||||
c.execute("PRAGMA table_info(pets)")
|
||||
print("\n=== COLUMNS ===")
|
||||
for col in c.fetchall():
|
||||
print(col)
|
||||
|
||||
conn.close()
|
||||
@ -637,6 +637,60 @@
|
||||
margin-top: 2px;
|
||||
}
|
||||
|
||||
/* ── 반려동물 카드 ── */
|
||||
.detail-pets-section {
|
||||
margin: 16px 0;
|
||||
}
|
||||
.pets-grid {
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
.pet-card {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
padding: 10px 14px;
|
||||
background: linear-gradient(135deg, #fef3c7, #fde68a);
|
||||
border-radius: 12px;
|
||||
flex: 1;
|
||||
min-width: 140px;
|
||||
max-width: 200px;
|
||||
}
|
||||
.pet-photo {
|
||||
width: 44px;
|
||||
height: 44px;
|
||||
border-radius: 50%;
|
||||
object-fit: cover;
|
||||
border: 2px solid #fff;
|
||||
box-shadow: 0 2px 6px rgba(0,0,0,0.15);
|
||||
}
|
||||
.pet-photo-placeholder {
|
||||
width: 44px;
|
||||
height: 44px;
|
||||
border-radius: 50%;
|
||||
background: #fff;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 22px;
|
||||
box-shadow: 0 2px 6px rgba(0,0,0,0.1);
|
||||
}
|
||||
.pet-info {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
.pet-name {
|
||||
font-weight: 700;
|
||||
font-size: 14px;
|
||||
color: #92400e;
|
||||
}
|
||||
.pet-breed {
|
||||
font-size: 11px;
|
||||
color: #a16207;
|
||||
margin-top: 2px;
|
||||
}
|
||||
|
||||
/* ── 반응형 ── */
|
||||
@media (max-width: 768px) {
|
||||
.control-section {
|
||||
@ -852,8 +906,15 @@
|
||||
|
||||
let claimedHtml = '-';
|
||||
if (sale.claimed_name) {
|
||||
// 반려동물 아이콘 생성
|
||||
let petIcons = '';
|
||||
if (sale.pets && sale.pets.length > 0) {
|
||||
petIcons = sale.pets.map(p =>
|
||||
p.species === 'dog' ? '🐕' : p.species === 'cat' ? '🐈' : '🐾'
|
||||
).join('');
|
||||
}
|
||||
claimedHtml = `
|
||||
<div class="claimed-info">${sale.claimed_name}</div>
|
||||
<div class="claimed-info">${sale.claimed_name} ${petIcons}</div>
|
||||
<div class="claimed-phone">${formatPhone(sale.claimed_phone)}</div>
|
||||
`;
|
||||
}
|
||||
@ -986,6 +1047,33 @@
|
||||
</div>`
|
||||
: '';
|
||||
|
||||
// 반려동물 섹션
|
||||
let petsSection = '';
|
||||
if (sale.pets && sale.pets.length > 0) {
|
||||
const petsHtml = sale.pets.map(pet => {
|
||||
const speciesIcon = pet.species === 'dog' ? '🐕' : pet.species === 'cat' ? '🐈' : '🐾';
|
||||
const speciesName = pet.species === 'dog' ? '강아지' : pet.species === 'cat' ? '고양이' : '반려동물';
|
||||
const photoHtml = pet.photo_url
|
||||
? `<img src="${pet.photo_url}" class="pet-photo" alt="${pet.name}">`
|
||||
: `<div class="pet-photo-placeholder">${speciesIcon}</div>`;
|
||||
return `
|
||||
<div class="pet-card">
|
||||
${photoHtml}
|
||||
<div class="pet-info">
|
||||
<div class="pet-name">${speciesIcon} ${pet.name}</div>
|
||||
<div class="pet-breed">${pet.breed || speciesName}</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
}).join('');
|
||||
petsSection = `
|
||||
<div class="detail-pets-section">
|
||||
<div class="detail-items-title">🐾 반려동물</div>
|
||||
<div class="pets-grid">${petsHtml}</div>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
// 기본 정보 표시
|
||||
document.getElementById('detailContent').innerHTML = `
|
||||
<!-- 액션 버튼 -->
|
||||
@ -1029,6 +1117,7 @@
|
||||
</div>
|
||||
</div>
|
||||
${claimedInfo}
|
||||
${petsSection}
|
||||
<div class="detail-items-title">📦 품목 목록</div>
|
||||
<div id="itemsList">
|
||||
<div class="loading"><div class="spinner"></div>품목 로딩 중...</div>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user