等待后端更新接口
This commit is contained in:
+80
-28
@@ -192,6 +192,10 @@
|
||||
return articleId ? url + '&articleId=' + encodeURIComponent(articleId) : url;
|
||||
}
|
||||
|
||||
function canEditArticles(genealogy) {
|
||||
return Boolean(genealogy && (genealogy.canEditContent === true || genealogy.canManage === true));
|
||||
}
|
||||
|
||||
function detailValue(label, value) {
|
||||
return '<p><span>' + escapeHtml(label) + '</span><b>' + escapeHtml(value || '未提供') + '</b></p>';
|
||||
}
|
||||
@@ -199,7 +203,7 @@
|
||||
function renderArticleDetail(article) {
|
||||
var actions = '';
|
||||
|
||||
if (!article) return '<div class="api-empty">请选择一篇谱文查看详情</div>';
|
||||
if (!article) return stateHtml('empty', '请选择一篇谱文查看详情');
|
||||
if (canEditContent) {
|
||||
actions = '<div class="bottom-actions"><a class="btn ghost" href="' +
|
||||
escapeHtml(buildEditUrl(article.genealogyId, article.articleId)) + '">编辑谱文</a>' +
|
||||
@@ -256,17 +260,49 @@
|
||||
else if (root.alert) root.alert(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 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 getStateType(message) {
|
||||
if (message.indexOf('无权') >= 0) return 'forbidden';
|
||||
if (/失败|缺少/.test(message)) return 'error';
|
||||
if (/正在|读取中|加载中/.test(message)) return 'loading';
|
||||
return 'empty';
|
||||
}
|
||||
|
||||
function syncLinks() {
|
||||
if (root.ProfileUI && root.ProfileUI.syncGenealogyContextLinks) root.ProfileUI.syncGenealogyContextLinks();
|
||||
}
|
||||
|
||||
function setFormStatus(message) {
|
||||
function setFormStatus(message, type) {
|
||||
var target = query('[data-article-form-status]');
|
||||
|
||||
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 setEditorEnabled(enabled, message) {
|
||||
function setEditorEnabled(enabled, message, type) {
|
||||
var placeholder = query('[data-article-editor-placeholder]');
|
||||
|
||||
queryAll('[data-article-editor], [data-article-editor-action]').forEach(function (element) {
|
||||
@@ -274,15 +310,22 @@
|
||||
});
|
||||
if (placeholder) {
|
||||
placeholder.hidden = Boolean(enabled);
|
||||
if (message) placeholder.textContent = message;
|
||||
if (message) setState(placeholder, type || getStateType(message), message);
|
||||
}
|
||||
}
|
||||
|
||||
function setWritePending(value) {
|
||||
function setWritePending(value, label) {
|
||||
var submit = query('[data-article-form] [type="submit"]');
|
||||
|
||||
writePending = Boolean(value);
|
||||
queryAll('[data-article-form] button, [data-article-form] input, [data-article-form] textarea, [data-article-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 renderNoContext() {
|
||||
@@ -290,10 +333,10 @@
|
||||
var list = query('[data-article-list]');
|
||||
var detail = query('[data-article-detail]');
|
||||
|
||||
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', '当前没有家谱上下文。');
|
||||
setEditorEnabled(false, message, 'empty');
|
||||
setFormStatus(message, 'empty');
|
||||
}
|
||||
|
||||
function requireGenealogyId() {
|
||||
@@ -306,7 +349,7 @@
|
||||
async function loadCapability(api, genealogyId) {
|
||||
var detail = await api.genealogyDetail(genealogyId);
|
||||
|
||||
canEditContent = Boolean(detail && (detail.canEditContent || detail.canManage));
|
||||
canEditContent = canEditArticles(detail);
|
||||
queryAll('[data-article-create-link], [data-article-editor-action]').forEach(function (element) {
|
||||
element.hidden = !canEditContent;
|
||||
});
|
||||
@@ -323,11 +366,11 @@
|
||||
});
|
||||
if (!container) return articles;
|
||||
if (!Array.isArray(data) || (data.length && !articles.length)) {
|
||||
container.innerHTML = '<div class="api-empty">谱文响应缺少稳定 ArticleVo 字段,请联系后端核对。</div>';
|
||||
setState(container, 'error', '谱文响应缺少稳定 ArticleVo 字段,请联系后端核对。');
|
||||
return [];
|
||||
}
|
||||
if (!articles.length) {
|
||||
container.innerHTML = '<div class="api-empty">暂无谱文</div>';
|
||||
setState(container, 'empty', '暂无谱文');
|
||||
return [];
|
||||
}
|
||||
container.innerHTML = articles.map(renderArticleRow).join('');
|
||||
@@ -346,6 +389,7 @@
|
||||
var article;
|
||||
|
||||
if (!genealogyId || !normalizeId(articleId) || redirectUnauthorized(api)) return null;
|
||||
setState(query('[data-article-detail]'), 'loading', '正在加载谱文详情…');
|
||||
try {
|
||||
article = normalizeArticle(await api.articleDetail(genealogyId, articleId));
|
||||
if (!article || article.articleId !== normalizeId(articleId)) {
|
||||
@@ -356,7 +400,8 @@
|
||||
return article;
|
||||
} catch (error) {
|
||||
if (redirectUnauthorized(api, error)) return null;
|
||||
renderDetail(null);
|
||||
setState(query('[data-article-detail]'), isForbidden(error) ? 'forbidden' : 'error',
|
||||
isForbidden(error) ? '当前账号无权查看该谱文。' : '谱文详情加载失败,请稍后重试。');
|
||||
showMessage(isForbidden(error) ? '当前账号无权查看该谱文。' : (error.message || '谱文详情加载失败'));
|
||||
return null;
|
||||
}
|
||||
@@ -372,6 +417,7 @@
|
||||
genealogyId = requireGenealogyId();
|
||||
if (!genealogyId) return;
|
||||
syncLinks();
|
||||
setState(query('[data-article-list]'), 'loading', '正在加载谱文…');
|
||||
try {
|
||||
await loadCapability(api, genealogyId);
|
||||
articles = renderArticles(await api.articles(genealogyId));
|
||||
@@ -381,11 +427,8 @@
|
||||
else renderDetail(null);
|
||||
} catch (error) {
|
||||
if (redirectUnauthorized(api, error)) return;
|
||||
if (query('[data-article-list]')) {
|
||||
query('[data-article-list]').innerHTML = '<div class="api-empty">' +
|
||||
(isForbidden(error) ? '当前账号无权查看该家谱的谱文。' : '谱文加载失败,请稍后重试。') +
|
||||
'</div>';
|
||||
}
|
||||
setState(query('[data-article-list]'), isForbidden(error) ? 'forbidden' : 'error',
|
||||
isForbidden(error) ? '当前账号无权查看该家谱的谱文。' : '谱文加载失败,请稍后重试。');
|
||||
showMessage(isForbidden(error) ? '当前账号无权查看该家谱的谱文。' : (error.message || '谱文加载失败'));
|
||||
}
|
||||
}
|
||||
@@ -438,7 +481,8 @@
|
||||
if (!genealogyId) return;
|
||||
articleId = getCurrentArticleId();
|
||||
syncLinks();
|
||||
setEditorEnabled(false, '正在加载谱文编辑信息…');
|
||||
setEditorEnabled(false, '正在加载谱文编辑信息…', 'loading');
|
||||
setFormStatus('正在读取家谱权限…', 'loading');
|
||||
try {
|
||||
await loadCapability(api, genealogyId);
|
||||
if (!canEditContent) throw { status: 403, message: '当前账号无权维护该家谱的谱文。' };
|
||||
@@ -449,12 +493,16 @@
|
||||
if (query('[data-article-editor-title]')) query('[data-article-editor-title]').textContent = '编辑谱文';
|
||||
}
|
||||
setEditorEnabled(true);
|
||||
setFormStatus('');
|
||||
} catch (error) {
|
||||
if (redirectUnauthorized(api, error)) return;
|
||||
setEditorEnabled(false, isForbidden(error)
|
||||
? '当前账号无权维护该家谱的谱文。'
|
||||
: (error.message || '谱文编辑信息加载失败'));
|
||||
setFormStatus(isForbidden(error) ? '当前账号无权维护该家谱的谱文。' : (error.message || '谱文编辑信息加载失败'));
|
||||
: (error.message || '谱文编辑信息加载失败'), isForbidden(error) ? 'forbidden' : 'error');
|
||||
setFormStatus(
|
||||
isForbidden(error) ? '当前账号无权维护该家谱的谱文。' : (error.message || '谱文编辑信息加载失败'),
|
||||
isForbidden(error) ? 'forbidden' : 'error'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -468,18 +516,18 @@
|
||||
var saved;
|
||||
var savedId;
|
||||
|
||||
if (writePending || !genealogyId || redirectUnauthorized(api)) return;
|
||||
if (writePending || !canEditContent || !genealogyId || redirectUnauthorized(api)) return;
|
||||
if (root.AppRichEditor && root.AppRichEditor.syncAll) root.AppRichEditor.syncAll();
|
||||
body = buildArticleBody(getFormValues(form));
|
||||
validation = validateArticleBody(body);
|
||||
if (validation) {
|
||||
setFormStatus(validation);
|
||||
setFormStatus(validation, 'error');
|
||||
return;
|
||||
}
|
||||
delete body.invalidCoverOssId;
|
||||
delete body.invalidSortOrder;
|
||||
setWritePending(true);
|
||||
setFormStatus('正在保存谱文…');
|
||||
setWritePending(true, '正在保存…');
|
||||
setFormStatus('正在保存谱文…', 'loading');
|
||||
try {
|
||||
result = articleId
|
||||
? await api.updateArticle(genealogyId, articleId, body)
|
||||
@@ -493,7 +541,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 || '谱文保存失败'),
|
||||
isForbidden(error) ? 'forbidden' : 'error'
|
||||
);
|
||||
} finally {
|
||||
setWritePending(false);
|
||||
}
|
||||
@@ -504,7 +555,7 @@
|
||||
var genealogyId = requireGenealogyId();
|
||||
var article = articlesById[articleId];
|
||||
|
||||
if (writePending || !genealogyId || !normalizeId(articleId) || redirectUnauthorized(api)) return;
|
||||
if (writePending || !canEditContent || !genealogyId || !normalizeId(articleId) || redirectUnauthorized(api)) return;
|
||||
if (root.confirm && !root.confirm('确认删除“' + (article ? article.articleTitle : '该谱文') + '”吗?删除后不可恢复。')) return;
|
||||
setWritePending(true);
|
||||
try {
|
||||
@@ -557,6 +608,7 @@
|
||||
buildArticleBody: buildArticleBody,
|
||||
validateArticleBody: validateArticleBody,
|
||||
normalizeArticle: normalizeArticle,
|
||||
canEditArticles: canEditArticles,
|
||||
normalizeArticles: normalizeArticles,
|
||||
matchesSavedArticle: matchesSavedArticle,
|
||||
renderArticleDetail: renderArticleDetail,
|
||||
|
||||
Reference in New Issue
Block a user