|
|
@@ -1672,10 +1672,13 @@ def search_member():
|
|
|
def get_lineage(member_id):
|
|
|
if 'user_id' not in session:
|
|
|
return jsonify({"success": False, "message": "Unauthorized"}), 401
|
|
|
-
|
|
|
+
|
|
|
+ # 追溯模式:incense(香火传承,入继→养父为上辈) | blood(血脉追溯,亲生父为上辈)
|
|
|
+ mode = request.args.get('mode', 'incense')
|
|
|
+
|
|
|
import time
|
|
|
start_time = time.time()
|
|
|
- print(f"[Lineage Query] Starting query for member_id: {member_id} at {time.strftime('%Y-%m-%d %H:%M:%S')}")
|
|
|
+ print(f"[Lineage Query] Starting query for member_id: {member_id} mode={mode} at {time.strftime('%Y-%m-%d %H:%M:%S')}")
|
|
|
|
|
|
conn = get_db_connection()
|
|
|
try:
|
|
|
@@ -1714,21 +1717,36 @@ def get_lineage(member_id):
|
|
|
if not parents:
|
|
|
break
|
|
|
|
|
|
- # 优先选择直系父母(非出继),如果都是出继/入继,选择入继
|
|
|
- parent = None
|
|
|
- adoptive_parent = None
|
|
|
-
|
|
|
+ # 分拣各类父母关系
|
|
|
+ normal_parent = None
|
|
|
+ adoptive_parent = None # sub_type=3:入继养父
|
|
|
+ bio_parent = None # sub_type=2:出继亲生父
|
|
|
+
|
|
|
for p in parents:
|
|
|
- if p['sub_relation_type'] == 2: # 出继(亲生父母)
|
|
|
- parent = p
|
|
|
- elif p['sub_relation_type'] == 3: # 入继(养父母)
|
|
|
+ if p['sub_relation_type'] == 3:
|
|
|
adoptive_parent = p
|
|
|
- else: # 普通关系(亲生)
|
|
|
- parent = p
|
|
|
-
|
|
|
- # 如果没有找到普通父母,使用入继父母
|
|
|
- if not parent:
|
|
|
- parent = adoptive_parent
|
|
|
+ elif p['sub_relation_type'] == 2:
|
|
|
+ bio_parent = p
|
|
|
+ else:
|
|
|
+ normal_parent = p
|
|
|
+
|
|
|
+ if mode == 'blood':
|
|
|
+ # 血脉追溯:亲生父优先(出继亦沿亲生路径)
|
|
|
+ parent = normal_parent or bio_parent or adoptive_parent
|
|
|
+ else:
|
|
|
+ # 香火传承(默认):入继养父优先
|
|
|
+ parent = adoptive_parent or normal_parent or bio_parent
|
|
|
+ # 若走入继路径,在当事人卡片标注"从xx出继"
|
|
|
+ if parent is adoptive_parent and adoptive_parent is not None:
|
|
|
+ bio_name = (bio_parent.get('simplified_name') or bio_parent.get('name')) if bio_parent else None
|
|
|
+ adopt_label = f"从{bio_name}出继" if bio_name else "出继"
|
|
|
+ if depth == 0:
|
|
|
+ center['adoption_label'] = adopt_label
|
|
|
+ elif generations:
|
|
|
+ generations[-1]['ancestor']['adoption_label'] = adopt_label
|
|
|
+
|
|
|
+ # 祖先卡片不携带子辈关系类型(避免把子的出继/入继标在父身上)
|
|
|
+ parent['sub_relation_type'] = None
|
|
|
|
|
|
# 循环检测:如果该祖先已在链中出现过,终止(数据异常保护)
|
|
|
if parent['id'] in visited_ancestor_ids:
|
|
|
@@ -1745,6 +1763,7 @@ def get_lineage(member_id):
|
|
|
FROM family_relation_info r
|
|
|
JOIN family_member_info gp ON r.parent_mid = gp.id
|
|
|
WHERE r.child_mid = %s AND r.relation_type IN (1, 2)
|
|
|
+ ORDER BY CASE WHEN COALESCE(r.sub_relation_type, 0) = 3 THEN 1 ELSE 0 END, r.id
|
|
|
LIMIT 1
|
|
|
""", (parent['id'],))
|
|
|
grandparent = cursor.fetchone()
|
|
|
@@ -1761,11 +1780,12 @@ def get_lineage(member_id):
|
|
|
co_row = cursor.fetchone()
|
|
|
parent['child_order'] = co_row['child_order'] if co_row else None
|
|
|
|
|
|
- # 获取祖先的兄弟(含 child_order,用于前端排序与徽章)
|
|
|
+ # 获取祖先的兄弟(含 child_order 和 sub_relation_type,用于出继/入继标注)
|
|
|
cursor.execute("""
|
|
|
SELECT c.id, c.name, c.simplified_name, c.name_word, c.name_word_generation,
|
|
|
EXISTS(SELECT 1 FROM family_relation_info WHERE parent_mid = c.id AND relation_type IN (1, 2)) as has_children,
|
|
|
- COALESCE(r.child_order, NULL) AS child_order
|
|
|
+ COALESCE(r.child_order, NULL) AS child_order,
|
|
|
+ r.sub_relation_type
|
|
|
FROM family_relation_info r
|
|
|
JOIN family_member_info c ON r.child_mid = c.id
|
|
|
WHERE r.parent_mid = %s AND r.relation_type IN (1, 2) AND c.id != %s
|
|
|
@@ -1773,7 +1793,20 @@ def get_lineage(member_id):
|
|
|
LIMIT 30
|
|
|
""", (grandparent['id'], parent['id']))
|
|
|
parent_siblings = cursor.fetchall()
|
|
|
-
|
|
|
+ # 为入继兄弟补充"从xx出继"标注
|
|
|
+ for sib in parent_siblings:
|
|
|
+ if sib.get('sub_relation_type') == 3:
|
|
|
+ cursor.execute("""
|
|
|
+ SELECT p.simplified_name, p.name
|
|
|
+ FROM family_relation_info r
|
|
|
+ JOIN family_member_info p ON r.parent_mid = p.id
|
|
|
+ WHERE r.child_mid = %s AND r.sub_relation_type = 2 LIMIT 1
|
|
|
+ """, (sib['id'],))
|
|
|
+ sbp = cursor.fetchone()
|
|
|
+ sib['adoption_label'] = (
|
|
|
+ f"从{sbp['simplified_name'] or sbp['name']}出继" if sbp else "出继"
|
|
|
+ )
|
|
|
+
|
|
|
# Mark sibling IDs as displayed
|
|
|
for sibling in parent_siblings:
|
|
|
displayed_ids.add(sibling['id'])
|
|
|
@@ -1809,11 +1842,21 @@ def get_lineage(member_id):
|
|
|
# Step 3: Get immediate children only (limited count)
|
|
|
step_start = time.time()
|
|
|
|
|
|
- # 获取子女:
|
|
|
- # - 包含入继子女(sub_relation_type=3,养父母侧)
|
|
|
- # - 包含普通子女(sub_relation_type 为空或非2/3)
|
|
|
- # - 排除出继子女(sub_relation_type=2,生父母侧)若该子女已有养父母记录
|
|
|
- cursor.execute("""
|
|
|
+ # 获取子女:根据模式选择不同过滤策略
|
|
|
+ # 香火传承:包含入继子女、普通子女,排除已被人收继的出继子女
|
|
|
+ # 血脉追溯:包含亲生子女(含出继走的),排除从别处入继的子女
|
|
|
+ if mode == 'blood':
|
|
|
+ children_filter = "AND COALESCE(r.sub_relation_type, 0) != 3"
|
|
|
+ else:
|
|
|
+ children_filter = """AND (
|
|
|
+ COALESCE(r.sub_relation_type, 0) != 2
|
|
|
+ OR NOT EXISTS (
|
|
|
+ SELECT 1 FROM family_relation_info r2
|
|
|
+ WHERE r2.child_mid = c.id AND r2.sub_relation_type = 3
|
|
|
+ )
|
|
|
+ )"""
|
|
|
+
|
|
|
+ cursor.execute(f"""
|
|
|
SELECT c.id, c.name, c.simplified_name, c.name_word, c.name_word_generation,
|
|
|
EXISTS(SELECT 1 FROM family_relation_info WHERE parent_mid = c.id AND relation_type IN (1, 2)) as has_children,
|
|
|
r.sub_relation_type,
|
|
|
@@ -1821,36 +1864,37 @@ def get_lineage(member_id):
|
|
|
FROM family_relation_info r
|
|
|
JOIN family_member_info c ON r.child_mid = c.id
|
|
|
WHERE r.parent_mid = %s AND r.relation_type IN (1, 2)
|
|
|
- AND (
|
|
|
- COALESCE(r.sub_relation_type, 0) != 2
|
|
|
- OR NOT EXISTS (
|
|
|
- SELECT 1 FROM family_relation_info r2
|
|
|
- WHERE r2.child_mid = c.id AND r2.sub_relation_type = 3
|
|
|
- )
|
|
|
- )
|
|
|
+ {children_filter}
|
|
|
ORDER BY COALESCE(r.child_order, 99999), c.id
|
|
|
LIMIT 30
|
|
|
""", (member_id,))
|
|
|
children = cursor.fetchall()
|
|
|
|
|
|
- # 对于入继的子女,获取其生父母信息并生成"由xxx公第N子入继"说明
|
|
|
- _order_labels_lg = {1:'长', 2:'次', 3:'三', 4:'四', 5:'五',
|
|
|
- 6:'六', 7:'七', 8:'八', 9:'九', 10:'十'}
|
|
|
+ # 香火模式:对入继子女标注"从xx出继";血脉模式:对出继子女标注"出继至xx"
|
|
|
for child in children:
|
|
|
- if child['sub_relation_type'] == 3: # 入继
|
|
|
+ if mode == 'incense' and child['sub_relation_type'] == 3:
|
|
|
cursor.execute("""
|
|
|
- SELECT p.id, p.name, p.simplified_name, r.child_order
|
|
|
+ SELECT p.simplified_name, p.name
|
|
|
FROM family_relation_info r
|
|
|
JOIN family_member_info p ON r.parent_mid = p.id
|
|
|
- WHERE r.child_mid = %s AND r.sub_relation_type = 2
|
|
|
- LIMIT 1
|
|
|
+ WHERE r.child_mid = %s AND r.sub_relation_type = 2 LIMIT 1
|
|
|
""", (child['id'],))
|
|
|
- bio_parent = cursor.fetchone()
|
|
|
- if bio_parent:
|
|
|
- bio_name = bio_parent['simplified_name'] or bio_parent['name']
|
|
|
- order = bio_parent['child_order']
|
|
|
- order_str = _order_labels_lg.get(order, f'第{order}') if order else '某'
|
|
|
- child['adopt_info'] = f"由{bio_name}公{order_str}子入继"
|
|
|
+ bio_p = cursor.fetchone()
|
|
|
+ child['adoption_label'] = (
|
|
|
+ f"从{bio_p['simplified_name'] or bio_p['name']}出继" if bio_p else "出继"
|
|
|
+ )
|
|
|
+ elif mode == 'blood' and child['sub_relation_type'] == 2:
|
|
|
+ # 血脉模式下标注出继子女的去向(养父)
|
|
|
+ cursor.execute("""
|
|
|
+ SELECT p.simplified_name, p.name
|
|
|
+ FROM family_relation_info r
|
|
|
+ JOIN family_member_info p ON r.parent_mid = p.id
|
|
|
+ WHERE r.child_mid = %s AND r.sub_relation_type = 3 LIMIT 1
|
|
|
+ """, (child['id'],))
|
|
|
+ adop_p = cursor.fetchone()
|
|
|
+ if adop_p:
|
|
|
+ child['adoption_label'] = f"出继至{adop_p['simplified_name'] or adop_p['name']}"
|
|
|
+ child['sub_relation_type'] = 2 # 保持供前端显示 adopted-out 样式
|
|
|
|
|
|
# Initialize children array
|
|
|
for child in children:
|
|
|
@@ -1885,6 +1929,20 @@ def get_lineage(member_id):
|
|
|
LIMIT 30
|
|
|
""", (parent_id, member_id))
|
|
|
siblings = cursor.fetchall()
|
|
|
+ # 为入继兄弟补充"从xx出继"标注
|
|
|
+ for sib in siblings:
|
|
|
+ if sib.get('sub_relation_type') == 3:
|
|
|
+ cursor.execute("""
|
|
|
+ SELECT p.simplified_name, p.name
|
|
|
+ FROM family_relation_info r
|
|
|
+ JOIN family_member_info p ON r.parent_mid = p.id
|
|
|
+ WHERE r.child_mid = %s AND r.sub_relation_type = 2 LIMIT 1
|
|
|
+ """, (sib['id'],))
|
|
|
+ sbp = cursor.fetchone()
|
|
|
+ if sbp:
|
|
|
+ sib['adoption_label'] = f"从{sbp['simplified_name'] or sbp['name']}出继"
|
|
|
+ else:
|
|
|
+ sib['adoption_label'] = "出继"
|
|
|
print(f"[Lineage Query] Step 4 - Get siblings ({len(siblings)}): {time.time() - step_start:.3f}s")
|
|
|
|
|
|
total_time = time.time() - start_time
|
|
|
@@ -1925,6 +1983,8 @@ def get_ancestors_above(ancestor_id):
|
|
|
if 'user_id' not in session:
|
|
|
return jsonify({"success": False, "message": "Unauthorized"}), 401
|
|
|
|
|
|
+ mode = request.args.get('mode', 'incense')
|
|
|
+
|
|
|
conn = get_db_connection()
|
|
|
try:
|
|
|
with conn.cursor() as cursor:
|
|
|
@@ -1933,6 +1993,26 @@ def get_ancestors_above(ancestor_id):
|
|
|
max_depth = 100
|
|
|
visited_ids = set([ancestor_id])
|
|
|
|
|
|
+ # 计算 anchor 节点(ancestor_id)自身的 adoption_label(已在上层渲染,此处只补充标签)
|
|
|
+ anchor_adoption_label = None
|
|
|
+ cursor.execute("""
|
|
|
+ SELECT p.id, p.name, p.simplified_name, r.sub_relation_type
|
|
|
+ FROM family_relation_info r
|
|
|
+ JOIN family_member_info p ON r.parent_mid = p.id
|
|
|
+ WHERE r.child_mid = %s AND r.relation_type IN (1, 2)
|
|
|
+ """, (ancestor_id,))
|
|
|
+ anchor_parents = cursor.fetchall()
|
|
|
+ anchor_bio = None
|
|
|
+ has_adoptive = False
|
|
|
+ for ap in anchor_parents:
|
|
|
+ if ap['sub_relation_type'] == 3:
|
|
|
+ has_adoptive = True
|
|
|
+ elif ap['sub_relation_type'] == 2:
|
|
|
+ anchor_bio = ap
|
|
|
+ if has_adoptive and anchor_bio:
|
|
|
+ bio_name = anchor_bio.get('simplified_name') or anchor_bio.get('name')
|
|
|
+ anchor_adoption_label = f"从{bio_name}出继" if bio_name else "出继"
|
|
|
+
|
|
|
for depth in range(max_depth):
|
|
|
cursor.execute("""
|
|
|
SELECT p.id, p.name, p.simplified_name, p.name_word, p.name_word_generation,
|
|
|
@@ -1947,25 +2027,45 @@ def get_ancestors_above(ancestor_id):
|
|
|
if not parents:
|
|
|
break
|
|
|
|
|
|
- parent = None
|
|
|
+ # 分拣各类父母关系
|
|
|
+ normal_parent = None
|
|
|
adoptive_parent = None
|
|
|
+ bio_parent = None
|
|
|
for p in parents:
|
|
|
if p['sub_relation_type'] == 3:
|
|
|
adoptive_parent = p
|
|
|
+ elif p['sub_relation_type'] == 2:
|
|
|
+ bio_parent = p
|
|
|
else:
|
|
|
- parent = p
|
|
|
- if not parent:
|
|
|
- parent = adoptive_parent
|
|
|
+ normal_parent = p
|
|
|
+
|
|
|
+ if mode == 'blood':
|
|
|
+ parent = normal_parent or bio_parent or adoptive_parent
|
|
|
+ else:
|
|
|
+ parent = adoptive_parent or normal_parent or bio_parent
|
|
|
+ # 若走入继路径,在 current_id 对应的人物上标注"从xx出继"
|
|
|
+ if parent is adoptive_parent and adoptive_parent is not None:
|
|
|
+ bio_name = (bio_parent.get('simplified_name') or bio_parent.get('name')) if bio_parent else None
|
|
|
+ adopt_label = f"从{bio_name}出继" if bio_name else "出继"
|
|
|
+ if depth == 0:
|
|
|
+ anchor_adoption_label = adopt_label
|
|
|
+ elif generations:
|
|
|
+ generations[-1]['ancestor']['adoption_label'] = adopt_label
|
|
|
+
|
|
|
+ # 祖先卡片不携带子辈关系类型
|
|
|
+ parent['sub_relation_type'] = None
|
|
|
|
|
|
if parent['id'] in visited_ids:
|
|
|
break
|
|
|
visited_ids.add(parent['id'])
|
|
|
|
|
|
- # 查祖父,用于获取该祖先的兄弟
|
|
|
+ # 查祖父,用于获取该祖先的兄弟(优先亲生父母,排除养父)
|
|
|
cursor.execute("""
|
|
|
SELECT gp.id FROM family_relation_info r
|
|
|
JOIN family_member_info gp ON r.parent_mid = gp.id
|
|
|
- WHERE r.child_mid = %s AND r.relation_type IN (1, 2) LIMIT 1
|
|
|
+ WHERE r.child_mid = %s AND r.relation_type IN (1, 2)
|
|
|
+ ORDER BY CASE WHEN COALESCE(r.sub_relation_type, 0) = 3 THEN 1 ELSE 0 END, r.id
|
|
|
+ LIMIT 1
|
|
|
""", (parent['id'],))
|
|
|
grandparent = cursor.fetchone()
|
|
|
|
|
|
@@ -2020,7 +2120,8 @@ def get_ancestors_above(ancestor_id):
|
|
|
"data": {
|
|
|
"generations": generations,
|
|
|
"has_more_ancestors": has_more_ancestors,
|
|
|
- "topmost_ancestor_id": topmost_ancestor_id
|
|
|
+ "topmost_ancestor_id": topmost_ancestor_id,
|
|
|
+ "anchor_adoption_label": anchor_adoption_label
|
|
|
}
|
|
|
})
|
|
|
except Exception as e:
|
|
|
@@ -5832,6 +5933,8 @@ def api_get_lineage(member_id):
|
|
|
if not token:
|
|
|
return jsonify({"success": False, "message": "未登录"}), 401
|
|
|
|
|
|
+ mode = request.args.get('mode', 'incense')
|
|
|
+
|
|
|
conn = get_db_connection()
|
|
|
try:
|
|
|
with conn.cursor() as cursor:
|
|
|
@@ -5864,25 +5967,45 @@ def api_get_lineage(member_id):
|
|
|
if not parents:
|
|
|
break
|
|
|
|
|
|
- # 优先取非养父母关系
|
|
|
- parent = None
|
|
|
+ # 分拣各类父母关系
|
|
|
+ normal_parent = None
|
|
|
+ adoptive_parent = None
|
|
|
+ bio_parent = None
|
|
|
for p in parents:
|
|
|
- if p['sub_relation_type'] != 3:
|
|
|
- parent = p
|
|
|
- break
|
|
|
- if not parent:
|
|
|
- parent = parents[0]
|
|
|
+ if p['sub_relation_type'] == 3:
|
|
|
+ adoptive_parent = p
|
|
|
+ elif p['sub_relation_type'] == 2:
|
|
|
+ bio_parent = p
|
|
|
+ else:
|
|
|
+ normal_parent = p
|
|
|
+
|
|
|
+ if mode == 'blood':
|
|
|
+ parent = normal_parent or bio_parent or adoptive_parent
|
|
|
+ else:
|
|
|
+ parent = adoptive_parent or normal_parent or bio_parent
|
|
|
+ if parent is adoptive_parent and adoptive_parent is not None:
|
|
|
+ bio_name = (bio_parent.get('simplified_name') or bio_parent.get('name')) if bio_parent else None
|
|
|
+ adopt_label = f"从{bio_name}出继" if bio_name else "出继"
|
|
|
+ if depth == 0:
|
|
|
+ center['adoption_label'] = adopt_label
|
|
|
+ elif generations:
|
|
|
+ generations[-1]['ancestor']['adoption_label'] = adopt_label
|
|
|
+
|
|
|
+ # 祖先卡片不携带子辈关系类型
|
|
|
+ parent['sub_relation_type'] = None
|
|
|
|
|
|
# 循环检测
|
|
|
if parent['id'] in visited_ancestor_ids:
|
|
|
break
|
|
|
visited_ancestor_ids.add(parent['id'])
|
|
|
|
|
|
- # 查祖父以获取该祖先的兄弟
|
|
|
+ # 查祖父以获取该祖先的兄弟(优先亲生父母,排除养父)
|
|
|
cursor.execute("""
|
|
|
SELECT gp.id FROM family_relation_info r
|
|
|
JOIN family_member_info gp ON r.parent_mid = gp.id
|
|
|
- WHERE r.child_mid = %s AND r.relation_type IN (1, 2) LIMIT 1
|
|
|
+ WHERE r.child_mid = %s AND r.relation_type IN (1, 2)
|
|
|
+ ORDER BY CASE WHEN COALESCE(r.sub_relation_type, 0) = 3 THEN 1 ELSE 0 END, r.id
|
|
|
+ LIMIT 1
|
|
|
""", (parent['id'],))
|
|
|
grandparent = cursor.fetchone()
|
|
|
|
|
|
@@ -5943,14 +6066,12 @@ def api_get_lineage(member_id):
|
|
|
LIMIT 20
|
|
|
""", (member_id,))
|
|
|
children = cursor.fetchall()
|
|
|
- _order_labels_alg = {1:'长', 2:'次', 3:'三', 4:'四', 5:'五',
|
|
|
- 6:'六', 7:'七', 8:'八', 9:'九', 10:'十'}
|
|
|
for c in children:
|
|
|
c['has_children'] = bool(c['has_children'])
|
|
|
- # 入继子女:附加生父母信息,生成"由xxx公第N子入继"说明
|
|
|
+ # 入继子女:附加生父母信息,生成"从xx出继"标注
|
|
|
if c['sub_relation_type'] == 3:
|
|
|
cursor.execute("""
|
|
|
- SELECT p.name, p.simplified_name, r.child_order
|
|
|
+ SELECT p.name, p.simplified_name
|
|
|
FROM family_relation_info r
|
|
|
JOIN family_member_info p ON r.parent_mid = p.id
|
|
|
WHERE r.child_mid = %s AND r.sub_relation_type = 2 LIMIT 1
|
|
|
@@ -5958,9 +6079,9 @@ def api_get_lineage(member_id):
|
|
|
bp = cursor.fetchone()
|
|
|
if bp:
|
|
|
bio_name = bp['simplified_name'] or bp['name']
|
|
|
- order = bp['child_order']
|
|
|
- order_str = _order_labels_alg.get(order, f'第{order}') if order else '某'
|
|
|
- c['adopt_info'] = f"由{bio_name}公{order_str}子入继"
|
|
|
+ c['adoption_label'] = f"从{bio_name}出继"
|
|
|
+ else:
|
|
|
+ c['adoption_label'] = "出继"
|
|
|
|
|
|
# Step 4: 获取查询人物的同辈兄弟(含center自己的child_order)
|
|
|
siblings = []
|
|
|
@@ -6027,6 +6148,8 @@ def api_get_ancestors_above(ancestor_id):
|
|
|
if not token:
|
|
|
return jsonify({"success": False, "message": "未登录"}), 401
|
|
|
|
|
|
+ mode = request.args.get('mode', 'incense')
|
|
|
+
|
|
|
conn = get_db_connection()
|
|
|
try:
|
|
|
with conn.cursor() as cursor:
|
|
|
@@ -6035,6 +6158,26 @@ def api_get_ancestors_above(ancestor_id):
|
|
|
max_depth = 100
|
|
|
visited_ids = set([ancestor_id])
|
|
|
|
|
|
+ # 计算 anchor 节点(ancestor_id)自身的 adoption_label
|
|
|
+ anchor_adoption_label_wx = None
|
|
|
+ cursor.execute("""
|
|
|
+ SELECT p.id, p.name, p.simplified_name, r.sub_relation_type
|
|
|
+ FROM family_relation_info r
|
|
|
+ JOIN family_member_info p ON r.parent_mid = p.id
|
|
|
+ WHERE r.child_mid = %s AND r.relation_type IN (1, 2)
|
|
|
+ """, (ancestor_id,))
|
|
|
+ anchor_parents_wx = cursor.fetchall()
|
|
|
+ anchor_bio_wx = None
|
|
|
+ has_adoptive_wx = False
|
|
|
+ for ap in anchor_parents_wx:
|
|
|
+ if ap['sub_relation_type'] == 3:
|
|
|
+ has_adoptive_wx = True
|
|
|
+ elif ap['sub_relation_type'] == 2:
|
|
|
+ anchor_bio_wx = ap
|
|
|
+ if has_adoptive_wx and anchor_bio_wx:
|
|
|
+ bio_name_wx = anchor_bio_wx.get('simplified_name') or anchor_bio_wx.get('name')
|
|
|
+ anchor_adoption_label_wx = f"从{bio_name_wx}出继" if bio_name_wx else "出继"
|
|
|
+
|
|
|
for depth in range(max_depth):
|
|
|
cursor.execute("""
|
|
|
SELECT p.id, p.name, p.simplified_name, p.name_word, p.name_word_generation,
|
|
|
@@ -6049,13 +6192,32 @@ def api_get_ancestors_above(ancestor_id):
|
|
|
if not parents:
|
|
|
break
|
|
|
|
|
|
- parent = None
|
|
|
+ # 分拣各类父母关系
|
|
|
+ normal_parent = None
|
|
|
+ adoptive_parent = None
|
|
|
+ bio_parent = None
|
|
|
for p in parents:
|
|
|
- if p['sub_relation_type'] != 3:
|
|
|
- parent = p
|
|
|
- break
|
|
|
- if not parent:
|
|
|
- parent = parents[0]
|
|
|
+ if p['sub_relation_type'] == 3:
|
|
|
+ adoptive_parent = p
|
|
|
+ elif p['sub_relation_type'] == 2:
|
|
|
+ bio_parent = p
|
|
|
+ else:
|
|
|
+ normal_parent = p
|
|
|
+
|
|
|
+ if mode == 'blood':
|
|
|
+ parent = normal_parent or bio_parent or adoptive_parent
|
|
|
+ else:
|
|
|
+ parent = adoptive_parent or normal_parent or bio_parent
|
|
|
+ if parent is adoptive_parent and adoptive_parent is not None:
|
|
|
+ bio_name = (bio_parent.get('simplified_name') or bio_parent.get('name')) if bio_parent else None
|
|
|
+ adopt_label = f"从{bio_name}出继" if bio_name else "出继"
|
|
|
+ if depth == 0:
|
|
|
+ anchor_adoption_label_wx = adopt_label
|
|
|
+ elif generations:
|
|
|
+ generations[-1]['ancestor']['adoption_label'] = adopt_label
|
|
|
+
|
|
|
+ # 祖先卡片不携带子辈关系类型
|
|
|
+ parent['sub_relation_type'] = None
|
|
|
|
|
|
if parent['id'] in visited_ids:
|
|
|
break
|
|
|
@@ -6064,7 +6226,9 @@ def api_get_ancestors_above(ancestor_id):
|
|
|
cursor.execute("""
|
|
|
SELECT gp.id FROM family_relation_info r
|
|
|
JOIN family_member_info gp ON r.parent_mid = gp.id
|
|
|
- WHERE r.child_mid = %s AND r.relation_type IN (1, 2) LIMIT 1
|
|
|
+ WHERE r.child_mid = %s AND r.relation_type IN (1, 2)
|
|
|
+ ORDER BY CASE WHEN COALESCE(r.sub_relation_type, 0) = 3 THEN 1 ELSE 0 END, r.id
|
|
|
+ LIMIT 1
|
|
|
""", (parent['id'],))
|
|
|
grandparent = cursor.fetchone()
|
|
|
|
|
|
@@ -6118,7 +6282,8 @@ def api_get_ancestors_above(ancestor_id):
|
|
|
"data": {
|
|
|
"generations": generations,
|
|
|
"has_more_ancestors": has_more_ancestors,
|
|
|
- "topmost_ancestor_id": topmost_ancestor_id
|
|
|
+ "topmost_ancestor_id": topmost_ancestor_id,
|
|
|
+ "anchor_adoption_label": anchor_adoption_label_wx
|
|
|
}
|
|
|
})
|
|
|
except Exception as e:
|