等待后端更新接口

This commit is contained in:
2026-08-03 16:49:26 +08:00
parent ac5823547a
commit 5b79893650
131 changed files with 5324 additions and 1392 deletions
+107 -36
View File
@@ -232,7 +232,7 @@
function renderVideoDetail(video, managementAccess) {
var actions = '';
if (!video) return '<div class="api-empty">请选择一个视频查看详情</div>';
if (!video) return '';
if (managementAccess) {
actions = '<div class="bottom-actions"><a class="btn ghost" href="' +
escapeHtml(buildEditUrl(video.genealogyId, video.videoId)) + '">编辑视频</a>' +
@@ -287,15 +287,15 @@
if (root.ProfileUI && root.ProfileUI.syncGenealogyContextLinks) root.ProfileUI.syncGenealogyContextLinks();
}
function renderNoContext() {
var list = query('[data-video-list]');
var detail = query('[data-video-detail]');
var placeholder = query('[data-video-permission-placeholder]');
function canEditVideos(genealogy) {
return Boolean(genealogy && (genealogy.canEditContent === true || genealogy.canManage === true));
}
if (list) list.innerHTML = '<div class="api-empty">请先选择家谱,再查看家族视频。</div>';
if (detail) detail.innerHTML = '<div class="api-empty">当前没有家谱上下文。</div>';
if (placeholder) placeholder.textContent = '请先选择家谱,再发布视频。';
setFormStatus('请先选择家谱,再发布视频。');
function renderNoContext() {
setVideoListState('empty', '请先选择家谱,再查看家族视频。');
setVideoDetailState('empty', '当前没有家谱上下文。');
setPermissionPlaceholder('empty', '请先选择家谱,再发布视频。');
setFormStatus('请先选择家谱,再发布视频。', 'forbidden');
setManagementAccess(false);
}
@@ -316,17 +316,67 @@
if (placeholder) placeholder.hidden = canEditContent;
}
function setFormStatus(message) {
var status = query('[data-video-form-status]');
if (status) status.textContent = message || '';
function getApiStateType(error) {
return isForbidden(error) ? 'forbidden' : 'error';
}
function setWritePending(pending) {
function setVideoState(selector, type, message) {
var container = query(selector);
if (!container) return;
if (root.ProfileUI && root.ProfileUI.setApiState) {
root.ProfileUI.setApiState(container, type, message);
return;
}
container.textContent = message;
}
function setVideoListState(type, message) {
setVideoState('[data-video-list]', type, message);
}
function setVideoDetailState(type, message) {
setVideoState('[data-video-detail]', type, message);
}
function setPermissionPlaceholder(type, message) {
var placeholder = query('[data-video-permission-placeholder]');
if (!placeholder) return;
if (root.ProfileUI && root.ProfileUI.setApiState) {
root.ProfileUI.setApiState(placeholder, type, message);
return;
}
placeholder.textContent = message;
}
function setFormStatus(message, type) {
var status = query('[data-video-form-status]');
if (!status) return;
if (!message) {
status.innerHTML = '';
return;
}
if (type && root.ProfileUI && root.ProfileUI.setApiState) {
root.ProfileUI.setApiState(status, type, message);
return;
}
status.textContent = message;
}
function setWritePending(pending, label) {
var submit = query('[data-video-form] [type="submit"]');
writePending = Boolean(pending);
queryAll('[data-video-form] input, [data-video-form] textarea, [data-video-form] button, [data-video-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 renderVideos(data) {
@@ -341,11 +391,11 @@
});
if (!container) return videos;
if (!Array.isArray(data) || invalidCount) {
container.innerHTML = '<div class="api-empty">视频响应缺少稳定 VideoVo 字段,请联系后端核对。</div>';
setVideoListState('error', '视频响应缺少稳定 VideoVo 字段,请联系后端核对。');
return [];
}
if (!videos.length) {
container.innerHTML = '<div class="api-empty">暂无家族视频</div>';
setVideoListState('empty', '暂无家族视频');
return [];
}
container.innerHTML = videos.map(function (video) {
@@ -357,7 +407,12 @@
function renderDetail(video) {
var container = query('[data-video-detail]');
if (container) container.innerHTML = renderVideoDetail(video, canEditContent);
if (!container) return;
if (!video) {
setVideoDetailState('empty', '请选择一个视频查看详情');
return;
}
container.innerHTML = renderVideoDetail(video, canEditContent);
}
async function loadVideoDetail(videoId) {
@@ -366,6 +421,7 @@
var video;
if (!genealogyId || !normalizeId(videoId) || redirectUnauthorized(api)) return null;
setVideoDetailState('loading', '正在加载视频详情…');
try {
video = normalizeVideo(await api.videoDetail(genealogyId, videoId));
if (!video) throw new Error('视频详情响应缺少稳定 VideoVo 字段');
@@ -374,7 +430,10 @@
return video;
} catch (error) {
if (redirectUnauthorized(api, error)) return null;
renderDetail(null);
setVideoDetailState(
getApiStateType(error),
isForbidden(error) ? '当前账号无权查看该视频。' : (error.message || '视频详情加载失败')
);
showMessage(error.message || '视频详情加载失败');
return null;
}
@@ -391,9 +450,11 @@
genealogyId = requireGenealogyId();
if (!genealogyId) return;
syncGenealogyLinks();
setVideoListState('loading', '正在加载视频…');
setVideoDetailState('loading', '正在加载视频详情…');
try {
result = await Promise.all([api.genealogyDetail(genealogyId), api.videos(genealogyId)]);
setManagementAccess(Boolean(result[0] && result[0].canEditContent === true));
setManagementAccess(canEditVideos(result[0]));
videos = renderVideos(result[1]);
requestedVideoId = getCurrentVideoId();
if (requestedVideoId && videosById[requestedVideoId]) {
@@ -407,10 +468,12 @@
if (redirectUnauthorized(api, error)) return;
if (isForbidden(error)) {
setManagementAccess(false);
if (query('[data-video-list]')) query('[data-video-list]').innerHTML = '<div class="api-empty">当前账号无权查看该家谱视频。</div>';
setVideoListState('forbidden', '当前账号无权查看该家谱视频。');
setVideoDetailState('forbidden', '当前账号无权查看该家谱视频。');
return;
}
if (query('[data-video-list]')) query('[data-video-list]').innerHTML = '<div class="api-empty">视频加载失败,请稍后重试。</div>';
setVideoListState('error', '视频加载失败,请稍后重试。');
setVideoDetailState('error', '视频详情加载失败,请稍后重试。');
showMessage(error.message || '视频加载失败');
}
}
@@ -454,17 +517,17 @@
if (!genealogyId) return;
videoId = getCurrentVideoId();
syncGenealogyLinks();
setFormStatus('正在读取家谱权限…', 'loading');
setPermissionPlaceholder('loading', '正在核对视频维护权限…');
try {
result = await Promise.all([
api.genealogyDetail(genealogyId),
videoId ? api.videoDetail(genealogyId, videoId) : Promise.resolve(null)
]);
setManagementAccess(Boolean(result[0] && result[0].canEditContent === true));
setManagementAccess(canEditVideos(result[0]));
if (!canEditContent) {
if (query('[data-video-permission-placeholder]')) {
query('[data-video-permission-placeholder]').textContent = '当前账号没有视频维护权限。';
}
setFormStatus('当前账号没有视频维护权限。');
setPermissionPlaceholder('forbidden', '当前账号没有视频维护权限。');
setFormStatus('当前账号没有视频维护权限。', 'forbidden');
return;
}
if (videoId) {
@@ -473,15 +536,18 @@
fillVideoForm(video);
if (query('[data-video-editor-title]')) query('[data-video-editor-title]').textContent = '编辑视频';
}
setFormStatus('');
} catch (error) {
if (redirectUnauthorized(api, error)) return;
setManagementAccess(false);
if (query('[data-video-permission-placeholder]')) {
query('[data-video-permission-placeholder]').textContent = isForbidden(error)
? '当前账号没有视频维护权限。'
: (error.message || '视频编辑信息加载失败');
}
setFormStatus(isForbidden(error) ? '当前账号没有视频维护权限。' : (error.message || '视频编辑信息加载失败'));
setPermissionPlaceholder(
getApiStateType(error),
isForbidden(error) ? '当前账号没有视频维护权限。' : (error.message || '视频编辑信息加载失败')
);
setFormStatus(
isForbidden(error) ? '当前账号没有视频维护权限。' : (error.message || '视频编辑信息加载失败'),
getApiStateType(error)
);
}
}
@@ -497,13 +563,13 @@
if (writePending || !canEditContent || !genealogyId || redirectUnauthorized(api)) return;
if (validation) {
setFormStatus(validation);
setFormStatus(validation, 'error');
return;
}
delete body.invalidDuration;
delete body.invalidSortOrder;
setWritePending(true);
setFormStatus('正在保存视频…');
setWritePending(true, '正在保存…');
setFormStatus('正在保存视频…', 'loading');
try {
result = videoId ? await api.updateVideo(genealogyId, videoId, body) : await api.createVideo(genealogyId, body);
saved = normalizeVideo(result);
@@ -513,7 +579,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);
}
@@ -607,8 +676,10 @@
validateVideoBody: validateVideoBody,
normalizeVideo: normalizeVideo,
normalizeDurationSeconds: normalizeDurationSeconds,
canEditVideos: canEditVideos,
renderVideoRow: renderVideoRow,
renderVideoDetail: renderVideoDetail,
setPermissionPlaceholder: setPermissionPlaceholder,
shouldRedirectToLogin: shouldRedirectToLogin,
isForbidden: isForbidden,
init: init