Browse Source

commit 优化人员录入便捷性

Hai Lin 3 weeks ago
parent
commit
0f7b99dc7d
2 changed files with 315 additions and 85 deletions
  1. 15 4
      app.py
  2. 300 81
      templates/add_member.html

+ 15 - 4
app.py

@@ -25,8 +25,8 @@ os.makedirs(app.config['UPLOAD_FOLDER'], exist_ok=True)
 DB_CONFIG = {
 DB_CONFIG = {
     "host": "rm-f8ze60yirdj8786u2wo.mysql.rds.aliyuncs.com",
     "host": "rm-f8ze60yirdj8786u2wo.mysql.rds.aliyuncs.com",
     "port": 3306,
     "port": 3306,
-    "user": "csqz",
-    "password": "csqz@2026",
+    "user": "root",
+    "password": "csqz@20255",
     "db": "csqz-client",
     "db": "csqz-client",
     "charset": "utf8mb4",
     "charset": "utf8mb4",
     "cursorclass": pymysql.cursors.DictCursor
     "cursorclass": pymysql.cursors.DictCursor
@@ -819,7 +819,8 @@ def get_members():
                               (f'%{search}%', f'%{search}%'))
                               (f'%{search}%', f'%{search}%'))
             else:
             else:
                 cursor.execute("SELECT COUNT(*) as total FROM family_member_info")
                 cursor.execute("SELECT COUNT(*) as total FROM family_member_info")
-            total = cursor.fetchone()['total']
+            total_result = cursor.fetchone()
+            total = total_result['total'] if total_result else 0
             
             
             # Get members for current page
             # Get members for current page
             if search:
             if search:
@@ -830,7 +831,17 @@ def get_members():
                               (per_page, offset))
                               (per_page, offset))
             members = cursor.fetchall()
             members = cursor.fetchall()
             
             
-            return jsonify({"members": members, "total": total})
+            # Convert to list of dictionaries if needed
+            members_list = []
+            for member in members:
+                members_list.append({
+                    'id': member['id'],
+                    'name': member['name'],
+                    'simplified_name': member['simplified_name'],
+                    'sex': member['sex']
+                })
+            
+            return jsonify({"members": members_list, "total": total})
     except Exception as e:
     except Exception as e:
         return jsonify({"success": False, "message": f"获取成员失败: {e}"}), 500
         return jsonify({"success": False, "message": f"获取成员失败: {e}"}), 500
     finally:
     finally:

+ 300 - 81
templates/add_member.html

