修改部分样式

This commit is contained in:
rain
2026-07-27 17:29:58 +08:00
parent 04287e6777
commit 1e9e25fe67
53 changed files with 11562 additions and 2617 deletions
+138 -69
View File
@@ -85,48 +85,50 @@
/>
<template v-else-if="treeState === 'tree'">
<view
v-for="connector in lineageConnectors"
:key="connector.id"
class="lineage-connector"
:class="{ 'lineage-connector--spouse': connector.kind === 'spouse' }"
:style="connector.style"
/>
<view
v-for="connector in lineageConnectors"
:key="connector.id"
class="lineage-connector"
:class="{
'lineage-connector--spouse': connector.kind === 'spouse',
}"
:style="connector.style"
/>
<view
v-for="member in layoutMembers"
:key="member.id"
:id="`tree-member-${member.id}`"
class="member-node"
:class="{
'member-node--selected': selected?.id === member.id,
'member-node--spouse': Boolean(member.spouseOf),
}"
:style="nodeGridStyle(member)"
@click="openMemberPanel(member)"
>
<view class="member-node__surface">
<view class="member-node__portrait">
<view
v-for="member in layoutMembers"
:key="member.id"
:id="`tree-member-${member.id}`"
class="member-node"
:class="{
'member-node--selected': selected?.id === member.id,
'member-node--spouse': Boolean(member.spouseOf),
}"
:style="nodeGridStyle(member)"
@click="openMemberPanel(member)"
>
<view class="member-node__surface">
<view class="member-node__portrait">
<image
class="member-node__avatar"
src="/static/assets/foundation/transparent/tab-profile.png"
mode="aspectFit"
/>
</view>
<image
class="member-node__avatar"
src="/static/assets/foundation/transparent/tab-profile.png"
class="member-node__divider"
src="/static/assets/foundation/transparent/auth-divider-knot.png"
mode="aspectFit"
/>
</view>
<image
class="member-node__divider"
src="/static/assets/foundation/transparent/auth-divider-knot.png"
mode="aspectFit"
/>
<view class="member-node__copy">
<text class="node-name">{{ member.name }}</text>
<text class="node-relation"
>{{ nodeRelationText(member) }}</text
>
<text class="node-years">{{ member.years }}</text>
<view class="member-node__copy">
<text class="node-name">{{ member.name }}</text>
<text class="node-relation">{{
nodeRelationText(member)
}}</text>
<text class="node-years">{{ member.years }}</text>
</view>
</view>
</view>
</view>
</template>
<view v-else class="tree-state-card">
@@ -177,7 +179,10 @@
/>
<view class="member-action-profile__copy">
<text>{{ selected.name }}</text>
<text> {{ selected.generation }} · {{ selected.relation }} · {{ selected.branch }}</text>
<text
> {{ selected.generation }} · {{ selected.relation }} ·
{{ selected.branch }}</text
>
<text>点击头像查看资料</text>
</view>
</view>
@@ -197,7 +202,9 @@
:visible="unavailableActionVisible"
eyebrow="服务状态"
:title="unavailableAction?.label || '当前操作'"
:message="unavailableAction?.unavailableCopy || '该操作暂未接入可靠服务合同。'"
:message="
unavailableAction?.unavailableCopy || '该操作暂未接入可靠服务合同。'
"
confirm-text="我知道了"
@confirm="unavailableActionVisible = false"
@cancel="unavailableActionVisible = false"
@@ -247,17 +254,43 @@ const members = ref([]);
const memberActions = Object.freeze([
{ key: "VIEW_PROFILE", label: "查看资料", routeKey: "T03" },
{ key: "ADD_FATHER", label: "添加父亲", routeKey: "T04", relationType: "FATHER" },
{ key: "ADD_MOTHER", label: "添加母亲", routeKey: "T04", relationType: "MOTHER" },
{ key: "ADD_SPOUSE", label: "添加配偶", routeKey: "T04", relationType: "SPOUSE" },
{ key: "ADD_SIBLING", label: "添加兄弟姐妹", routeKey: "T04", relationType: "SIBLING" },
{
key: "ADD_FATHER",
label: "添加父亲",
routeKey: "T04",
relationType: "FATHER",
},
{
key: "ADD_MOTHER",
label: "添加母亲",
routeKey: "T04",
relationType: "MOTHER",
},
{
key: "ADD_SPOUSE",
label: "添加配偶",
routeKey: "T04",
relationType: "SPOUSE",
},
{
key: "ADD_SIBLING",
label: "添加兄弟姐妹",
routeKey: "T04",
relationType: "SIBLING",
},
{ key: "ADJUST_RANK", label: "调整排行", routeKey: "T06", mode: "rank" },
{ key: "ADD_SON", label: "添加儿子", routeKey: "T04", relationType: "SON" },
{ key: "ADD_DAUGHTER", label: "添加女儿", routeKey: "T04", relationType: "DAUGHTER" },
{
key: "ADD_DAUGHTER",
label: "添加女儿",
routeKey: "T04",
relationType: "DAUGHTER",
},
{
key: "BIND_INVITE",
label: "邀请绑定",
unavailableCopy: "邀请签发、目标身份查找、绑定 mutation 和结果查询尚无可靠合同;当前不会借邀请码或普通入谱申请替代。",
unavailableCopy:
"邀请签发、目标身份查找、绑定 mutation 和结果查询尚无可靠合同;当前不会借邀请码或普通入谱申请替代。",
},
{ key: "EDIT_PROFILE", label: "编辑信息", routeKey: "T05" },
]);
@@ -278,14 +311,21 @@ const layoutMembers = computed(() => {
.filter((member) => Number(member.generation) === generation)
.sort(
(left, right) =>
String(left.parentId || "").localeCompare(String(right.parentId || "")) ||
String(left.spouseOf || left.id).localeCompare(String(right.spouseOf || right.id)) ||
String(left.parentId || "").localeCompare(
String(right.parentId || ""),
) ||
String(left.spouseOf || left.id).localeCompare(
String(right.spouseOf || right.id),
) ||
Number(Boolean(left.spouseOf)) - Number(Boolean(right.spouseOf)) ||
String(left.id).localeCompare(String(right.id)),
),
]),
);
const maxCount = Math.max(1, ...Array.from(groups.values()).map((group) => group.length));
const maxCount = Math.max(
1,
...Array.from(groups.values()).map((group) => group.length),
);
const canvasWidth = Math.max(660, maxCount * MEMBER_GAP + 80);
return generations.flatMap((generation, generationIndex) => {
const group = groups.get(generation) || [];
@@ -365,7 +405,8 @@ const lineageConnectors = computed(() => {
});
const childrenByParent = new Map();
layoutMembers.value.forEach((member) => {
if (member.spouseOf || !member.parentId || !memberById.has(member.parentId)) return;
if (member.spouseOf || !member.parentId || !memberById.has(member.parentId))
return;
const children = childrenByParent.get(member.parentId) || [];
children.push(member);
childrenByParent.set(member.parentId, children);
@@ -382,7 +423,9 @@ const lineageConnectors = computed(() => {
const parentAnchorY = spouse
? snapToGrid(parentBottom + FAMILY_LINK_OFFSET)
: parentBottom;
const childTop = Math.min(...children.map((child) => child.y - NODE_HALF_HEIGHT));
const childTop = Math.min(
...children.map((child) => child.y - NODE_HALF_HEIGHT),
);
const branchY = snapToGrid((parentAnchorY + childTop) / 2);
const minX = Math.min(...children.map((child) => child.x));
const maxX = Math.max(...children.map((child) => child.x));
@@ -403,12 +446,20 @@ const lineageConnectors = computed(() => {
connectors.push({
id: `${parentId}-${spouse.id}-family-spouse`,
kind: "family",
style: verticalStyle(spouse.x, spouse.y + NODE_HALF_HEIGHT, parentAnchorY),
style: verticalStyle(
spouse.x,
spouse.y + NODE_HALF_HEIGHT,
parentAnchorY,
),
});
connectors.push({
id: `${parentId}-${spouse.id}-family-bridge`,
kind: "family",
style: horizontalStyle(Math.min(parent.x, spouse.x), Math.max(parent.x, spouse.x), parentAnchorY),
style: horizontalStyle(
Math.min(parent.x, spouse.x),
Math.max(parent.x, spouse.x),
parentAnchorY,
),
});
}
connectors.push({
@@ -422,10 +473,12 @@ const lineageConnectors = computed(() => {
gridRow: `${Math.round(branchY / GRID_UNIT) + 1} / span 1`,
},
});
children.forEach((child) => connectors.push({
id: `${parentId}-${child.id}`,
style: verticalStyle(child.x, branchY, child.y - NODE_HALF_HEIGHT),
}));
children.forEach((child) =>
connectors.push({
id: `${parentId}-${child.id}`,
style: verticalStyle(child.x, branchY, child.y - NODE_HALF_HEIGHT),
}),
);
});
layoutMembers.value.forEach((member) => {
if (!member.spouseOf) return;
@@ -505,7 +558,9 @@ const loadTree = async (query = {}) => {
selected.value =
layoutMembers.value.find(
(item) => String(item.id) === String(query.selectedId),
) || layoutMembers.value[0] || null;
) ||
layoutMembers.value[0] ||
null;
treeState.value = members.value.length ? "tree" : "empty";
if (treeState.value === "tree" && selected.value) {
await nextTick();
@@ -545,14 +600,17 @@ const handleTreeScroll = (event) => {
if (ignoreTreeScroll || treeState.value !== "tree") return;
const scrollLeft = Number(event?.detail?.scrollLeft || 0);
currentTreeScrollLeft.value = scrollLeft;
treeHasDrifted.value = Math.abs(scrollLeft - centeredTreeScrollLeft.value) > 80;
treeHasDrifted.value =
Math.abs(scrollLeft - centeredTreeScrollLeft.value) > 80;
};
const getFamilyPartner = (member) => {
if (!member) return null;
const partnerId = member.spouseOf || layoutMembers.value.find(
(item) => String(item.spouseOf || "") === String(member.id),
)?.id;
const partnerId =
member.spouseOf ||
layoutMembers.value.find(
(item) => String(item.spouseOf || "") === String(member.id),
)?.id;
const partner = layoutMembers.value.find(
(item) => String(item.id) === String(partnerId || ""),
);
@@ -566,9 +624,7 @@ const recenterSelectedMember = async () => {
const [scrollRect, nodeRect, spouseRect] = await new Promise((resolve) => {
const query = uni.createSelectorQuery();
query.select(".tree-scroll").boundingClientRect();
query
.select(`#tree-member-${selected.value.id}`)
.boundingClientRect();
query.select(`#tree-member-${selected.value.id}`).boundingClientRect();
if (spouse) {
query.select(`#tree-member-${spouse.id}`).boundingClientRect();
}
@@ -580,14 +636,15 @@ const recenterSelectedMember = async () => {
: nodeRect.left;
const targetRight = spouseRect
? Math.max(
nodeRect.left + nodeRect.width,
spouseRect.left + spouseRect.width,
)
nodeRect.left + nodeRect.width,
spouseRect.left + spouseRect.width,
)
: nodeRect.left + nodeRect.width;
const centeredScrollLeft = Math.max(
0,
currentTreeScrollLeft.value +
(targetLeft + targetRight) / 2 - (scrollRect.left + scrollRect.width / 2),
(targetLeft + targetRight) / 2 -
(scrollRect.left + scrollRect.width / 2),
);
treeScrollLeft.value = centeredScrollLeft;
currentTreeScrollLeft.value = centeredScrollLeft;
@@ -623,13 +680,25 @@ const handleStateAction = () => {
const toMember = () => {
if (!selected.value) return Promise.resolve(false);
memberActionPanelVisible.value = false;
return openPage("T03", { genealogyId: genealogyId.value, personId: String(selected.value.id) }, "T01");
return openPage(
"T03",
{ genealogyId: genealogyId.value, personId: String(selected.value.id) },
"T01",
);
};
const toDirectory = () =>
openPage("T07", { genealogyId: genealogyId.value }, "T01");
const toRank = () =>
selected.value
? openPage("T06", { genealogyId: genealogyId.value, personId: String(selected.value.id), mode: "rank" }, "T01")
? openPage(
"T06",
{
genealogyId: genealogyId.value,
personId: String(selected.value.id),
mode: "rank",
},
"T01",
)
: Promise.resolve(false);
const openMemberPanel = (member) => {
selected.value = member;