feat(postcards): add notes field to postcards with edit, detail, and truncated list display

This commit is contained in:
2026-07-06 21:07:28 +08:00
parent f6db3a4f55
commit 68c88a7910
6 changed files with 16 additions and 0 deletions

View File

@@ -83,6 +83,8 @@ class Postcard(Base):
# received # received
sender_name = Column(String(64)) sender_name = Column(String(64))
receive_time = Column(DateTime) receive_time = Column(DateTime)
# misc
notes = Column(Text, nullable=False, default="")
# images # images
showcase_hidden = Column(default=False, nullable=False) showcase_hidden = Column(default=False, nullable=False)
image_front = Column(String(256)) image_front = Column(String(256))

View File

@@ -529,6 +529,7 @@ def postcard_create(
arrival_time: str = Form(""), arrival_time: str = Form(""),
sender_name: str = Form(""), sender_name: str = Form(""),
receive_time: str = Form(""), receive_time: str = Form(""),
notes: str = Form(""),
user: User = Depends(get_current_user_web), user: User = Depends(get_current_user_web),
db: Session = Depends(get_db), db: Session = Depends(get_db),
): ):
@@ -558,6 +559,7 @@ def postcard_create(
arrival_time=_parse_dt(arrival_time), arrival_time=_parse_dt(arrival_time),
sender_name=sender_name or None, sender_name=sender_name or None,
receive_time=_parse_dt(receive_time), receive_time=_parse_dt(receive_time),
notes=notes.strip(),
) )
db.add(pc) db.add(pc)
db.commit() db.commit()
@@ -602,6 +604,7 @@ def postcard_update(
arrival_time: str = Form(""), arrival_time: str = Form(""),
sender_name: str = Form(""), sender_name: str = Form(""),
receive_time: str = Form(""), receive_time: str = Form(""),
notes: str = Form(""),
user: User = Depends(get_current_user_web), user: User = Depends(get_current_user_web),
db: Session = Depends(get_db), db: Session = Depends(get_db),
): ):
@@ -634,6 +637,7 @@ def postcard_update(
pc.arrival_time = None if status == "sent" else _parse_dt(arrival_time) pc.arrival_time = None if status == "sent" else _parse_dt(arrival_time)
pc.sender_name = sender_name or None pc.sender_name = sender_name or None
pc.receive_time = _parse_dt(receive_time) pc.receive_time = _parse_dt(receive_time)
pc.notes = notes.strip()
db.commit() db.commit()
return _redirect(f"/postcards/{postcard_id}") return _redirect(f"/postcards/{postcard_id}")

View File

@@ -135,6 +135,7 @@ code { background: var(--bg); padding: .15rem .4rem; border-radius: 4px; font-si
.detail-meta dl { display: grid; grid-template-columns: auto 1fr; gap: .3rem 1rem; } .detail-meta dl { display: grid; grid-template-columns: auto 1fr; gap: .3rem 1rem; }
.detail-meta dt { font-weight: 600; font-size: .85rem; color: var(--text-muted); } .detail-meta dt { font-weight: 600; font-size: .85rem; color: var(--text-muted); }
.detail-meta dd { font-size: .95rem; } .detail-meta dd { font-size: .95rem; }
.detail-notes { margin-top: .75rem; padding: .5rem .75rem; background: var(--bg); border-radius: 6px; font-size: .88rem; color: var(--text-muted); white-space: pre-wrap; word-break: break-word; }
/* Tabs */ /* Tabs */
.tabs { display: flex; gap: 0; border-bottom: 2px solid var(--border); margin-bottom: 1rem; } .tabs { display: flex; gap: 0; border-bottom: 2px solid var(--border); margin-bottom: 1rem; }
@@ -215,6 +216,7 @@ code { background: var(--bg); padding: .15rem .4rem; border-radius: 4px; font-si
.postcard-row-action { flex-shrink: 0; } .postcard-row-action { flex-shrink: 0; }
.postcard-row-date { font-size: .78rem; color: var(--text-muted); white-space: nowrap; } .postcard-row-date { font-size: .78rem; color: var(--text-muted); white-space: nowrap; }
.postcard-row-detail { display: flex; flex-direction: column; gap: 0; font-size: .85rem; color: var(--text-muted); } .postcard-row-detail { display: flex; flex-direction: column; gap: 0; font-size: .85rem; color: var(--text-muted); }
.postcard-row-notes { font-size: .8rem; color: var(--text-muted); max-width: 200px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.detail-title-row { display: flex; align-items: center; gap: .75rem; } .detail-title-row { display: flex; align-items: center; gap: .75rem; }
.detail-title-row h1 { margin: 0; } .detail-title-row h1 { margin: 0; }
.btn-back { padding: .35rem .6rem; font-size: 1rem; text-decoration: none; } .btn-back { padding: .35rem .6rem; font-size: 1rem; text-decoration: none; }

View File

@@ -61,6 +61,9 @@
{% endif %} {% endif %}
<dt>所属 Profile</dt><dd>{{ postcard.profile.nickname }}</dd> <dt>所属 Profile</dt><dd>{{ postcard.profile.nickname }}</dd>
</dl> </dl>
{% if postcard.notes %}
<div class="detail-notes">{{ postcard.notes }}</div>
{% endif %}
</div> </div>
</div> </div>
{% endblock %} {% endblock %}

View File

@@ -33,6 +33,9 @@
<input type="date" name="receive_time" id="input-receive" value="{{ postcard.receive_time.strftime('%Y-%m-%d') if postcard and postcard.receive_time else '' }}"> <input type="date" name="receive_time" id="input-receive" value="{{ postcard.receive_time.strftime('%Y-%m-%d') if postcard and postcard.receive_time else '' }}">
</div> </div>
<label>备注</label>
<textarea name="notes" rows="3" placeholder="可选备注信息">{{ postcard.notes if postcard else '' }}</textarea>
<div class="form-actions"> <div class="form-actions">
<button type="submit" class="btn btn-primary">保存</button> <button type="submit" class="btn btn-primary">保存</button>
<a href="/profiles/{{ profile.id }}/postcards" class="btn">取消</a> <a href="/profiles/{{ profile.id }}/postcards" class="btn">取消</a>

View File

@@ -44,6 +44,7 @@
<span>{{ pc.country|flag }} {{ pc.country or '-' }}</span> <span>{{ pc.country|flag }} {{ pc.country or '-' }}</span>
<span>→ {{ pc.recipient_name or '-' }}</span> <span>→ {{ pc.recipient_name or '-' }}</span>
</div> </div>
{% if pc.notes %}<span class="postcard-row-notes">{{ pc.notes[:50] }}{% if pc.notes|length > 50 %}…{% endif %}</span>{% endif %}
<span class="badge badge-{{ pc.status }}">{{ {'sent':'已寄出','delivered':'已送达'}.get(pc.status) }}</span> <span class="badge badge-{{ pc.status }}">{{ {'sent':'已寄出','delivered':'已送达'}.get(pc.status) }}</span>
<span class="postcard-row-date"> <span class="postcard-row-date">
{% if pc.send_time %}{{ pc.send_time.strftime('%Y-%m-%d') }}寄出{% endif %} {% if pc.send_time %}{{ pc.send_time.strftime('%Y-%m-%d') }}寄出{% endif %}
@@ -80,6 +81,7 @@
<div class="postcard-row-detail"> <div class="postcard-row-detail">
<span>← {{ pc.sender_name or '-' }}</span> <span>← {{ pc.sender_name or '-' }}</span>
</div> </div>
{% if pc.notes %}<span class="postcard-row-notes">{{ pc.notes[:50] }}{% if pc.notes|length > 50 %}…{% endif %}</span>{% endif %}
{% if pc.receive_time %}<span class="postcard-row-date">{{ pc.receive_time.strftime('%Y-%m-%d') }}收到</span>{% endif %} {% if pc.receive_time %}<span class="postcard-row-date">{{ pc.receive_time.strftime('%Y-%m-%d') }}收到</span>{% endif %}
</div> </div>
</a> </a>