chore: sync remaining local changes to Gitea

This commit is contained in:
shumengya
2026-06-24 22:13:01 +08:00
parent 0752ceccb4
commit 8b55485a82
20 changed files with 2720 additions and 121 deletions

77
test-layout.html Normal file
View File

@@ -0,0 +1,77 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Layout Test</title>
</head>
<body>
<pre id="output"></pre>
<script>
const members = [{"id":"4661dd7b-f3b9-42d1-bf00-b14899e2a92e","name":"唐治明","birthYear":1960,"gender":"男","generation":"父亲","fatherId":"f24a95c7-fa68-4f56-b0ed-e1f7fb2c91e1"},{"id":"d4498bfb-c0ce-4218-bc8f-3f0cc0cf6984","name":"舒邦莲","birthYear":1960,"gender":"女","generation":"父亲"},{"id":"f24a95c7-fa68-4f56-b0ed-e1f7fb2c91e1","name":"唐有奎","birthYear":1900,"gender":"男","generation":"祖父"},{"id":"1be537aa-88cb-4b82-8c09-e18e05922499","name":"唐治安","birthYear":1960,"gender":"男","generation":"父亲","fatherId":"f24a95c7-fa68-4f56-b0ed-e1f7fb2c91e1"},{"id":"e6d9c5b3-6397-4d88-878b-e22e5c9f512b","name":"万华群","birthYear":1960,"gender":"女","generation":"父亲"},{"name":"唐治芳","birthYear":1960,"gender":"女","generation":"父亲","fatherId":"f24a95c7-fa68-4f56-b0ed-e1f7fb2c91e1","id":"4b78f55d-34b0-4407-a672-3d6b3e826f0f"},{"name":"邓能春","birthYear":1960,"gender":"男","generation":"父亲","id":"a7bcc3b5-c4fc-4fca-8bd4-44cf6078d678"},{"id":"208fb133-6a0b-4540-a1ff-ad8ce154c33f","name":"唐伟","birthYear":1990,"gender":"男","generation":"自己","fatherId":"4661dd7b-f3b9-42d1-bf00-b14899e2a92e","motherId":"d4498bfb-c0ce-4218-bc8f-3f0cc0cf6984"},{"name":"唐永洪","birthYear":1990,"gender":"男","generation":"自己","fatherId":"4661dd7b-f3b9-42d1-bf00-b14899e2a92e","motherId":"d4498bfb-c0ce-4218-bc8f-3f0cc0cf6984","id":"ab86880b-502c-4249-9ce4-ff3327c3fd1b"},{"id":"de8e2fc8-2a1e-4dc1-b010-cd29b9312105","name":"唐雪","birthYear":1990,"gender":"女","generation":"自己","fatherId":"1be537aa-88cb-4b82-8c09-e18e05922499","motherId":"e6d9c5b3-6397-4d88-878b-e22e5c9f512b"},{"name":"唐波","birthYear":1990,"gender":"男","generation":"自己","fatherId":"1be537aa-88cb-4b82-8c09-e18e05922499","motherId":"e6d9c5b3-6397-4d88-878b-e22e5c9f512b","id":"08a22bcd-5af6-4589-8739-9ea796c41a01"},{"name":"邓静","birthYear":1990,"gender":"女","generation":"自己","fatherId":"a7bcc3b5-c4fc-4fca-8bd4-44cf6078d678","motherId":"4b78f55d-34b0-4407-a672-3d6b3e826f0f","id":"1ebd23c6-dadf-4cec-98fe-5bff971bc591"},{"id":"4c3f6e87-8756-48de-9141-5881778974ce","name":"邓正悦","birthYear":1990,"gender":"女","generation":"自己","fatherId":"a7bcc3b5-c4fc-4fca-8bd4-44cf6078d678","motherId":"4b78f55d-34b0-4407-a672-3d6b3e826f0f"},{"name":"张红","birthYear":1990,"gender":"女","generation":"自己","id":"a74c5ba0-5fe1-4862-a651-f81b641deb72"},{"name":"郭思琪","birthYear":1990,"gender":"女","generation":"自己","id":"95672071-9f60-4728-9209-00a24a01fb3a"},{"id":"a1fa7080-3e49-49bb-b2d7-ec94e005369f","name":"唐世宁","birthYear":2020,"gender":"女","generation":"子女","fatherId":"ab86880b-502c-4249-9ce4-ff3327c3fd1b","motherId":"95672071-9f60-4728-9209-00a24a01fb3a"},{"id":"74ab3d7a-3dad-4279-aecb-13e7ef12c0ff","name":"唐瑾瑜","birthYear":2020,"gender":"女","generation":"子女","fatherId":"08a22bcd-5af6-4589-8739-9ea796c41a01","motherId":"a74c5ba0-5fe1-4862-a651-f81b641deb72"},{"id":"6365ca6a-f31f-4b7a-b233-bc5a101f7025","name":"唐世严","birthYear":2020,"gender":"男","generation":"子女","fatherId":"08a22bcd-5af6-4589-8739-9ea796c41a01","motherId":"a74c5ba0-5fe1-4862-a651-f81b641deb72"}];
const GEN_ORDER = [
'鼻祖','远祖','太祖','烈祖','天祖',
'高祖','曾祖','祖父','父亲','自己',
'子女','孙辈','曾孙','玄孙','来孙',
'晜孙','仍孙','云孙','耳孙'
];
const map = {};
members.forEach(m => map[m.id] = m);
const childrenOf = {};
members.forEach(m => {
if (m.fatherId && map[m.fatherId]) (childrenOf[m.fatherId] = childrenOf[m.fatherId] || []).push(m.id);
if (m.motherId && map[m.motherId]) (childrenOf[m.motherId] = childrenOf[m.motherId] || []).push(m.id);
});
Object.keys(childrenOf).forEach(pid => { childrenOf[pid] = [...new Set(childrenOf[pid])]; });
const rankOf = {};
members.forEach(m => {
if (m.generation) {
const idx = GEN_ORDER.indexOf(m.generation);
rankOf[m.id] = (idx >= 0 ? idx : 9) * 1000;
}
});
const bfsQueue = Object.keys(rankOf);
const visitedBFS = new Set(bfsQueue);
let qi = 0;
while (qi < bfsQueue.length) {
const pid = bfsQueue[qi++];
(childrenOf[pid] || []).forEach(cid => {
const needed = Math.max(
map[cid].fatherId && rankOf[map[cid].fatherId] !== undefined ? rankOf[map[cid].fatherId] + 1000 : 0,
map[cid].motherId && rankOf[map[cid].motherId] !== undefined ? rankOf[map[cid].motherId] + 1000 : 0
);
if (rankOf[cid] === undefined || needed > rankOf[cid]) rankOf[cid] = needed;
if (!visitedBFS.has(cid)) { visitedBFS.add(cid); bfsQueue.push(cid); }
});
}
members.forEach(m => { if (rankOf[m.id] === undefined) rankOf[m.id] = 9 * 1000; });
const uniqueRanks = [...new Set(Object.values(rankOf))].sort((a, b) => a - b);
const rankToRow = {};
uniqueRanks.forEach((r, i) => { rankToRow[r] = i; });
const rowOf = {};
members.forEach(m => { rowOf[m.id] = rankToRow[rankOf[m.id]]; });
let output = "成员布局分析:\n\n";
members.forEach(m => {
output += `${m.name}: generation="${m.generation}" rank=${rankOf[m.id]} row=${rowOf[m.id]}`;
if (m.fatherId) output += ` 父=${map[m.fatherId]?.name}(rank=${rankOf[m.fatherId]})`;
if (m.motherId) output += ` 母=${map[m.motherId]?.name}(rank=${rankOf[m.motherId]})`;
output += '\n';
});
output += "\n\n按行分组\n";
const maxRow = Math.max(...Object.values(rowOf));
for (let g = 0; g <= maxRow; g++) {
const rowMembers = members.filter(m => rowOf[m.id] === g);
output += `\n${g}行: ${rowMembers.map(m => m.name).join(', ')}\n`;
}
document.getElementById('output').textContent = output;
</script>
</body>
</html>