@@ -79,6 +79,20 @@
     .filter-controls input[type=range] { width: 80px; }
     .filter-controls input[type=range] { width: 80px; }
     .page-nav { margin-bottom: 10px; display: flex; gap: 10px; align-items: center; }
     .page-nav { margin-bottom: 10px; display: flex; gap: 10px; align-items: center; }
     .section-title { border-left: 4px solid #0d6efd; padding-left: 10px; margin: 25px 0 15px; font-weight: bold; color: #333; }
     .section-title { border-left: 4px solid #0d6efd; padding-left: 10px; margin: 25px 0 15px; font-weight: bold; color: #333; }
+    
+    .father-lineage-hint {
+        background-color: #f8f9fa;
+        border-left: 4px solid #17a2b8;
+        padding: 8px 12px;
+        border-radius: 4px;
+        font-size: 14px;
+        margin-top: 8px;
+        margin-bottom: 12px;
+    }
+    
+    .father-lineage-hint .text-info {
+        color: #17a2b8;
+    }
 </style>
 </style>
 {% endblock %}
 {% endblock %}
 
 
@@ -1263,29 +1277,77 @@
             if (person.matches.father && person.matches.father.length > 0) {
             if (person.matches.father && person.matches.father.length > 0) {
                 // Pick the first one for now (could show UI to choose if multiple)
                 // Pick the first one for now (could show UI to choose if multiple)
                 const father = person.matches.father[0];
                 const father = person.matches.father[0];
-                const relSelect = form.querySelector('[name="related_mid"]');
                 const relTypeSelect = form.querySelector('[name="relation_type"]');
                 const relTypeSelect = form.querySelector('[name="relation_type"]');
                 
                 
-                if (relSelect && relTypeSelect) {
-                    if (typeof tomSelectInstance !== 'undefined' && tomSelectInstance) {
-                        tomSelectInstance.setValue(father.id);
-                    } else {
-                        relSelect.value = father.id;
-                    }
+                if (relTypeSelect) {
+                    // Set the related member
+                    document.getElementById('related-member-display').value = father.name;
+                    document.getElementById('related_mid').value = father.id;
+                    
+                    // Set relation type to father
                     relTypeSelect.value = '1'; // 父子
                     relTypeSelect.value = '1'; // 父子
-                    // Trigger change event if needed by other logic (not needed here yet)
+                    
+                    // Trigger the lineage generation reference display
+                    const relatedMid = document.getElementById('related_mid').value;
+                    if (relTypeSelect.value == 1 && relatedMid) {
+                        fetch(`/manager/api/member/${relatedMid}`)
+                            .then(response => response.json())
+                            .then(data => {
+                                if (data.member && data.member.name_word_generation) {
+                                    // 显示父亲的世系世代
+                                    const lineageContainer = document.getElementById('lineage-generations-container');
+                                    const fatherLineageDiv = document.getElementById('father-lineage');
+                                    
+                                    if (!fatherLineageDiv) {
+                                        const newDiv = document.createElement('div');
+                                        newDiv.id = 'father-lineage';
+                                        newDiv.className = 'father-lineage-hint';
+                                        newDiv.innerHTML = `
+                                            <div class="d-flex align-items-center">
+                                                <i class="bi bi-info-circle me-2 text-info"></i>
+                                                <div>
+                                                    <strong class="text-info">父亲世系世代参考:</strong>
+                                                    <span>${data.member.name_word_generation}</span>
+                                                </div>
+                                            </div>
+                                        `;
+                                        // Find the add button container
+                                        const addButtonContainer = document.querySelector('#lineage-generations-container .d-flex.justify-content-between.align-items-center');
+                                        if (addButtonContainer) {
+                                            // Insert after the add button container
+                                            addButtonContainer.parentNode.insertBefore(newDiv, addButtonContainer.nextSibling);
+                                        } else if (lineageContainer.firstChild) {
+                                            // Insert after the first child
+                                            lineageContainer.insertBefore(newDiv, lineageContainer.firstChild.nextSibling);
+                                        } else {
+                                            // Append to container
+                                            lineageContainer.appendChild(newDiv);
+                                        }
+                                    } else {
+                                        fatherLineageDiv.innerHTML = `
+                                            <div class="d-flex align-items-center">
+                                                <i class="bi bi-info-circle me-2 text-info"></i>
+                                                <div>
+                                                    <strong class="text-info">父亲世系世代参考:</strong>
+                                                    <span>${data.member.name_word_generation}</span>
+                                                </div>
+                                            </div>
+                                        `;
+                                    }
+                                }
+                            });
+                    }
                 }
                 }
             } else if (person.matches.spouse && person.matches.spouse.length > 0) {
             } else if (person.matches.spouse && person.matches.spouse.length > 0) {
                 const spouse = person.matches.spouse[0];
                 const spouse = person.matches.spouse[0];
-                const relSelect = form.querySelector('[name="related_mid"]');
                 const relTypeSelect = form.querySelector('[name="relation_type"]');
                 const relTypeSelect = form.querySelector('[name="relation_type"]');
                 
                 
-                if (relSelect && relTypeSelect) {
-                    if (typeof tomSelectInstance !== 'undefined' && tomSelectInstance) {
-                        tomSelectInstance.setValue(spouse.id);
-                    } else {
-                        relSelect.value = spouse.id;
-                    }
+                if (relTypeSelect) {
+                    // Set the related member
+                    document.getElementById('related-member-display').value = spouse.name;
+                    document.getElementById('related_mid').value = spouse.id;
+                    
+                    // Set relation type to spouse
                     relTypeSelect.value = '10'; // 夫妻
                     relTypeSelect.value = '10'; // 夫妻
                 }
                 }
             }
             }
@@ -1863,50 +1925,135 @@
     window.checkSpouseInNotes = function() {
     window.checkSpouseInNotes = function() {
         if (!notesInput || !sexSelect) return;
         if (!notesInput || !sexSelect) return;
         
         
-        // Only trigger if female
+        const val = notesInput.value;
+        
+        // Check for father information
+        const fatherMatch = val.match(/父亲[::\s]*([^\s;;,,。]+)/);
+        if (fatherMatch && fatherMatch[1]) {
+            const fatherName = fatherMatch[1].trim();
+            const relationTypeSelect = document.querySelector('select[name="relation_type"]');
+            
+            if (relationTypeSelect) {
+                // Find the father in the members list
+                fetch(`/manager/api/members?search=${encodeURIComponent(fatherName)}`) 
+                    .then(response => response.json())
+                    .then(data => {
+                        if (data.members && data.members.length > 0) {
+                            // Find the best match
+                            let bestMatch = null;
+                            for (const member of data.members) {
+                                const optName = member.name;
+                                const normalizedOpt = optName.replace(/公$/, '').replace(/^留/, '');
+                                const normalizedFather = fatherName.replace(/公$/, '').replace(/^留/, '');
+                                
+                                if (optName === fatherName || normalizedOpt === normalizedFather ||
+                                    (normalizedOpt && normalizedFather && (normalizedOpt.includes(normalizedFather) || normalizedFather.includes(normalizedOpt)))) {
+                                    bestMatch = member;
+                                    break;
+                                }
+                            }
+                            
+                            if (bestMatch) {
+                                // Set the related member
+                                document.getElementById('related-member-display').value = bestMatch.name;
+                                document.getElementById('related_mid').value = bestMatch.id;
+                                
+                                // Set relation type to father
+                                relationTypeSelect.value = '1';
+                                
+                                // Trigger the lineage generation reference display
+                                const relatedMid = document.getElementById('related_mid').value;
+                                if (relationTypeSelect.value == 1 && relatedMid) {
+                                    fetch(`/manager/api/member/${relatedMid}`)
+                                        .then(response => response.json())
+                                        .then(data => {
+                                            if (data.member && data.member.name_word_generation) {
+                                                // 显示父亲的世系世代
+                                                const lineageContainer = document.getElementById('lineage-generations-container');
+                                                const fatherLineageDiv = document.getElementById('father-lineage');
+                                                
+                                                if (!fatherLineageDiv) {
+                                                    const newDiv = document.createElement('div');
+                                                    newDiv.id = 'father-lineage';
+                                                    newDiv.className = 'father-lineage-hint';
+                                                    newDiv.innerHTML = `
+                                                        <div class="d-flex align-items-center">
+                                                            <i class="bi bi-info-circle me-2 text-info"></i>
+                                                            <div>
+                                                                <strong class="text-info">父亲世系世代参考:</strong>
+                                                                <span>${data.member.name_word_generation}</span>
+                                                            </div>
+                                                        </div>
+                                                    `;
+                                                    // Find the add button container
+                                                    const addButtonContainer = document.querySelector('#lineage-generations-container .d-flex.justify-content-between.align-items-center');
+                                                    if (addButtonContainer) {
+                                                        // Insert after the add button container
+                                                        addButtonContainer.parentNode.insertBefore(newDiv, addButtonContainer.nextSibling);
+                                                    } else if (lineageContainer.firstChild) {
+                                                        // Insert after the first child
+                                                        lineageContainer.insertBefore(newDiv, lineageContainer.firstChild.nextSibling);
+                                                    } else {
+                                                        // Append to container
+                                                        lineageContainer.appendChild(newDiv);
+                                                    }
+                                                } else {
+                                                    fatherLineageDiv.innerHTML = `
+                                                        <div class="d-flex align-items-center">
+                                                            <i class="bi bi-info-circle me-2 text-info"></i>
+                                                            <div>
+                                                                <strong class="text-info">父亲世系世代参考:</strong>
+                                                                <span>${data.member.name_word_generation}</span>
+                                                            </div>
+                                                        </div>
+                                                    `;
+                                                }
+                                            }
+                                        });
+                                }
+                            }
+                        }
+                    });
+            }
+        }
+        
+        // Only check for spouse if female
         if (sexSelect.value === '2') {
         if (sexSelect.value === '2') {
-            const val = notesInput.value;
-            // Match cases like "配偶:张三", "配偶:张三", "配偶 张三", "配偶张三"
-            // We use a robust regex to get the word after 配偶
-            const match = val.match(/配偶[::\s]*([^\s;;,,。]+)/);
-            if (match && match[1]) {
-                const spouseName = match[1].trim();
-                const normalizedSpouse = spouseName.replace(/公$/, '').replace(/^留/, '');
-                const relatedSelect = document.querySelector('select[name="related_mid"]');
+            const spouseMatch = val.match(/配偶[::\s]*([^\s;;,,。]+)/);
+            if (spouseMatch && spouseMatch[1]) {
+                const spouseName = spouseMatch[1].trim();
                 const relationTypeSelect = document.querySelector('select[name="relation_type"]');
                 const relationTypeSelect = document.querySelector('select[name="relation_type"]');
                 
                 
-                if (relatedSelect && relationTypeSelect) {
-                    for (let i = 0; i < relatedSelect.options.length; i++) {
-                        const opt = relatedSelect.options[i];
-                        if (!opt.value) continue;
-                        
-                        const optText = opt.text.trim();
-                        // Extract name before " (ID:" robustly
-                        const optName = optText.replace(/\s*\(ID:.*$/, '').trim();
-                        const normalizedOpt = optName.replace(/公$/, '').replace(/^留/, '');
-                        
-                        // Match exact or without '公' suffix and without '留' prefix
-                        if (optName === spouseName || normalizedOpt === normalizedSpouse || 
-                            (normalizedOpt && normalizedSpouse && (normalizedOpt.includes(normalizedSpouse) || normalizedSpouse.includes(normalizedOpt)))) {
-                            // If not already selected, select it and set relation to Spouse
-                            if (relatedSelect.value !== opt.value) {
-                                if (typeof tomSelectInstance !== 'undefined' && tomSelectInstance) {
-                                    tomSelectInstance.setValue(opt.value);
-                                } else {
-                                    relatedSelect.value = opt.value;
+                if (relationTypeSelect) {
+                    // Find the spouse in the members list
+                    fetch(`/manager/api/members?search=${encodeURIComponent(spouseName)}`) 
+                        .then(response => response.json())
+                        .then(data => {
+                            if (data.members && data.members.length > 0) {
+                                // Find the best match
+                                let bestMatch = null;
+                                for (const member of data.members) {
+                                    const optName = member.name;
+                                    const normalizedOpt = optName.replace(/公$/, '').replace(/^留/, '');
+                                    const normalizedSpouse = spouseName.replace(/公$/, '').replace(/^留/, '');
+                                    
+                                    if (optName === spouseName || normalizedOpt === normalizedSpouse ||
+                                        (normalizedOpt && normalizedSpouse && (normalizedOpt.includes(normalizedSpouse) || normalizedSpouse.includes(normalizedOpt)))) {
+                                        bestMatch = member;
+                                        break;
+                                    }
                                 }
                                 }
-                                relationTypeSelect.value = '10'; // 10 is Spouse
                                 
                                 
-                                // Optional visual feedback to user
-                                notesInput.style.transition = "background-color 0.3s";
-                                notesInput.style.backgroundColor = "#e8f5e9";
-                                setTimeout(() => notesInput.style.backgroundColor = "", 1000);
-                                
-                                console.log("Auto-linked spouse: ", optName);
+                                if (bestMatch) {
+                                    // Set the related member
+                                    document.getElementById('related-member-display').value = bestMatch.name;
+                                    document.getElementById('related_mid').value = bestMatch.id;
+                                    
+                                    // Set relation type to spouse
+                                    relationTypeSelect.value = '10';
+                                }
                             }
                             }
-                            break;
-                        }
-                    }
+                        });
                 }
                 }
             }
             }
         }
         }
@@ -1996,20 +2143,50 @@
 
 
     // 加载成员数据
     // 加载成员数据
     function loadMembers(page = 1, search = '') {
     function loadMembers(page = 1, search = '') {
+        console.log('Loading members...', { page, search });
         fetch(`/manager/api/members?page=${page}&search=${encodeURIComponent(search)}`)
         fetch(`/manager/api/members?page=${page}&search=${encodeURIComponent(search)}`)
-            .then(response => response.json())
+            .then(response => {
+                console.log('Response status:', response.status);
+                return response.json();
+            })
             .then(data => {
             .then(data => {
-                membersData = data.members;
-                totalMembers = data.total;
-                totalPages = Math.ceil(totalMembers / 10);
-                currentPage = page;
-                
-                // 更新成员列表
-                updateMemberList();
-                // 更新分页
-                updatePagination();
-                // 更新总数
-                document.getElementById('total-members').textContent = totalMembers;
+                console.log('Response data:', data);
+                // Check if it's an error response
+                if (data.message && data.success === false) {
+                    console.error('API error:', data.message);
+                    // If unauthorized, redirect to login
+                    if (data.message === 'Unauthorized') {
+                        window.location.href = '/manager/login';
+                    }
+                    return;
+                }
+                // Handle success response - check if members and total exist
+                if (data.members !== undefined && data.total !== undefined) {
+                    membersData = data.members;
+                    totalMembers = data.total;
+                    totalPages = Math.ceil(totalMembers / 10);
+                    currentPage = page;
+                    
+                    // 更新成员列表
+                    updateMemberList();
+                    // 更新分页
+                    updatePagination();
+                    // 更新总数
+                    document.getElementById('total-members').textContent = totalMembers;
+                } else {
+                    console.error('Invalid response structure:', data);
+                    // Set default values
+                    membersData = [];
+                    totalMembers = 0;
+                    totalPages = 1;
+                    currentPage = 1;
+                    updateMemberList();
+                    updatePagination();
+                    document.getElementById('total-members').textContent = 0;
+                }
+            })
+            .catch(error => {
+                console.error('Error loading members:', error);
             });
             });
     }
     }
 
 
@@ -2023,17 +2200,19 @@
             return;
             return;
         }
         }
         
         
-        membersData.forEach(member => {
+        membersData.forEach(function(member) {
             const item = document.createElement('div');
             const item = document.createElement('div');
             item.className = 'list-group-item list-group-item-action';
             item.className = 'list-group-item list-group-item-action';
-            item.onclick = () => selectMember(member);
+            item.onclick = function() {
+                selectMemberById(member.id);
+            };
             item.innerHTML = `
             item.innerHTML = `
                 <div class="d-flex justify-content-between align-items-center">
                 <div class="d-flex justify-content-between align-items-center">
                     <div>
                     <div>
                         <h6 class="mb-0">${member.name}</h6>
                         <h6 class="mb-0">${member.name}</h6>
                         <small class="text-muted">ID: ${member.id} | ${member.sex === 1 ? '男' : '女'}</small>
                         <small class="text-muted">ID: ${member.id} | ${member.sex === 1 ? '男' : '女'}</small>
                     </div>
                     </div>
-                    <button type="button" class="btn btn-sm btn-outline-primary" onclick="event.stopPropagation(); selectMember(member);">
+                    <button type="button" class="btn btn-sm btn-outline-primary" onclick="event.stopPropagation(); selectMemberById(${member.id});">
                         选择
                         选择
                     </button>
                     </button>
                 </div>
                 </div>
@@ -2057,7 +2236,7 @@
         for (let i = 1; i <= totalPages; i++) {
         for (let i = 1; i <= totalPages; i++) {
             const li = document.createElement('li');
             const li = document.createElement('li');
             li.className = `page-item ${i === currentPage ? 'active' : ''}`;
             li.className = `page-item ${i === currentPage ? 'active' : ''}`;
-            li.innerHTML = `<a class="page-link" href="#" onclick="changePage(${i})"><onclick="changePage(${i})">${i}</a>`;
+            li.innerHTML = `<a class="page-link" href="#" onclick="changePage(${i})">${i}</a>`;
             pagination.appendChild(li);
             pagination.appendChild(li);
         }
         }
         
         
@@ -2100,23 +2279,34 @@
                         if (!fatherLineageDiv) {
                         if (!fatherLineageDiv) {
                             const newDiv = document.createElement('div');
                             const newDiv = document.createElement('div');
                             newDiv.id = 'father-lineage';
                             newDiv.id = 'father-lineage';
-                            newDiv.className = 'alert alert-info alert-sm mb-3 p-2';
+                            newDiv.className = 'father-lineage-hint';
                             newDiv.innerHTML = `
                             newDiv.innerHTML = `
                                 <div class="d-flex align-items-center">
                                 <div class="d-flex align-items-center">
-                                    <i class="bi bi-info-circle me-2"></i>
+                                    <i class="bi bi-info-circle me-2 text-info"></i>
                                     <div>
                                     <div>
-                                        <strong>父亲世系世代参考:</strong>
+                                        <strong class="text-info">父亲世系世代参考:</strong>
                                         <span>${data.member.name_word_generation}</span>
                                         <span>${data.member.name_word_generation}</span>
                                     </div>
                                     </div>
                                 </div>
                                 </div>
                             `;
                             `;
-                            lineageContainer.insertBefore(newDiv, lineageContainer.firstChild);
+                            // Find the add button container
+                            const addButtonContainer = document.querySelector('#lineage-generations-container .d-flex.justify-content-between.align-items-center');
+                            if (addButtonContainer) {
+                                // Insert after the add button container
+                                addButtonContainer.parentNode.insertBefore(newDiv, addButtonContainer.nextSibling);
+                            } else if (lineageContainer.firstChild) {
+                                // Insert after the first child
+                                lineageContainer.insertBefore(newDiv, lineageContainer.firstChild.nextSibling);
+                            } else {
+                                // Append to container
+                                lineageContainer.appendChild(newDiv);
+                            }
                         } else {
                         } else {
                             fatherLineageDiv.innerHTML = `
                             fatherLineageDiv.innerHTML = `
                                 <div class="d-flex align-items-center">
                                 <div class="d-flex align-items-center">
-                                    <i class="bi bi-info-circle me-2"></i>
+                                    <i class="bi bi-info-circle me-2 text-info"></i>
                                     <div>
                                     <div>
-                                        <strong>父亲世系世代参考:</strong>
+                                        <strong class="text-info">父亲世系世代参考:</strong>
                                         <span>${data.member.name_word_generation}</span>
                                         <span>${data.member.name_word_generation}</span>
                                     </div>
                                     </div>
                                 </div>
                                 </div>
@@ -2130,6 +2320,24 @@
         const modal = bootstrap.Modal.getInstance(document.getElementById('memberSelectModal'));
         const modal = bootstrap.Modal.getInstance(document.getElementById('memberSelectModal'));
         modal.hide();
         modal.hide();
     }
     }
+    
+    // 通过ID选择成员
+    function selectMemberById(memberId) {
+        // 先在当前加载的成员中查找
+        const member = membersData.find(m => m.id === memberId);
+        if (member) {
+            selectMember(member);
+        } else {
+            // 如果没找到,从API获取
+            fetch(`/manager/api/member/${memberId}`)
+                .then(response => response.json())
+                .then(data => {
+                    if (data.member) {
+                        selectMember(data.member);
+                    }
+                });
+        }
+    }
 
 
     // 监听关系类型变化
     // 监听关系类型变化
     document.addEventListener('DOMContentLoaded', function() {
     document.addEventListener('DOMContentLoaded', function() {
@@ -2150,23 +2358,34 @@
                                 if (!fatherLineageDiv) {
                                 if (!fatherLineageDiv) {
                                     const newDiv = document.createElement('div');
                                     const newDiv = document.createElement('div');
                                     newDiv.id = 'father-lineage';
                                     newDiv.id = 'father-lineage';
-                                    newDiv.className = 'alert alert-info alert-sm mb-3 p-2';
+                                    newDiv.className = 'father-lineage-hint';
                                     newDiv.innerHTML = `
                                     newDiv.innerHTML = `
                                         <div class="d-flex align-items-center">
                                         <div class="d-flex align-items-center">
-                                            <i class="bi bi-info-circle me-2"></i>
+                                            <i class="bi bi-info-circle me-2 text-info"></i>
                                             <div>
                                             <div>
-                                                <strong>父亲世系世代参考:</strong>
+                                                <strong class="text-info">父亲世系世代参考:</strong>
                                                 <span>${data.member.name_word_generation}</span>
                                                 <span>${data.member.name_word_generation}</span>
                                             </div>
                                             </div>
                                         </div>
                                         </div>
                                     `;
                                     `;
-                                    lineageContainer.insertBefore(newDiv, lineageContainer.firstChild);
+                                    // Find the add button container
+                                    const addButtonContainer = document.querySelector('#lineage-generations-container .d-flex.justify-content-between.align-items-center');
+                                    if (addButtonContainer) {
+                                        // Insert after the add button container
+                                        addButtonContainer.parentNode.insertBefore(newDiv, addButtonContainer.nextSibling);
+                                    } else if (lineageContainer.firstChild) {
+                                        // Insert after the first child
+                                        lineageContainer.insertBefore(newDiv, lineageContainer.firstChild.nextSibling);
+                                    } else {
+                                        // Append to container
+                                        lineageContainer.appendChild(newDiv);
+                                    }
                                 } else {
                                 } else {
                                     fatherLineageDiv.innerHTML = `
                                     fatherLineageDiv.innerHTML = `
                                         <div class="d-flex align-items-center">
                                         <div class="d-flex align-items-center">
-                                            <i class="bi bi-info-circle me-2"></i>
+                                            <i class="bi bi-info-circle me-2 text-info"></i>
                                             <div>
                                             <div>
-                                                <strong>父亲世系世代参考:</strong>
+                                                <strong class="text-info">父亲世系世代参考:</strong>
                                                 <span>${data.member.name_word_generation}</span>
                                                 <span>${data.member.name_word_generation}</span>
                                             </div>
                                             </div>
                                         </div>
                                         </div>