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

385 lines
12 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.CeremonyPages = factory(root);
if (root.document) {
root.document.addEventListener('DOMContentLoaded', function () {
root.CeremonyPages.init();
});
}
})(typeof globalThis !== 'undefined' ? globalThis : window, function (root) {
'use strict';
var documentRef = root.document;
var selectedCeremonyId = '';
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-ceremony-page], [data-ceremony-edit-page], [data-merit-page], [data-merit-edit-page]');
return getQueryParam(search, 'genealogyId') ||
(page && page.getAttribute('data-genealogy-id')) ||
getQueryParam(search, 'id') ||
'';
}
function getCurrentCeremonyId() {
var search = root.location && root.location.search;
return getQueryParam(search, 'ceremonyId') || '';
}
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 buildCeremonyBody(values) {
// CeremonyBody 来自 APP.openapi.jsonceremonyType 和 ceremonyTitle 必填。
var source = values || {};
return {
ceremonyType: String(source.ceremonyType || '').trim(),
ceremonyTitle: String(source.ceremonyTitle || '').trim(),
ceremonyDesc: trimOrUndefined(source.ceremonyDesc),
ceremonyTime: trimOrUndefined(source.ceremonyTime),
location: trimOrUndefined(source.location),
coverOssId: toNumber(source.coverOssId),
sortOrder: toNumber(source.sortOrder, 1),
status: String(source.status || '').trim() || '0'
};
}
function buildGiftBody(values) {
var source = values || {};
return {
giverName: trimOrUndefined(source.giverName),
giftAmount: toNumber(source.giftAmount, 0),
giftMessage: trimOrUndefined(source.giftMessage)
};
}
function buildMeritBody(values) {
// MeritRecordBody 来自 APP.openapi.jsondonorName 和 meritTitle 必填。
var source = values || {};
return {
donorName: String(source.donorName || '').trim(),
meritType: String(source.meritType || '').trim() || 'donation',
meritTitle: String(source.meritTitle || '').trim(),
meritContent: trimOrUndefined(source.meritContent),
amount: toNumber(source.amount, 0),
meritTime: trimOrUndefined(source.meritTime),
sortOrder: toNumber(source.sortOrder, 1),
status: String(source.status || '').trim() || '0'
};
}
function getCeremonyId(item) {
return pick(item, ['ceremonyId', 'id'], '');
}
function buildCeremonyRow(item) {
var ceremonyId = getCeremonyId(item);
var title = pick(item, ['ceremonyTitle', 'title'], '未命名活动');
var type = pick(item, ['ceremonyType', 'type'], 'ceremony');
var time = pick(item, ['ceremonyTime', 'time', 'createTime'], '未设置时间');
var giftCount = pick(item, ['giftCount', 'gifts'], '0');
return '<button class="module-row ceremony-row" type="button" data-ceremony-id="' + escapeHtml(ceremonyId) + '">' +
'<div><h3>' + escapeHtml(title) + '</h3><p>' + escapeHtml(type) + ' · ' + escapeHtml(time) + ' · ' + escapeHtml(giftCount) + ' 条献礼</p></div>' +
'<span class="pill">管理</span></button>';
}
function buildGiftRow(item) {
var name = pick(item, ['giverName', 'memberName', 'name'], '匿名');
var amount = pick(item, ['giftAmount', 'amount'], '0');
var message = pick(item, ['giftMessage', 'message'], '暂无留言');
return '<div class="module-row ceremony-gift-row"><div><h3>' + escapeHtml(name) + '</h3><p>' + escapeHtml(amount) + ' 元 · ' + escapeHtml(message) + '</p></div><span class="pill">献礼</span></div>';
}
function buildMeritRow(item) {
var name = pick(item, ['donorName', 'name'], '未命名功德人');
var title = pick(item, ['meritTitle', 'title'], '功德记录');
var time = pick(item, ['meritTime', 'createTime'], '未记录时间');
return '<div class="module-row merit-row"><div><h3>' + escapeHtml(name) + '</h3><p>' + escapeHtml(title) + ' · ' + escapeHtml(time) + '</p></div><span class="pill">查看</span></div>';
}
function renderCeremonies(items) {
var container = query('[data-ceremony-list]');
var list = normalizeList(items);
if (!container) return;
if (!list.length) {
container.innerHTML = '<div class="api-empty">暂无贺礼邀请</div>';
return;
}
container.innerHTML = list.map(buildCeremonyRow).join('');
}
function renderGifts(items) {
var container = query('[data-ceremony-gift-list]');
var list = normalizeList(items);
if (!container) return;
if (!list.length) {
container.innerHTML = '<div class="api-empty">暂无献礼记录</div>';
return;
}
container.innerHTML = list.map(buildGiftRow).join('');
}
function renderMerits(items) {
var container = query('[data-merit-list]');
var list = normalizeList(items);
if (!container) return;
if (!list.length) {
container.innerHTML = '<div class="api-empty">暂无功德记录</div>';
return;
}
container.innerHTML = list.map(buildMeritRow).join('');
}
function getFormValues(form) {
var values = {};
queryAll('[name]', form).forEach(function (field) {
values[field.name] = field.value;
});
return values;
}
async function loadCeremonies() {
var api = getApi();
var genealogyId = getCurrentGenealogyId();
var ceremonyId = getCurrentCeremonyId();
if (!api || !genealogyId) return;
try {
if (query('[data-ceremony-list]')) {
renderCeremonies(await api.ceremonies(genealogyId));
}
if (ceremonyId && query('[data-ceremony-gift-list]')) {
selectedCeremonyId = ceremonyId;
renderGifts(await api.ceremonyGifts(genealogyId, ceremonyId));
}
} catch (error) {
showMessage(error.message || '贺礼数据加载失败');
}
}
async function loadMerits() {
var api = getApi();
var genealogyId = getCurrentGenealogyId();
if (!api || !genealogyId || !query('[data-merit-list]')) return;
try {
renderMerits(await api.meritRecords(genealogyId));
} catch (error) {
showMessage(error.message || '功德记录加载失败');
}
}
async function submitCeremony(form) {
var api = getApi();
var genealogyId = getCurrentGenealogyId();
var ceremonyId = getCurrentCeremonyId();
var body = buildCeremonyBody(getFormValues(form));
if (!api || !genealogyId) return;
if (!body.ceremonyType || !body.ceremonyTitle) {
showMessage('请填写贺礼类型和标题');
return;
}
try {
if (ceremonyId) {
await api.updateCeremony(genealogyId, ceremonyId, body);
} else {
await api.createCeremony(genealogyId, body);
}
showMessage('贺礼已保存');
root.location.href = 'profile-gift.html?genealogyId=' + encodeURIComponent(genealogyId);
} catch (error) {
showMessage(error.message || '保存贺礼失败');
}
}
async function submitGift(form) {
var api = getApi();
var genealogyId = getCurrentGenealogyId();
var ceremonyId = selectedCeremonyId || getCurrentCeremonyId();
var body = buildGiftBody(getFormValues(form));
if (!api || !genealogyId || !ceremonyId) {
showMessage('请先选择贺礼邀请');
return;
}
try {
await api.createCeremonyGift(genealogyId, ceremonyId, body);
form.reset();
showMessage('献礼已保存');
renderGifts(await api.ceremonyGifts(genealogyId, ceremonyId));
} catch (error) {
showMessage(error.message || '保存献礼失败');
}
}
async function submitMerit(form) {
var api = getApi();
var genealogyId = getCurrentGenealogyId();
var body = buildMeritBody(getFormValues(form));
if (!api || !genealogyId) return;
if (!body.donorName || !body.meritTitle) {
showMessage('请填写功德人和功德标题');
return;
}
try {
await api.createMeritRecord(genealogyId, body);
showMessage('功德记录已保存');
root.location.href = 'profile-merit.html?genealogyId=' + encodeURIComponent(genealogyId);
} catch (error) {
showMessage(error.message || '保存功德记录失败');
}
}
function bindActions() {
if (!documentRef) return;
documentRef.addEventListener('click', function (event) {
var ceremonyButton = event.target.closest('[data-ceremony-id]');
if (!ceremonyButton) return;
selectedCeremonyId = ceremonyButton.getAttribute('data-ceremony-id');
if (getApi() && getCurrentGenealogyId()) {
getApi().ceremonyGifts(getCurrentGenealogyId(), selectedCeremonyId).then(renderGifts).catch(function (error) {
showMessage(error.message || '献礼加载失败');
});
}
});
documentRef.addEventListener('submit', function (event) {
var ceremonyForm = event.target.closest('[data-ceremony-form]');
var giftForm = event.target.closest('[data-ceremony-gift-form]');
var meritForm = event.target.closest('[data-merit-form]');
if (ceremonyForm) {
event.preventDefault();
submitCeremony(ceremonyForm);
}
if (giftForm) {
event.preventDefault();
submitGift(giftForm);
}
if (meritForm) {
event.preventDefault();
submitMerit(meritForm);
}
});
}
function init() {
if (!documentRef) return;
bindActions();
loadCeremonies();
loadMerits();
}
return {
normalizeList: normalizeList,
buildCeremonyBody: buildCeremonyBody,
buildMeritBody: buildMeritBody,
buildCeremonyRow: buildCeremonyRow,
init: init
};
});