diff --git a/app/models.py b/app/models.py index 7dfe254..4d2759f 100644 --- a/app/models.py +++ b/app/models.py @@ -83,8 +83,8 @@ class Postcard(Base): status = Column(String(16), nullable=False) # sent & delivered recipient_name = Column(String(64)) - country = Column(String(64)) country_from = Column(String(2)) + country_to = Column(String(2)) send_time = Column(DateTime) arrival_time = Column(DateTime) # received @@ -101,14 +101,14 @@ class Postcard(Base): profile = relationship("Profile", back_populates="postcards") - @validates("country") - def _upper_country(self, key, value): - return value.strip().upper() if value else None - @validates("country_from") def _upper_country_from(self, key, value): return value.strip().upper() if value else None + @validates("country_to") + def _upper_country_to(self, key, value): + return value.strip().upper() if value else None + class ApiKey(Base): __tablename__ = "api_keys" diff --git a/app/routers/api.py b/app/routers/api.py index a168e05..c9a66ec 100644 --- a/app/routers/api.py +++ b/app/routers/api.py @@ -103,8 +103,8 @@ class PostcardCreate(BaseModel): card_number: str status: str recipient_name: str | None = None - country: str | None = None country_from: str | None = None + country_to: str | None = None send_time: str | None = None arrival_time: str | None = None sender_name: str | None = None @@ -115,8 +115,8 @@ class PostcardUpdate(BaseModel): card_number: str | None = None status: str | None = None recipient_name: str | None = None - country: str | None = None country_from: str | None = None + country_to: str | None = None send_time: str | None = None arrival_time: str | None = None sender_name: str | None = None @@ -129,8 +129,8 @@ class PostcardOut(BaseModel): card_number: str status: str recipient_name: str | None - country: str | None country_from: str | None + country_to: str | None send_time: datetime | None arrival_time: datetime | None sender_name: str | None @@ -294,8 +294,8 @@ def create_postcard( card_number=cn, status=body.status, recipient_name=body.recipient_name, - country=body.country.strip().upper() if body.country else None, country_from=body.country_from.strip().upper() if body.country_from else None, + country_to=body.country_to.strip().upper() if body.country_to else None, send_time=_parse_date(body.send_time), arrival_time=_parse_date(body.arrival_time), sender_name=body.sender_name, @@ -340,8 +340,8 @@ def update_postcard( if dup: raise HTTPException(status_code=409, detail="Card number already exists") pc.card_number = cn - if body.country is not None: - pc.country = body.country.strip().upper() if body.country else None + if body.country_to is not None: + pc.country_to = body.country_to.strip().upper() if body.country_to else None if body.country_from is not None: pc.country_from = body.country_from.strip().upper() if body.country_from else None for field in ("send_time", "arrival_time", "receive_time"): diff --git a/app/routers/web.py b/app/routers/web.py index 55cea60..ba3ceea 100644 --- a/app/routers/web.py +++ b/app/routers/web.py @@ -190,7 +190,7 @@ def api_public_cards( "cards": [{ "image_front": c.image_front, "country_from": c.country_from, - "country": c.country, + "country_to": c.country_to, "status": c.status, } for c in batch], }) @@ -232,7 +232,7 @@ def api_public_cards_user( "cards": [{ "image_front": c.image_front, "country_from": c.country_from, - "country": c.country, + "country_to": c.country_to, } for c in batch], }) @@ -593,7 +593,7 @@ def dashboard(request: Request, user: User = Depends(get_current_user_web), db: sent = sum(1 for c in all_cards if c.status == "sent") delivered = sum(1 for c in all_cards if c.status == "delivered") received = sum(1 for c in all_cards if c.status == "received") - countries = len({c.country for c in all_cards if c.country}) + countries = len({c.country_to for c in all_cards if c.country_to}) # recent postcards across all profiles (last 8), sorted by most recently updated all_cards.sort(key=lambda c: c.updated_at or c.created_at, reverse=True) @@ -611,12 +611,12 @@ def dashboard(request: Request, user: User = Depends(get_current_user_web), db: sent_country_counts: dict[str, int] = {} received_country_counts: dict[str, int] = {} for c in all_cards: - if not c.country: + if not c.country_to: continue if c.status in ("sent", "delivered"): - sent_country_counts[c.country] = sent_country_counts.get(c.country, 0) + 1 + sent_country_counts[c.country_to] = sent_country_counts.get(c.country_to, 0) + 1 elif c.status == "received": - received_country_counts[c.country] = received_country_counts.get(c.country, 0) + 1 + received_country_counts[c.country_to] = received_country_counts.get(c.country_to, 0) + 1 sent_country_stats = sorted(sent_country_counts.items(), key=lambda x: -x[1]) received_country_stats = sorted(received_country_counts.items(), key=lambda x: -x[1]) @@ -645,7 +645,7 @@ def profile_list(request: Request, user: User = Depends(get_current_user_web), d "sent": sum(1 for c in cards if c.status == "sent"), "delivered": sum(1 for c in cards if c.status == "delivered"), "received": sum(1 for c in cards if c.status == "received"), - "countries": len({c.country for c in cards if c.country}), + "countries": len({c.country_to for c in cards if c.country_to}), } return templates.TemplateResponse("profiles.html", {"request": request, "user": user, "profiles": profiles, "extras": extras}) @@ -701,11 +701,11 @@ def postcard_list( return _redirect("/profiles") q = db.query(Postcard).filter(Postcard.profile_id == profile_id) if country: - q = q.filter(Postcard.country == country) + q = q.filter(Postcard.country_to == country) postcards = q.all() # collect existing countries for dropdown - all_countries = sorted({pc.country for pc in db.query(Postcard.country).filter(Postcard.profile_id == profile_id, Postcard.country.isnot(None)).all()}) + all_countries = sorted({pc.country_to for pc in db.query(Postcard.country_to).filter(Postcard.profile_id == profile_id, Postcard.country_to.isnot(None)).all()}) # status sort order: sent=0, delivered=1, received=2 _status_order = {"sent": 0, "delivered": 1, "received": 2} @@ -777,8 +777,8 @@ def postcard_create( card_number=card_number.strip(), status=status, recipient_name=recipient_name or None, - country=(country.strip().upper() if country else None), country_from=(country_from.strip().upper() if country_from else profile.country), + country_to=(country.strip().upper() if country else None), send_time=_parse_dt(send_time), arrival_time=_parse_dt(arrival_time), sender_name=sender_name or None, @@ -868,8 +868,8 @@ def postcard_update( pc.card_number = card_number.strip() pc.status = status pc.recipient_name = recipient_name or None - pc.country = country or None pc.country_from = country_from.strip().upper() if country_from else pc.country_from + pc.country_to = country or None pc.send_time = _parse_dt(send_time) pc.arrival_time = None if status == "sent" else _parse_dt(arrival_time) pc.sender_name = sender_name or None diff --git a/app/schemas.py b/app/schemas.py index 8bc54df..ecac069 100644 --- a/app/schemas.py +++ b/app/schemas.py @@ -30,8 +30,8 @@ class PostcardCreate(BaseModel): card_number: str status: str recipient_name: str | None = None - country: str | None = None country_from: str | None = None + country_to: str | None = None send_time: datetime | None = None arrival_time: datetime | None = None sender_name: str | None = None @@ -42,8 +42,8 @@ class PostcardUpdate(BaseModel): card_number: str | None = None status: str | None = None recipient_name: str | None = None - country: str | None = None country_from: str | None = None + country_to: str | None = None send_time: datetime | None = None arrival_time: datetime | None = None sender_name: str | None = None @@ -56,8 +56,8 @@ class PostcardOut(BaseModel): card_number: str status: str recipient_name: str | None - country: str | None country_from: str | None + country_to: str | None send_time: datetime | None arrival_time: datetime | None sender_name: str | None diff --git a/app/templates/dashboard.html b/app/templates/dashboard.html index d855759..05a7f32 100644 --- a/app/templates/dashboard.html +++ b/app/templates/dashboard.html @@ -118,8 +118,10 @@ new Chart(document.getElementById('chart-received'), { {{ {'sent':'已寄出','delivered':'已送达','received':'已收到'}.get(pc.status) if user.language=='zh' else {'sent':'Sent','delivered':'Delivered','received':'Received'}.get(pc.status) }}
+ {% if pc.country_from and pc.country_to %}{{ pc.country_from|flag }} {{ pc.country_from }} → {{ pc.country_to|flag }} {{ pc.country_to }} + {% elif pc.country_to %}{{ pc.country_to|flag }} {{ pc.country_to }} + {% endif %} {% if pc.status in ('sent','delivered') %} - {{ pc.country|flag }} {{ pc.country or '' }} → {{ pc.recipient_name or '-' }} {% else %} ← {{ pc.sender_name or '-' }} diff --git a/app/templates/index.html b/app/templates/index.html index c9ff6f0..66b6301 100644 --- a/app/templates/index.html +++ b/app/templates/index.html @@ -37,8 +37,8 @@
- {% if pc.country_from and pc.country %}{{ pc.country_from|flag }} {{ pc.country_from }} → {{ pc.country|flag }} {{ pc.country }} - {% elif pc.country %}{{ pc.country|flag }} {{ pc.country }} + {% if pc.country_to_from and pc.country_to %}{{ pc.country_to_from|flag }} {{ pc.country_to_from }} → {{ pc.country_to|flag }} {{ pc.country_to }} + {% elif pc.country_to %}{{ pc.country_to|flag }} {{ pc.country_to }} {% endif %}
@@ -78,8 +78,8 @@ function _appendCard(c) { div.setAttribute('data-front', c.image_front); div.onclick = function() { openLightbox(div); }; var countryHtml = ''; - if (c.country_from && c.country) countryHtml = '' + _flag(c.country_from) + ' ' + c.country_from + ' → ' + _flag(c.country) + ' ' + c.country + ''; - else if (c.country) countryHtml = '' + _flag(c.country) + ' ' + c.country + ''; + if (c.country_from && c.country_to) countryHtml = '' + _flag(c.country_from) + ' ' + c.country_from + ' → ' + _flag(c.country_to) + ' ' + c.country_to + ''; + else if (c.country_to) countryHtml = '' + _flag(c.country_to) + ' ' + c.country_to + ''; div.innerHTML = '' + '
' + countryHtml + '
'; grid.appendChild(div); diff --git a/app/templates/postcard_detail.html b/app/templates/postcard_detail.html index a7bfaec..ef98b4a 100644 --- a/app/templates/postcard_detail.html +++ b/app/templates/postcard_detail.html @@ -52,12 +52,12 @@
{{ 'pc_detail.status'|t(user.language) }}
{{ {'sent':'已寄出','delivered':'已送达','received':'已收到'}.get(postcard.status, postcard.status) if user.language=='zh' else {'sent':'Sent','delivered':'Delivered','received':'Received'}.get(postcard.status, postcard.status) }}
{% if postcard.status in ('sent','delivered') %}
{{ 'pc_detail.recipient'|t(user.language) }}
{{ postcard.recipient_name or '-' }}
-
{{ 'pc_detail.route'|t(user.language) }}
{% if postcard.country_from %}{{ postcard.country_from|flag }} {{ postcard.country_from }} → {% endif %}{{ postcard.country|flag }} {{ postcard.country or '-' }}
+
{{ 'pc_detail.route'|t(user.language) }}
{% if postcard.country_to_from %}{{ postcard.country_to_from|flag }} {{ postcard.country_to_from }} → {% endif %}{{ postcard.country_to|flag }} {{ postcard.country_to or '-' }}
{{ 'pc_detail.send_time'|t(user.language) }}
{{ postcard.send_time.strftime('%Y-%m-%d') if postcard.send_time else '-' }}
{{ 'pc_detail.arrival_time'|t(user.language) }}
{{ postcard.arrival_time.strftime('%Y-%m-%d') if postcard.arrival_time else '-' }}
{% else %}
{{ 'pc_detail.sender'|t(user.language) }}
{{ postcard.sender_name or '-' }}
-
{{ 'pc_detail.route'|t(user.language) }}
{% if postcard.country_from %}{{ postcard.country_from|flag }} {{ postcard.country_from }} → {% endif %}{{ postcard.country|flag }} {{ postcard.country or '-' }}
+
{{ 'pc_detail.route'|t(user.language) }}
{% if postcard.country_to_from %}{{ postcard.country_to_from|flag }} {{ postcard.country_to_from }} → {% endif %}{{ postcard.country_to|flag }} {{ postcard.country_to or '-' }}
{{ 'pc_detail.receive_time'|t(user.language) }}
{{ postcard.receive_time.strftime('%Y-%m-%d') if postcard.receive_time else '-' }}
{% endif %}
{{ 'pc_detail.profile'|t(user.language) }}
{{ postcard.profile.nickname }}
diff --git a/app/templates/postcard_form.html b/app/templates/postcard_form.html index 2442316..6ea0bd2 100644 --- a/app/templates/postcard_form.html +++ b/app/templates/postcard_form.html @@ -32,10 +32,10 @@
- + - + diff --git a/app/templates/postcards.html b/app/templates/postcards.html index 895b224..6c19cdd 100644 --- a/app/templates/postcards.html +++ b/app/templates/postcards.html @@ -41,7 +41,7 @@
{{ pc.card_number }}
- {% if pc.country_from %}{{ pc.country_from|flag }}→{% endif %}{{ pc.country|flag }} {{ pc.country or '-' }} + {% if pc.country_to_from %}{{ pc.country_to_from|flag }}→{% endif %}{{ pc.country_to|flag }} {{ pc.country_to or '-' }} → {{ pc.recipient_name or '-' }}
{{ {'sent':'已寄出','delivered':'已送达'}.get(pc.status) if user.language=='zh' else {'sent':'Sent','delivered':'Delivered'}.get(pc.status) }} diff --git a/app/templates/showcase.html b/app/templates/showcase.html index f7f88b9..44d8903 100644 --- a/app/templates/showcase.html +++ b/app/templates/showcase.html @@ -49,8 +49,8 @@
- {% if pc.country_from and pc.country %}{{ pc.country_from|flag }} {{ pc.country_from }} → {{ pc.country|flag }} {{ pc.country }} - {% elif pc.country %}{{ pc.country|flag }} + {% if pc.country_to_from and pc.country_to %}{{ pc.country_to_from|flag }} {{ pc.country_to_from }} → {{ pc.country_to|flag }} {{ pc.country_to }} + {% elif pc.country_to %}{{ pc.country_to|flag }} {% endif %} {% if pc.send_time %}{{ pc.send_time.strftime('%Y-%m-%d') }}{% endif %}
@@ -74,8 +74,8 @@
- {% if pc.country_from and pc.country %}{{ pc.country_from|flag }} {{ pc.country_from }} → {{ pc.country|flag }} {{ pc.country }} - {% elif pc.country %}{{ pc.country|flag }} + {% if pc.country_to_from and pc.country_to %}{{ pc.country_to_from|flag }} {{ pc.country_to_from }} → {{ pc.country_to|flag }} {{ pc.country_to }} + {% elif pc.country_to %}{{ pc.country_to|flag }} {% endif %} {% if pc.send_time %}{{ pc.send_time.strftime('%Y-%m-%d') }}{% endif %}
@@ -98,8 +98,8 @@
- {% if pc.country_from and pc.country %}{{ pc.country_from|flag }} {{ pc.country_from }} → {{ pc.country|flag }} {{ pc.country }} - {% elif pc.country %}{{ pc.country|flag }} + {% if pc.country_to_from and pc.country_to %}{{ pc.country_to_from|flag }} {{ pc.country_to_from }} → {{ pc.country_to|flag }} {{ pc.country_to }} + {% elif pc.country_to %}{{ pc.country_to|flag }} {% endif %} {% if pc.receive_time %}{{ pc.receive_time.strftime('%Y-%m-%d') }}{% endif %}
@@ -123,8 +123,8 @@
- {% if pc.country_from and pc.country %}{{ pc.country_from|flag }} {{ pc.country_from }} → {{ pc.country|flag }} {{ pc.country }} - {% elif pc.country %}{{ pc.country|flag }} + {% if pc.country_to_from and pc.country_to %}{{ pc.country_to_from|flag }} {{ pc.country_to_from }} → {{ pc.country_to|flag }} {{ pc.country_to }} + {% elif pc.country_to %}{{ pc.country_to|flag }} {% endif %} {% if pc.receive_time %}{{ pc.receive_time.strftime('%Y-%m-%d') }}{% endif %}
@@ -169,8 +169,8 @@ function _appendCard(c, gridId) { div.setAttribute('data-front', c.image_front); div.onclick = function() { openLightbox(div); }; var countryHtml = ''; - if (c.country_from && c.country) countryHtml = '' + _flag(c.country_from) + ' ' + c.country_from + ' → ' + _flag(c.country) + ' ' + c.country + ''; - else if (c.country) countryHtml = '' + _flag(c.country) + ''; + if (c.country_from && c.country_to) countryHtml = '' + _flag(c.country_from) + ' ' + c.country_from + ' → ' + _flag(c.country_to) + ' ' + c.country_to + ''; + else if (c.country_to) countryHtml = '' + _flag(c.country_to) + ''; div.innerHTML = '' + '
' + countryHtml + '
'; grid.appendChild(div);