完成50%
This commit is contained in:
@@ -4,13 +4,13 @@
|
||||
class="add-relative-page"
|
||||
:class="{
|
||||
'add-state--form': addState === 'form',
|
||||
'add-state--success': addState === 'success',
|
||||
'add-state--preview': addState === 'preview',
|
||||
'add-state--error': addState === 'error',
|
||||
}"
|
||||
>
|
||||
<ModulePageBackground module="tree" />
|
||||
<view class="add-relative-page__header">
|
||||
<PageHeader :title="isFirstMember ? '录入首位成员' : '新增亲属'" />
|
||||
<PageHeader :title="isFirstMember ? '录入首位成员' : '新增亲属'" custom-back @back="requestBack" />
|
||||
</view>
|
||||
|
||||
<view class="add-relative-panel">
|
||||
@@ -75,17 +75,17 @@
|
||||
<text class="form-note">{{ formNote }}</text>
|
||||
<view class="form-action" @click="submitAdd">
|
||||
<image src="/static/assets/foundation/transparent/a01-scroll-primary-v3.png" mode="scaleToFill" />
|
||||
<text>{{ isSubmitting ? "正在保存…" : isFirstMember ? "保存首位成员" : "保存亲属" }}</text>
|
||||
<text>{{ isSubmitting ? "正在校验…" : "生成本地预览" }}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view v-else class="add-result">
|
||||
<text class="form-eyebrow">{{ addState === "success" ? "世系资料已更新" : "成员未保存" }}</text>
|
||||
<text class="form-title">{{ addState === "success" ? successTitle : "暂时无法保存成员" }}</text>
|
||||
<text class="form-copy">{{ addState === "success" ? successCopy : "当前填写内容仍保留,可返回修改后重试。" }}</text>
|
||||
<view class="form-action" @click="addState === 'success' ? returnToTree() : retryForm()">
|
||||
<text class="form-eyebrow">{{ addState === "preview" ? "本地流程预览" : hasValidContext ? "成员未保存" : "成员入口无效" }}</text>
|
||||
<text class="form-title">{{ addState === "preview" ? previewTitle : hasValidContext ? "暂时无法校验成员" : "没有找到要关联的成员" }}</text>
|
||||
<text class="form-copy">{{ addState === "preview" ? previewCopy : hasValidContext ? "当前填写内容仍保留,可返回修改后重试。" : "请从世系树重新进入,页面不会创建临时成员身份。" }}</text>
|
||||
<view class="form-action" @click="addState === 'preview' ? returnToTree() : retryForm()">
|
||||
<image src="/static/assets/foundation/transparent/a01-scroll-primary-v3.png" mode="scaleToFill" />
|
||||
<text>{{ addState === "success" ? "返回世系树" : "返回修改" }}</text>
|
||||
<text>{{ addState === "preview" ? "返回世系树(不保存)" : hasValidContext ? "返回修改" : "返回上一页" }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
@@ -98,9 +98,9 @@
|
||||
cancel-text="继续填写"
|
||||
confirm-text="放弃并返回"
|
||||
show-cancel
|
||||
@close="discardDialogVisible = false"
|
||||
@cancel="discardDialogVisible = false"
|
||||
@confirm="discardAndBack"
|
||||
:close-on-mask="false"
|
||||
@cancel="cancelDiscard"
|
||||
@confirm="confirmDiscard"
|
||||
/>
|
||||
</view>
|
||||
</template>
|
||||
@@ -111,7 +111,14 @@ import { onBackPress, onLoad, onUnload } from "@dcloudio/uni-app";
|
||||
import AppDialog from "@/components/AppDialog.vue";
|
||||
import ModulePageBackground from "@/components/ModulePageBackground.vue";
|
||||
import PageHeader from "@/components/PageHeader.vue";
|
||||
import { genealogyContext } from "@/utils/genealogy-context.js";
|
||||
import { findTreeMemberFixture } from "@/data/mock.js";
|
||||
import { createDiscardConfirmation } from "@/utils/discard-confirmation.js";
|
||||
import {
|
||||
goBack,
|
||||
handleBackPress,
|
||||
returnTo,
|
||||
runBackGuard,
|
||||
} from "@/utils/navigation.js";
|
||||
|
||||
const addState = ref("form");
|
||||
const genealogyId = ref("");
|
||||
@@ -121,21 +128,21 @@ const isSubmitting = ref(false);
|
||||
const discardDialogVisible = ref(false);
|
||||
let submitTimer = null;
|
||||
|
||||
const memberFixtures = {
|
||||
101: { id: 101, name: "汤文远", generation: 12 },
|
||||
102: { id: 102, name: "汤正国", generation: 13 },
|
||||
103: { id: 103, name: "汤正华", generation: 13 },
|
||||
};
|
||||
const relationOptions = ["长子", "次子", "女儿", "配偶", "兄弟", "姐妹"];
|
||||
const genderOptions = ["男", "女", "未说明"];
|
||||
const addForm = reactive({ name: "", relation: "", gender: "", birthDate: "", summary: "" });
|
||||
const fieldErrors = reactive({ name: "", relation: "", gender: "" });
|
||||
|
||||
const isFirstMember = computed(
|
||||
() => mode.value === "first" || (!personId.value && mode.value !== "relative"),
|
||||
const isFirstMember = computed(() => mode.value === "first");
|
||||
const currentMember = computed(() =>
|
||||
isFirstMember.value
|
||||
? null
|
||||
: findTreeMemberFixture(genealogyId.value, personId.value),
|
||||
);
|
||||
const currentMember = computed(
|
||||
() => memberFixtures[personId.value] || { id: personId.value, name: "当前成员", generation: "待确认" },
|
||||
const hasValidContext = computed(
|
||||
() =>
|
||||
Boolean(genealogyId.value) &&
|
||||
(isFirstMember.value ? !personId.value : Boolean(currentMember.value)),
|
||||
);
|
||||
const relationIndex = computed(() => Math.max(0, relationOptions.indexOf(addForm.relation)));
|
||||
const genderIndex = computed(() => Math.max(0, genderOptions.indexOf(addForm.gender)));
|
||||
@@ -149,43 +156,54 @@ const formCopy = computed(() =>
|
||||
);
|
||||
const formNote = computed(() =>
|
||||
isFirstMember.value
|
||||
? "保存后进入世系树,并可继续为首位成员添加亲属。"
|
||||
: "保存后成员会出现在相应世代;详细生平可在成员档案中继续完善。",
|
||||
? "当前阶段只校验首位成员资料,不会修改世系树。"
|
||||
: "当前阶段只校验亲属资料,不会新增成员或改变世系关系。",
|
||||
);
|
||||
const successTitle = computed(() =>
|
||||
isFirstMember.value ? `${addForm.name}已成为世系起点` : `${addForm.name}已加入世系`,
|
||||
const previewTitle = computed(() =>
|
||||
isFirstMember.value ? `${addForm.name}可作为世系起点` : `${addForm.name}的亲属资料已通过本地校验`,
|
||||
);
|
||||
const successCopy = computed(() =>
|
||||
isFirstMember.value
|
||||
? "首位成员已保存,世系树现在可以继续向下补充。"
|
||||
: `${addForm.relation}关系已记录,返回后可查看新的成员节点。`,
|
||||
const previewCopy = computed(() =>
|
||||
`本地预览尚未提交服务器,返回后不会保存${isFirstMember.value ? "首位成员" : `${addForm.relation}关系`},世系树也不会变化。`,
|
||||
);
|
||||
const hasDraft = computed(() =>
|
||||
Object.values(addForm).some((value) => String(value).trim()),
|
||||
);
|
||||
const discardConfirmation = createDiscardConfirmation((visible) => {
|
||||
discardDialogVisible.value = visible;
|
||||
});
|
||||
const requestDiscardConfirmation = discardConfirmation.request;
|
||||
const confirmDiscard = discardConfirmation.confirm;
|
||||
const cancelDiscard = discardConfirmation.cancel;
|
||||
|
||||
onLoad((query) => {
|
||||
genealogyId.value = query.genealogyId || genealogyContext.getCurrentGenealogyId() || "";
|
||||
personId.value = query.personId || "";
|
||||
genealogyId.value = String(query.genealogyId || "");
|
||||
personId.value = String(query.personId || "");
|
||||
mode.value = query.mode === "first" ? "first" : "relative";
|
||||
if (genealogyId.value) genealogyContext.setCurrentGenealogyId(genealogyId.value);
|
||||
addState.value = query.state === "success" ? "success" : query.state === "error" ? "error" : "form";
|
||||
addState.value = !hasValidContext.value || query.state === "error"
|
||||
? "error"
|
||||
: query.state === "preview"
|
||||
? "preview"
|
||||
: "form";
|
||||
});
|
||||
onUnload(() => {
|
||||
if (submitTimer) clearTimeout(submitTimer);
|
||||
});
|
||||
onBackPress(() => {
|
||||
if (discardDialogVisible.value) {
|
||||
discardDialogVisible.value = false;
|
||||
return true;
|
||||
}
|
||||
if (addState.value === "form" && hasDraft.value) {
|
||||
discardDialogVisible.value = true;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
const timer = submitTimer;
|
||||
submitTimer = null;
|
||||
if (timer) clearTimeout(timer);
|
||||
discardConfirmation.dispose();
|
||||
});
|
||||
|
||||
const requestBack = () =>
|
||||
runBackGuard({
|
||||
transientOpen: discardDialogVisible.value,
|
||||
dirty: (addState.value === "form" || addState.value === "preview") && hasDraft.value,
|
||||
submitting: isSubmitting.value,
|
||||
"close-transient": cancelDiscard,
|
||||
"block-submitting": () => true,
|
||||
"confirm-discard": requestDiscardConfirmation,
|
||||
});
|
||||
|
||||
onBackPress((event) => handleBackPress(event, requestBack));
|
||||
|
||||
const clearError = (field) => { fieldErrors[field] = ""; };
|
||||
const selectRelation = (event) => {
|
||||
addForm.relation = relationOptions[Number(event.detail.value)] || "";
|
||||
@@ -204,18 +222,26 @@ const validateAddForm = () => {
|
||||
};
|
||||
const submitAdd = () => {
|
||||
if (isSubmitting.value || !validateAddForm()) return;
|
||||
const submitSnapshot = Object.freeze({ ...addForm });
|
||||
isSubmitting.value = true;
|
||||
submitTimer = setTimeout(() => {
|
||||
addState.value = addForm.name.trim() === "失败" ? "error" : "success";
|
||||
const timer = setTimeout(() => {
|
||||
if (submitTimer !== timer) return;
|
||||
addState.value = submitSnapshot.name.trim() === "失败" ? "error" : "preview";
|
||||
isSubmitting.value = false;
|
||||
submitTimer = null;
|
||||
}, 280);
|
||||
submitTimer = timer;
|
||||
};
|
||||
const retryForm = () => { addState.value = "form"; };
|
||||
const returnToTree = () => uni.navigateBack();
|
||||
const discardAndBack = () => {
|
||||
discardDialogVisible.value = false;
|
||||
uni.navigateBack();
|
||||
const retryForm = () => {
|
||||
if (!hasValidContext.value) return goBack();
|
||||
addState.value = "form";
|
||||
};
|
||||
const returnToTree = async () => {
|
||||
const confirmed = hasDraft.value
|
||||
? await requestDiscardConfirmation()
|
||||
: true;
|
||||
if (!confirmed) return false;
|
||||
return returnTo("T01", { genealogyId: genealogyId.value });
|
||||
};
|
||||
</script>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user