|
|
@@ -183,14 +183,13 @@
|
|
|
<div class="row g-3 mb-4">
|
|
|
<div class="col-md-5">
|
|
|
<label class="form-label">关联成员</label>
|
|
|
- <select name="related_mid" class="form-select">
|
|
|
- <option value="">-- 请选择 --</option>
|
|
|
- {% for m in all_members %}
|
|
|
- <option value="{{ m.id }}" data-birthday="{{ m.birthday }}" {{ 'selected' if current_relation and current_relation.parent_mid == m.id else '' }}>
|
|
|
- {{ m.name }} (ID: {{ m.id }})
|
|
|
- </option>
|
|
|
- {% endfor %}
|
|
|
- </select>
|
|
|
+ <div class="input-group">
|
|
|
+ <input type="text" id="related-member-display" class="form-control" placeholder="点击选择关联成员" readonly value="{{ selected_member_name }}">
|
|
|
+ <input type="hidden" name="related_mid" id="related_mid" value="{{ current_relation.parent_mid if current_relation else '' }}">
|
|
|
+ <button type="button" class="btn btn-outline-primary" data-bs-toggle="modal" data-bs-target="#memberSelectModal">
|
|
|
+ <i class="bi bi-search"></i>
|
|
|
+ </button>
|
|
|
+ </div>
|
|
|
</div>
|
|
|
<div class="col-md-4">
|
|
|
<label class="form-label">关系类型</label>
|
|
|
@@ -414,12 +413,60 @@
|
|
|
<button onclick="nextImage()" class="btn btn-sm btn-outline-secondary">下一张</button>
|
|
|
</div>
|
|
|
</div>
|
|
|
+
|
|
|
+ <!-- 成员选择弹窗 -->
|
|
|
+ <div class="modal fade" id="memberSelectModal" tabindex="-1" aria-hidden="true">
|
|
|
+ <div class="modal-dialog modal-lg">
|
|
|
+ <div class="modal-content">
|
|
|
+ <div class="modal-header">
|
|
|
+ <h5 class="modal-title"><i class="bi bi-people me-2"></i>选择关联成员</h5>
|
|
|
+ <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
|
|
+ </div>
|
|
|
+ <div class="modal-body">
|
|
|
+ <div class="mb-4">
|
|
|
+ <div class="input-group">
|
|
|
+ <input type="text" id="member-search" class="form-control" placeholder="搜索成员姓名(支持繁体和简体)">
|
|
|
+ <button type="button" class="btn btn-outline-primary" onclick="searchMembers()">
|
|
|
+ <i class="bi bi-search"></i> 搜索
|
|
|
+ </button>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div id="member-list" class="list-group mb-4 max-h-96 overflow-y-auto">
|
|
|
+ <!-- 成员列表将通过JavaScript动态生成 -->
|
|
|
+ </div>
|
|
|
+ <div class="d-flex justify-content-between align-items-center">
|
|
|
+ <div class="text-muted small">共 <span id="total-members">0</span> 个成员</div>
|
|
|
+ <nav>
|
|
|
+ <ul class="pagination pagination-sm">
|
|
|
+ <li class="page-item disabled">
|
|
|
+ <a class="page-link" href="#" onclick="changePage(0)">上一页</a>
|
|
|
+ </li>
|
|
|
+ <li class="page-item active">
|
|
|
+ <a class="page-link" href="#" onclick="changePage(1)">1</a>
|
|
|
+ </li>
|
|
|
+ <li class="page-item">
|
|
|
+ <a class="page-link" href="#" onclick="changePage(2)">下一页</a>
|
|
|
+ </li>
|
|
|
+ </ul>
|
|
|
+ </nav>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="modal-footer">
|
|
|
+ <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">取消</button>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
</div>
|
|
|
{% endblock %}
|
|
|
|
|
|
{% block extra_js %}
|
|
|
<script>
|
|
|
let tomSelectInstance = null;
|
|
|
+ let currentPage = 1;
|
|
|
+ let totalPages = 1;
|
|
|
+ let totalMembers = 0;
|
|
|
+ let membersData = [];
|
|
|
function toggleBirthdayUnknown() {
|
|
|
const cb = document.getElementById('birthdayUnknown');
|
|
|
const input = document.querySelector('input[name="birthday"]');
|
|
|
@@ -1946,5 +1993,196 @@
|
|
|
addButton.classList.remove('d-none');
|
|
|
});
|
|
|
});
|
|
|
+
|
|
|
+ // 加载成员数据
|
|
|
+ function loadMembers(page = 1, search = '') {
|
|
|
+ fetch(`/manager/api/members?page=${page}&search=${encodeURIComponent(search)}`)
|
|
|
+ .then(response => response.json())
|
|
|
+ .then(data => {
|
|
|
+ membersData = data.members;
|
|
|
+ totalMembers = data.total;
|
|
|
+ totalPages = Math.ceil(totalMembers / 10);
|
|
|
+ currentPage = page;
|
|
|
+
|
|
|
+ // 更新成员列表
|
|
|
+ updateMemberList();
|
|
|
+ // 更新分页
|
|
|
+ updatePagination();
|
|
|
+ // 更新总数
|
|
|
+ document.getElementById('total-members').textContent = totalMembers;
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ // 更新成员列表
|
|
|
+ function updateMemberList() {
|
|
|
+ const memberList = document.getElementById('member-list');
|
|
|
+ memberList.innerHTML = '';
|
|
|
+
|
|
|
+ if (membersData.length === 0) {
|
|
|
+ memberList.innerHTML = '<div class="list-group-item text-center text-muted">暂无成员数据</div>';
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ membersData.forEach(member => {
|
|
|
+ const item = document.createElement('div');
|
|
|
+ item.className = 'list-group-item list-group-item-action';
|
|
|
+ item.onclick = () => selectMember(member);
|
|
|
+ item.innerHTML = `
|
|
|
+ <div class="d-flex justify-content-between align-items-center">
|
|
|
+ <div>
|
|
|
+ <h6 class="mb-0">${member.name}</h6>
|
|
|
+ <small class="text-muted">ID: ${member.id} | ${member.sex === 1 ? '男' : '女'}</small>
|
|
|
+ </div>
|
|
|
+ <button type="button" class="btn btn-sm btn-outline-primary" onclick="event.stopPropagation(); selectMember(member);">
|
|
|
+ 选择
|
|
|
+ </button>
|
|
|
+ </div>
|
|
|
+ `;
|
|
|
+ memberList.appendChild(item);
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ // 更新分页
|
|
|
+ function updatePagination() {
|
|
|
+ const pagination = document.querySelector('.pagination');
|
|
|
+ pagination.innerHTML = '';
|
|
|
+
|
|
|
+ // 上一页
|
|
|
+ const prevLi = document.createElement('li');
|
|
|
+ prevLi.className = `page-item ${currentPage === 1 ? 'disabled' : ''}`;
|
|
|
+ prevLi.innerHTML = `<a class="page-link" href="#" onclick="changePage(${currentPage - 1})">«</a>`;
|
|
|
+ pagination.appendChild(prevLi);
|
|
|
+
|
|
|
+ // 页码
|
|
|
+ for (let i = 1; i <= totalPages; i++) {
|
|
|
+ const li = document.createElement('li');
|
|
|
+ li.className = `page-item ${i === currentPage ? 'active' : ''}`;
|
|
|
+ li.innerHTML = `<a class="page-link" href="#" onclick="changePage(${i})"><onclick="changePage(${i})">${i}</a>`;
|
|
|
+ pagination.appendChild(li);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 下一页
|
|
|
+ const nextLi = document.createElement('li');
|
|
|
+ nextLi.className = `page-item ${currentPage === totalPages ? 'disabled' : ''}`;
|
|
|
+ nextLi.innerHTML = `<a class="page-link" href="#" onclick="changePage(${currentPage + 1})">»</a>`;
|
|
|
+ pagination.appendChild(nextLi);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 改变页码
|
|
|
+ function changePage(page) {
|
|
|
+ if (page < 1 || page > totalPages) return;
|
|
|
+ const search = document.getElementById('member-search').value;
|
|
|
+ loadMembers(page, search);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 搜索成员
|
|
|
+ function searchMembers() {
|
|
|
+ const search = document.getElementById('member-search').value;
|
|
|
+ loadMembers(1, search);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 选择成员
|
|
|
+ function selectMember(member) {
|
|
|
+ document.getElementById('related-member-display').value = member.name;
|
|
|
+ document.getElementById('related_mid').value = member.id;
|
|
|
+
|
|
|
+ // 检查是否是父子关系,如果是,显示父亲的世系世代
|
|
|
+ const relationType = document.querySelector('select[name="relation_type"]').value;
|
|
|
+ if (relationType == 1) { // 父子关系
|
|
|
+ fetch(`/manager/api/member/${member.id}`)
|
|
|
+ .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 = 'alert alert-info alert-sm mb-3 p-2';
|
|
|
+ newDiv.innerHTML = `
|
|
|
+ <div class="d-flex align-items-center">
|
|
|
+ <i class="bi bi-info-circle me-2"></i>
|
|
|
+ <div>
|
|
|
+ <strong>父亲世系世代参考:</strong>
|
|
|
+ <span>${data.member.name_word_generation}</span>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ `;
|
|
|
+ lineageContainer.insertBefore(newDiv, lineageContainer.firstChild);
|
|
|
+ } else {
|
|
|
+ fatherLineageDiv.innerHTML = `
|
|
|
+ <div class="d-flex align-items-center">
|
|
|
+ <i class="bi bi-info-circle me-2"></i>
|
|
|
+ <div>
|
|
|
+ <strong>父亲世系世代参考:</strong>
|
|
|
+ <span>${data.member.name_word_generation}</span>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ `;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ // 关闭模态框
|
|
|
+ const modal = bootstrap.Modal.getInstance(document.getElementById('memberSelectModal'));
|
|
|
+ modal.hide();
|
|
|
+ }
|
|
|
+
|
|
|
+ // 监听关系类型变化
|
|
|
+ document.addEventListener('DOMContentLoaded', function() {
|
|
|
+ // 监听关系类型变化
|
|
|
+ const relationTypeSelect = document.querySelector('select[name="relation_type"]');
|
|
|
+ if (relationTypeSelect) {
|
|
|
+ relationTypeSelect.addEventListener('change', function() {
|
|
|
+ const relatedMid = document.getElementById('related_mid').value;
|
|
|
+ if (this.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 = 'alert alert-info alert-sm mb-3 p-2';
|
|
|
+ newDiv.innerHTML = `
|
|
|
+ <div class="d-flex align-items-center">
|
|
|
+ <i class="bi bi-info-circle me-2"></i>
|
|
|
+ <div>
|
|
|
+ <strong>父亲世系世代参考:</strong>
|
|
|
+ <span>${data.member.name_word_generation}</span>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ `;
|
|
|
+ lineageContainer.insertBefore(newDiv, lineageContainer.firstChild);
|
|
|
+ } else {
|
|
|
+ fatherLineageDiv.innerHTML = `
|
|
|
+ <div class="d-flex align-items-center">
|
|
|
+ <i class="bi bi-info-circle me-2"></i>
|
|
|
+ <div>
|
|
|
+ <strong>父亲世系世代参考:</strong>
|
|
|
+ <span>${data.member.name_word_generation}</span>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ `;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ // 监听成员选择模态框显示
|
|
|
+ const memberSelectModal = document.getElementById('memberSelectModal');
|
|
|
+ memberSelectModal.addEventListener('shown.bs.modal', function() {
|
|
|
+ loadMembers();
|
|
|
+ });
|
|
|
+ });
|
|
|
</script>
|
|
|
{% endblock %}
|