Files
jiapu/public/js/album-pages.js
T
2026-07-09 17:30:10 +08:00

315 lines
8.7 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
(function (root, factory) {
// 相册模块同时支持浏览器页面和 Node 单元测试。
if (typeof module === 'object' && module.exports) {
module.exports = factory(root);
return;
}
root.AlbumPages = factory(root);
if (root.document) {
root.document.addEventListener('DOMContentLoaded', function () {
root.AlbumPages.init();
});
}
})(typeof globalThis !== 'undefined' ? globalThis : window, function (root) {
'use strict';
var documentRef = root.document;
var selectedAlbumId = '';
function normalizeList(data) {
// 相册接口列表响应兼容数组、rows、records、list、data。
if (Array.isArray(data)) return data;
if (!data || typeof data !== 'object') return [];
if (Array.isArray(data.rows)) return data.rows;
if (Array.isArray(data.records)) return data.records;
if (Array.isArray(data.list)) return data.list;
if (Array.isArray(data.data)) return data.data;
return [];
}
function pick(item, keys, fallback) {
var source = item || {};
var index;
var value;
for (index = 0; index < keys.length; index += 1) {
value = source[keys[index]];
if (value !== undefined && value !== null && value !== '') return value;
}
return fallback || '';
}
function escapeHtml(value) {
// 相册名称和照片说明进入 innerHTML 前统一转义。
return String(value === undefined || value === null ? '' : value)
.replace(/&/g, '&amp;')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;')
.replace(/"/g, '&quot;')
.replace(/'/g, '&#39;');
}
function getApi() {
return root.GenealogyApi && root.GenealogyApi.defaultClient;
}
function query(selector, rootNode) {
return (rootNode || documentRef).querySelector(selector);
}
function queryAll(selector, rootNode) {
return Array.prototype.slice.call((rootNode || documentRef).querySelectorAll(selector));
}
function showMessage(message) {
if (root.layui && root.layui.layer) {
root.layui.layer.msg(message);
return;
}
root.alert(message);
}
function getQueryParam(search, name) {
var params = new URLSearchParams(String(search || '').replace(/^\?/, ''));
return params.get(name) || '';
}
function getCurrentGenealogyId() {
var search = root.location && root.location.search;
var page = query('[data-album-page], [data-promo-album-page]');
return getQueryParam(search, 'genealogyId') ||
(page && page.getAttribute('data-genealogy-id')) ||
getQueryParam(search, 'id') ||
'';
}
function trimOrUndefined(value) {
var text = String(value === undefined || value === null ? '' : value).trim();
return text || undefined;
}
function toNumber(value, fallback) {
var text = String(value === undefined || value === null ? '' : value).trim();
var number = Number(text);
return text && Number.isFinite(number) ? number : fallback;
}
function buildAlbumBody(values) {
// AlbumBody 来自 APP.openapi.jsonalbumName 必填。
var source = values || {};
return {
albumName: String(source.albumName || '').trim(),
albumDesc: trimOrUndefined(source.albumDesc),
coverOssId: toNumber(source.coverOssId),
sortOrder: toNumber(source.sortOrder, 1),
status: String(source.status || '').trim() || '0'
};
}
function buildPhotoBody(values) {
// AlbumPhotoBody 来自 APP.openapi.jsonossId 必填。
var source = values || {};
return {
ossId: toNumber(source.ossId),
photoTitle: trimOrUndefined(source.photoTitle),
photoDesc: trimOrUndefined(source.photoDesc),
photographer: trimOrUndefined(source.photographer),
shootTime: trimOrUndefined(source.shootTime),
sortOrder: toNumber(source.sortOrder, 1),
status: String(source.status || '').trim() || '0'
};
}
function getAlbumId(item) {
return pick(item, ['albumId', 'id'], '');
}
function buildAlbumRow(item) {
var albumId = getAlbumId(item);
var name = pick(item, ['albumName', 'name'], '未命名相册');
var photoCount = pick(item, ['photoCount', 'photos'], '0');
var desc = pick(item, ['albumDesc', 'description'], '暂无说明');
return '<button class="module-row album-row" type="button" data-album-id="' + escapeHtml(albumId) + '">' +
'<div><h3>' + escapeHtml(name) + '</h3><p>' + escapeHtml(photoCount) + ' 张照片 · ' + escapeHtml(desc) + '</p></div>' +
'<span class="pill">管理</span></button>';
}
function buildPhotoRow(item) {
var title = pick(item, ['photoTitle', 'title'], '未命名照片');
var desc = pick(item, ['photoDesc', 'description'], '暂无说明');
var photographer = pick(item, ['photographer'], '未记录拍摄人');
return '<div class="module-row album-photo-row"><div><h3>' + escapeHtml(title) + '</h3><p>' + escapeHtml(desc) + ' · ' + escapeHtml(photographer) + '</p></div><span class="pill">照片</span></div>';
}
function renderAlbums(items) {
var container = query('[data-album-list], [data-promo-album-list]');
var list = normalizeList(items);
if (!container) return;
if (!list.length) {
container.innerHTML = '<div class="api-empty">暂无相册</div>';
return;
}
container.innerHTML = list.map(buildAlbumRow).join('');
}
function renderPhotos(items) {
var container = query('[data-album-photo-list]');
var list = normalizeList(items);
if (!container) return;
if (!list.length) {
container.innerHTML = '<div class="api-empty">暂无照片</div>';
return;
}
container.innerHTML = list.map(buildPhotoRow).join('');
}
function getFormValues(form) {
var values = {};
queryAll('[name]', form).forEach(function (field) {
values[field.name] = field.value;
});
return values;
}
async function loadAlbums() {
var api = getApi();
var genealogyId = getCurrentGenealogyId();
if (!api || !genealogyId) return;
try {
renderAlbums(await api.albums(genealogyId));
} catch (error) {
showMessage(error.message || '相册加载失败');
}
}
async function loadPhotos(albumId) {
var api = getApi();
var genealogyId = getCurrentGenealogyId();
if (!api || !genealogyId || !albumId) return;
selectedAlbumId = albumId;
try {
renderPhotos(await api.albumPhotos(genealogyId, albumId));
} catch (error) {
showMessage(error.message || '照片加载失败');
}
}
async function submitAlbum(form) {
var api = getApi();
var genealogyId = getCurrentGenealogyId();
var body = buildAlbumBody(getFormValues(form));
if (!api || !genealogyId) {
showMessage('请从具体家谱进入相册管理');
return;
}
if (!body.albumName) {
showMessage('请填写相册名称');
return;
}
try {
if (selectedAlbumId) {
await api.updateAlbum(genealogyId, selectedAlbumId, body);
} else {
await api.createAlbum(genealogyId, body);
}
form.reset();
selectedAlbumId = '';
showMessage('相册已保存');
loadAlbums();
} catch (error) {
showMessage(error.message || '保存相册失败');
}
}
async function submitPhoto(form) {
var api = getApi();
var genealogyId = getCurrentGenealogyId();
var body = buildPhotoBody(getFormValues(form));
if (!api || !genealogyId || !selectedAlbumId) {
showMessage('请先选择相册');
return;
}
if (!body.ossId) {
showMessage('请填写照片 OSS ID');
return;
}
try {
await api.createAlbumPhoto(genealogyId, selectedAlbumId, body);
form.reset();
showMessage('照片已添加');
loadPhotos(selectedAlbumId);
} catch (error) {
showMessage(error.message || '添加照片失败');
}
}
function bindActions() {
if (!documentRef) return;
documentRef.addEventListener('click', function (event) {
var albumButton = event.target.closest('[data-album-id]');
if (!albumButton) return;
event.preventDefault();
loadPhotos(albumButton.getAttribute('data-album-id'));
});
documentRef.addEventListener('submit', function (event) {
var albumForm = event.target.closest('[data-album-form]');
var photoForm = event.target.closest('[data-album-photo-form]');
if (albumForm) {
event.preventDefault();
submitAlbum(albumForm);
}
if (photoForm) {
event.preventDefault();
submitPhoto(photoForm);
}
});
}
function init() {
if (!documentRef) return;
bindActions();
loadAlbums();
}
return {
normalizeList: normalizeList,
buildAlbumBody: buildAlbumBody,
buildPhotoBody: buildPhotoBody,
buildAlbumRow: buildAlbumRow,
init: init
};
});