验收完成40%
This commit is contained in:
@@ -1,16 +1,10 @@
|
||||
<!-- 页面编号:G-01;用途:我的家谱列表与首次分流;本轮仍待用户重新审核。 -->
|
||||
<template>
|
||||
<view class="page-shell genealogy-index">
|
||||
<image
|
||||
class="page-paper-texture"
|
||||
src="/static/assets/foundation/opaque/page-paper.jpg"
|
||||
mode="scaleToFill"
|
||||
/>
|
||||
<image
|
||||
class="page-footer-landscape"
|
||||
src="/static/assets/foundation/transparent/footer-mountain-bamboo.png"
|
||||
mode="scaleToFill"
|
||||
/>
|
||||
<view
|
||||
class="page-shell genealogy-index"
|
||||
:class="{ 'genealogy-index--split': isListLayout }"
|
||||
>
|
||||
<GenealogyPageBackground />
|
||||
<PageHeader
|
||||
root
|
||||
title="我的家谱"
|
||||
@@ -31,14 +25,15 @@
|
||||
<text class="state-title">暂时无法读取家谱</text>
|
||||
<text class="state-copy">网络或服务暂不可用,请稍后重新查看。</text>
|
||||
<view class="state-retry" hover-class="action-hover" @click="retryLoad">
|
||||
<image class="state-retry__skin" src="/static/assets/foundation/opaque/a01-primary-button.png" mode="scaleToFill" />
|
||||
<image class="state-retry__skin" src="/static/assets/foundation/transparent/a01-scroll-primary-v3.png" mode="aspectFit" />
|
||||
<text class="state-retry__copy">重新加载</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<template v-else-if="hasGenealogies">
|
||||
<view class="current-slip" @click="openSwitcher">
|
||||
<view class="genealogy-fixed-zone">
|
||||
<view class="current-slip" @click="openSwitcher">
|
||||
<image
|
||||
class="current-frame"
|
||||
src="/static/assets/modules/genealogy/transparent/current-slip-frame.png"
|
||||
@@ -87,90 +82,98 @@
|
||||
<text class="current-meta-item-text">管理员</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="shortcut-grid">
|
||||
<view
|
||||
v-for="item in shortcuts"
|
||||
:key="item.key"
|
||||
class="shortcut-item"
|
||||
@click="openShortcut(item.key)"
|
||||
>
|
||||
<image class="shortcut-icon" :src="item.icon" mode="aspectFit" />
|
||||
<text class="shortcut-label">{{ item.label }}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<image
|
||||
class="section-divider"
|
||||
src="/static/assets/modules/genealogy/transparent/section-divider.png"
|
||||
mode="scaleToFill"
|
||||
/>
|
||||
|
||||
<view class="genealogy-lower">
|
||||
<view v-if="createdGenealogies.length" class="list-section">
|
||||
<view class="section-heading"><text>我创建的</text></view>
|
||||
<GenealogyCard
|
||||
v-for="item in createdGenealogies"
|
||||
:key="item.id"
|
||||
:genealogy="item"
|
||||
role="管理员"
|
||||
:selected="item.id === currentGenealogy.id"
|
||||
@select="openGenealogy"
|
||||
/>
|
||||
</view>
|
||||
|
||||
<view v-if="joinedGenealogies.length" class="list-section">
|
||||
<view class="section-heading"><text>我加入的</text></view>
|
||||
<GenealogyCard
|
||||
v-for="item in joinedGenealogies"
|
||||
:key="item.id"
|
||||
:genealogy="item"
|
||||
role="成员"
|
||||
@select="openGenealogy"
|
||||
/>
|
||||
</view>
|
||||
|
||||
<view class="list-section application-section">
|
||||
<view class="section-heading"><text>加入申请</text></view>
|
||||
<view class="shortcut-grid">
|
||||
<view
|
||||
v-for="item in applicationRecords"
|
||||
:key="item.id"
|
||||
class="application-record"
|
||||
hover-class="action-hover"
|
||||
@click="openApplication(item)"
|
||||
v-for="item in shortcuts"
|
||||
:key="item.key"
|
||||
class="shortcut-item"
|
||||
@click="openShortcut(item.key)"
|
||||
>
|
||||
<image class="application-record__skin" src="/static/assets/modules/genealogy/transparent/list-slip-frame.png" mode="scaleToFill" />
|
||||
<view class="application-record__main">
|
||||
<view class="application-record__title-row">
|
||||
<text class="application-record__name">{{ item.name }}</text>
|
||||
<text class="application-record__status" :class="`application-record__status--${item.tone}`">{{ item.statusLabel }}</text>
|
||||
</view>
|
||||
<text class="application-record__copy">{{ item.description }}</text>
|
||||
</view>
|
||||
<image class="application-record__chevron" src="/static/assets/foundation/transparent/chevron-right.png" mode="aspectFit" />
|
||||
<image class="shortcut-icon" :src="item.icon" mode="aspectFit" />
|
||||
<text class="shortcut-label">{{ item.label }}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="create-action" @click="openAddDialog">
|
||||
<image
|
||||
class="create-cloud"
|
||||
src="/static/assets/modules/genealogy/transparent/create-cloud.png"
|
||||
mode="aspectFit"
|
||||
/>
|
||||
<image
|
||||
class="create-icon"
|
||||
src="/static/assets/modules/genealogy/transparent/add.png"
|
||||
mode="aspectFit"
|
||||
/>
|
||||
<text>添加家谱</text>
|
||||
<image
|
||||
class="create-cloud create-cloud--right"
|
||||
src="/static/assets/modules/genealogy/transparent/create-cloud.png"
|
||||
mode="aspectFit"
|
||||
/>
|
||||
</view>
|
||||
<image
|
||||
class="section-divider"
|
||||
src="/static/assets/modules/genealogy/transparent/section-divider.png"
|
||||
mode="scaleToFill"
|
||||
/>
|
||||
</view>
|
||||
|
||||
<scroll-view
|
||||
class="genealogy-list-scroll"
|
||||
scroll-y
|
||||
:scroll-top="listScrollCommand"
|
||||
@scroll="handleListScroll"
|
||||
>
|
||||
<view class="genealogy-lower">
|
||||
<view v-if="createdGenealogies.length" class="list-section">
|
||||
<view class="section-heading"><text>我创建的</text></view>
|
||||
<GenealogyCard
|
||||
v-for="item in createdGenealogies"
|
||||
:key="item.id"
|
||||
:genealogy="item"
|
||||
role="管理员"
|
||||
:selected="item.id === currentGenealogy.id"
|
||||
@select="openGenealogy"
|
||||
/>
|
||||
</view>
|
||||
|
||||
<view v-if="joinedGenealogies.length" class="list-section">
|
||||
<view class="section-heading"><text>我加入的</text></view>
|
||||
<GenealogyCard
|
||||
v-for="item in joinedGenealogies"
|
||||
:key="item.id"
|
||||
:genealogy="item"
|
||||
role="成员"
|
||||
@select="openGenealogy"
|
||||
/>
|
||||
</view>
|
||||
|
||||
<view class="list-section application-section">
|
||||
<view class="section-heading"><text>加入申请</text></view>
|
||||
<view
|
||||
v-for="item in applicationRecords"
|
||||
:key="item.id"
|
||||
class="application-record"
|
||||
hover-class="action-hover"
|
||||
@click="openApplication(item)"
|
||||
>
|
||||
<image class="application-record__skin" src="/static/assets/modules/genealogy/transparent/list-slip-frame.png" mode="scaleToFill" />
|
||||
<view class="application-record__main">
|
||||
<view class="application-record__title-row">
|
||||
<text class="application-record__name">{{ item.name }}</text>
|
||||
<text class="application-record__status" :class="`application-record__status--${item.tone}`">{{ item.statusLabel }}</text>
|
||||
</view>
|
||||
<text class="application-record__copy">{{ item.description }}</text>
|
||||
</view>
|
||||
<image class="application-record__chevron" src="/static/assets/foundation/transparent/chevron-right.png" mode="aspectFit" />
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="create-action" @click="openAddDialog">
|
||||
<image
|
||||
class="create-cloud"
|
||||
src="/static/assets/modules/genealogy/transparent/create-cloud.png"
|
||||
mode="aspectFit"
|
||||
/>
|
||||
<image
|
||||
class="create-icon"
|
||||
src="/static/assets/modules/genealogy/transparent/add.png"
|
||||
mode="aspectFit"
|
||||
/>
|
||||
<text>添加家谱</text>
|
||||
<image
|
||||
class="create-cloud create-cloud--right"
|
||||
src="/static/assets/modules/genealogy/transparent/create-cloud.png"
|
||||
mode="aspectFit"
|
||||
/>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</template>
|
||||
|
||||
<view v-else class="genealogy-empty-state">
|
||||
@@ -203,8 +206,8 @@
|
||||
>
|
||||
<image
|
||||
class="empty-search-action__skin"
|
||||
src="/static/assets/foundation/opaque/a01-primary-button.png"
|
||||
mode="scaleToFill"
|
||||
src="/static/assets/foundation/transparent/a01-scroll-primary-v3.png"
|
||||
mode="aspectFit"
|
||||
/>
|
||||
<text class="empty-search-action__copy empty-search-action__copy--primary">搜索家谱</text>
|
||||
</view>
|
||||
@@ -215,8 +218,8 @@
|
||||
>
|
||||
<image
|
||||
class="empty-invite-action__skin"
|
||||
src="/static/assets/foundation/opaque/a01-secondary-button.png"
|
||||
mode="scaleToFill"
|
||||
src="/static/assets/foundation/transparent/a01-scroll-secondary-v3.png"
|
||||
mode="aspectFit"
|
||||
/>
|
||||
<text class="empty-invite-action__copy">邀请码加入</text>
|
||||
</view>
|
||||
@@ -231,19 +234,13 @@
|
||||
|
||||
<view v-if="addDialogVisible" class="add-dialog-layer" @click="closeAddDialog">
|
||||
<view class="add-dialog" @click.stop>
|
||||
<image class="add-dialog__skin" src="/static/assets/modules/genealogy/opaque/g01-empty-panel.png" mode="scaleToFill" />
|
||||
<image class="add-dialog__skin" src="/static/assets/modules/auth/transparent/a01-scroll-dialog-v3.png" mode="aspectFit" />
|
||||
<view class="add-dialog__content">
|
||||
<text class="dialog-title">添加家谱</text>
|
||||
<text class="dialog-copy">建议先搜索已有家谱,避免重复创建</text>
|
||||
<view class="dialog-primary" @click="applyToJoin">
|
||||
<image class="dialog-action__skin" src="/static/assets/foundation/opaque/a01-primary-button.png" mode="scaleToFill" />
|
||||
<text class="dialog-primary__copy">搜索家谱</text>
|
||||
</view>
|
||||
<view class="dialog-secondary" @click="joinByInvite">
|
||||
<image class="dialog-action__skin" src="/static/assets/foundation/opaque/a01-secondary-button.png" mode="scaleToFill" />
|
||||
<text>邀请码加入</text>
|
||||
</view>
|
||||
<view class="dialog-create" @click="createGenealogy">确认没有现有家谱,继续创建</view>
|
||||
<AppButton block label="搜索家谱" @click="applyToJoin" />
|
||||
<AppButton block type="secondary" label="邀请码加入" @click="joinByInvite" />
|
||||
<AppButton block type="secondary" label="确认没有现有家谱,继续创建" @click="createGenealogy" />
|
||||
<view class="dialog-close" @click="closeAddDialog">取消</view>
|
||||
</view>
|
||||
</view>
|
||||
@@ -251,7 +248,7 @@
|
||||
|
||||
<view v-if="switcherVisible" class="genealogy-switcher-layer" @click="closeSwitcher">
|
||||
<view class="genealogy-switcher" @click.stop>
|
||||
<image class="genealogy-switcher__skin" src="/static/assets/modules/genealogy/opaque/g01-empty-panel.png" mode="scaleToFill" />
|
||||
<image class="genealogy-switcher__skin" src="/static/assets/modules/auth/transparent/a01-scroll-dialog-v3.png" mode="aspectFit" />
|
||||
<view class="genealogy-switcher__content">
|
||||
<text class="dialog-title">切换当前家谱</text>
|
||||
<view
|
||||
@@ -277,10 +274,12 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { computed, ref } from "vue";
|
||||
import { computed, nextTick, ref } from "vue";
|
||||
import { onLoad, onShow } from "@dcloudio/uni-app";
|
||||
import AppTabbar from "@/components/AppTabbar.vue";
|
||||
import AppButton from "@/components/AppButton.vue";
|
||||
import GenealogyCard from "@/components/GenealogyCard.vue";
|
||||
import GenealogyPageBackground from "@/components/GenealogyPageBackground.vue";
|
||||
import PageHeader from "@/components/PageHeader.vue";
|
||||
import { genealogies, notifications } from "@/data/mock.js";
|
||||
|
||||
@@ -291,6 +290,8 @@ const forceEmptyState = ref(false);
|
||||
const addDialogVisible = ref(false);
|
||||
const switcherVisible = ref(false);
|
||||
const selectedGenealogyId = ref(genealogies[0]?.id || null);
|
||||
const listScrollCommand = ref(0);
|
||||
const currentListScrollTop = ref(0);
|
||||
|
||||
const readPresentationState = () => {
|
||||
if (typeof location !== "undefined") {
|
||||
@@ -322,6 +323,9 @@ const unreadCount = computed(
|
||||
() => notifications.filter((item) => item.unread).length,
|
||||
);
|
||||
const hasGenealogies = computed(() => !forceEmptyState.value && list.value.length > 0);
|
||||
const isListLayout = computed(
|
||||
() => !isLoading.value && !hasError.value && hasGenealogies.value,
|
||||
);
|
||||
const createdGenealogies = computed(() =>
|
||||
list.value.filter((item, index) => index === 0),
|
||||
);
|
||||
@@ -376,9 +380,19 @@ const openAddDialog = () => { addDialogVisible.value = true; };
|
||||
const closeAddDialog = () => { addDialogVisible.value = false; };
|
||||
const openSwitcher = () => { switcherVisible.value = true; };
|
||||
const closeSwitcher = () => { switcherVisible.value = false; };
|
||||
const selectGenealogy = (genealogy) => {
|
||||
const handleListScroll = (event) => {
|
||||
currentListScrollTop.value = Number(event?.detail?.scrollTop || 0);
|
||||
};
|
||||
const resetListScroll = async () => {
|
||||
listScrollCommand.value = currentListScrollTop.value;
|
||||
await nextTick();
|
||||
listScrollCommand.value = 0;
|
||||
currentListScrollTop.value = 0;
|
||||
};
|
||||
const selectGenealogy = async (genealogy) => {
|
||||
selectedGenealogyId.value = genealogy.id;
|
||||
closeSwitcher();
|
||||
await resetListScroll();
|
||||
};
|
||||
const openApplication = (record) => {
|
||||
const statusQuery = record.id === "pending" ? "pending" : record.id;
|
||||
@@ -408,37 +422,40 @@ const openShortcut = (key) => {
|
||||
background: #f9f6ef;
|
||||
}
|
||||
|
||||
.page-paper-texture {
|
||||
position: absolute;
|
||||
top: calc(124rpx + var(--status-bar-height, 0px));
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
z-index: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
opacity: 0.72;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.page-footer-landscape {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
bottom: 112rpx;
|
||||
left: 0;
|
||||
z-index: 1;
|
||||
width: 100%;
|
||||
height: 480rpx;
|
||||
opacity: 0.5;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.genealogy-content {
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
padding: 24rpx 32rpx 176rpx;
|
||||
}
|
||||
|
||||
.genealogy-index--split {
|
||||
display: flex;
|
||||
height: 100vh;
|
||||
min-height: 0;
|
||||
flex-direction: column;
|
||||
padding-bottom: calc(112rpx + env(safe-area-inset-bottom));
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.genealogy-index--split .genealogy-content {
|
||||
display: flex;
|
||||
min-height: 0;
|
||||
flex: 1;
|
||||
flex-direction: column;
|
||||
padding-bottom: 0;
|
||||
}
|
||||
|
||||
.genealogy-fixed-zone {
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
|
||||
.genealogy-list-scroll {
|
||||
width: 100%;
|
||||
height: 0;
|
||||
min-height: 0;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.current-slip {
|
||||
position: relative;
|
||||
display: block;
|
||||
@@ -531,8 +548,9 @@ const openShortcut = (key) => {
|
||||
flex-wrap: nowrap;
|
||||
justify-content: space-between;
|
||||
margin-top: 0;
|
||||
color: $ink-muted;
|
||||
font-size: 25rpx;
|
||||
color: #62584c;
|
||||
font-size: 27rpx;
|
||||
font-weight: 500;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
@@ -635,10 +653,23 @@ const openShortcut = (key) => {
|
||||
.application-record__main { position: relative; z-index: 1; min-width: 0; flex: 1; }
|
||||
.application-record__title-row { display: flex; align-items: center; justify-content: space-between; }
|
||||
.application-record__name { overflow: hidden; color: $ink; font-family: "STKaiti", "KaiTi", serif; font-size: 32rpx; font-weight: 700; text-overflow: ellipsis; white-space: nowrap; }
|
||||
.application-record__status { flex: 0 0 auto; margin-left: 16rpx; color: #9a641f; font-size: 23rpx; }
|
||||
.application-record__status {
|
||||
flex: 0 0 auto;
|
||||
margin-left: 16rpx;
|
||||
color: #7f4f16;
|
||||
font-size: 27rpx;
|
||||
font-weight: 600;
|
||||
}
|
||||
.application-record__status--rejected { color: #a7160c; }
|
||||
.application-record__status--muted { color: $ink-muted; }
|
||||
.application-record__copy { display: block; margin-top: 10rpx; color: $ink-muted; font-size: 23rpx; }
|
||||
.application-record__status--muted { color: #62584c; }
|
||||
.application-record__copy {
|
||||
display: block;
|
||||
margin-top: 10rpx;
|
||||
color: #62584c;
|
||||
font-size: 28rpx;
|
||||
font-weight: 500;
|
||||
line-height: 1.4;
|
||||
}
|
||||
.application-record__chevron { position: relative; z-index: 1; width: 32rpx; height: 32rpx; margin-left: 14rpx; }
|
||||
|
||||
.create-action {
|
||||
@@ -862,14 +893,8 @@ const openShortcut = (key) => {
|
||||
.genealogy-switcher__content { position: relative; z-index: 1; display: flex; min-height: 720rpx; flex-direction: column; align-items: center; box-sizing: border-box; padding: 78rpx 58rpx 50rpx; }
|
||||
.dialog-title { color: $brand-red; font-family: "STKaiti", "KaiTi", serif; font-size: 42rpx; font-weight: 700; letter-spacing: 4rpx; }
|
||||
.dialog-copy { margin-top: 18rpx; color: $ink-muted; font-size: 23rpx; }
|
||||
.dialog-primary,
|
||||
.dialog-secondary { position: relative; display: flex; width: 100%; height: 98rpx; align-items: center; justify-content: center; overflow: hidden; font-family: "STKaiti", "KaiTi", serif; font-size: 29rpx; }
|
||||
.dialog-primary { margin-top: 42rpx; color: #fff9ec; }
|
||||
.dialog-secondary { margin-top: 16rpx; color: #7b4e24; }
|
||||
.dialog-action__skin { position: absolute; inset: 0; width: 100%; height: 100%; }
|
||||
.dialog-primary__copy,
|
||||
.dialog-secondary > text { position: relative; z-index: 1; }
|
||||
.dialog-create { display: flex; min-height: 76rpx; align-items: center; margin-top: 8rpx; color: $brand-red; font-size: 23rpx; }
|
||||
.add-dialog__content > .app-button:first-of-type { margin-top: 34rpx; }
|
||||
.add-dialog__content > .app-button + .app-button { margin-top: 10rpx; }
|
||||
.dialog-close { display: flex; min-height: 72rpx; align-items: center; justify-content: center; margin-top: auto; color: $ink-muted; font-size: 24rpx; }
|
||||
.switcher-item { display: flex; width: 100%; min-height: 108rpx; align-items: center; justify-content: space-between; box-sizing: border-box; padding: 18rpx 12rpx; border-bottom: 1rpx solid rgba(181, 138, 75, 0.42); }
|
||||
.switcher-item:first-of-type { margin-top: 28rpx; }
|
||||
|
||||
@@ -1,17 +1,7 @@
|
||||
<!-- 页面编号:G-03;用途:创建家谱与录入首代人物的同路由两步流程。 -->
|
||||
<template>
|
||||
<view class="flow-page">
|
||||
<!-- 纸纹、页头和山水均由完整位图承载,流程内容只叠加文字和控件。 -->
|
||||
<image
|
||||
class="page-paper-texture"
|
||||
src="/static/assets/foundation/opaque/page-paper.jpg"
|
||||
mode="scaleToFill"
|
||||
/>
|
||||
<image
|
||||
class="page-footer-landscape"
|
||||
src="/static/assets/foundation/transparent/footer-mountain-bamboo.png"
|
||||
mode="scaleToFill"
|
||||
/>
|
||||
<GenealogyPageBackground />
|
||||
|
||||
<view class="flow-header">
|
||||
<image
|
||||
@@ -81,8 +71,8 @@
|
||||
<view class="flow-primary-action" hover-class="action-hover" @click="submitCreate">
|
||||
<image
|
||||
class="flow-primary-action__skin"
|
||||
src="/static/assets/foundation/opaque/a01-primary-button.png"
|
||||
mode="scaleToFill"
|
||||
src="/static/assets/foundation/transparent/a01-scroll-primary-v3.png"
|
||||
mode="aspectFit"
|
||||
/>
|
||||
<text class="flow-primary-action__copy">{{ createState === 'submitting' ? '正在创建…' : '创建并录入首代' }}</text>
|
||||
</view>
|
||||
@@ -118,8 +108,8 @@
|
||||
<view class="flow-primary-action" hover-class="action-hover" @click="submitAncestor">
|
||||
<image
|
||||
class="flow-primary-action__skin"
|
||||
src="/static/assets/foundation/opaque/a01-primary-button.png"
|
||||
mode="scaleToFill"
|
||||
src="/static/assets/foundation/transparent/a01-scroll-primary-v3.png"
|
||||
mode="aspectFit"
|
||||
/>
|
||||
<text class="flow-primary-action__copy">{{ ancestorState === 'submitting' ? '正在保存…' : '保存并进入家谱' }}</text>
|
||||
</view>
|
||||
@@ -129,16 +119,16 @@
|
||||
|
||||
<view v-if="duplicateReminderVisible" class="duplicate-reminder-layer" @click="closeDuplicateReminder">
|
||||
<view class="duplicate-reminder" @click.stop>
|
||||
<image class="duplicate-reminder__skin" src="/static/assets/modules/genealogy/opaque/g03-create-flow-panel.png" mode="scaleToFill" />
|
||||
<image class="duplicate-reminder__skin" src="/static/assets/modules/auth/transparent/a01-scroll-dialog-v3.png" mode="aspectFit" />
|
||||
<view class="duplicate-reminder__content">
|
||||
<text class="duplicate-reminder__title">先确认是否已有家谱</text>
|
||||
<text class="duplicate-reminder__copy">同一家族可能已经建谱。建议先搜索谱名、地区和堂号,避免重复创建。</text>
|
||||
<view class="duplicate-reminder__search" @click="searchExistingGenealogy">
|
||||
<image src="/static/assets/foundation/opaque/a01-secondary-button.png" mode="scaleToFill" />
|
||||
<image src="/static/assets/foundation/transparent/a01-scroll-secondary-v3.png" mode="aspectFit" />
|
||||
<text>先搜索已有家谱</text>
|
||||
</view>
|
||||
<view class="duplicate-reminder__confirm" @click="confirmCreate">
|
||||
<image src="/static/assets/foundation/opaque/a01-primary-button.png" mode="scaleToFill" />
|
||||
<image src="/static/assets/foundation/transparent/a01-scroll-primary-v3.png" mode="aspectFit" />
|
||||
<text>确认没有,继续创建</text>
|
||||
</view>
|
||||
<view class="duplicate-reminder__cancel" @click="closeDuplicateReminder">返回修改</view>
|
||||
@@ -148,12 +138,12 @@
|
||||
|
||||
<view v-if="ancestorState === 'success'" class="flow-success-layer">
|
||||
<view class="flow-success-dialog">
|
||||
<image class="flow-success-dialog__skin" src="/static/assets/modules/genealogy/opaque/g03-create-flow-panel.png" mode="scaleToFill" />
|
||||
<image class="flow-success-dialog__skin" src="/static/assets/modules/auth/transparent/a01-scroll-dialog-v3.png" mode="aspectFit" />
|
||||
<view class="flow-success-dialog__content">
|
||||
<text class="flow-success-dialog__title">家谱创建完成</text>
|
||||
<text class="flow-success-dialog__copy">首代人物已保存,接下来进入家谱总览继续完善资料。</text>
|
||||
<view class="flow-success-dialog__action" @click="enterOverview">
|
||||
<image src="/static/assets/foundation/opaque/a01-primary-button.png" mode="scaleToFill" />
|
||||
<image src="/static/assets/foundation/transparent/a01-scroll-primary-v3.png" mode="aspectFit" />
|
||||
<text>进入家谱总览</text>
|
||||
</view>
|
||||
</view>
|
||||
@@ -165,6 +155,7 @@
|
||||
<script setup>
|
||||
import { computed, onMounted, onUnmounted, reactive, ref } from "vue";
|
||||
import { onLoad, onShow } from "@dcloudio/uni-app";
|
||||
import GenealogyPageBackground from "@/components/GenealogyPageBackground.vue";
|
||||
|
||||
const currentStep = ref("create");
|
||||
const genealogyId = ref("");
|
||||
@@ -305,31 +296,6 @@ const enterOverview = () => uni.redirectTo({ url: `/pages/genealogy/g05-genealog
|
||||
background: #f9f6ef;
|
||||
}
|
||||
|
||||
.page-paper-texture {
|
||||
position: absolute;
|
||||
top: 112rpx;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
z-index: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
opacity: 0.74;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.page-footer-landscape {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
z-index: 1;
|
||||
width: 100%;
|
||||
height: 430rpx;
|
||||
opacity: 0.42;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.flow-header {
|
||||
position: relative;
|
||||
z-index: 3;
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
<!-- 页面编号:G-05;用途:家谱总览与加载、空数据、失败状态。 -->
|
||||
<template>
|
||||
<view class="overview-page">
|
||||
<image class="overview-page__paper" src="/static/assets/foundation/opaque/page-paper.jpg" mode="aspectFill" />
|
||||
<image class="overview-page__footer" src="/static/assets/foundation/transparent/footer-mountain-bamboo.png" mode="widthFix" />
|
||||
<GenealogyPageBackground />
|
||||
<view class="overview-page__header">
|
||||
<PageHeader :title="viewMode === 'public' ? '家谱公开预览' : '家谱总览'" :action="overviewState === 'ready' && viewMode === 'member' && accessRole === 'owner' ? '管理' : ''" @action="toSettings" />
|
||||
</view>
|
||||
@@ -66,7 +65,7 @@
|
||||
<text>{{ genealogy.publicDescription }}</text>
|
||||
</view>
|
||||
<view class="overview-public__action" @click="applyToJoin">
|
||||
<image src="/static/assets/foundation/opaque/a01-primary-button.png" mode="scaleToFill" />
|
||||
<image src="/static/assets/foundation/transparent/a01-scroll-primary-v3.png" mode="aspectFit" />
|
||||
<text>申请加入这部家谱</text>
|
||||
</view>
|
||||
</view>
|
||||
@@ -80,7 +79,7 @@
|
||||
<text class="overview-state-panel__title">{{ stateTitle }}</text>
|
||||
<text class="overview-state-panel__copy">{{ stateCopy }}</text>
|
||||
<view v-if="overviewState !== 'loading'" class="overview-state-panel__action" @click="overviewState === 'error' ? reloadOverview() : toGenealogies()">
|
||||
<image src="/static/assets/foundation/opaque/a01-primary-button.png" mode="scaleToFill" />
|
||||
<image src="/static/assets/foundation/transparent/a01-scroll-primary-v3.png" mode="aspectFit" />
|
||||
<text>{{ overviewState === 'error' ? '重新查看' : '返回我的家谱' }}</text>
|
||||
</view>
|
||||
</view>
|
||||
@@ -91,6 +90,7 @@
|
||||
<script setup>
|
||||
import { computed, ref } from 'vue'
|
||||
import { onLoad } from '@dcloudio/uni-app'
|
||||
import GenealogyPageBackground from '@/components/GenealogyPageBackground.vue'
|
||||
import PageHeader from '@/components/PageHeader.vue'
|
||||
|
||||
const genealogy = ref(null)
|
||||
@@ -168,8 +168,6 @@ const applyToJoin = () => uni.navigateTo({ url: `/pages/genealogy/g08-join-appli
|
||||
|
||||
<style scoped lang="scss">
|
||||
.overview-page { position: relative; min-height: 100vh; overflow-x: hidden; background: $paper; }
|
||||
.overview-page__paper { position: absolute; inset: 0; z-index: 0; width: 100%; height: 100%; opacity: .98; pointer-events: none; }
|
||||
.overview-page__footer { position: absolute; right: 0; bottom: 0; left: 0; z-index: 1; width: 100%; opacity: .13; pointer-events: none; }
|
||||
.overview-page__header { position: relative; z-index: 3; }
|
||||
.overview-surface { position: relative; z-index: 2; width: 100%; height: min(483px, calc(100vw * 1.3422)); }
|
||||
.overview-surface__skin { position: absolute; inset: 0; width: 100%; height: 100%; }
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
<!-- 页面编号:G-06;用途:搜索家谱/邀请码加入双模式定位目标家谱。 -->
|
||||
<template>
|
||||
<view class="search-page">
|
||||
<image class="search-page__paper" src="/static/assets/foundation/opaque/page-paper.jpg" mode="scaleToFill" />
|
||||
<image class="search-page__footer" src="/static/assets/foundation/transparent/footer-mountain-bamboo.png" mode="widthFix" />
|
||||
<GenealogyPageBackground />
|
||||
<view class="search-page__header"><PageHeader title="加入家谱" /></view>
|
||||
|
||||
<view class="search-page__content">
|
||||
@@ -130,6 +129,7 @@
|
||||
<script setup>
|
||||
import { computed, ref } from 'vue'
|
||||
import { onLoad, onUnload, onShow } from '@dcloudio/uni-app'
|
||||
import GenealogyPageBackground from '@/components/GenealogyPageBackground.vue'
|
||||
import PageHeader from '@/components/PageHeader.vue'
|
||||
|
||||
const mode = ref('search')
|
||||
@@ -220,8 +220,6 @@ const confirmInvite = () => uni.navigateTo({ url: `/pages/genealogy/g08-join-app
|
||||
|
||||
<style scoped lang="scss">
|
||||
.search-page { position: relative; min-height: 100vh; overflow-x: hidden; background: $paper; }
|
||||
.search-page__paper { position: absolute; inset: 0; z-index: 0; width: 100%; height: 100%; opacity: .98; pointer-events: none; }
|
||||
.search-page__footer { position: fixed; right: 0; bottom: 0; left: 0; z-index: 1; width: 100%; opacity: .15; pointer-events: none; }
|
||||
.search-page__header { position: relative; z-index: 2; }
|
||||
.search-page__content { position: relative; z-index: 3; min-height: calc(100vh - 104rpx); padding: 30rpx 24rpx calc(58rpx + env(safe-area-inset-bottom)); box-sizing: border-box; }
|
||||
.search-title-strip { position: relative; width: 100%; height: 138rpx; }
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
<!-- 页面编号:G-08;用途:申请加入家谱与提交成功/失败状态。 -->
|
||||
<template>
|
||||
<view class="join-page">
|
||||
<image class="join-page__paper" src="/static/assets/foundation/opaque/page-paper.jpg" mode="aspectFill" />
|
||||
<image class="join-page__footer" src="/static/assets/foundation/transparent/footer-mountain-bamboo.png" mode="widthFix" />
|
||||
<GenealogyPageBackground />
|
||||
<view class="join-page__header"><PageHeader :title="sourceContract.headerTitle" /></view>
|
||||
|
||||
<view class="join-panel" :class="{
|
||||
@@ -35,7 +34,7 @@
|
||||
|
||||
<text class="join-form__note">{{ sourceContract.note }}</text>
|
||||
<view class="join-action" @click="submitJoin">
|
||||
<image src="/static/assets/foundation/opaque/a01-primary-button.png" mode="scaleToFill" />
|
||||
<image src="/static/assets/foundation/transparent/a01-scroll-primary-v3.png" mode="aspectFit" />
|
||||
<text>{{ isSubmitting ? sourceContract.submittingLabel : sourceContract.submitLabel }}</text>
|
||||
</view>
|
||||
</view>
|
||||
@@ -45,7 +44,7 @@
|
||||
<text class="join-result__title">{{ joinState === 'success' ? sourceContract.successTitle : sourceContract.errorTitle }}</text>
|
||||
<text class="join-result__copy">{{ resultCopy }}</text>
|
||||
<view class="join-action" @click="joinState === 'success' ? completeFlow() : retryForm()">
|
||||
<image src="/static/assets/foundation/opaque/a01-primary-button.png" mode="scaleToFill" />
|
||||
<image src="/static/assets/foundation/transparent/a01-scroll-primary-v3.png" mode="aspectFit" />
|
||||
<text>{{ joinState === 'success' ? sourceContract.nextLabel : '重新填写' }}</text>
|
||||
</view>
|
||||
</view>
|
||||
@@ -56,6 +55,7 @@
|
||||
<script setup>
|
||||
import { computed, reactive, ref } from 'vue'
|
||||
import { onLoad } from '@dcloudio/uni-app'
|
||||
import GenealogyPageBackground from '@/components/GenealogyPageBackground.vue'
|
||||
import PageHeader from '@/components/PageHeader.vue'
|
||||
|
||||
const genealogyId = ref('')
|
||||
@@ -143,8 +143,6 @@ const completeFlow = () => source.value === 'invite' ? toMyGenealogies() : toMyA
|
||||
|
||||
<style scoped lang="scss">
|
||||
.join-page { position: relative; min-height: 100vh; overflow-x: hidden; background: $paper; }
|
||||
.join-page__paper { position: absolute; inset: 0; z-index: 0; width: 100%; height: 100%; opacity: .98; pointer-events: none; }
|
||||
.join-page__footer { position: absolute; right: 0; bottom: 0; left: 0; z-index: 1; width: 100%; opacity: .13; pointer-events: none; }
|
||||
.join-page__header { position: relative; z-index: 3; }
|
||||
.join-panel { position: relative; z-index: 2; width: calc(100% - 32rpx); height: min(590px, calc((100vw - 16px) * 1.337)); margin: 22rpx auto 0; }
|
||||
.join-panel__skin { position: absolute; inset: 0; width: 100%; height: 100%; }
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
<!-- 页面编号:G-09;用途:我的家谱申请列表与空/失败状态。 -->
|
||||
<template>
|
||||
<view class="application-page">
|
||||
<image class="application-page__paper" src="/static/assets/foundation/opaque/page-paper.jpg" mode="aspectFill" />
|
||||
<image class="application-page__footer" src="/static/assets/foundation/transparent/footer-mountain-bamboo.png" mode="widthFix" />
|
||||
<GenealogyPageBackground />
|
||||
<view class="application-page__header"><PageHeader title="我的申请" /></view>
|
||||
|
||||
<view class="application-content" :class="{
|
||||
@@ -35,30 +34,30 @@
|
||||
</view>
|
||||
</view>
|
||||
<view v-if="applicationState !== 'list'" class="application-page__action" @click="applicationState === 'error' ? loadApplications({}) : toSearch()">
|
||||
<image src="/static/assets/foundation/opaque/a01-primary-button.png" mode="scaleToFill" />
|
||||
<image src="/static/assets/foundation/transparent/a01-scroll-primary-v3.png" mode="aspectFit" />
|
||||
<text>{{ applicationState === 'error' ? '重新查看' : '查找公开家谱' }}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view v-if="withdrawTarget" class="withdraw-layer" @click="cancelWithdraw">
|
||||
<view class="withdraw-dialog" @click.stop>
|
||||
<image class="withdraw-dialog__skin" src="/static/assets/modules/genealogy/opaque/application-status-card.png" mode="scaleToFill" />
|
||||
<view class="withdraw-dialog__content">
|
||||
<text class="withdraw-dialog__title">撤回加入申请</text>
|
||||
<text class="withdraw-dialog__copy">确认撤回对“{{ withdrawTarget.genealogyName }}”的申请?撤回后如需加入,可重新提交。</text>
|
||||
<view class="withdraw-dialog__actions">
|
||||
<view class="withdraw-action" @click="cancelWithdraw">暂不撤回</view>
|
||||
<view class="withdraw-action withdraw-action--danger" @click="confirmWithdraw">确认撤回</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<AppDialog
|
||||
:visible="!!withdrawTarget"
|
||||
title="撤回加入申请"
|
||||
:message="withdrawTarget ? `确认撤回对“${withdrawTarget.genealogyName}”的申请?撤回后如需加入,可重新提交。` : ''"
|
||||
confirm-text="确认撤回"
|
||||
cancel-text="暂不撤回"
|
||||
show-cancel
|
||||
@confirm="confirmWithdraw"
|
||||
@cancel="cancelWithdraw"
|
||||
@close="cancelWithdraw"
|
||||
/>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { computed, ref } from 'vue'
|
||||
import { onLoad } from '@dcloudio/uni-app'
|
||||
import AppDialog from '@/components/AppDialog.vue'
|
||||
import GenealogyPageBackground from '@/components/GenealogyPageBackground.vue'
|
||||
import PageHeader from '@/components/PageHeader.vue'
|
||||
|
||||
const applications = ref([])
|
||||
@@ -116,8 +115,6 @@ const toSearch = () => uni.navigateTo({ url: '/pages/genealogy/g06-search-geneal
|
||||
|
||||
<style scoped lang="scss">
|
||||
.application-page { position: relative; min-height: 100vh; overflow-x: hidden; background: $paper; }
|
||||
.application-page__paper { position: absolute; inset: 0; z-index: 0; width: 100%; height: 100%; opacity: .98; pointer-events: none; }
|
||||
.application-page__footer { position: absolute; right: 0; bottom: 0; left: 0; z-index: 1; width: 100%; opacity: .13; pointer-events: none; }
|
||||
.application-page__header { position: relative; z-index: 3; }
|
||||
.application-content { position: relative; z-index: 2; padding: 28rpx 24rpx 60rpx; }
|
||||
.application-intro { display: flex; align-items: baseline; justify-content: space-between; margin: 0 8rpx 20rpx; }
|
||||
@@ -142,13 +139,4 @@ const toSearch = () => uni.navigateTo({ url: '/pages/genealogy/g06-search-geneal
|
||||
.application-page__action { position: relative; width: 420rpx; height: 82rpx; margin: 34rpx auto 0; }
|
||||
.application-page__action image { position: absolute; inset: 0; width: 100%; height: 100%; }
|
||||
.application-page__action text { position: relative; z-index: 1; display: flex; align-items: center; justify-content: center; height: 100%; color: #fff9ed; font-size: 26rpx; font-weight: 700; }
|
||||
.withdraw-layer { position: fixed; z-index: 30; inset: 0; display: flex; align-items: center; justify-content: center; box-sizing: border-box; padding: 42rpx; background: rgba(34, 20, 12, .58); }
|
||||
.withdraw-dialog { position: relative; width: 100%; max-width: 660rpx; min-height: 390rpx; }
|
||||
.withdraw-dialog__skin { position: absolute; inset: 0; width: 100%; height: 100%; }
|
||||
.withdraw-dialog__content { position: relative; z-index: 1; display: flex; min-height: 390rpx; flex-direction: column; align-items: center; box-sizing: border-box; padding: 74rpx 60rpx 46rpx; text-align: center; }
|
||||
.withdraw-dialog__title { color: $ink; font-family: 'STKaiti', 'KaiTi', serif; font-size: 36rpx; font-weight: 700; }
|
||||
.withdraw-dialog__copy { margin-top: 24rpx; color: $ink-muted; font-size: 23rpx; line-height: 38rpx; }
|
||||
.withdraw-dialog__actions { display: flex; width: 100%; margin-top: auto; border-top: 1rpx solid rgba(181, 138, 75, .42); }
|
||||
.withdraw-action { display: flex; flex: 1; min-height: 76rpx; align-items: center; justify-content: center; color: $ink-muted; font-size: 23rpx; }
|
||||
.withdraw-action--danger { border-left: 1rpx solid rgba(181, 138, 75, .42); color: $brand-red; }
|
||||
</style>
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
<!-- 页面编号:G-10;用途:管理员入谱申请审核与空/失败状态。 -->
|
||||
<template>
|
||||
<view class="review-page">
|
||||
<image class="review-page__paper" src="/static/assets/foundation/opaque/page-paper.jpg" mode="aspectFill" />
|
||||
<image class="review-page__footer" src="/static/assets/foundation/transparent/footer-mountain-bamboo.png" mode="widthFix" />
|
||||
<GenealogyPageBackground />
|
||||
<view class="review-page__header"><PageHeader title="入谱审核" action="说明" @action="showHelp" /></view>
|
||||
|
||||
<view class="review-content" :class="{
|
||||
@@ -27,10 +26,10 @@
|
||||
<text class="application-card__relation">{{ item.relation }}</text>
|
||||
<view v-if="item.status === 'PENDING'" class="review-actions">
|
||||
<view class="review-action" @click="confirmAudit(item, false)">
|
||||
<image src="/static/assets/foundation/opaque/a01-secondary-button.png" mode="scaleToFill" /><text>拒绝</text>
|
||||
<image src="/static/assets/foundation/transparent/a01-scroll-secondary-v3.png" mode="aspectFit" /><text>拒绝</text>
|
||||
</view>
|
||||
<view class="review-action" @click="confirmAudit(item, true)">
|
||||
<image src="/static/assets/foundation/opaque/a01-primary-button.png" mode="scaleToFill" /><text>通过</text>
|
||||
<image src="/static/assets/foundation/transparent/a01-scroll-primary-v3.png" mode="aspectFit" /><text>通过</text>
|
||||
</view>
|
||||
</view>
|
||||
<text v-else class="application-card__status">{{ item.status === 'APPROVED' ? '已通过' : '已拒绝' }}</text>
|
||||
@@ -46,33 +45,23 @@
|
||||
</view>
|
||||
</view>
|
||||
<view v-if="reviewState === 'error'" class="review-page__retry" @click="loadApplications({ genealogyId })">
|
||||
<image src="/static/assets/foundation/opaque/a01-primary-button.png" mode="scaleToFill" /><text>重新查看</text>
|
||||
<image src="/static/assets/foundation/transparent/a01-scroll-primary-v3.png" mode="aspectFit" /><text>重新查看</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view v-if="confirmation || helpVisible" class="review-dialog-layer" @click="closeDialog">
|
||||
<view class="review-dialog" @click.stop>
|
||||
<image class="review-dialog__skin" src="/static/assets/modules/genealogy/opaque/application-status-card.png" mode="scaleToFill" />
|
||||
<view class="review-dialog__content">
|
||||
<template v-if="helpVisible">
|
||||
<text class="review-dialog__title">审核说明</text>
|
||||
<text class="review-dialog__copy">请核对申请人的姓名、亲属关系和补充说明,仅确认与本家谱存在真实关系的申请。</text>
|
||||
<view class="review-dialog__single" @click="closeDialog">我知道了</view>
|
||||
</template>
|
||||
<template v-else>
|
||||
<text class="review-dialog__title">{{ confirmation.approved ? '确认通过申请?' : '确认拒绝申请?' }}</text>
|
||||
<text class="review-dialog__copy">{{ confirmation.approved ? '通过后,申请人将成为本家谱成员。' : '拒绝后,申请人会收到审核结果,并可修改后重新申请。' }}</text>
|
||||
<view class="review-dialog__actions">
|
||||
<view class="review-dialog__action" @click="closeDialog">取消</view>
|
||||
<view class="review-dialog__action review-dialog__action--primary" @click="applyAudit">{{ confirmation.approved ? '确认通过' : '确认拒绝' }}</view>
|
||||
</view>
|
||||
</template>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<AppDialog
|
||||
:visible="!!confirmation || helpVisible"
|
||||
:title="helpVisible ? '审核说明' : confirmation?.approved ? '确认通过申请?' : '确认拒绝申请?'"
|
||||
:message="helpVisible ? '请核对申请人的姓名、亲属关系和补充说明,仅确认与本家谱存在真实关系的申请。' : confirmation?.approved ? '通过后,申请人将成为本家谱成员。' : '拒绝后,申请人会收到审核结果,并可修改后重新申请。'"
|
||||
:confirm-text="helpVisible ? '我知道了' : confirmation?.approved ? '确认通过' : '确认拒绝'"
|
||||
:show-cancel="!!confirmation"
|
||||
@confirm="helpVisible ? closeDialog() : applyAudit()"
|
||||
@cancel="closeDialog"
|
||||
@close="closeDialog"
|
||||
/>
|
||||
|
||||
<view v-if="feedbackVisible" class="review-feedback">
|
||||
<image src="/static/assets/foundation/opaque/a01-secondary-button.png" mode="scaleToFill" />
|
||||
<image src="/static/assets/foundation/transparent/a01-scroll-toast-v3.png" mode="scaleToFill" />
|
||||
<text>{{ feedbackMessage }}</text>
|
||||
</view>
|
||||
</view>
|
||||
@@ -81,6 +70,8 @@
|
||||
<script setup>
|
||||
import { computed, ref } from 'vue'
|
||||
import { onLoad, onUnload } from '@dcloudio/uni-app'
|
||||
import AppDialog from '@/components/AppDialog.vue'
|
||||
import GenealogyPageBackground from '@/components/GenealogyPageBackground.vue'
|
||||
import PageHeader from '@/components/PageHeader.vue'
|
||||
import { genealogyContext } from '@/utils/genealogy-context.js'
|
||||
|
||||
@@ -141,8 +132,6 @@ const showHelp = () => { helpVisible.value = true }
|
||||
|
||||
<style scoped lang="scss">
|
||||
.review-page { position: relative; min-height: 100vh; overflow-x: hidden; background: $paper; }
|
||||
.review-page__paper { position: absolute; inset: 0; z-index: 0; width: 100%; height: 100%; opacity: .98; pointer-events: none; }
|
||||
.review-page__footer { position: absolute; right: 0; bottom: 0; left: 0; z-index: 1; width: 100%; opacity: .13; pointer-events: none; }
|
||||
.review-page__header { position: relative; z-index: 3; }
|
||||
.review-content { position: relative; z-index: 2; padding: 24rpx 24rpx 60rpx; }
|
||||
.review-intro { position: relative; margin: 0 8rpx 24rpx; padding-bottom: 22rpx; }
|
||||
@@ -171,16 +160,6 @@ const showHelp = () => { helpVisible.value = true }
|
||||
.review-page__retry { position: relative; width: 420rpx; height: 82rpx; margin: 32rpx auto 0; }
|
||||
.review-page__retry image { position: absolute; inset: 0; width: 100%; height: 100%; }
|
||||
.review-page__retry text { position: relative; z-index: 1; display: flex; align-items: center; justify-content: center; height: 100%; color: #fff9ed; font-size: 26rpx; font-weight: 700; }
|
||||
.review-dialog-layer { position: fixed; z-index: 30; inset: 0; display: flex; align-items: center; justify-content: center; box-sizing: border-box; padding: 42rpx; background: rgba(34, 20, 12, .58); }
|
||||
.review-dialog { position: relative; width: 100%; max-width: 660rpx; min-height: 410rpx; }
|
||||
.review-dialog__skin { position: absolute; inset: 0; width: 100%; height: 100%; }
|
||||
.review-dialog__content { position: relative; z-index: 1; display: flex; min-height: 410rpx; flex-direction: column; align-items: center; box-sizing: border-box; padding: 72rpx 60rpx 42rpx; text-align: center; }
|
||||
.review-dialog__title { color: $ink; font-family: 'STKaiti', 'KaiTi', serif; font-size: 36rpx; font-weight: 700; }
|
||||
.review-dialog__copy { margin-top: 24rpx; color: $ink-muted; font-size: 23rpx; line-height: 38rpx; }
|
||||
.review-dialog__actions { display: flex; width: 100%; margin-top: auto; border-top: 1rpx solid rgba(181, 138, 75, .42); }
|
||||
.review-dialog__action { display: flex; flex: 1; min-height: 74rpx; align-items: center; justify-content: center; color: $ink-muted; font-size: 23rpx; }
|
||||
.review-dialog__action--primary { border-left: 1rpx solid rgba(181, 138, 75, .42); color: $brand-red; font-weight: 700; }
|
||||
.review-dialog__single { display: flex; min-height: 76rpx; align-items: center; margin-top: auto; color: $brand-red; font-size: 24rpx; font-weight: 700; }
|
||||
.review-feedback { position: fixed; z-index: 40; top: 140rpx; left: 50%; display: flex; min-width: 250rpx; min-height: 76rpx; align-items: center; justify-content: center; padding: 0 36rpx; transform: translateX(-50%); }
|
||||
.review-feedback image { position: absolute; inset: 0; width: 100%; height: 100%; }
|
||||
.review-feedback text { position: relative; z-index: 1; color: $ink; font-size: 23rpx; }
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
<!-- 页面编号:G-11;用途:家谱设置、公开范围与访问说明(页面设计阶段使用本地模拟交互)。 -->
|
||||
<template>
|
||||
<view class="settings-page">
|
||||
<image class="settings-page__paper" src="/static/assets/foundation/opaque/page-paper.jpg" mode="aspectFill" />
|
||||
<image class="settings-page__footer" src="/static/assets/foundation/transparent/footer-mountain-bamboo.png" mode="widthFix" />
|
||||
<GenealogyPageBackground />
|
||||
<view class="settings-page__header"><PageHeader title="家谱设置" /></view>
|
||||
|
||||
<view class="settings-panel" :class="{
|
||||
@@ -29,7 +28,7 @@
|
||||
<text class="visibility-block__label">公开范围</text>
|
||||
<view class="visibility-options">
|
||||
<view v-for="option in visibilityOptions" :key="option.value" class="visibility-option" @click="genealogyDraft.visibility = option.value">
|
||||
<image :src="genealogyDraft.visibility === option.value ? '/static/assets/foundation/opaque/a01-primary-button.png' : '/static/assets/foundation/opaque/a01-secondary-button.png'" mode="scaleToFill" />
|
||||
<image :src="genealogyDraft.visibility === option.value ? '/static/assets/foundation/transparent/a01-scroll-primary-v3.png' : '/static/assets/foundation/transparent/a01-scroll-secondary-v3.png'" mode="aspectFit" />
|
||||
<text :class="{ 'visibility-option__text--active': genealogyDraft.visibility === option.value }">{{ option.label }}</text>
|
||||
</view>
|
||||
</view>
|
||||
@@ -43,7 +42,7 @@
|
||||
</view>
|
||||
|
||||
<view class="settings-action" @click="saveSettings">
|
||||
<image src="/static/assets/foundation/opaque/a01-primary-button.png" mode="scaleToFill" />
|
||||
<image src="/static/assets/foundation/transparent/a01-scroll-primary-v3.png" mode="aspectFit" />
|
||||
<text>保存设置</text>
|
||||
</view>
|
||||
</view>
|
||||
@@ -53,13 +52,13 @@
|
||||
<text class="settings-result__title">{{ settingsState === 'success' ? '新的访问规则已经生效' : settingsState === 'no-permission' ? '当前账号不能修改家谱' : '暂时无法打开家谱设置' }}</text>
|
||||
<text class="settings-result__copy">{{ settingsState === 'success' ? `${genealogyDraft.name} · ${visibilityLabel}` : settingsState === 'no-permission' ? '只有家谱所有者可以修改名称、公开范围和访问说明。' : '请从家谱总览重新进入,当前修改不会被保留。' }}</text>
|
||||
<view class="settings-action" @click="settingsState = 'form'">
|
||||
<image src="/static/assets/foundation/opaque/a01-primary-button.png" mode="scaleToFill" />
|
||||
<image src="/static/assets/foundation/transparent/a01-scroll-primary-v3.png" mode="aspectFit" />
|
||||
<text>{{ settingsState === 'success' ? '继续调整' : '重新查看' }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view v-if="feedbackVisible" class="settings-feedback">
|
||||
<image src="/static/assets/foundation/opaque/a01-secondary-button.png" mode="scaleToFill" />
|
||||
<image src="/static/assets/foundation/transparent/a01-scroll-secondary-v3.png" mode="aspectFit" />
|
||||
<text>设置已保存</text>
|
||||
</view>
|
||||
</view>
|
||||
@@ -68,6 +67,7 @@
|
||||
<script setup>
|
||||
import { computed, reactive, ref } from 'vue'
|
||||
import { onLoad, onUnload } from '@dcloudio/uni-app'
|
||||
import GenealogyPageBackground from '@/components/GenealogyPageBackground.vue'
|
||||
import PageHeader from '@/components/PageHeader.vue'
|
||||
|
||||
const genealogyId = ref('')
|
||||
@@ -108,8 +108,6 @@ const saveSettings = () => {
|
||||
|
||||
<style scoped lang="scss">
|
||||
.settings-page { position: relative; min-height: 100vh; overflow-x: hidden; background: $paper; }
|
||||
.settings-page__paper { position: absolute; inset: 0; z-index: 0; width: 100%; height: 100%; opacity: .98; pointer-events: none; }
|
||||
.settings-page__footer { position: absolute; right: 0; bottom: 0; left: 0; z-index: 1; width: 100%; opacity: .13; pointer-events: none; }
|
||||
.settings-page__header { position: relative; z-index: 3; }
|
||||
.settings-panel { position: relative; z-index: 2; width: calc(100% - 32rpx); height: min(620px, calc((100vw - 16px) * 1.43)); margin: 18rpx auto 0; }
|
||||
.settings-panel__skin { position: absolute; inset: 0; width: 100%; height: 100%; }
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
<!-- 页面编号:G-12;用途:字辈诗列表、空状态与批量维护(页面设计阶段使用本地模拟交互)。 -->
|
||||
<template>
|
||||
<view class="poem-page">
|
||||
<image class="poem-page__paper" src="/static/assets/foundation/opaque/page-paper.jpg" mode="aspectFill" />
|
||||
<image class="poem-page__footer" src="/static/assets/foundation/transparent/footer-mountain-bamboo.png" mode="widthFix" />
|
||||
<GenealogyPageBackground />
|
||||
<view class="poem-page__header"><PageHeader title="字辈诗" :action="poemState === 'list' ? '维护' : ''" @action="openEditor" /></view>
|
||||
|
||||
<view class="poem-panel" :class="{
|
||||
@@ -27,7 +26,7 @@
|
||||
</view>
|
||||
</view>
|
||||
<view class="poem-action" @click="openEditor">
|
||||
<image src="/static/assets/foundation/opaque/a01-primary-button.png" mode="scaleToFill" /><text>维护字辈诗</text>
|
||||
<image src="/static/assets/foundation/transparent/a01-scroll-primary-v3.png" mode="aspectFit" /><text>维护字辈诗</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
@@ -44,17 +43,17 @@
|
||||
<view class="poem-policy">
|
||||
<text>缺失旧世代时</text>
|
||||
<view class="poem-policy__option" @click="stopMissingOldGeneration = !stopMissingOldGeneration">
|
||||
<image :src="stopMissingOldGeneration ? '/static/assets/foundation/opaque/a01-primary-button.png' : '/static/assets/foundation/opaque/a01-secondary-button.png'" mode="scaleToFill" />
|
||||
<image :src="stopMissingOldGeneration ? '/static/assets/foundation/transparent/a01-scroll-primary-v3.png' : '/static/assets/foundation/transparent/a01-scroll-secondary-v3.png'" mode="aspectFit" />
|
||||
<text :class="{ 'poem-policy__option-text--active': stopMissingOldGeneration }">{{ stopMissingOldGeneration ? '停止并提醒' : '继续补录' }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<text class="poem-preview">预览:{{ previewCharacters || '尚未录入字辈' }}</text>
|
||||
<view class="poem-editor__actions">
|
||||
<view class="poem-action" @click="poemState = 'list'">
|
||||
<image src="/static/assets/foundation/opaque/a01-secondary-button.png" mode="scaleToFill" /><text class="poem-action__secondary">取消</text>
|
||||
<image src="/static/assets/foundation/transparent/a01-scroll-secondary-v3.png" mode="aspectFit" /><text class="poem-action__secondary">取消</text>
|
||||
</view>
|
||||
<view class="poem-action" @click="savePoems">
|
||||
<image src="/static/assets/foundation/opaque/a01-primary-button.png" mode="scaleToFill" /><text>保存字辈</text>
|
||||
<image src="/static/assets/foundation/transparent/a01-scroll-primary-v3.png" mode="aspectFit" /><text>保存字辈</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
@@ -64,12 +63,12 @@
|
||||
<text class="poem-list__title">{{ poemState === 'empty' ? '从第一段传承字序开始' : poemState === 'no-permission' ? '当前账号不能维护字辈' : '暂时无法读取字辈诗' }}</text>
|
||||
<text class="poem-list__copy">{{ poemState === 'empty' ? '管理员可以一次录入连续字辈,系统会按世代拆分展示。' : poemState === 'no-permission' ? '普通成员可以查看字辈,但只有具备管理权限的成员可以维护。' : '请从家谱总览重新进入,或稍后再试。' }}</text>
|
||||
<view class="poem-action" @click="poemState === 'empty' ? openEditor() : poemState = 'list'">
|
||||
<image src="/static/assets/foundation/opaque/a01-primary-button.png" mode="scaleToFill" /><text>{{ poemState === 'empty' ? '开始录入' : '重新查看' }}</text>
|
||||
<image src="/static/assets/foundation/transparent/a01-scroll-primary-v3.png" mode="aspectFit" /><text>{{ poemState === 'empty' ? '开始录入' : '重新查看' }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view v-if="feedbackVisible" class="poem-feedback">
|
||||
<image src="/static/assets/foundation/opaque/a01-secondary-button.png" mode="scaleToFill" />
|
||||
<image src="/static/assets/foundation/transparent/a01-scroll-secondary-v3.png" mode="aspectFit" />
|
||||
<text>字辈预览已更新</text>
|
||||
</view>
|
||||
</view>
|
||||
@@ -78,6 +77,7 @@
|
||||
<script setup>
|
||||
import { computed, ref } from 'vue'
|
||||
import { onLoad, onUnload } from '@dcloudio/uni-app'
|
||||
import GenealogyPageBackground from '@/components/GenealogyPageBackground.vue'
|
||||
import PageHeader from '@/components/PageHeader.vue'
|
||||
|
||||
const genealogyId = ref('')
|
||||
@@ -121,8 +121,6 @@ const savePoems = () => {
|
||||
|
||||
<style scoped lang="scss">
|
||||
.poem-page { position: relative; min-height: 100vh; overflow-x: hidden; background: $paper; }
|
||||
.poem-page__paper { position: absolute; inset: 0; z-index: 0; width: 100%; height: 100%; opacity: .98; pointer-events: none; }
|
||||
.poem-page__footer { position: absolute; right: 0; bottom: 0; left: 0; z-index: 1; width: 100%; opacity: .13; pointer-events: none; }
|
||||
.poem-page__header { position: relative; z-index: 3; }
|
||||
.poem-panel { position: relative; z-index: 2; width: calc(100% - 32rpx); height: min(650px, calc((100vw - 16px) * 1.5)); margin: 18rpx auto 0; }
|
||||
.poem-panel__skin { position: absolute; inset: 0; width: 100%; height: 100%; }
|
||||
|
||||
Reference in New Issue
Block a user