feat(storage): add S3 image storage support with file-based config and migration script

This commit is contained in:
2026-07-18 08:03:18 +08:00
parent ddeec36a01
commit 3a931fe752
11 changed files with 242 additions and 30 deletions

View File

@@ -45,8 +45,8 @@
{% if mode == 'flat' %}
<div class="showcase-grid" id="grid-sent">
{% for pc in sent_visible %}
<div class="showcase-card" data-front="{{ pc.image_front }}" onclick="openLightbox(this)">
<img src="{{ pc.image_front }}" alt="" class="showcase-card-img" loading="lazy">
<div class="showcase-card" data-front="{{ pc.image_front|image_url }}" onclick="openLightbox(this)">
<img src="{{ pc.image_front|image_url }}" alt="" class="showcase-card-img" loading="lazy">
<div class="showcase-card-body">
<div class="showcase-card-meta">
{% if pc.country_from and pc.country_to %}<span>{{ pc.country_from|flag }} {{ pc.country_from }} → {{ pc.country_to|flag }} {{ pc.country_to }}</span>
@@ -70,8 +70,8 @@
<h3 style="margin:1rem 0 .75rem;font-size:.95rem;color:var(--text-muted)">{{ g.profile.nickname }}</h3>
<div class="showcase-grid">
{% for pc in g_sent %}
<div class="showcase-card" data-front="{{ pc.image_front }}" onclick="openLightbox(this)">
<img src="{{ pc.image_front }}" alt="" class="showcase-card-img" loading="lazy">
<div class="showcase-card" data-front="{{ pc.image_front|image_url }}" onclick="openLightbox(this)">
<img src="{{ pc.image_front|image_url }}" alt="" class="showcase-card-img" loading="lazy">
<div class="showcase-card-body">
<div class="showcase-card-meta">
{% if pc.country_from and pc.country_to %}<span>{{ pc.country_from|flag }} {{ pc.country_from }} → {{ pc.country_to|flag }} {{ pc.country_to }}</span>
@@ -96,8 +96,8 @@
{% if mode == 'flat' %}
<div class="showcase-grid" id="grid-received">
{% for pc in received_visible %}
<div class="showcase-card" data-front="{{ pc.image_front }}" onclick="openLightbox(this)">
<img src="{{ pc.image_front }}" alt="" class="showcase-card-img" loading="lazy">
<div class="showcase-card" data-front="{{ pc.image_front|image_url }}" onclick="openLightbox(this)">
<img src="{{ pc.image_front|image_url }}" alt="" class="showcase-card-img" loading="lazy">
<div class="showcase-card-body">
<div class="showcase-card-meta">
{% if pc.country_from and pc.country_to %}<span>{{ pc.country_from|flag }} {{ pc.country_from }} → {{ pc.country_to|flag }} {{ pc.country_to }}</span>
@@ -121,8 +121,8 @@
<h3 style="margin:1rem 0 .75rem;font-size:.95rem;color:var(--text-muted)">{{ g.profile.nickname }}</h3>
<div class="showcase-grid">
{% for pc in g_received %}
<div class="showcase-card" data-front="{{ pc.image_front }}" onclick="openLightbox(this)">
<img src="{{ pc.image_front }}" alt="" class="showcase-card-img" loading="lazy">
<div class="showcase-card" data-front="{{ pc.image_front|image_url }}" onclick="openLightbox(this)">
<img src="{{ pc.image_front|image_url }}" alt="" class="showcase-card-img" loading="lazy">
<div class="showcase-card-body">
<div class="showcase-card-meta">
{% if pc.country_from and pc.country_to %}<span>{{ pc.country_from|flag }} {{ pc.country_from }} → {{ pc.country_to|flag }} {{ pc.country_to }}</span>