|
|
@@ -0,0 +1,142 @@
|
|
|
+<script setup lang="ts">
|
|
|
+import { Notify } from '@/platform';
|
|
|
+import { tryOnBeforeMount, tryOnUnmounted, useCountdown } from '@vueuse/core';
|
|
|
+
|
|
|
+import { getAlcoholReportMethod } from '@/request/api';
|
|
|
+import type { Flow, FlowRoute } from '@/request/model';
|
|
|
+import { getRoutePath, useRouteNext } from '@/computable/useRouteNext';
|
|
|
+import { useRouteMeta } from '@/router/hooks/useRouteMeta';
|
|
|
+
|
|
|
+import NavHomeSelect from '@/assets/images/nav-home.select.png?url';
|
|
|
+import alcohol_0 from '@/assets/images/alcohol-0.png?url';
|
|
|
+import alcohol_1 from '@/assets/images/alcohol-1.png?url';
|
|
|
+
|
|
|
+const router = useRouter();
|
|
|
+const actionText = computed(() => `获取健康调理方案`);
|
|
|
+/* 倒计时完成动作 */
|
|
|
+const done = shallowRef<Flow>();
|
|
|
+/* 下一动作可选 */
|
|
|
+const next = shallowRef<Flow>();
|
|
|
+
|
|
|
+const title = useRouteMeta('title');
|
|
|
+const { handle, flow, loading } = useRouteNext({
|
|
|
+ onSuccess(flow) { return load(flow); },
|
|
|
+ onError(error) { Notify.warning(error.message); },
|
|
|
+});
|
|
|
+
|
|
|
+const { remaining, start, stop } = useCountdown(5, {
|
|
|
+ onComplete() { replace(done.value!); },
|
|
|
+ immediate: false,
|
|
|
+});
|
|
|
+const countdown = computed(() => remaining.value.toString().padStart(2, '0'));
|
|
|
+
|
|
|
+tryOnBeforeMount(() => handle());
|
|
|
+tryOnUnmounted(() => stop());
|
|
|
+
|
|
|
+const report = ref<Awaited<ReturnType<typeof getAlcoholReportMethod>>>();
|
|
|
+const tips = '建议您每日饮酒';
|
|
|
+const description = computed(() => report.value?.alcohol?.description?.replace?.(new RegExp(`^${tips}`), '')?.replace?.(/(\S)\s*(或)/, '$1\n$2') ?? '');
|
|
|
+
|
|
|
+async function load(flow: FlowRoute) {
|
|
|
+ stop();
|
|
|
+ report.value = await getAlcoholReportMethod();
|
|
|
+
|
|
|
+ done.value = flow.next.optional ? { title: '返回首页', route: '/screen' } : flow.next;
|
|
|
+ next.value = flow.next.optional ? flow.next : void 0;
|
|
|
+ start(report.value?.alcohol?.description ? 10 : 5);
|
|
|
+}
|
|
|
+
|
|
|
+const replace = (flow: Flow) => router.push({ path: getRoutePath(flow), replace: true });
|
|
|
+</script>
|
|
|
+<template>
|
|
|
+ <div>
|
|
|
+ <div class="page-header flex py-4 px-4">
|
|
|
+ <div class="grow shrink-0 h-full min-w-16"></div>
|
|
|
+ <div class="grow-[3] shrink mx-2 flex flex-col justify-center overflow-hidden">
|
|
|
+ <div class="font-bold text-3xl text-nowrap text-center tracking-wide overflow-ellipsis overflow-hidden">
|
|
|
+ {{ flow?.value.title ?? title }}
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="grow shrink-0 h-full min-w-16 flex items-center justify-end overflow-hidden">
|
|
|
+ <router-link :to="{ path: '/screen' }" replace>
|
|
|
+ <img class="size-8 object-scale-down" :src="NavHomeSelect" alt="返回首页" />
|
|
|
+ </router-link>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="page-content flex flex-col">
|
|
|
+ <van-toast v-if="loading" show type="loading" message="加载中" />
|
|
|
+ <template v-else>
|
|
|
+ <header>
|
|
|
+ <div class="my-6 text-primary text-2xl text-center" v-if="report?.date">报告日期:{{ report.date }}</div>
|
|
|
+ </header>
|
|
|
+ <main class="flex flex-col justify-evenly">
|
|
|
+ <div class="report-wrapper" v-if="report">
|
|
|
+ <div class="card m-6 text-lg" v-if="report.alcohol?.condition">
|
|
|
+ <div v-if="title" class="card__title mb-3 text-primary text-2xl font-bold">您的情况为</div>
|
|
|
+ <div class="card__content">
|
|
|
+ <div class="text-center text-4xl font-bold pre" style="letter-spacing: 4px">
|
|
|
+ {{ report.alcohol?.condition }}
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="card m-6 text-lg">
|
|
|
+ <div v-if="title" class="card__title mb-3 text-primary text-2xl">{{ tips }}</div>
|
|
|
+ <div class="card__content">
|
|
|
+ <div class="flex items-center justify-center min-h-32" v-if="report.alcohol?.description">
|
|
|
+ <div class="text-center text-5xl font-semibold whitespace-pre" style="letter-spacing: 4px; line-height: 1.25em">
|
|
|
+ {{ description }}
|
|
|
+ </div>
|
|
|
+ <img v-if="report.alcohol?.volume?.length" class="image-container object-scale-down" :src="alcohol_1" alt="可饮酒" />
|
|
|
+ </div>
|
|
|
+ <van-empty v-else :image="alcohol_0" image-size="160" description="暂无建议" />
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </main>
|
|
|
+ <footer class="flex flex-col justify-center items-center gap-4">
|
|
|
+ <van-button v-if="next" class="decorate !text-xl" @click="replace(next)">
|
|
|
+ {{ next.title ?? actionText }}
|
|
|
+ </van-button>
|
|
|
+ <van-button v-if="done" class="decorate !text-xl !text-primary-400" @click="replace(done)">
|
|
|
+ {{ done.title ?? actionText }}
|
|
|
+ <template v-if="remaining">({{ countdown }}s)</template>
|
|
|
+ </van-button>
|
|
|
+ </footer>
|
|
|
+ </template>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+<style scoped lang="scss">
|
|
|
+header {
|
|
|
+ flex: 1 1 10%;
|
|
|
+}
|
|
|
+
|
|
|
+footer {
|
|
|
+ flex: 1 1 30%;
|
|
|
+}
|
|
|
+
|
|
|
+main {
|
|
|
+ position: relative;
|
|
|
+ flex: 1 1 50%;
|
|
|
+}
|
|
|
+
|
|
|
+.image-container {
|
|
|
+ width: 30vw;
|
|
|
+ height: 30vw;
|
|
|
+ max-width: 216px;
|
|
|
+ max-height: 216px;
|
|
|
+}
|
|
|
+
|
|
|
+.card__content {
|
|
|
+ --van-empty-description-color: #fff;
|
|
|
+ --van-empty-description-margin-top: 36px;
|
|
|
+ --van-empty-description-font-size: 18px;
|
|
|
+}
|
|
|
+</style>
|
|
|
+<style scoped lang="scss">
|
|
|
+.report-wrapper .card {
|
|
|
+ padding: 24px;
|
|
|
+ border-radius: 24px;
|
|
|
+ box-shadow: inset 0 0 80px 0 #34a76b60;
|
|
|
+}
|
|
|
+</style>
|