feat: 完成前端业务闭环与后端联调

This commit is contained in:
2026-08-24 23:37:56 +08:00
parent c59e36f933
commit 9ad572907b
175 changed files with 10711 additions and 1740 deletions
+69 -6
View File
@@ -202,7 +202,9 @@ const genealogyName = ref("汤氏家谱");
const memberTrail = reactive([]);
const trailIndex = ref(-1);
const memberReadRequestController = createRequestController();
const sensitiveProfileRequestController = createRequestController();
const memberDeletionRequestController = createRequestController();
const sensitiveProfileError = ref("");
let memberLoadGeneration = 0;
let pageActive = true;
@@ -212,7 +214,8 @@ const profileDetails = computed(() => {
const visibleProfileValue = (profileValue) =>
member.value.status === "forbidden" ? "按权限隐藏" : profileValue;
return [
{ label: "别名", value: member.value.aliasName },
{ label: "表字", value: member.value.courtesyName },
{ label: "别号", value: member.value.aliasName },
{ label: "字辈", value: member.value.generationName },
{
label: "性别",
@@ -227,8 +230,14 @@ const profileDetails = computed(() => {
label: "出生农历",
value: visibleProfileValue(member.value.birthLunarLabel),
},
{ label: "生肖", value: visibleProfileValue(member.value.zodiac) },
{ label: "生卒信息", value: member.value.years },
{ label: "出生地", value: visibleProfileValue(member.value.birthplace) },
{ label: "现居地", value: visibleProfileValue(member.value.currentAddress) },
{ label: "联系电话", value: visibleProfileValue(member.value.mobile) },
{ label: "电子邮箱", value: visibleProfileValue(member.value.email) },
{ label: "教育经历", value: visibleProfileValue(member.value.education) },
{ label: "职业", value: visibleProfileValue(member.value.occupation) },
...(isDeceased.value
? [
{ label: "逝世日期", value: visibleProfileValue(member.value.deathDate) },
@@ -236,7 +245,29 @@ const profileDetails = computed(() => {
label: "逝世农历",
value: visibleProfileValue(member.value.deathLunarLabel),
},
{
label: "享年",
value:
member.value.deathAge === null
? ""
: visibleProfileValue(`${member.value.deathAge}`),
},
{ label: "逝世地", value: visibleProfileValue(member.value.deathPlace) },
{
label: "逝世原因或类型",
value: visibleProfileValue(member.value.deathType),
},
...(member.value.canManageSensitiveMedicalHistory
? [
{
label: "遗传病史",
value: sensitiveProfileError.value
? "敏感资料暂时无法读取"
: visibleProfileValue(member.value.hereditaryMedicalHistory),
},
]
: []),
{ label: "安葬日期", value: visibleProfileValue(member.value.burialDate) },
{ label: "安葬地", value: visibleProfileValue(member.value.burialPlace) },
]
: []),
@@ -307,6 +338,27 @@ const loadMember = async (nextPersonId, { preserveCurrent = false } = {}) => {
normalizedPersonId,
{ requestController: memberReadRequestController },
);
if (nextMember.canManageSensitiveMedicalHistory) {
try {
const sensitiveProfile = await lineageApi.getSensitiveProfile(
genealogyId.value,
normalizedPersonId,
{ requestController: sensitiveProfileRequestController },
);
nextMember.hereditaryMedicalHistory =
sensitiveProfile.hereditaryMedicalHistory;
sensitiveProfileError.value = "";
} catch (error) {
if (isRequestCancelled(error)) return false;
nextMember.hereditaryMedicalHistory = "";
sensitiveProfileError.value = getRequestErrorMessage(
error,
"敏感资料暂时无法读取。",
);
}
} else {
sensitiveProfileError.value = "";
}
if (activeLoadGeneration !== memberLoadGeneration) return false;
if (personId.value && personId.value !== String(nextMember.id)) {
personDocumentDialog.value?.reset();
@@ -415,7 +467,10 @@ const requestBack = () =>
onLoad((query) => {
genealogyId.value = String(query.genealogyId || "");
const initialPersonId = String(query.personId || "");
if (!genealogyId.value || !initialPersonId) {
if (
!/^[1-9]\d*$/.test(genealogyId.value) ||
!/^[1-9]\d*$/.test(initialPersonId)
) {
memberState.value = "error";
errorMessage.value = !initialPersonId
? "没有指定成员,请从世系树重新选择。"
@@ -449,6 +504,7 @@ onUnload(() => {
pageActive = false;
memberLoadGeneration += 1;
memberReadRequestController.abort();
sensitiveProfileRequestController.abort();
memberDeletionRequestController.abort();
});
@@ -517,7 +573,7 @@ const toTree = requestBack;
display: flex;
min-height: 100vh;
flex-direction: column;
padding-bottom: 28rpx;
padding-bottom: calc(28rpx + env(safe-area-inset-bottom));
box-sizing: border-box;
background: $paper;
}
@@ -571,6 +627,10 @@ const toTree = requestBack;
box-shadow: 0 3rpx 7rpx rgba(100, 65, 29, 0.14);
overflow: hidden;
}
.member-heading > view:last-child {
min-width: 0;
overflow-wrap: anywhere;
}
.member-heading > view:last-child text {
display: block;
color: $ink-muted;
@@ -592,6 +652,7 @@ const toTree = requestBack;
grid-template-columns: auto minmax(0, 1fr) auto;
align-items: center;
gap: 14rpx;
min-height: var(--app-touch-min);
margin-top: 18rpx;
padding: 18rpx 22rpx;
}
@@ -637,6 +698,8 @@ const toTree = requestBack;
}
.member-relatives > view {
display: flex;
min-height: var(--app-touch-min);
align-items: center;
justify-content: space-between;
gap: 20rpx;
padding: 12rpx 18rpx;
@@ -661,7 +724,7 @@ const toTree = requestBack;
.member-record-actions > view {
@include adaptive-scroll-button(secondary);
display: flex;
min-height: 72rpx;
min-height: var(--app-touch-min);
align-items: center;
justify-content: center;
padding: 8rpx 14rpx;
@@ -676,7 +739,7 @@ const toTree = requestBack;
.member-profile-action {
@include adaptive-scroll-button(primary);
display: flex;
min-height: 76rpx;
min-height: var(--app-touch-min);
align-items: center;
justify-content: center;
margin-top: 22rpx;
@@ -714,7 +777,7 @@ const toTree = requestBack;
.member-restricted-action {
@include adaptive-scroll-button(secondary);
display: flex;
min-height: 76rpx;
min-height: var(--app-touch-min);
align-items: center;
justify-content: center;
margin-top: 22rpx;