(function (root, factory) { if (typeof module === 'object' && module.exports) { module.exports = factory(root); return; } root.SiteNewsPages = factory(root); if (root.document) { root.document.addEventListener('DOMContentLoaded', function () { root.SiteNewsPages.init(); }); } })(typeof globalThis !== 'undefined' ? globalThis : window, function (root) { 'use strict'; var ARTICLE_TYPE_LABELS = { news: '新闻', notice: '公告', download: '下载' }; function escapeHtml(value) { return String(value === undefined || value === null ? '' : value) .replace(/&/g, '&') .replace(//g, '>') .replace(/"/g, '"') .replace(/'/g, '''); } function text(value) { return value === undefined || value === null ? '' : String(value).trim(); } function normalizeId(value) { var normalized; if (typeof value === 'number' && !Number.isSafeInteger(value)) return ''; if (value === undefined || value === null) return ''; normalized = String(value).trim(); return /^[1-9][0-9]*$/.test(normalized) ? normalized : ''; } function normalizeArticleType(value) { var normalized = text(value); return Object.prototype.hasOwnProperty.call(ARTICLE_TYPE_LABELS, normalized) ? normalized : ''; } function normalizeExternalUrl(value) { var normalized = text(value); var parsed; if (!normalized) return ''; try { parsed = new URL(normalized); } catch (error) { return ''; } return parsed.protocol === 'http:' || parsed.protocol === 'https:' ? parsed.href : ''; } function normalizeArticle(item) { var source = item || {}; var articleId = normalizeId(source.articleId); var articleType = normalizeArticleType(source.articleType); var articleTitle = text(source.articleTitle); if (!articleId || !articleType || !articleTitle || String(source.status) !== '0') { return null; } return { articleId: articleId, articleType: articleType, articleTitle: articleTitle, articleSummary: text(source.articleSummary), articleContent: text(source.articleContent), externalUrl: normalizeExternalUrl(source.externalUrl), publishTime: text(source.publishTime) }; } function normalizeArticleList(data) { var items; if (!Array.isArray(data)) return []; items = data.map(normalizeArticle); return items.some(function (item) { return !item; }) ? [] : items; } function renderNormalizedArticleList(items) { return items.map(function (item) { return '' + '' + escapeHtml(ARTICLE_TYPE_LABELS[item.articleType]) + '' + '

' + escapeHtml(item.articleTitle) + '

' + '

' + escapeHtml(item.articleSummary) + '

' + '' + escapeHtml(item.publishTime) + '
'; }).join(''); } function renderArticleList(data) { return renderNormalizedArticleList(normalizeArticleList(data)); } function renderNormalizedArticleDetail(item) { var externalLink = item.externalUrl ? '查看外部内容' : ''; var content = escapeHtml(item.articleContent).replace(/\r?\n/g, '
'); return '
' + '
' + escapeHtml(ARTICLE_TYPE_LABELS[item.articleType]) + '

' + escapeHtml(item.articleTitle) + '

' + escapeHtml(item.articleSummary) + '

' + '

' + escapeHtml(item.articleSummary) + '

' + '
' + '

' + content + '

' + externalLink + '
'; } function renderArticleDetail(item) { var article = normalizeArticle(item); return article ? renderNormalizedArticleDetail(article) : ''; } function readQueryValue(search, key) { var params = new URLSearchParams(String(search || '').replace(/^\?/, '')); return text(params.get(key)); } function readArticleId(search) { return normalizeId(readQueryValue(search, 'articleId')); } async function loadArticles(api, articleType) { var requestedType = text(articleType); var normalizedType = normalizeArticleType(requestedType); var query = { limit: 100 }; var data; var items; if (!api || typeof api.siteArticles !== 'function') throw new Error('资讯接口不可用'); if (requestedType && !normalizedType) throw new Error('资讯分类无效'); if (normalizedType) query.articleType = normalizedType; data = await api.siteArticles(query); items = normalizeArticleList(data); if (!Array.isArray(data) || items.length !== data.length) { throw new Error('资讯列表响应无效'); } return items; } async function loadArticleDetail(api, targetArticleId) { var normalizedId = normalizeId(targetArticleId); var items; var match; if (!normalizedId) throw new Error('资讯编号无效'); items = await loadArticles(api, ''); match = items.find(function (item) { return item.articleId === normalizedId; }); if (!match) throw new Error('资讯不存在或已下线'); return match; } function isForbidden(error) { return Number(error && (error.status || error.code)) === 403; } function isMissingArticleError(error) { return error && error.message === '资讯不存在或已下线'; } function setSiteState(container, type, message) { if (!container) return; if (root.ProfileUI && root.ProfileUI.setApiState) { root.ProfileUI.setApiState(container, type, message); return; } container.textContent = message; } function setSiteStatus(container, message) { if (container) container.textContent = message || ''; } async function init() { var document = root.document; var api = root.GenealogyApi && root.GenealogyApi.defaultClient; var search = root.location && root.location.search || ''; var listPage = document && document.querySelector('[data-site-news-page]'); var detailPage = document && document.querySelector('[data-site-article-page]'); var list; var status; var requestedType; var detail; var articleId; if (listPage) { list = document.querySelector('[data-site-news-list]'); status = document.querySelector('[data-site-news-status]'); requestedType = readQueryValue(search, 'articleType'); if (!list) return; if (requestedType && !normalizeArticleType(requestedType)) { setSiteState(list, 'error', '资讯分类无效。'); setSiteStatus(status, '资讯分类无效。'); return; } setSiteState(list, 'loading', '正在读取资讯…'); try { var items = await loadArticles(api, requestedType); if (!items.length) setSiteState(list, 'empty', '当前暂无资讯。'); else list.innerHTML = renderNormalizedArticleList(items); setSiteStatus(status, ''); } catch (error) { setSiteState( list, isForbidden(error) ? 'forbidden' : 'error', isForbidden(error) ? '当前账号无权查看资讯。' : '资讯读取失败,请稍后重试。' ); setSiteStatus(status, error.message || '资讯读取失败,请稍后重试。'); } return; } if (detailPage) { detail = document.querySelector('[data-site-article-detail]'); status = document.querySelector('[data-site-article-status]'); articleId = readArticleId(search); if (!detail) return; if (!articleId) { setSiteState(detail, 'error', '资讯编号无效。'); setSiteStatus(status, '资讯编号无效。'); return; } setSiteState(detail, 'loading', '正在读取资讯详情…'); try { detail.innerHTML = renderNormalizedArticleDetail(await loadArticleDetail(api, articleId)); setSiteStatus(status, ''); } catch (error) { setSiteState( detail, isForbidden(error) ? 'forbidden' : (isMissingArticleError(error) ? 'empty' : 'error'), isForbidden(error) ? '当前账号无权查看该资讯。' : (isMissingArticleError(error) ? '资讯不存在或已下线。' : '资讯详情读取失败,请稍后重试。') ); setSiteStatus(status, error.message || '资讯详情读取失败,请稍后重试。'); } } } return { normalizeArticle: normalizeArticle, normalizeArticleList: normalizeArticleList, normalizeArticleType: normalizeArticleType, normalizeExternalUrl: normalizeExternalUrl, readArticleId: readArticleId, renderArticleList: renderArticleList, renderArticleDetail: renderArticleDetail, loadArticles: loadArticles, loadArticleDetail: loadArticleDetail, isForbidden: isForbidden, isMissingArticleError: isMissingArticleError, setSiteState: setSiteState, init: init }; });