等待后端更新接口
This commit is contained in:
@@ -133,9 +133,7 @@
|
||||
var source = values || {};
|
||||
var body = {};
|
||||
var memberName = trimOrUndefined(source.memberName);
|
||||
var relationName = source.relationName === undefined || source.relationName === null
|
||||
? undefined
|
||||
: stringValue(source.relationName).trim();
|
||||
var relationName = trimOrUndefined(source.relationName);
|
||||
var roleType = trimOrUndefined(source.roleType);
|
||||
var lineagePersonId = normalizeId(source.lineagePersonId);
|
||||
|
||||
@@ -175,8 +173,8 @@
|
||||
return Boolean(role && role !== 'owner');
|
||||
}
|
||||
|
||||
function canTransferOwner(role) {
|
||||
return role === 'owner';
|
||||
function canTransferOwner(role, canManage) {
|
||||
return role === 'owner' && canManage === true;
|
||||
}
|
||||
|
||||
function buildOwnerTransferBody(targetMemberId) {
|
||||
@@ -246,10 +244,39 @@
|
||||
else if (root.alert) root.alert(message);
|
||||
}
|
||||
|
||||
function setStatus(selector, message) {
|
||||
function setStatus(selector, message, type) {
|
||||
var target = query(selector);
|
||||
|
||||
if (target) target.textContent = message || '';
|
||||
if (!target) return;
|
||||
if (!message) {
|
||||
target.innerHTML = '';
|
||||
return;
|
||||
}
|
||||
if (type && root.ProfileUI && root.ProfileUI.setApiState) {
|
||||
root.ProfileUI.setApiState(target, type, message);
|
||||
return;
|
||||
}
|
||||
target.textContent = message;
|
||||
}
|
||||
|
||||
function setMemberListState(type, message) {
|
||||
var target = query('[data-member-list]');
|
||||
|
||||
if (!target) return;
|
||||
if (root.ProfileUI && root.ProfileUI.setApiState) {
|
||||
root.ProfileUI.setApiState(target, type, message);
|
||||
return;
|
||||
}
|
||||
target.innerHTML = '<div class="api-state api-state--' + escapeHtml(type) + '" data-api-state="' + escapeHtml(type) + '">' +
|
||||
escapeHtml(message) + '</div>';
|
||||
}
|
||||
|
||||
function setPendingButton(selector, pending, pendingLabel) {
|
||||
queryAll(selector).forEach(function (button) {
|
||||
if (!button.dataset.defaultLabel) button.dataset.defaultLabel = button.textContent;
|
||||
button.textContent = pending ? pendingLabel : button.dataset.defaultLabel;
|
||||
button.setAttribute('aria-busy', pending ? 'true' : 'false');
|
||||
});
|
||||
}
|
||||
|
||||
function syncLinks() {
|
||||
@@ -261,6 +288,9 @@
|
||||
queryAll('[data-member-form] input, [data-member-form] select, [data-member-form] button, [data-owner-transfer-form] select, [data-owner-transfer-form] button, [data-member-edit-id], [data-member-remove-id], [data-member-leave]').forEach(function (control) {
|
||||
control.disabled = writePending;
|
||||
});
|
||||
setPendingButton('[data-member-submit]', writePending, '正在保存…');
|
||||
setPendingButton('[data-owner-transfer-submit]', writePending, '正在转让…');
|
||||
setPendingButton('[data-member-leave]', writePending, '正在退出…');
|
||||
}
|
||||
|
||||
function renderLineageOptions(data) {
|
||||
@@ -299,16 +329,21 @@
|
||||
members.forEach(function (member) { membersById[member.memberId] = member; });
|
||||
if (!container) return members;
|
||||
if (!Array.isArray(data) || (data.length && !members.length)) {
|
||||
container.innerHTML = '<div class="api-empty">成员响应缺少稳定 GenealogyMemberVo 字段,请联系后端核对。</div>';
|
||||
setMemberListState('error', '成员响应缺少稳定 GenealogyMemberVo 字段,请联系后端核对。');
|
||||
return [];
|
||||
}
|
||||
container.innerHTML = members.length ? members.map(function (member) {
|
||||
if (!members.length) {
|
||||
setMemberListState('empty', '暂无正常成员');
|
||||
renderTransferOptions(members);
|
||||
return members;
|
||||
}
|
||||
container.innerHTML = members.map(function (member) {
|
||||
return renderMemberRow(member, {
|
||||
actorRole: actorRole,
|
||||
currentMemberId: currentMemberId,
|
||||
canManage: managementAccess
|
||||
});
|
||||
}).join('') : '<div class="api-empty">暂无正常成员</div>';
|
||||
}).join('');
|
||||
renderTransferOptions(members);
|
||||
return members;
|
||||
}
|
||||
@@ -358,8 +393,9 @@
|
||||
}
|
||||
|
||||
function renderNoContext() {
|
||||
if (query('[data-member-list]')) query('[data-member-list]').innerHTML = '<div class="api-empty">请先选择家谱,再管理成员。</div>';
|
||||
setStatus('[data-member-overview]', '当前没有家谱上下文。');
|
||||
setMemberListState('forbidden', '请先选择家谱,再管理成员。');
|
||||
setStatus('[data-member-overview]', '当前没有家谱上下文。', 'forbidden');
|
||||
setStatus('[data-member-action-status]', '请先选择家谱,再进行成员操作。', 'forbidden');
|
||||
queryAll('[data-member-management], [data-member-leave-section], [data-owner-transfer-section]').forEach(function (element) {
|
||||
element.hidden = true;
|
||||
});
|
||||
@@ -381,6 +417,9 @@
|
||||
return;
|
||||
}
|
||||
syncLinks();
|
||||
setStatus('[data-member-overview]', '正在加载家谱和当前权限…', 'loading');
|
||||
setMemberListState('loading', '正在加载成员…');
|
||||
setStatus('[data-member-action-status]', '');
|
||||
try {
|
||||
results = await Promise.all([
|
||||
api.genealogyDetail(genealogyId),
|
||||
@@ -399,13 +438,13 @@
|
||||
setStatus('[data-member-overview]', (detail.genealogyName || '当前家谱') + ' · ' + members.length + ' 位正常成员 · 当前角色:' + (roleLabels[actorRole] || '成员'));
|
||||
queryAll('[data-member-management]').forEach(function (element) { element.hidden = !managementAccess; });
|
||||
queryAll('[data-member-leave-section]').forEach(function (element) { element.hidden = !currentMember || !canLeaveGenealogy(actorRole); });
|
||||
queryAll('[data-owner-transfer-section]').forEach(function (element) { element.hidden = !currentMember || !canTransferOwner(actorRole); });
|
||||
queryAll('[data-owner-transfer-section]').forEach(function (element) { element.hidden = !currentMember || !canTransferOwner(actorRole, managementAccess); });
|
||||
renderLineageOptions(results[3]);
|
||||
renderMembers(results[2]);
|
||||
} catch (error) {
|
||||
if (redirectUnauthorized(api, error)) return;
|
||||
if (query('[data-member-list]')) query('[data-member-list]').innerHTML = '<div class="api-empty">' +
|
||||
(isForbidden(error) ? '当前账号无权查看该家谱成员。' : '成员加载失败,请稍后重试。') + '</div>';
|
||||
setMemberListState(isForbidden(error) ? 'forbidden' : 'error', isForbidden(error) ? '当前账号无权查看该家谱成员。' : '成员加载失败,请稍后重试。');
|
||||
setStatus('[data-member-overview]', isForbidden(error) ? '当前账号无权查看该家谱成员。' : '成员加载失败,请稍后重试。', isForbidden(error) ? 'forbidden' : 'error');
|
||||
showMessage(isForbidden(error) ? '当前账号无权查看该家谱成员。' : (error.message || '成员加载失败'));
|
||||
}
|
||||
}
|
||||
@@ -429,12 +468,12 @@
|
||||
body = buildMemberUpdateBody(getFormValues(form));
|
||||
validation = validateMemberUpdateBody(body);
|
||||
if (validation) {
|
||||
setStatus('[data-member-form-status]', validation);
|
||||
setStatus('[data-member-form-status]', validation, 'error');
|
||||
return;
|
||||
}
|
||||
delete body.invalidLineagePersonId;
|
||||
setWritePending(true);
|
||||
setStatus('[data-member-form-status]', '正在保存成员…');
|
||||
setStatus('[data-member-form-status]', '正在保存成员…', 'loading');
|
||||
try {
|
||||
saved = normalizeMember(await api.updateGenealogyMember(genealogyId, selectedMemberId, body));
|
||||
if (!saved || saved.memberId !== selectedMemberId) throw new Error('成员修改响应缺少稳定 memberId');
|
||||
@@ -445,7 +484,7 @@
|
||||
showMessage('成员信息已更新');
|
||||
} catch (error) {
|
||||
if (redirectUnauthorized(api, error)) return;
|
||||
setStatus('[data-member-form-status]', isForbidden(error) ? '当前账号无权修改该成员。' : (error.message || '成员修改失败'));
|
||||
setStatus('[data-member-form-status]', isForbidden(error) ? '当前账号无权修改该成员。' : (error.message || '成员修改失败'), isForbidden(error) ? 'forbidden' : 'error');
|
||||
} finally {
|
||||
setWritePending(false);
|
||||
}
|
||||
@@ -459,6 +498,7 @@
|
||||
if (writePending || !genealogyId || !target || !managementAccess || !canRemoveMember(actorRole, target.roleType) || redirectUnauthorized(api)) return;
|
||||
if (root.confirm && !root.confirm('确认将“' + memberDisplayName(target) + '”移出当前家谱吗?该操作不会删除其世系人物资料。')) return;
|
||||
setWritePending(true);
|
||||
setStatus('[data-member-action-status]', '正在移出成员…', 'loading');
|
||||
try {
|
||||
await api.removeGenealogyMember(genealogyId, memberId);
|
||||
if ((await fetchAndRenderMembers(api, genealogyId)).some(function (member) { return member.memberId === memberId; })) {
|
||||
@@ -468,6 +508,7 @@
|
||||
showMessage('成员已移出家谱');
|
||||
} catch (error) {
|
||||
if (redirectUnauthorized(api, error)) return;
|
||||
setStatus('[data-member-action-status]', isForbidden(error) ? '当前账号无权移出该成员。' : (error.message || '移出成员失败'), isForbidden(error) ? 'forbidden' : 'error');
|
||||
showMessage(isForbidden(error) ? '当前账号无权移出该成员。' : (error.message || '移出成员失败'));
|
||||
} finally {
|
||||
setWritePending(false);
|
||||
@@ -481,11 +522,13 @@
|
||||
if (writePending || !genealogyId || !currentMemberId || !canLeaveGenealogy(actorRole) || redirectUnauthorized(api)) return;
|
||||
if (root.confirm && !root.confirm('确认退出当前家谱吗?退出后需重新受邀才能进入。世系人物资料不会被删除。')) return;
|
||||
setWritePending(true);
|
||||
setStatus('[data-member-action-status]', '正在退出当前家谱…', 'loading');
|
||||
try {
|
||||
await api.leaveGenealogy(genealogyId);
|
||||
if (root.location) root.location.href = 'profile-families.html';
|
||||
} catch (error) {
|
||||
if (redirectUnauthorized(api, error)) return;
|
||||
setStatus('[data-member-action-status]', isForbidden(error) ? '当前账号无权退出该家谱。' : (error.message || '退出家谱失败'), isForbidden(error) ? 'forbidden' : 'error');
|
||||
showMessage(isForbidden(error) ? '当前账号无权退出该家谱。' : (error.message || '退出家谱失败'));
|
||||
} finally {
|
||||
setWritePending(false);
|
||||
@@ -499,21 +542,21 @@
|
||||
var validation = validateOwnerTransferBody(body, currentMemberId);
|
||||
var target = membersById[body.targetMemberId];
|
||||
|
||||
if (writePending || !genealogyId || !canTransferOwner(actorRole) || redirectUnauthorized(api)) return;
|
||||
if (writePending || !genealogyId || !canTransferOwner(actorRole, managementAccess) || redirectUnauthorized(api)) return;
|
||||
if (validation || !target) {
|
||||
setStatus('[data-owner-transfer-status]', validation || '请选择成员列表中的新谱主');
|
||||
setStatus('[data-owner-transfer-status]', validation || '请选择成员列表中的新谱主', 'error');
|
||||
return;
|
||||
}
|
||||
if (root.confirm && !root.confirm('确认将谱主转让给“' + memberDisplayName(target) + '”吗?转让后当前账号将变为管理员。')) return;
|
||||
setWritePending(true);
|
||||
setStatus('[data-owner-transfer-status]', '正在转让谱主…');
|
||||
setStatus('[data-owner-transfer-status]', '正在转让谱主…', 'loading');
|
||||
try {
|
||||
await api.transferGenealogyOwner(genealogyId, body);
|
||||
await loadPage();
|
||||
setStatus('[data-owner-transfer-status]', '谱主已转让');
|
||||
} catch (error) {
|
||||
if (redirectUnauthorized(api, error)) return;
|
||||
setStatus('[data-owner-transfer-status]', isForbidden(error) ? '只有当前谱主可以执行转让。' : (error.message || '谱主转让失败'));
|
||||
setStatus('[data-owner-transfer-status]', isForbidden(error) ? '只有当前谱主可以执行转让。' : (error.message || '谱主转让失败'), isForbidden(error) ? 'forbidden' : 'error');
|
||||
} finally {
|
||||
setWritePending(false);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user