Files
jiapuapp/pages/records/r03-gift-list.vue
T
2026-07-21 20:59:10 +08:00

195 lines
5.0 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!-- 页面编号R-03用途贺礼簿列表空态失败与新增入口 -->
<template>
<view class="gift-page" :class="stateClasses">
<ModulePageBackground module="records" />
<view class="page-header">
<PageHeader title="贺礼簿" action="新增" @action="createGift" />
</view>
<view v-if="giftState === 'loading'" class="page-loading">
<AppLoading
text="正在整理贺礼簿"
description="请稍候,正在读取家人的礼仪往来。"
/>
</view>
<view v-else class="page-content">
<template v-if="giftState === 'ready' && giftBooks.length">
<view
v-for="gift in giftBooks"
:key="gift.id"
class="record-card"
role="button"
:aria-label="`查看${gift.title}`"
@click="openGiftBook(gift)"
>
<text class="record-card__tag">{{ gift.occasion }}</text>
<text class="record-card__title">{{ gift.title }}</text>
<text class="record-card__copy">
{{ gift.from }} · {{ gift.date }}
</text>
<text class="record-card__hint">查看并编辑贺礼</text>
</view>
<AppButton block label="新增贺礼" @click="createGift" />
</template>
<view v-else class="state-card">
<text>
{{ giftState === "error" ? "贺礼簿暂不可用" : "还没有贺礼记录" }}
</text>
<text>
{{
giftState === "error"
? "请稍后重新查看,已有记录不会受到影响。"
: "从第一份家人之间的心意开始记录。"
}}
</text>
<AppButton
:type="giftState === 'error' ? 'secondary' : 'primary'"
block
:label="giftState === 'error' ? '重新查看' : '新增贺礼'"
@click="giftState === 'error' ? restoreGifts() : createGift()"
/>
</view>
</view>
</view>
</template>
<script setup>
import { computed, ref } from "vue";
import { onLoad } from "@dcloudio/uni-app";
import AppButton from "@/components/AppButton.vue";
import AppLoading from "@/components/AppLoading.vue";
import ModulePageBackground from "@/components/ModulePageBackground.vue";
import PageHeader from "@/components/PageHeader.vue";
const baseGifts = [
{
id: "301",
title: "新春贺礼",
occasion: "春节",
from: "汤文正一家",
date: "2024 年 2 月 10 日",
},
{
id: "302",
title: "寿宴礼单",
occasion: "寿辰",
from: "汤淑华",
date: "2024 年 4 月 18 日",
},
{
id: "303",
title: "添丁祝福",
occasion: "新生",
from: "汤文清一家",
date: "2024 年 6 月 2 日",
},
];
const giftBooks = ref([...baseGifts]);
const giftState = ref("loading");
const stateClasses = computed(() => ({
"gift-state--loading": giftState.value === "loading",
"gift-state--empty": giftState.value === "empty",
"gift-state--error": giftState.value === "error",
}));
onLoad((query) => {
const count = Math.max(
1,
Math.min(Number(query.count) || baseGifts.length, 50),
);
giftBooks.value = Array.from({ length: count }, (_, i) => ({
...baseGifts[i % baseGifts.length],
id: String(301 + i),
title:
count > 3 ? `${baseGifts[i % 3].title}${i + 1}` : baseGifts[i].title,
}));
giftState.value = ["loading", "empty", "error"].includes(query.state)
? query.state
: "ready";
});
const openGiftBook = (gift) =>
uni.navigateTo({
url: `/pages/records/r04-gift-editor?mode=view&giftId=${gift.id}`,
});
const createGift = () =>
uni.navigateTo({ url: "/pages/records/r04-gift-editor?mode=create" });
const restoreGifts = () => {
giftState.value = "ready";
};
</script>
<style scoped lang="scss">
@use "../../styles/adaptive-frame-profiles.scss" as adaptive;
.gift-page {
display: flex;
min-height: 100vh;
flex-direction: column;
background: $paper;
}
.page-header,
.page-loading,
.page-content {
z-index: 1;
}
.page-loading {
min-height: calc(100vh - 100rpx);
}
.page-content {
display: flex;
flex-direction: column;
gap: 16rpx;
padding: 18rpx 24rpx 72rpx;
}
.record-card,
.state-card {
box-sizing: border-box;
@include adaptive.adaptive-records-content;
}
.record-card {
min-height: 190rpx;
padding: 34rpx 46rpx;
}
.record-card > text,
.state-card > text {
display: block;
}
.record-card__tag {
color: $brand-red;
font-size: 21rpx;
font-weight: 700;
}
.record-card__title {
margin-top: 6rpx;
color: $ink;
font-family: STKaiti, KaiTi, serif;
font-size: 31rpx;
font-weight: 700;
}
.record-card__copy {
margin-top: 9rpx;
color: $ink-muted;
font-size: 23rpx;
line-height: 1.5;
}
.record-card__hint {
margin-top: 10rpx;
color: $brand-red;
font-size: 21rpx;
}
.state-card {
min-height: 340rpx;
padding: 78rpx 52rpx 50rpx;
text-align: center;
}
.state-card > text:first-child {
color: $ink;
font-size: 35rpx;
font-weight: 700;
}
.state-card > text:nth-child(2) {
margin-top: 18rpx;
color: $ink-muted;
font-size: 24rpx;
line-height: 1.65;
}
.state-card .app-button {
margin-top: 28rpx;
}
</style>