完成70%
This commit is contained in:
@@ -1,394 +1,11 @@
|
||||
<!-- 页面编号:G-09;用途:我的家谱申请列表与空/失败状态。 -->
|
||||
<!-- 页面编号:G-09;用途:我的申请。列表 DTO 未声明时不展示 fixture 申请。 -->
|
||||
<template>
|
||||
<view class="application-page">
|
||||
<GenealogyPageBackground />
|
||||
<view class="application-page__header">
|
||||
<PageHeader title="我的申请" custom-back @back="requestBack" />
|
||||
</view>
|
||||
|
||||
<view
|
||||
class="application-content"
|
||||
:class="{
|
||||
'application-state--list': applicationState === 'list',
|
||||
'application-state--empty': applicationState === 'empty',
|
||||
'application-state--error': applicationState === 'error',
|
||||
}"
|
||||
>
|
||||
<template v-if="applicationState === 'list'">
|
||||
<view class="application-intro">
|
||||
<text>入谱申请进度</text><text>审核结果会同步到消息中心</text>
|
||||
</view>
|
||||
<view
|
||||
v-for="item in applications"
|
||||
:key="item.id"
|
||||
class="application-card"
|
||||
>
|
||||
<view class="application-card__body">
|
||||
<text class="application-card__name">{{ item.genealogyName }}</text>
|
||||
<text class="application-card__time">{{ item.appliedAt }}</text>
|
||||
<text class="application-card__relation">{{ item.relation }}</text>
|
||||
<text
|
||||
class="application-card__status"
|
||||
:class="`application-card__status--${item.status.toLowerCase()}`"
|
||||
>{{ statusLabel(item.status) }}</text
|
||||
>
|
||||
<text class="application-card__hint">{{
|
||||
statusHint(item.status)
|
||||
}}</text>
|
||||
<view
|
||||
v-if="actionFor(item)"
|
||||
class="application-card__action"
|
||||
@click="handleApplicationAction(item)"
|
||||
>{{ actionFor(item) }}</view
|
||||
>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<AppLoading
|
||||
v-else-if="applicationState === 'loading'"
|
||||
text="正在整理申请记录"
|
||||
description="请稍候,正在同步审核状态。"
|
||||
/>
|
||||
<view v-else class="application-state-card">
|
||||
<view class="application-state-card__copy">
|
||||
<text>{{ stateTitle }}</text>
|
||||
<text>{{ stateCopy }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view
|
||||
v-if="applicationState !== 'list' && applicationState !== 'loading'"
|
||||
class="application-page__action"
|
||||
@click="
|
||||
applicationState === 'error' ? loadApplications({}) : toSearch()
|
||||
"
|
||||
>
|
||||
<text>{{
|
||||
applicationState === "error" ? "重新查看" : "查找公开家谱"
|
||||
}}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<AppDialog
|
||||
:visible="!!withdrawTarget"
|
||||
title="预览撤回效果"
|
||||
:message="
|
||||
withdrawTarget
|
||||
? `当前只更新本页对“${withdrawTarget.genealogyName}”的撤回预览,不会向服务器提交;真实申请仍可能处于审核中。`
|
||||
: ''
|
||||
"
|
||||
confirm-text="查看本地效果"
|
||||
cancel-text="暂不撤回"
|
||||
show-cancel
|
||||
:close-on-mask="false"
|
||||
@confirm="confirmWithdraw"
|
||||
@cancel="cancelWithdraw"
|
||||
/>
|
||||
</view>
|
||||
<view class="applications-page"><GenealogyPageBackground /><view class="page-header"><PageHeader title="我的申请" custom-back @back="returnToGenealogies" /></view><view class="page-content"><view class="state-card"><text>申请列表待后端字段合同</text><text>申请读取响应没有声明申请 ID、家谱名称、申请时间、状态或审核备注字段;页面已停止展示本地申请和本地撤回结果。</text><AppButton block label="返回我的家谱" @click="returnToGenealogies" /></view></view></view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { computed, ref } from "vue";
|
||||
import { onBackPress, onLoad } from "@dcloudio/uni-app";
|
||||
import AppDialog from "@/components/AppDialog.vue";
|
||||
import AppLoading from "@/components/AppLoading.vue";
|
||||
import GenealogyPageBackground from "@/components/GenealogyPageBackground.vue";
|
||||
import PageHeader from "@/components/PageHeader.vue";
|
||||
import { findGenealogyFixture } from "@/data/mock.js";
|
||||
import { handleBackPress, openPage, runBackGuard } from "@/utils/navigation.js";
|
||||
|
||||
const applications = ref([]);
|
||||
const applicationState = ref("loading");
|
||||
const errorMessage = ref("");
|
||||
const withdrawTarget = ref(null);
|
||||
const genealogyNameFor = (genealogyId) =>
|
||||
findGenealogyFixture(genealogyId)?.name || "未知家谱";
|
||||
const applicationSamples = [
|
||||
{
|
||||
id: "pending-2003",
|
||||
genealogyId: "2003",
|
||||
genealogyName: genealogyNameFor("2003"),
|
||||
relation: "自述为汤正华堂侄",
|
||||
appliedAt: "今天 10:24",
|
||||
status: "PENDING",
|
||||
},
|
||||
{
|
||||
id: "approved-1002",
|
||||
genealogyId: "1002",
|
||||
genealogyName: genealogyNameFor("1002"),
|
||||
relation: "祖居河南汝南",
|
||||
appliedAt: "昨天 18:02",
|
||||
status: "APPROVED",
|
||||
},
|
||||
{
|
||||
id: "rejected-2004",
|
||||
genealogyId: "2004",
|
||||
genealogyName: genealogyNameFor("2004"),
|
||||
relation: "补充材料不足",
|
||||
appliedAt: "7月12日 09:18",
|
||||
status: "REJECTED",
|
||||
},
|
||||
];
|
||||
|
||||
const statusLabel = (status) =>
|
||||
({
|
||||
PENDING: "审核中",
|
||||
APPROVED: "已通过",
|
||||
REJECTED: "未通过",
|
||||
LOCAL_WITHDRAWN: "本地撤回预览",
|
||||
})[status] || "状态未知";
|
||||
|
||||
const statusHint = (status) =>
|
||||
({
|
||||
PENDING: "管理员尚未处理,可在审核前撤回",
|
||||
APPROVED: "申请已通过,可进入这部家谱",
|
||||
REJECTED: "请修改关系说明后重新提交",
|
||||
LOCAL_WITHDRAWN: "尚未提交服务器,真实申请仍可能处于审核中",
|
||||
})[status] || "";
|
||||
|
||||
const actionFor = (item) =>
|
||||
({ PENDING: "预览撤回效果", APPROVED: "进入家谱", REJECTED: "修改后重新提交" })[
|
||||
item.status
|
||||
] || "";
|
||||
const stateTitle = computed(() =>
|
||||
applicationState.value === "empty"
|
||||
? "还没有入谱申请"
|
||||
: applicationState.value === "loading"
|
||||
? "正在整理申请记录"
|
||||
: "申请记录暂时无法读取",
|
||||
);
|
||||
const stateCopy = computed(() =>
|
||||
applicationState.value === "empty"
|
||||
? "从家谱搜索提交的申请会显示在这里;邀请码本地校验不会生成申请记录。"
|
||||
: applicationState.value === "loading"
|
||||
? "请稍候,正在同步审核状态。"
|
||||
: errorMessage.value || "请检查网络后重新查看。",
|
||||
);
|
||||
|
||||
const loadApplications = (query = {}) => {
|
||||
applicationState.value = "loading";
|
||||
errorMessage.value = "";
|
||||
if (query.state === "empty") {
|
||||
applicationState.value = "empty";
|
||||
return;
|
||||
}
|
||||
if (query.state === "error") {
|
||||
applicationState.value = "error";
|
||||
return;
|
||||
}
|
||||
if (query.state === "loading") {
|
||||
applicationState.value = "loading";
|
||||
return;
|
||||
}
|
||||
applications.value = applicationSamples.map((item) => ({ ...item }));
|
||||
if (query.status) {
|
||||
const requestedStatus = String(query.status).toUpperCase();
|
||||
applications.value = applications.value.filter(
|
||||
(item) => item.status === requestedStatus,
|
||||
);
|
||||
if (!applications.value.length) applicationState.value = "empty";
|
||||
}
|
||||
if (applicationState.value !== "empty") applicationState.value = "list";
|
||||
};
|
||||
|
||||
onLoad(loadApplications);
|
||||
const requestBack = () =>
|
||||
runBackGuard({
|
||||
transientOpen: Boolean(withdrawTarget.value),
|
||||
"close-transient": cancelWithdraw,
|
||||
});
|
||||
|
||||
onBackPress((event) => handleBackPress(event, requestBack));
|
||||
|
||||
const handleApplicationAction = (item) => {
|
||||
if (item.status === "APPROVED")
|
||||
return openPage(
|
||||
"G05",
|
||||
{ genealogyId: String(item.genealogyId) },
|
||||
"G09",
|
||||
);
|
||||
if (item.status === "REJECTED")
|
||||
return openPage(
|
||||
"G08",
|
||||
{ genealogyId: String(item.genealogyId), source: "search" },
|
||||
"G09",
|
||||
);
|
||||
if (item.status === "PENDING") withdrawTarget.value = item;
|
||||
};
|
||||
const cancelWithdraw = () => {
|
||||
withdrawTarget.value = null;
|
||||
};
|
||||
const confirmWithdraw = () => {
|
||||
const target = applications.value.find(
|
||||
(item) => item.id === withdrawTarget.value?.id,
|
||||
);
|
||||
if (target) target.status = "LOCAL_WITHDRAWN";
|
||||
cancelWithdraw();
|
||||
};
|
||||
const toSearch = () => openPage("G06", {}, "G09");
|
||||
import AppButton from "@/components/AppButton.vue"; import GenealogyPageBackground from "@/components/GenealogyPageBackground.vue"; import PageHeader from "@/components/PageHeader.vue"; import { returnTo } from "@/utils/navigation.js"; const returnToGenealogies=()=>returnTo("G01");
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@use "../../styles/adaptive-frame-profiles.scss" as adaptive;
|
||||
|
||||
.application-page {
|
||||
display: flex;
|
||||
min-height: 100vh;
|
||||
flex-direction: column;
|
||||
background: $paper;
|
||||
}
|
||||
.application-page__header {
|
||||
z-index: 3;
|
||||
}
|
||||
.application-content {
|
||||
z-index: 2;
|
||||
padding: 28rpx 24rpx 60rpx;
|
||||
}
|
||||
.application-intro {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
justify-content: space-between;
|
||||
margin: 0 8rpx 20rpx;
|
||||
}
|
||||
.application-intro text:first-child {
|
||||
color: $ink;
|
||||
font-family: "STKaiti", "KaiTi", serif;
|
||||
font-size: 31rpx;
|
||||
font-weight: 700;
|
||||
}
|
||||
.application-intro text:last-child {
|
||||
color: $ink-muted;
|
||||
font-size: 24rpx;
|
||||
}
|
||||
.application-card {
|
||||
@include adaptive.adaptive-genealogy-list-card;
|
||||
display: grid;
|
||||
width: 100%;
|
||||
min-height: 210rpx;
|
||||
margin-bottom: 12rpx;
|
||||
}
|
||||
.application-card__body {
|
||||
display: grid;
|
||||
min-width: 0;
|
||||
min-height: 174rpx;
|
||||
grid-template-columns: minmax(0, 1fr) auto;
|
||||
gap: 8rpx 14rpx;
|
||||
padding: 26rpx 28rpx 22rpx 40rpx;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.application-card__name {
|
||||
grid-row: 1;
|
||||
grid-column: 1;
|
||||
align-self: start;
|
||||
justify-self: start;
|
||||
color: $ink;
|
||||
font-family: "STKaiti", "KaiTi", serif;
|
||||
font-size: 30rpx;
|
||||
font-weight: 700;
|
||||
}
|
||||
.application-card__time {
|
||||
grid-row: 1;
|
||||
grid-column: 2;
|
||||
align-self: start;
|
||||
justify-self: end;
|
||||
margin-top: 3rpx;
|
||||
color: #998873;
|
||||
font-size: 23rpx;
|
||||
}
|
||||
.application-card__relation {
|
||||
display: block;
|
||||
grid-row: 2;
|
||||
grid-column: 1 / -1;
|
||||
align-self: start;
|
||||
justify-self: start;
|
||||
margin-top: 0;
|
||||
color: $ink-muted;
|
||||
font-size: 24rpx;
|
||||
}
|
||||
.application-card__status {
|
||||
grid-row: 2;
|
||||
grid-column: 2;
|
||||
align-self: center;
|
||||
justify-self: end;
|
||||
margin-right: 3%;
|
||||
color: $brand-red;
|
||||
font-size: 25rpx;
|
||||
font-weight: 700;
|
||||
}
|
||||
.application-card__status--approved {
|
||||
color: #537368;
|
||||
}
|
||||
.application-card__status--rejected {
|
||||
color: #7e6f62;
|
||||
}
|
||||
.application-card__hint {
|
||||
grid-row: 3;
|
||||
grid-column: 1;
|
||||
align-self: center;
|
||||
justify-self: start;
|
||||
margin-bottom: 4rpx;
|
||||
color: #766653;
|
||||
font-size: 23rpx;
|
||||
}
|
||||
.application-card__action {
|
||||
z-index: 2;
|
||||
display: flex;
|
||||
grid-row: 3;
|
||||
grid-column: 2;
|
||||
align-self: center;
|
||||
justify-self: end;
|
||||
min-height: 54rpx;
|
||||
align-items: center;
|
||||
margin-right: 2%;
|
||||
margin-bottom: 0;
|
||||
color: $brand-red;
|
||||
font-size: 23rpx;
|
||||
font-weight: 700;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.application-state-card {
|
||||
@include adaptive.adaptive-genealogy-list-card;
|
||||
display: flex;
|
||||
width: 100%;
|
||||
min-height: 228rpx;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-top: 80rpx;
|
||||
padding: 48rpx 12%;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.application-state-card__copy {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
text-align: center;
|
||||
}
|
||||
.application-state-card__copy text:first-child {
|
||||
color: $ink;
|
||||
font-family: "STKaiti", "KaiTi", serif;
|
||||
font-size: 31rpx;
|
||||
font-weight: 700;
|
||||
}
|
||||
.application-state-card__copy text:last-child {
|
||||
margin-top: 16rpx;
|
||||
color: $ink-muted;
|
||||
font-size: 24rpx;
|
||||
line-height: 1.6;
|
||||
}
|
||||
.application-page__action {
|
||||
display: flex;
|
||||
width: 420rpx;
|
||||
min-height: 82rpx;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin: 34rpx auto 0;
|
||||
background: url("/static/assets/foundation/transparent/a01-scroll-primary-v3.png")
|
||||
center / contain no-repeat;
|
||||
}
|
||||
.application-page__action text {
|
||||
z-index: 1;
|
||||
color: #fff9ed;
|
||||
font-size: 26rpx;
|
||||
font-weight: 700;
|
||||
}
|
||||
.applications-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{box-sizing:border-box;min-height:340rpx;padding:78rpx 52rpx 50rpx;text-align:center;@include adaptive.adaptive-genealogy-state-panel}.state-card text{display:block}.state-card text:first-child{color:$ink;font-family:STKaiti,KaiTi,serif;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>
|
||||
|
||||
Reference in New Issue
Block a user