File size: 5,123 Bytes
4bacf8a
 
8868524
b112783
4bacf8a
 
b112783
8868524
 
b112783
 
 
 
 
 
 
 
8868524
4bacf8a
b112783
 
 
 
 
8868524
b112783
 
 
4bacf8a
b112783
4bacf8a
 
b112783
4bacf8a
b112783
 
 
 
 
 
4bacf8a
b112783
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8868524
 
b112783
8868524
 
 
b112783
 
 
 
 
 
4bacf8a
b112783
4bacf8a
b112783
 
 
 
 
 
4bacf8a
b112783
 
4bacf8a
b112783
 
4bacf8a
8868524
b112783
 
 
 
 
 
 
 
 
 
 
 
4bacf8a
 
b112783
4bacf8a
8868524
 
 
 
 
b112783
8868524
 
b112783
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8868524
b112783
 
 
 
 
8868524
b112783
 
 
 
 
8868524
 
 
b112783
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
import json
import gradio as gr
import os
import re

# ==========================================
# 1. 配置与 CSS (隐藏下载按钮)
# ==========================================
PROJECT_NAME = "冯氏亲戚关系网"
ARCHIVE_ROOT = "archives"
PHOTO_ROOT = "photos"

CUSTOM_CSS = """
footer {display: none !important;}
.download-button {display: none !important;}
.share-button {display: none !important;}
"""

def load_family_data():
    db = {}
    if os.path.exists("family_data.jsonl"):
        with open("family_data.jsonl", "r", encoding="utf-8") as f:
            for line in f:
                try:
                    data = json.loads(line.strip())
                    if "n" in data: db[data["n"].strip()] = data
                except: continue
    return db

family_db = load_family_data()

# ==========================================
# 2. 逻辑函数
# ==========================================

def get_person_basic_info(name):
    """提取基本信息:父母、配偶、生卒"""
    name = name.strip()
    if name not in family_db:
        return "未找到该成员信息", "无", "无", None
    
    rec = family_db[name]
    father = rec.get("f", "不详")
    mother = rec.get("m", "不详")
    
    # 配偶处理 (支持字符串或列表)
    sp = rec.get("sp", "无")
    if isinstance(sp, list):
        sp = "、".join(sp) if sp else "无"
        
    # 提取生卒 (简单从 info 中匹配数字)
    info = rec.get("info", "")
    years = "资料待补充"
    # 匹配如 "1900-1980" 或 "1920年出生"
    year_match = re.findall(r'(\d{4})', info)
    if len(year_match) >= 2:
        years = f"{year_match[0]}{year_match[1]}"
    elif len(year_match) == 1:
        years = f"{year_match[0]}年出生"

    # 查找照片
    photo_path = None
    for ext in ['.jpg', '.png', '.jpeg']:
        p = os.path.join(PHOTO_ROOT, f"{name}{ext}")
        if os.path.exists(p):
            photo_path = p
            break
            
    # 获取档案文件列表
    person_dir = os.path.join(ARCHIVE_ROOT, name)
    files = []
    if os.path.exists(person_dir):
        files = [f for f in os.listdir(person_dir) if os.path.isfile(os.path.join(person_dir, f))]
    
    basic_md = f"**父亲:** {father}    **母亲:** {mother}    **配偶:** {sp}\n\n**生卒:** {years}"
    
    return basic_md, gr.update(choices=files, value=None), photo_path

def handle_file_display(name, filename):
    """统一展示框逻辑"""
    if not name or not filename:
        return [gr.update(visible=False)] * 4
    
    fpath = os.path.join(ARCHIVE_ROOT, name.strip(), filename)
    ext = os.path.splitext(filename)[1].lower()
    
    # 初始化:全部隐藏
    res = [gr.update(visible=False, value=None) for _ in range(4)]
    
    try:
        if ext in ['.txt', '.md']:
            with open(fpath, 'r', encoding='utf-8') as f:
                res[0] = gr.update(visible=True, value=f.read())
        elif ext in ['.jpg', '.png', '.jpeg', '.gif']:
            res[1] = gr.update(visible=True, value=fpath)
        elif ext in ['.mp4', '.mov']:
            res[2] = gr.update(visible=True, value=fpath)
        elif ext in ['.mp3', '.wav']:
            res[3] = gr.update(visible=True, value=fpath)
    except:
        pass
    return res

# ==========================================
# 3. 界面布局
# ==========================================
with gr.Blocks(title=PROJECT_NAME) as demo:
    gr.Markdown(f"# 👨‍👩‍👧‍👦 {PROJECT_NAME}")
    
    with gr.Tabs():
        with gr.Tab("🔍 查亲戚"):
            gr.Markdown("请输入姓名进行关系链查询")

        with gr.Tab("📋 个人资料"):
            # 1. 顶部:姓名输入
            name_input = gr.Textbox(label="输入姓名并回车", placeholder="例如:冯乔福")
            
            # 2. 基本信息区域 (父母、配偶、生卒)
            info_display = gr.Markdown("### 基本信息\n请输入姓名加载数据...")
            
            # 3. 照片区域
            person_photo = gr.Image(label="人物照片", height=300)
            
            # 4. 档案检索 (照片之下)
            file_list = gr.Dropdown(label="📁 统一档案检索目录 (文字/音视频)", choices=[])
            
            # 5. 统一内容展示
            gr.Markdown("---")
            out_txt = gr.Textbox(label="档案内容", lines=12, visible=False)
            out_img = gr.Image(label="档案图片", visible=False)
            out_vid = gr.Video(label="档案视频预览", visible=False)
            out_aud = gr.Audio(label="档案音频预览", visible=False)

            # 事件绑定
            name_input.submit(
                fn=get_person_basic_info,
                inputs=name_input,
                outputs=[info_display, file_list, person_photo]
            )
            
            file_list.change(
                fn=handle_file_display,
                inputs=[name_input, file_list],
                outputs=[out_txt, out_img, out_vid, out_aud]
            )

if __name__ == "__main__":
    demo.launch(css=CUSTOM_CSS)