修改完成
This commit is contained in:
@@ -1,5 +1,131 @@
|
||||
<!-- 页面编号:F-07;用途:家族相册列表。 -->
|
||||
<template><ModulePage page-id="f07" /></template>
|
||||
<!-- 页面编号:F-07;用途:家族相册列表、创建与受控状态。 -->
|
||||
<template>
|
||||
<view class="album-list-page" :class="albumStateClasses">
|
||||
<ModulePageBackground module="family" />
|
||||
<view class="album-list-header"><PageHeader title="家族相册" action="新建" @action="createAlbum" /></view>
|
||||
|
||||
<view v-if="albumState === 'loading'" class="album-list-loading">
|
||||
<AppLoading text="正在整理家族相册" description="请稍候,正在读取照片与更新时间。" />
|
||||
</view>
|
||||
|
||||
<view v-else class="album-list-content">
|
||||
<template v-if="albumState === 'ready'">
|
||||
<view class="album-list-lead"><text>让每一张照片都回到家人身边</text><text>共 {{ albums.length }} 本相册</text></view>
|
||||
<view v-if="albums.length" class="album-list">
|
||||
<view v-for="album in albums" :key="album.id" class="album-card" role="button" :aria-label="`打开相册${album.name}`" @click="openAlbum(album)">
|
||||
<view class="album-card__media"><image class="album-card__cover" :src="album.cover" mode="aspectFill" :alt="album.name" /></view>
|
||||
<view class="album-card__copy">
|
||||
<text>{{ album.name }}</text>
|
||||
<text>{{ album.photoCount }} 张照片 · {{ album.updatedAt }}</text>
|
||||
<text>{{ album.description }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<AppButton block label="新建相册" @click="createAlbum" />
|
||||
</view>
|
||||
<view v-else class="album-state-card">
|
||||
<text>还没有相册</text><text>创建一本相册,把团圆、成长与祖居旧影整理在一起。</text>
|
||||
<AppButton block label="新建相册" @click="createAlbum" />
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<view v-else class="album-state-card">
|
||||
<text>{{ albumState === 'empty' ? '还没有相册' : '相册暂不可用' }}</text>
|
||||
<text>{{ albumState === 'empty' ? '从第一本团圆相册开始收集家族影像。' : '请稍后重新查看,已有照片不会受到影响。' }}</text>
|
||||
<AppButton :type="albumState === 'error' ? 'secondary' : 'primary'" block :label="albumState === 'error' ? '重新查看' : '新建相册'" @click="albumState === 'error' ? restoreAlbums() : createAlbum()" />
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<AppDialog :visible="dialogVisible" eyebrow="新建相册" title="为家人整理一段影像" message="相册创建后可继续添加照片和说明。" confirm-text="创建相册" cancel-text="取消" show-cancel @confirm="confirmCreateAlbum" @cancel="closeCreateDialog">
|
||||
<view class="album-dialog-field">
|
||||
<text>相册名称</text>
|
||||
<input v-model="albumNameDraft" maxlength="30" placeholder="例如:春节团圆" />
|
||||
<text v-if="albumNameError">{{ albumNameError }}</text>
|
||||
</view>
|
||||
</AppDialog>
|
||||
<AppToast :visible="toastVisible" message="相册已创建" />
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import ModulePage from "@/components/ModulePage.vue";
|
||||
import { computed, onUnmounted, ref } from "vue";
|
||||
import { onLoad } from "@dcloudio/uni-app";
|
||||
import AppButton from "@/components/AppButton.vue";
|
||||
import AppDialog from "@/components/AppDialog.vue";
|
||||
import AppLoading from "@/components/AppLoading.vue";
|
||||
import AppToast from "@/components/AppToast.vue";
|
||||
import ModulePageBackground from "@/components/ModulePageBackground.vue";
|
||||
import PageHeader from "@/components/PageHeader.vue";
|
||||
|
||||
const baseAlbums = [
|
||||
{ id: "201", name: "2024 春节团圆", photoCount: 18, updatedAt: "今天更新", description: "三代家人的团圆饭与院前合影", cover: "/static/assets/modules/family/f08/f08-reunion-hero.png" },
|
||||
{ id: "202", name: "祖居旧影", photoCount: 32, updatedAt: "5 月 10 日更新", description: "祖居、旧物与长辈珍藏的老照片", cover: "/static/assets/modules/family/f08/f08-ancestral-home.png" },
|
||||
{ id: "203", name: "儿童成长", photoCount: 46, updatedAt: "持续更新", description: "记录孩子们每一个值得珍藏的瞬间", cover: "/static/assets/modules/family/f08/f08-family-portrait.png" },
|
||||
];
|
||||
const albums = ref([...baseAlbums]);
|
||||
const albumState = ref("loading");
|
||||
const dialogVisible = ref(false);
|
||||
const albumNameDraft = ref("");
|
||||
const albumNameError = ref("");
|
||||
const toastVisible = ref(false);
|
||||
let toastTimer = null;
|
||||
const albumStateClasses = computed(() => ({
|
||||
[`album-list-state--${albumState.value}`]: true,
|
||||
"album-state--empty": albumState.value === "empty",
|
||||
"album-list-state--loading": albumState.value === "loading",
|
||||
"album-list-state--error": albumState.value === "error",
|
||||
}));
|
||||
|
||||
onLoad((query) => {
|
||||
const count = Math.max(1, Math.min(Number(query.count) || baseAlbums.length, 30));
|
||||
albums.value = Array.from({ length: count }, (_, index) => ({
|
||||
...baseAlbums[index % baseAlbums.length],
|
||||
id: String(201 + index),
|
||||
name: count > baseAlbums.length ? `${baseAlbums[index % baseAlbums.length].name}(${index + 1})` : baseAlbums[index].name,
|
||||
}));
|
||||
albumState.value = ["loading", "empty", "error"].includes(query.state) ? query.state : "ready";
|
||||
});
|
||||
|
||||
const openAlbum = (album) => uni.navigateTo({ url: `/pages/family/f08-album-detail?albumId=${album.id}` });
|
||||
const createAlbum = () => { albumNameDraft.value = ""; albumNameError.value = ""; dialogVisible.value = true; };
|
||||
const closeCreateDialog = () => { dialogVisible.value = false; };
|
||||
const confirmCreateAlbum = () => {
|
||||
const name = albumNameDraft.value.trim();
|
||||
if (!name) { albumNameError.value = "请填写相册名称"; return; }
|
||||
albums.value.unshift({ id: String(Date.now()), name, photoCount: 0, updatedAt: "刚刚创建", description: "等待添加第一张照片", cover: "/static/assets/modules/family/f08/f08-reunion-hero.png" });
|
||||
albumState.value = "ready";
|
||||
dialogVisible.value = false;
|
||||
toastVisible.value = true;
|
||||
toastTimer = setTimeout(() => { toastVisible.value = false; }, 1800);
|
||||
};
|
||||
const restoreAlbums = () => { albumState.value = "ready"; };
|
||||
onUnmounted(() => { if (toastTimer) clearTimeout(toastTimer); });
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.album-list-page { display: flex; min-height: 100vh; flex-direction: column; background: $paper; }
|
||||
.album-list-header, .album-list-loading, .album-list-content { z-index: 1; }
|
||||
.album-list-loading { min-height: calc(100vh - 100rpx); }
|
||||
.album-list-content { padding: 18rpx 24rpx 72rpx; }
|
||||
.album-list-lead { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 8rpx 18rpx; min-height: 62rpx; padding: 0 20rpx; color: $ink-muted; font-size: 22rpx; background: url("/static/assets/modules/genealogy/transparent/section-divider.png") center / 100% 100% no-repeat; }
|
||||
.album-list { display: flex; flex-direction: column; gap: 16rpx; margin-top: 16rpx; }
|
||||
.album-card, .album-state-card { width: 100%; box-sizing: border-box; background: url("/static/assets/modules/family/transparent/module-content-frame.png") center / 100% 100% no-repeat; }
|
||||
.album-card { display: grid; grid-template-columns: minmax(150rpx, 0.7fr) minmax(0, 1.3fr); min-height: 210rpx; gap: 22rpx; padding: 30rpx 38rpx; }
|
||||
.album-card__media { width: 100%; aspect-ratio: 4 / 3; align-self: center; }
|
||||
.album-card__cover { display: block; width: 100%; height: 100%; }
|
||||
.album-card__copy { align-self: center; min-width: 0; }
|
||||
.album-card__copy text { display: block; overflow-wrap: anywhere; }
|
||||
.album-card__copy text:first-child { color: $ink; font-family: STKaiti, KaiTi, serif; font-size: 30rpx; font-weight: 700; }
|
||||
.album-card__copy text:nth-child(2) { margin-top: 9rpx; color: $brand-red; font-size: 21rpx; }
|
||||
.album-card__copy text:last-child { margin-top: 8rpx; color: $ink-muted; font-size: 22rpx; line-height: 1.5; }
|
||||
.album-list > .app-button { margin-top: 8rpx; }
|
||||
.album-state-card { min-height: 340rpx; margin-top: 30rpx; padding: 78rpx 52rpx 50rpx; text-align: center; }
|
||||
.album-state-card > text { display: block; }
|
||||
.album-state-card > text:first-child { color: $ink; font-family: STKaiti, KaiTi, serif; font-size: 35rpx; font-weight: 700; }
|
||||
.album-state-card > text:nth-child(2) { margin-top: 18rpx; color: $ink-muted; font-size: 24rpx; line-height: 1.65; }
|
||||
.album-state-card .app-button { margin-top: 28rpx; }
|
||||
.album-dialog-field { width: 100%; margin: 24rpx 0; text-align: left; }
|
||||
.album-dialog-field > text:first-child { display: block; color: $ink; font-size: 23rpx; font-weight: 700; }
|
||||
.album-dialog-field input { width: 100%; min-height: 76rpx; margin-top: 10rpx; padding: 0 22rpx; box-sizing: border-box; color: $ink; font-size: 24rpx; background: url("/static/assets/modules/family/transparent/module-field-frame.png") center / 100% 100% no-repeat; }
|
||||
.album-dialog-field > text:last-child { display: block; margin-top: 8rpx; color: $brand-red; font-size: 21rpx; }
|
||||
@media (max-width: 340px) { .album-card { grid-template-columns: 130rpx minmax(0, 1fr); gap: 16rpx; padding-right: 30rpx; padding-left: 30rpx; } }
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user