完成70%
This commit is contained in:
@@ -1,735 +1,4 @@
|
||||
<!-- 页面编号:G-03;用途:创建家谱与录入首代人物的同路由两步流程。 -->
|
||||
<template>
|
||||
<view class="flow-page">
|
||||
<GenealogyPageBackground />
|
||||
|
||||
<PageHeader
|
||||
:title="isAncestorStep ? '录入首代人物' : '创建家谱'"
|
||||
custom-back
|
||||
@back="requestBack"
|
||||
/>
|
||||
|
||||
<view class="flow-content">
|
||||
<view class="create-flow-panel">
|
||||
<view v-if="!isAncestorStep" class="create-flow-panel__content">
|
||||
<view class="flow-step-label"><text>第一步 · 立谱信息</text></view>
|
||||
<text class="flow-heading">为家族立一部可传承的谱</text>
|
||||
<text class="flow-note"
|
||||
>家谱建立后可继续完善,名称与访问规则由创建者维护。</text
|
||||
>
|
||||
|
||||
<view class="flow-fields">
|
||||
<view class="field-row">
|
||||
<text>姓氏</text>
|
||||
<input
|
||||
v-model="createForm.surname"
|
||||
maxlength="4"
|
||||
placeholder="请输入姓氏"
|
||||
placeholder-class="placeholder"
|
||||
@input="clearFieldError('surname')"
|
||||
/>
|
||||
</view>
|
||||
<text v-if="fieldErrors.surname" class="field-error">{{
|
||||
fieldErrors.surname
|
||||
}}</text>
|
||||
<view class="field-row">
|
||||
<text>谱名</text>
|
||||
<input
|
||||
v-model="createForm.name"
|
||||
maxlength="24"
|
||||
placeholder="请输入家谱名称"
|
||||
placeholder-class="placeholder"
|
||||
@input="clearFieldError('name')"
|
||||
/>
|
||||
</view>
|
||||
<text v-if="fieldErrors.name" class="field-error">{{
|
||||
fieldErrors.name
|
||||
}}</text>
|
||||
<view class="field-row">
|
||||
<text>堂号</text>
|
||||
<input
|
||||
v-model="createForm.hall"
|
||||
maxlength="12"
|
||||
placeholder="选填"
|
||||
placeholder-class="placeholder"
|
||||
/>
|
||||
</view>
|
||||
<view class="field-row">
|
||||
<text>所在地</text>
|
||||
<input
|
||||
v-model="createForm.location"
|
||||
maxlength="30"
|
||||
placeholder="请选择或输入"
|
||||
placeholder-class="placeholder"
|
||||
@input="clearFieldError('location')"
|
||||
/>
|
||||
</view>
|
||||
<text v-if="fieldErrors.location" class="field-error">{{
|
||||
fieldErrors.location
|
||||
}}</text>
|
||||
</view>
|
||||
|
||||
<view class="flow-rule">
|
||||
<text class="flow-rule__label">访问规则</text>
|
||||
<view class="flow-rule__options">
|
||||
<view
|
||||
v-for="option in GENEALOGY_ACCESS_PRESET_OPTIONS"
|
||||
:key="option.value"
|
||||
class="flow-rule__option"
|
||||
:class="{
|
||||
'flow-rule__option--active':
|
||||
createForm.accessPreset === option.value,
|
||||
}"
|
||||
@click="createForm.accessPreset = option.value"
|
||||
>{{ option.label }}</view
|
||||
>
|
||||
</view>
|
||||
</view>
|
||||
<text class="flow-rule__note"
|
||||
>保护族人资料;创建后可在家谱设置中开放搜索与申请加入。</text
|
||||
>
|
||||
<text v-if="createState === 'error'" class="flow-error"
|
||||
>创建样式模拟失败,请检查信息后重试。</text
|
||||
>
|
||||
|
||||
<view
|
||||
class="flow-primary-action"
|
||||
hover-class="action-hover"
|
||||
@click="submitCreate"
|
||||
>
|
||||
<text class="flow-primary-action__copy">{{
|
||||
createState === "submitting" ? "正在创建…" : "创建并录入首代"
|
||||
}}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view v-else class="create-flow-panel__content">
|
||||
<view class="flow-step-label"><text>第二步 · 首代人物</text></view>
|
||||
<text class="flow-heading">家谱从这一位开始</text>
|
||||
<text class="flow-note"
|
||||
>可先录入姓名、世代和简要生平,其他资料后续随时补充。</text
|
||||
>
|
||||
|
||||
<view class="flow-fields">
|
||||
<view class="field-row">
|
||||
<text>姓名</text>
|
||||
<input
|
||||
v-model="ancestorForm.personName"
|
||||
maxlength="20"
|
||||
placeholder="请输入首代姓名"
|
||||
placeholder-class="placeholder"
|
||||
@input="clearFieldError('personName')"
|
||||
/>
|
||||
</view>
|
||||
<text v-if="fieldErrors.personName" class="field-error">{{
|
||||
fieldErrors.personName
|
||||
}}</text>
|
||||
<view class="field-row">
|
||||
<text>世代</text>
|
||||
<text class="fixed-value">第一世</text>
|
||||
</view>
|
||||
<picker
|
||||
mode="selector"
|
||||
:range="sexOptions"
|
||||
range-key="label"
|
||||
@change="changeAncestorSex"
|
||||
>
|
||||
<view class="field-row">
|
||||
<text>性别</text>
|
||||
<text class="fixed-value">{{ sexLabel }}</text>
|
||||
</view>
|
||||
</picker>
|
||||
<view class="field-row">
|
||||
<text>出生日期</text>
|
||||
<picker
|
||||
mode="date"
|
||||
:value="ancestorForm.birthDate"
|
||||
start="1800-01-01"
|
||||
:end="new Date().toISOString().slice(0, 10)"
|
||||
@change="changeAncestorBirthDate"
|
||||
>
|
||||
<text class="fixed-value">{{
|
||||
ancestorForm.birthDate || "请选择日期"
|
||||
}}</text>
|
||||
</picker>
|
||||
</view>
|
||||
</view>
|
||||
<text v-if="ancestorState === 'error'" class="flow-error"
|
||||
>首代人物保存失败,请稍后重试。</text
|
||||
>
|
||||
|
||||
<view class="intro-field">
|
||||
<text>生平简述</text>
|
||||
<textarea
|
||||
v-model="ancestorForm.introduction"
|
||||
auto-height
|
||||
maxlength="200"
|
||||
placeholder="可选,记录家训、迁徙或重要经历"
|
||||
placeholder-class="placeholder"
|
||||
/>
|
||||
</view>
|
||||
|
||||
<view
|
||||
class="flow-primary-action"
|
||||
hover-class="action-hover"
|
||||
@click="submitAncestor"
|
||||
>
|
||||
<text class="flow-primary-action__copy">{{
|
||||
ancestorState === "submitting" ? "正在保存…" : "保存并进入家谱"
|
||||
}}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view
|
||||
v-if="duplicateReminderVisible"
|
||||
class="duplicate-reminder-layer"
|
||||
@click="closeDuplicateReminder"
|
||||
>
|
||||
<view class="duplicate-reminder" @click.stop>
|
||||
<view class="duplicate-reminder__content">
|
||||
<text class="duplicate-reminder__title">先确认是否已有家谱</text>
|
||||
<text class="duplicate-reminder__copy"
|
||||
>同一家族可能已经建谱。建议先搜索谱名、地区和堂号,避免重复创建。</text
|
||||
>
|
||||
<view
|
||||
class="duplicate-reminder__search"
|
||||
@click="searchExistingGenealogy"
|
||||
>
|
||||
<text>先搜索已有家谱</text>
|
||||
</view>
|
||||
<view class="duplicate-reminder__confirm" @click="confirmCreate">
|
||||
<text>确认没有,继续创建</text>
|
||||
</view>
|
||||
<view
|
||||
class="duplicate-reminder__cancel"
|
||||
@click="closeDuplicateReminder"
|
||||
>返回修改</view
|
||||
>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view v-if="ancestorState === 'success'" class="flow-success-layer">
|
||||
<view class="flow-success-dialog">
|
||||
<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">
|
||||
<text>进入家谱总览</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<AppDialog
|
||||
:visible="discardVisible"
|
||||
title="放弃创建?"
|
||||
message="当前填写内容尚未保存,确认返回后将清空。"
|
||||
confirm-text="放弃并返回"
|
||||
cancel-text="继续填写"
|
||||
show-cancel
|
||||
compact-actions
|
||||
:close-on-mask="false"
|
||||
@confirm="confirmDiscard"
|
||||
@cancel="cancelDiscard"
|
||||
/>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { computed, reactive, ref } from "vue";
|
||||
import { onBackPress, onUnload } from "@dcloudio/uni-app";
|
||||
import AppDialog from "@/components/AppDialog.vue";
|
||||
import GenealogyPageBackground from "@/components/GenealogyPageBackground.vue";
|
||||
import PageHeader from "@/components/PageHeader.vue";
|
||||
import {
|
||||
createLocalGenealogyPreview,
|
||||
removeLocalGenealogyPreview,
|
||||
updateLocalGenealogyPreview,
|
||||
updateLocalGenealogyPreviewAncestor,
|
||||
} from "@/data/mock.js";
|
||||
import { createDiscardConfirmation } from "@/utils/discard-confirmation.js";
|
||||
import {
|
||||
GENEALOGY_ACCESS_PRESET,
|
||||
GENEALOGY_ACCESS_PRESET_OPTIONS,
|
||||
} from "@/utils/genealogy-contracts.js";
|
||||
import { handleBackPress, openPage, returnTo, runBackGuard } from "@/utils/navigation.js";
|
||||
|
||||
const currentStep = ref("create");
|
||||
const genealogyId = ref("");
|
||||
const isSubmitting = ref(false);
|
||||
const createState = ref("form");
|
||||
const ancestorState = ref("form");
|
||||
const duplicateReminderVisible = ref(false);
|
||||
const discardVisible = ref(false);
|
||||
const fieldErrors = reactive({
|
||||
surname: "",
|
||||
name: "",
|
||||
location: "",
|
||||
personName: "",
|
||||
});
|
||||
let submitTimer = null;
|
||||
const createForm = reactive({
|
||||
surname: "",
|
||||
name: "",
|
||||
hall: "",
|
||||
location: "",
|
||||
accessPreset: GENEALOGY_ACCESS_PRESET.MEMBER_ONLY,
|
||||
});
|
||||
const ancestorForm = reactive({
|
||||
personName: "",
|
||||
generationNo: 1,
|
||||
generationName: "一世",
|
||||
sex: "0",
|
||||
birthDate: "",
|
||||
introduction: "",
|
||||
});
|
||||
const sexOptions = [
|
||||
{ value: "0", label: "男" },
|
||||
{ value: "1", label: "女" },
|
||||
{ value: "2", label: "暂不填写" },
|
||||
];
|
||||
const sexLabel = computed(
|
||||
() =>
|
||||
sexOptions.find((option) => option.value === ancestorForm.sex)?.label ||
|
||||
"请选择",
|
||||
);
|
||||
const changeAncestorSex = (event) => {
|
||||
ancestorForm.sex = sexOptions[Number(event.detail.value)]?.value || "2";
|
||||
};
|
||||
const changeAncestorBirthDate = (event) => {
|
||||
ancestorForm.birthDate = event.detail.value;
|
||||
};
|
||||
|
||||
const isAncestorStep = computed(() => currentStep.value === "ancestor");
|
||||
const isDirty = computed(() =>
|
||||
isAncestorStep.value
|
||||
? Boolean(
|
||||
ancestorForm.personName ||
|
||||
ancestorForm.birthDate ||
|
||||
ancestorForm.introduction ||
|
||||
ancestorForm.sex !== "0",
|
||||
)
|
||||
: Boolean(
|
||||
createForm.surname ||
|
||||
createForm.name ||
|
||||
createForm.hall ||
|
||||
createForm.location ||
|
||||
createForm.accessPreset !== GENEALOGY_ACCESS_PRESET.MEMBER_ONLY,
|
||||
),
|
||||
);
|
||||
|
||||
const discardConfirmation = createDiscardConfirmation((visible) => {
|
||||
discardVisible.value = visible;
|
||||
});
|
||||
const requestRawDiscardConfirmation = discardConfirmation.request;
|
||||
const requestDiscardConfirmation = async () => {
|
||||
const confirmed = await requestRawDiscardConfirmation();
|
||||
if (confirmed && currentStep.value === "create" && genealogyId.value) {
|
||||
removeLocalGenealogyPreview(genealogyId.value);
|
||||
genealogyId.value = "";
|
||||
}
|
||||
return confirmed;
|
||||
};
|
||||
const confirmDiscard = discardConfirmation.confirm;
|
||||
const cancelDiscard = discardConfirmation.cancel;
|
||||
|
||||
onUnload(() => {
|
||||
const timer = submitTimer;
|
||||
submitTimer = null;
|
||||
if (timer) clearTimeout(timer);
|
||||
discardConfirmation.dispose();
|
||||
});
|
||||
|
||||
const closeActiveTransient = () => {
|
||||
if (duplicateReminderVisible.value) closeDuplicateReminder();
|
||||
else cancelDiscard();
|
||||
};
|
||||
const popInternalTrail = () => {
|
||||
currentStep.value = "create";
|
||||
ancestorState.value = "form";
|
||||
return true;
|
||||
};
|
||||
const requestBack = () => {
|
||||
if (ancestorState.value === "success") return enterOverview();
|
||||
return runBackGuard({
|
||||
transientOpen: duplicateReminderVisible.value || discardVisible.value,
|
||||
internalTrail: isAncestorStep.value && !isSubmitting.value,
|
||||
dirty: isDirty.value,
|
||||
submitting: isSubmitting.value,
|
||||
"close-transient": closeActiveTransient,
|
||||
"pop-internal-trail": popInternalTrail,
|
||||
"block-submitting": () => true,
|
||||
"confirm-discard": requestDiscardConfirmation,
|
||||
});
|
||||
};
|
||||
|
||||
onBackPress((event) => handleBackPress(event, requestBack));
|
||||
|
||||
const clearFieldError = (field) => {
|
||||
fieldErrors[field] = "";
|
||||
};
|
||||
|
||||
const validateCreateForm = () => {
|
||||
fieldErrors.surname = createForm.surname.trim() ? "" : "请填写姓氏";
|
||||
fieldErrors.name = createForm.name.trim() ? "" : "请填写谱名";
|
||||
fieldErrors.location = createForm.location.trim() ? "" : "请填写所在地";
|
||||
return !fieldErrors.surname && !fieldErrors.name && !fieldErrors.location;
|
||||
};
|
||||
|
||||
const submitCreate = () => {
|
||||
if (isSubmitting.value) return;
|
||||
createState.value = "form";
|
||||
if (!validateCreateForm()) return;
|
||||
duplicateReminderVisible.value = true;
|
||||
};
|
||||
|
||||
const closeDuplicateReminder = () => {
|
||||
duplicateReminderVisible.value = false;
|
||||
};
|
||||
const searchExistingGenealogy = () => {
|
||||
closeDuplicateReminder();
|
||||
return openPage("G06", {}, "G03");
|
||||
};
|
||||
const confirmCreate = () => {
|
||||
if (isSubmitting.value) return;
|
||||
closeDuplicateReminder();
|
||||
const createSnapshot = Object.freeze({ ...createForm });
|
||||
isSubmitting.value = true;
|
||||
createState.value = "submitting";
|
||||
const timer = setTimeout(() => {
|
||||
if (submitTimer !== timer) return;
|
||||
submitTimer = null;
|
||||
isSubmitting.value = false;
|
||||
if (createSnapshot.name.trim() === "失败") {
|
||||
createState.value = "error";
|
||||
return;
|
||||
}
|
||||
genealogyId.value =
|
||||
updateLocalGenealogyPreview(genealogyId.value, createSnapshot) ||
|
||||
createLocalGenealogyPreview(createSnapshot);
|
||||
currentStep.value = "ancestor";
|
||||
createState.value = "form";
|
||||
}, 320);
|
||||
submitTimer = timer;
|
||||
};
|
||||
|
||||
const submitAncestor = () => {
|
||||
if (isSubmitting.value) return;
|
||||
if (!genealogyId.value) {
|
||||
ancestorState.value = "error";
|
||||
return;
|
||||
}
|
||||
if (!ancestorForm.personName.trim()) {
|
||||
fieldErrors.personName = "请填写首代姓名";
|
||||
return;
|
||||
}
|
||||
|
||||
const ancestorSnapshot = Object.freeze({ ...ancestorForm });
|
||||
isSubmitting.value = true;
|
||||
ancestorState.value = "submitting";
|
||||
const timer = setTimeout(() => {
|
||||
if (submitTimer !== timer) return;
|
||||
submitTimer = null;
|
||||
isSubmitting.value = false;
|
||||
if (ancestorSnapshot.personName.trim() === "失败") {
|
||||
ancestorState.value = "error";
|
||||
return;
|
||||
}
|
||||
ancestorState.value = updateLocalGenealogyPreviewAncestor(
|
||||
genealogyId.value,
|
||||
ancestorSnapshot,
|
||||
)
|
||||
? "success"
|
||||
: "error";
|
||||
}, 320);
|
||||
submitTimer = timer;
|
||||
};
|
||||
|
||||
const enterOverview = () =>
|
||||
returnTo("G05", { genealogyId: genealogyId.value });
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@use "../../styles/adaptive-frame-profiles.scss" as adaptive;
|
||||
.flow-page {
|
||||
display: flex;
|
||||
min-height: 100vh;
|
||||
flex-direction: column;
|
||||
background: #f9f6ef;
|
||||
}
|
||||
|
||||
.flow-content {
|
||||
z-index: 2;
|
||||
padding: 24rpx 32rpx 48rpx;
|
||||
}
|
||||
|
||||
.create-flow-panel {
|
||||
@include adaptive.adaptive-genealogy-state-panel;
|
||||
min-height: 1000rpx;
|
||||
}
|
||||
|
||||
.create-flow-panel__content {
|
||||
z-index: 1;
|
||||
display: flex;
|
||||
min-height: 1000rpx;
|
||||
flex-direction: column;
|
||||
box-sizing: border-box;
|
||||
padding: 48rpx 50rpx 42rpx;
|
||||
}
|
||||
|
||||
.flow-step-label {
|
||||
color: #a33b2b;
|
||||
font-family: "STKaiti", "KaiTi", serif;
|
||||
font-size: 25rpx;
|
||||
font-weight: 700;
|
||||
letter-spacing: 2rpx;
|
||||
}
|
||||
|
||||
.flow-heading {
|
||||
display: block;
|
||||
margin-top: 13rpx;
|
||||
color: #392719;
|
||||
font-family: "STKaiti", "KaiTi", serif;
|
||||
font-size: 39rpx;
|
||||
font-weight: 700;
|
||||
letter-spacing: 2rpx;
|
||||
}
|
||||
|
||||
.flow-note,
|
||||
.flow-rule__note {
|
||||
display: block;
|
||||
color: #786654;
|
||||
font-size: 25rpx;
|
||||
line-height: 1.65;
|
||||
}
|
||||
|
||||
.flow-note {
|
||||
min-height: 56rpx;
|
||||
margin-top: 12rpx;
|
||||
}
|
||||
|
||||
.flow-fields {
|
||||
margin-top: 10rpx;
|
||||
}
|
||||
|
||||
.field-row {
|
||||
display: flex;
|
||||
min-height: 86rpx;
|
||||
align-items: center;
|
||||
border-bottom: 1rpx solid rgba(181, 138, 75, 0.36);
|
||||
}
|
||||
|
||||
.field-row > text {
|
||||
width: 126rpx;
|
||||
flex: 0 0 auto;
|
||||
color: #786654;
|
||||
font-family: "STKaiti", "KaiTi", serif;
|
||||
font-size: 29rpx;
|
||||
}
|
||||
|
||||
.field-row input {
|
||||
min-width: 0;
|
||||
flex: 1;
|
||||
color: #392719;
|
||||
font-family: "STKaiti", "KaiTi", serif;
|
||||
font-size: 28rpx;
|
||||
}
|
||||
|
||||
.placeholder {
|
||||
color: #b7aa97;
|
||||
}
|
||||
.field-error {
|
||||
display: block;
|
||||
margin-top: 3rpx;
|
||||
color: $brand-red;
|
||||
font-size: 24rpx;
|
||||
line-height: 34rpx;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.fixed-value {
|
||||
color: #a33b2b !important;
|
||||
}
|
||||
|
||||
.flow-rule {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin-top: 20rpx;
|
||||
}
|
||||
|
||||
.flow-rule__label {
|
||||
color: #392719;
|
||||
font-family: "STKaiti", "KaiTi", serif;
|
||||
font-size: 29rpx;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.flow-rule__options {
|
||||
display: flex;
|
||||
gap: 12rpx;
|
||||
}
|
||||
.flow-rule__option {
|
||||
display: flex;
|
||||
min-height: 54rpx;
|
||||
align-items: center;
|
||||
padding: 0 10rpx;
|
||||
color: #786654;
|
||||
font-size: 23rpx;
|
||||
}
|
||||
.flow-rule__option--active {
|
||||
color: $brand-red;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.flow-rule__note {
|
||||
margin-top: 8rpx;
|
||||
}
|
||||
.flow-error {
|
||||
display: block;
|
||||
margin-top: 10rpx;
|
||||
color: $brand-red;
|
||||
font-size: 25rpx;
|
||||
line-height: 36rpx;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.intro-field {
|
||||
margin-top: 18rpx;
|
||||
}
|
||||
|
||||
.intro-field > text {
|
||||
display: block;
|
||||
color: #392719;
|
||||
font-family: "STKaiti", "KaiTi", serif;
|
||||
font-size: 29rpx;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.intro-field textarea {
|
||||
width: 100%;
|
||||
min-height: 142rpx;
|
||||
margin-top: 8rpx;
|
||||
color: #392719;
|
||||
font-family: "STKaiti", "KaiTi", serif;
|
||||
font-size: 26rpx;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.flow-primary-action {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
min-height: 96rpx;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-top: auto;
|
||||
background: url("/static/assets/foundation/transparent/a01-scroll-primary-v3.png")
|
||||
center / contain no-repeat;
|
||||
}
|
||||
|
||||
.flow-primary-action__copy {
|
||||
z-index: 1;
|
||||
color: #fff9ec;
|
||||
font-family: "STKaiti", "KaiTi", serif;
|
||||
font-size: 31rpx;
|
||||
font-weight: 700;
|
||||
letter-spacing: 4rpx;
|
||||
}
|
||||
|
||||
.action-hover {
|
||||
opacity: 0.82;
|
||||
}
|
||||
.duplicate-reminder-layer,
|
||||
.flow-success-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, 0.6);
|
||||
}
|
||||
.duplicate-reminder,
|
||||
.flow-success-dialog {
|
||||
width: 100%;
|
||||
max-width: 670rpx;
|
||||
min-height: 650rpx;
|
||||
background: url("/static/assets/modules/auth/transparent/a01-scroll-dialog-v3.png")
|
||||
center / contain no-repeat;
|
||||
}
|
||||
.duplicate-reminder__content,
|
||||
.flow-success-dialog__content {
|
||||
z-index: 1;
|
||||
display: flex;
|
||||
min-height: 650rpx;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
box-sizing: border-box;
|
||||
padding: 92rpx 64rpx 56rpx;
|
||||
text-align: center;
|
||||
}
|
||||
.duplicate-reminder__title,
|
||||
.flow-success-dialog__title {
|
||||
color: $ink;
|
||||
font-family: "STKaiti", "KaiTi", serif;
|
||||
font-size: 39rpx;
|
||||
font-weight: 700;
|
||||
}
|
||||
.duplicate-reminder__copy,
|
||||
.flow-success-dialog__copy {
|
||||
margin-top: 24rpx;
|
||||
color: $ink-muted;
|
||||
font-size: 24rpx;
|
||||
line-height: 40rpx;
|
||||
}
|
||||
.duplicate-reminder__search,
|
||||
.duplicate-reminder__confirm,
|
||||
.flow-success-dialog__action {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
min-height: 92rpx;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
.duplicate-reminder__search {
|
||||
margin-top: 38rpx;
|
||||
background: url("/static/assets/foundation/transparent/a01-scroll-secondary-v3.png")
|
||||
center / contain no-repeat;
|
||||
}
|
||||
.duplicate-reminder__confirm {
|
||||
margin-top: 14rpx;
|
||||
background: url("/static/assets/foundation/transparent/a01-scroll-primary-v3.png")
|
||||
center / contain no-repeat;
|
||||
}
|
||||
.duplicate-reminder__search text,
|
||||
.duplicate-reminder__confirm text,
|
||||
.flow-success-dialog__action text {
|
||||
z-index: 1;
|
||||
color: #fff9ec;
|
||||
font-size: 25rpx;
|
||||
font-weight: 700;
|
||||
}
|
||||
.duplicate-reminder__search text {
|
||||
color: #7b4e24;
|
||||
}
|
||||
.duplicate-reminder__cancel {
|
||||
display: flex;
|
||||
min-height: 68rpx;
|
||||
align-items: center;
|
||||
margin-top: auto;
|
||||
color: $ink-muted;
|
||||
font-size: 23rpx;
|
||||
}
|
||||
.flow-success-dialog__action {
|
||||
margin-top: 44rpx;
|
||||
background: url("/static/assets/foundation/transparent/a01-scroll-primary-v3.png")
|
||||
center / contain no-repeat;
|
||||
}
|
||||
</style>
|
||||
<!-- 页面编号:G-03;用途:创建家谱。两阶段创建的结果恢复链未闭合时保持关闭。 -->
|
||||
<template><view class="create-page"><GenealogyPageBackground /><view class="page-header"><PageHeader title="创建家谱" custom-back @back="backToGenealogies" /></view><view class="page-content"><view class="state-card"><text>创建家谱待结果恢复合同</text><text>创建家谱后还必须用真实响应中的 `genealogyId` 创建首位人物;当前没有可靠的创建结果恢复查询 owner,且不能从泛型“我的家谱”列表按名称猜 ID。页面不再生成本地家谱或本地首位人物预览。</text><AppButton block label="返回我的家谱" @click="backToGenealogies" /></view></view></view></template>
|
||||
<script setup>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 backToGenealogies=()=>returnTo("G01");</script>
|
||||
<style scoped lang="scss">@use "../../styles/adaptive-frame-profiles.scss" as adaptive;.create-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