Files
jiapuapp/pages/records/r06-ritual-detail.vue
T

166 lines
4.6 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.
<template>
<view class="ritual-detail-page"
><ModulePageBackground module="records" /><view class="page-header"
><PageHeader title="礼仪详情" custom-back @back="returnToList" /></view
><view class="page-content"
><view v-if="!valid" class="state-card"
><text>礼仪入口无效</text
><text>未获取到可查看的礼仪活动标识请从活动列表重新进入</text
><AppButton block label="返回上一页" @click="returnToList" /></view
><view v-else-if="state === 'loading'" class="state-card"
><AppLoading text="正在读取礼仪详情" /></view
><view v-else-if="state === 'error'" class="state-card"
><text>暂时无法读取礼仪详情</text
><text>请检查网络后重新加载</text
><AppButton
block
type="secondary"
label="重新加载"
@click="loadDetail" /></view
><view v-else class="detail-card"
><text>{{ detail.title }}</text
><text
>{{ detail.type }}{{ detail.time ? ` · ${detail.time}` : "" }}</text
><text v-if="detail.location">地点{{ detail.location }}</text
><text v-if="detail.description">{{ detail.description }}</text
><text>已有 {{ detail.giftCount }} 笔献礼</text></view
></view
></view
>
</template>
<script setup>
import { computed, ref } from "vue";
import { onLoad, onUnload } 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";
import {
appApi,
createRequestController,
isRequestCancelled,
} from "@/utils/api.js";
import { goBack, returnTo } from "@/utils/navigation.js";
const genealogyId = ref("");
const ceremonyId = ref("");
const state = ref("loading");
const detail = ref({
title: "",
type: "",
time: "",
location: "",
description: "",
giftCount: 0,
});
const controller = createRequestController();
let active = true;
const valid = computed(
() =>
/^[1-9]\d*$/.test(genealogyId.value) && /^[1-9]\d*$/.test(ceremonyId.value),
);
const loadDetail = async () => {
if (!valid.value) return;
controller.abort();
state.value = "loading";
try {
const item = await appApi.getCeremonyDetail(
genealogyId.value,
ceremonyId.value,
{ requestController: controller },
);
if (!active) return;
detail.value = {
title: String(item.ceremonyTitle || "未命名活动"),
type: String(item.ceremonyType || ""),
time: String(item.ceremonyTime || ""),
location: String(item.location || item.locationAddress || ""),
description: String(item.ceremonyDesc || ""),
giftCount: Number.isSafeInteger(item.giftCount) ? item.giftCount : 0,
};
state.value = "ready";
} catch (error) {
if (!active || isRequestCancelled(error)) return;
state.value = "error";
}
};
onLoad((query) => {
genealogyId.value = String(query?.genealogyId || "");
ceremonyId.value = String(query?.ceremonyId || "");
if (valid.value) loadDetail();
else state.value = "invalid";
});
onUnload(() => {
active = false;
controller.abort();
});
const returnToList = () =>
/^[1-9]\d*$/.test(genealogyId.value)
? returnTo("R05", { genealogyId: genealogyId.value })
: goBack();
</script>
<style scoped lang="scss">
@import "../../styles/adaptive-frame-profiles.scss";
.ritual-detail-page {
display: flex;
min-height: 100vh;
flex-direction: column;
background: $paper;
}
.page-header,
.page-content {
z-index: 1;
}
.page-content {
padding: 18rpx 24rpx 72rpx;
}
.state-card,
.detail-card {
@include adaptive-records-content;
}
.state-card {
display: flex;
min-height: 320rpx;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 42rpx;
text-align: center;
color: $ink;
font-size: clamp(16px, 28rpx, 20px);
}
.state-card .app-button {
width: 100%;
margin-top: 24rpx;
}
.state-card text {
display: block;
}
.state-card text:nth-child(2) {
margin-top: 14rpx;
color: $ink-muted;
font-size: clamp(14px, 22rpx, 17px);
line-height: 1.55;
}
.detail-card {
display: flex;
min-height: 320rpx;
flex-direction: column;
padding: 42rpx;
}
.detail-card text {
display: block;
}
.detail-card text:first-child {
color: $ink;
font-family: STKaiti, KaiTi, serif;
font-size: clamp(19px, 36rpx, 24px);
font-weight: 700;
}
.detail-card text:not(:first-child) {
margin-top: 14rpx;
color: $ink-muted;
font-size: clamp(14px, 23rpx, 17px);
line-height: 1.6;
}
</style>