等待后端更新接口
This commit is contained in:
+126
-37
@@ -15,6 +15,7 @@
|
||||
|
||||
var documentRef = root.document;
|
||||
var recordsById = Object.create(null);
|
||||
var canEditContent = false;
|
||||
var writePending = false;
|
||||
var meritTypes = {
|
||||
donation: '捐赠',
|
||||
@@ -284,17 +285,24 @@
|
||||
return meritId ? url + '&meritId=' + encodeURIComponent(meritId) : url;
|
||||
}
|
||||
|
||||
function canEditRecords(genealogy) {
|
||||
return Boolean(genealogy && (genealogy.canEditContent === true || genealogy.canManage === true));
|
||||
}
|
||||
|
||||
function renderMeritRow(record) {
|
||||
var summary = [meritTypes[record.meritType]];
|
||||
var actions = '<button class="pill" type="button" data-merit-detail-id="' +
|
||||
escapeHtml(record.meritId) + '">查看详情</button>';
|
||||
|
||||
if (record.meritTime) summary.push(record.meritTime);
|
||||
if (record.amount) summary.push('金额:' + record.amount);
|
||||
if (canEditContent) {
|
||||
actions += '<a class="pill" href="' + escapeHtml(buildEditUrl(record.genealogyId, record.meritId)) +
|
||||
'">编辑</a><button class="pill is-danger" type="button" data-merit-delete-id="' +
|
||||
escapeHtml(record.meritId) + '">删除</button>';
|
||||
}
|
||||
return '<article class="module-row merit-row"><div><h3>' + escapeHtml(record.meritTitle) + '</h3><p>' +
|
||||
escapeHtml(record.donorName + ' · ' + summary.join(' · ')) + '</p></div><div class="row-actions">' +
|
||||
'<button class="pill" type="button" data-merit-detail-id="' + escapeHtml(record.meritId) + '">查看详情</button>' +
|
||||
'<a class="pill" href="' + escapeHtml(buildEditUrl(record.genealogyId, record.meritId)) + '">编辑</a>' +
|
||||
'<button class="pill is-danger" type="button" data-merit-delete-id="' + escapeHtml(record.meritId) + '">删除</button>' +
|
||||
'</div></article>';
|
||||
escapeHtml(record.donorName + ' · ' + summary.join(' · ')) + '</p></div><div class="row-actions">' + actions + '</div></article>';
|
||||
}
|
||||
|
||||
function detailValue(label, value) {
|
||||
@@ -302,7 +310,15 @@
|
||||
}
|
||||
|
||||
function renderMeritDetail(record) {
|
||||
if (!record) return '<div class="api-empty">请选择一条功德记录查看详情</div>';
|
||||
var actions = '';
|
||||
|
||||
if (!record) return stateHtml('empty', '请选择一条功德记录查看详情');
|
||||
if (canEditContent) {
|
||||
actions = '<div class="bottom-actions"><a class="btn ghost" href="' +
|
||||
escapeHtml(buildEditUrl(record.genealogyId, record.meritId)) + '">编辑功德记录</a>' +
|
||||
'<button class="btn ghost" type="button" data-merit-delete-id="' +
|
||||
escapeHtml(record.meritId) + '">删除功德记录</button></div>';
|
||||
}
|
||||
return '<div class="form-like merit-detail">' +
|
||||
detailValue('功德人', record.donorName) +
|
||||
detailValue('功德类型', meritTypes[record.meritType]) +
|
||||
@@ -312,9 +328,7 @@
|
||||
detailValue('功德时间', record.meritTime) +
|
||||
detailValue('记录人', record.appUserNickName) +
|
||||
detailValue('备注', record.remark) +
|
||||
'</div><div class="bottom-actions"><a class="btn ghost" href="' +
|
||||
escapeHtml(buildEditUrl(record.genealogyId, record.meritId)) + '">编辑功德记录</a>' +
|
||||
'<button class="btn ghost" type="button" data-merit-delete-id="' + escapeHtml(record.meritId) + '">删除功德记录</button></div>';
|
||||
'</div>' + actions;
|
||||
}
|
||||
|
||||
function showMessage(message) {
|
||||
@@ -332,6 +346,10 @@
|
||||
return Number(error && (error.status || error.code)) === 403;
|
||||
}
|
||||
|
||||
function getApiStateType(error) {
|
||||
return isForbidden(error) ? 'forbidden' : 'error';
|
||||
}
|
||||
|
||||
function redirectUnauthorized(api, error) {
|
||||
if (!shouldRedirectToLogin(api, error)) return false;
|
||||
if (api && api.clearToken) api.clearToken();
|
||||
@@ -341,13 +359,38 @@
|
||||
return true;
|
||||
}
|
||||
|
||||
function setFormStatus(message) {
|
||||
var target = query('[data-merit-form-status]');
|
||||
|
||||
if (target) target.textContent = message || '';
|
||||
function stateHtml(type, message) {
|
||||
if (root.ProfileUI && root.ProfileUI.renderApiState) return root.ProfileUI.renderApiState(type, message);
|
||||
return '<div class="api-state api-state--' + type + '" role="' +
|
||||
(type === 'error' || type === 'forbidden' ? 'alert' : 'status') +
|
||||
'" aria-live="polite">' + escapeHtml(message) + '</div>';
|
||||
}
|
||||
|
||||
function setEditorEnabled(enabled, message) {
|
||||
function setState(container, type, message) {
|
||||
if (!container) return;
|
||||
if (root.ProfileUI && root.ProfileUI.setApiState) {
|
||||
root.ProfileUI.setApiState(container, type, message);
|
||||
return;
|
||||
}
|
||||
container.innerHTML = stateHtml(type, message);
|
||||
}
|
||||
|
||||
function setFormStatus(message, type) {
|
||||
var target = query('[data-merit-form-status]');
|
||||
|
||||
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 setEditorEnabled(enabled, message, type) {
|
||||
var placeholder = query('[data-merit-editor-placeholder]');
|
||||
|
||||
queryAll('[data-merit-editor], [data-merit-editor-action]').forEach(function (element) {
|
||||
@@ -355,15 +398,39 @@
|
||||
});
|
||||
if (placeholder) {
|
||||
placeholder.hidden = Boolean(enabled);
|
||||
if (message) placeholder.textContent = message;
|
||||
if (!enabled && message) {
|
||||
if (type) setState(placeholder, type, message);
|
||||
else placeholder.textContent = message;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function setWritePending(value) {
|
||||
function setEditAccess(enabled) {
|
||||
canEditContent = Boolean(enabled);
|
||||
queryAll('[data-merit-create-link]').forEach(function (element) {
|
||||
element.hidden = !canEditContent;
|
||||
});
|
||||
}
|
||||
|
||||
async function loadCapability(api, genealogyId) {
|
||||
var genealogy = await api.genealogyDetail(genealogyId);
|
||||
|
||||
setEditAccess(canEditRecords(genealogy));
|
||||
return genealogy;
|
||||
}
|
||||
|
||||
function setWritePending(value, label) {
|
||||
var submit = query('[data-merit-form] [type="submit"]');
|
||||
|
||||
writePending = Boolean(value);
|
||||
queryAll('[data-merit-form] button, [data-merit-form] input, [data-merit-form] textarea, [data-merit-form] select, [data-merit-delete-id]').forEach(function (control) {
|
||||
control.disabled = writePending;
|
||||
});
|
||||
if (submit) {
|
||||
if (!submit.dataset.defaultLabel) submit.dataset.defaultLabel = submit.textContent;
|
||||
submit.textContent = writePending && label ? label : submit.dataset.defaultLabel;
|
||||
submit.setAttribute('aria-busy', writePending ? 'true' : 'false');
|
||||
}
|
||||
}
|
||||
|
||||
function syncLinks() {
|
||||
@@ -375,10 +442,11 @@
|
||||
var detail = query('[data-merit-detail]');
|
||||
var message = '请先选择家谱,再查看或维护功德记录。';
|
||||
|
||||
if (list) list.innerHTML = '<div class="api-empty">' + message + '</div>';
|
||||
if (detail) detail.innerHTML = '<div class="api-empty">当前没有家谱上下文。</div>';
|
||||
setEditorEnabled(false, message);
|
||||
setFormStatus(message);
|
||||
setState(list, 'empty', message);
|
||||
setState(detail, 'empty', '当前没有家谱上下文。');
|
||||
setEditAccess(false);
|
||||
setEditorEnabled(false, message, 'empty');
|
||||
setFormStatus(message, 'empty');
|
||||
}
|
||||
|
||||
function requireGenealogyId() {
|
||||
@@ -400,11 +468,11 @@
|
||||
});
|
||||
if (!container) return records;
|
||||
if (!Array.isArray(data) || invalidCount) {
|
||||
container.innerHTML = '<div class="api-empty">功德记录响应缺少稳定 MeritRecordVo 字段,请联系后端核对。</div>';
|
||||
setState(container, 'error', '功德记录响应缺少稳定 MeritRecordVo 字段,请联系后端核对。');
|
||||
return [];
|
||||
}
|
||||
if (!records.length) {
|
||||
container.innerHTML = '<div class="api-empty">暂无功德记录</div>';
|
||||
setState(container, 'empty', '暂无功德记录');
|
||||
return [];
|
||||
}
|
||||
container.innerHTML = records.map(renderMeritRow).join('');
|
||||
@@ -423,6 +491,7 @@
|
||||
var record;
|
||||
|
||||
if (!genealogyId || !normalizeId(meritId) || redirectUnauthorized(api)) return null;
|
||||
setState(query('[data-merit-detail]'), 'loading', '正在加载功德记录详情…');
|
||||
try {
|
||||
record = normalizeMeritRecord(await api.meritRecordDetail(genealogyId, meritId));
|
||||
if (!record) throw new Error('功德记录详情响应缺少稳定 MeritRecordVo 字段');
|
||||
@@ -431,7 +500,11 @@
|
||||
return record;
|
||||
} catch (error) {
|
||||
if (redirectUnauthorized(api, error)) return null;
|
||||
renderDetail(null);
|
||||
setState(
|
||||
query('[data-merit-detail]'),
|
||||
getApiStateType(error),
|
||||
isForbidden(error) ? '当前账号无权查看该功德记录。' : '功德记录详情加载失败,请稍后重试。'
|
||||
);
|
||||
showMessage(isForbidden(error) ? '当前账号无权查看该功德记录。' : (error.message || '功德记录详情加载失败'));
|
||||
return null;
|
||||
}
|
||||
@@ -447,7 +520,9 @@
|
||||
genealogyId = requireGenealogyId();
|
||||
if (!genealogyId) return;
|
||||
syncLinks();
|
||||
setState(query('[data-merit-list]'), 'loading', '正在加载功德记录…');
|
||||
try {
|
||||
await loadCapability(api, genealogyId);
|
||||
records = renderMeritRecords(await api.meritRecords(genealogyId));
|
||||
requestedMeritId = getCurrentMeritId();
|
||||
if (requestedMeritId && recordsById[requestedMeritId]) {
|
||||
@@ -459,11 +534,12 @@
|
||||
}
|
||||
} catch (error) {
|
||||
if (redirectUnauthorized(api, error)) return;
|
||||
if (query('[data-merit-list]')) {
|
||||
query('[data-merit-list]').innerHTML = '<div class="api-empty">' +
|
||||
(isForbidden(error) ? '当前账号无权查看该家谱的功德记录。' : '功德记录加载失败,请稍后重试。') +
|
||||
'</div>';
|
||||
}
|
||||
setEditAccess(false);
|
||||
setState(
|
||||
query('[data-merit-list]'),
|
||||
getApiStateType(error),
|
||||
isForbidden(error) ? '当前账号无权查看该家谱的功德记录。' : '功德记录加载失败,请稍后重试。'
|
||||
);
|
||||
showMessage(isForbidden(error) ? '当前账号无权查看该家谱的功德记录。' : (error.message || '功德记录加载失败'));
|
||||
}
|
||||
}
|
||||
@@ -517,8 +593,11 @@
|
||||
if (!genealogyId) return;
|
||||
meritId = getCurrentMeritId();
|
||||
syncLinks();
|
||||
setEditorEnabled(false, '正在加载功德记录编辑信息…');
|
||||
setEditorEnabled(false, '正在加载功德记录编辑信息…', 'loading');
|
||||
setFormStatus('正在读取家谱权限…', 'loading');
|
||||
try {
|
||||
await loadCapability(api, genealogyId);
|
||||
if (!canEditContent) throw { status: 403, message: '当前账号无权维护该家谱的功德记录。' };
|
||||
if (meritId) {
|
||||
record = normalizeMeritRecord(await api.meritRecordDetail(genealogyId, meritId));
|
||||
if (!record) throw new Error('功德记录详情响应缺少稳定 MeritRecordVo 字段');
|
||||
@@ -526,12 +605,17 @@
|
||||
if (query('[data-merit-editor-title]')) query('[data-merit-editor-title]').textContent = '编辑功德记录';
|
||||
}
|
||||
setEditorEnabled(true);
|
||||
setFormStatus('');
|
||||
} catch (error) {
|
||||
if (redirectUnauthorized(api, error)) return;
|
||||
setEditAccess(false);
|
||||
setEditorEnabled(false, isForbidden(error)
|
||||
? '当前账号无权维护该家谱的功德记录。'
|
||||
: (error.message || '功德记录编辑信息加载失败'));
|
||||
setFormStatus(error.message || '功德记录编辑信息加载失败');
|
||||
: (error.message || '功德记录编辑信息加载失败'), getApiStateType(error));
|
||||
setFormStatus(
|
||||
isForbidden(error) ? '当前账号无权维护该家谱的功德记录。' : (error.message || '功德记录编辑信息加载失败'),
|
||||
getApiStateType(error)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -546,18 +630,19 @@
|
||||
var savedId;
|
||||
var verifiedDetail;
|
||||
|
||||
if (writePending || !genealogyId || redirectUnauthorized(api)) return;
|
||||
if (writePending || !canEditContent || !genealogyId || redirectUnauthorized(api)) return;
|
||||
if (root.AppRichEditor && root.AppRichEditor.syncAll) root.AppRichEditor.syncAll();
|
||||
body = buildMeritRecordBody(getFormValues(form));
|
||||
validation = validateMeritRecordBody(body);
|
||||
if (validation) {
|
||||
setFormStatus(validation);
|
||||
setFormStatus(validation, 'error');
|
||||
return;
|
||||
}
|
||||
delete body.invalidAmount;
|
||||
delete body.invalidAmountPrecision;
|
||||
delete body.invalidSortOrder;
|
||||
setWritePending(true);
|
||||
setFormStatus('正在保存功德记录…');
|
||||
setWritePending(true, '正在保存…');
|
||||
setFormStatus('正在保存功德记录…', 'loading');
|
||||
try {
|
||||
result = meritId
|
||||
? await api.updateMeritRecord(genealogyId, meritId, body)
|
||||
@@ -570,7 +655,10 @@
|
||||
if (root.location) root.location.href = buildListUrl(genealogyId, savedId);
|
||||
} catch (error) {
|
||||
if (redirectUnauthorized(api, error)) return;
|
||||
setFormStatus(isForbidden(error) ? '当前账号无权保存该功德记录。' : (error.message || '功德记录保存失败'));
|
||||
setFormStatus(
|
||||
isForbidden(error) ? '当前账号无权保存该功德记录。' : (error.message || '功德记录保存失败'),
|
||||
getApiStateType(error)
|
||||
);
|
||||
} finally {
|
||||
setWritePending(false);
|
||||
}
|
||||
@@ -581,7 +669,7 @@
|
||||
var genealogyId = requireGenealogyId();
|
||||
var record = recordsById[meritId];
|
||||
|
||||
if (writePending || !genealogyId || !normalizeId(meritId) || redirectUnauthorized(api)) return;
|
||||
if (writePending || !canEditContent || !genealogyId || !normalizeId(meritId) || redirectUnauthorized(api)) return;
|
||||
if (root.confirm && !root.confirm('确认删除“' + (record ? record.meritTitle : '该功德记录') + '”吗?删除后不可恢复。')) return;
|
||||
setWritePending(true);
|
||||
try {
|
||||
@@ -635,6 +723,7 @@
|
||||
validateMeritRecordBody: validateMeritRecordBody,
|
||||
normalizeMeritRecord: normalizeMeritRecord,
|
||||
matchesSavedMerit: matchesSavedMerit,
|
||||
canEditRecords: canEditRecords,
|
||||
isEditableMerit: isEditableMerit,
|
||||
renderMeritDetail: renderMeritDetail,
|
||||
shouldRedirectToLogin: shouldRedirectToLogin,
|
||||
|
||||
Reference in New Issue
Block a user