修改功能

This commit is contained in:
2026-08-29 19:06:07 +08:00
parent f94c652c7c
commit aaed0584b1
142 changed files with 6176 additions and 869 deletions
+240 -19
View File
@@ -7,6 +7,69 @@
var genealogyContextStorageKey = 'genealogy_current_context_v1';
var mobileMenuId = 'profile-mobile-menu';
var apiStateTypes = ['loading', 'empty', 'error', 'forbidden'];
var familyWorkspacePages = [
'profile-family-home.html', 'profile-tree.html', 'profile-generation.html',
'profile-family-admin.html', 'profile-admin-permissions.html', 'profile-join-review.html',
'profile-content.html', 'profile-article.html', 'profile-article-edit.html',
'profile-album.html', 'profile-album-detail.html', 'profile-album-edit.html',
'profile-video.html', 'profile-video-edit.html', 'profile-feed.html',
'profile-feed-detail.html', 'profile-feed-edit.html', 'profile-ceremony.html',
'profile-ceremony-detail.html', 'profile-gift-edit.html', 'profile-gift.html',
'profile-growth.html', 'profile-growth-edit.html', 'profile-merit.html',
'profile-merit-edit.html', 'profile-memo.html', 'profile-memo-edit.html',
'profile-relative.html', 'profile-relative-edit.html', 'profile-invite.html',
'profile-data-reminders.html', 'profile-documents.html', 'profile-family-settings.html'
];
var familyWorkspaceNavigation = [
{ label: '家谱主页', href: 'profile-family-home.html', context: true },
{ label: '世系管理', items: [
{ label: '世系图', href: 'profile-tree.html', context: true },
{ label: '字辈谱', href: 'profile-generation.html', context: true },
{ label: '资料提醒', href: 'profile-data-reminders.html', context: true }
] },
{ label: '内容发布', items: [
{ label: '内容工作台', href: 'profile-content.html', context: true },
{ label: '谱文', href: 'profile-article.html', pages: ['profile-article-edit.html'], context: true },
{ label: '家族圈', href: 'profile-feed.html', pages: ['profile-feed-detail.html', 'profile-feed-edit.html'], context: true },
{ label: '相册', href: 'profile-album.html', pages: ['profile-album-detail.html', 'profile-album-edit.html'], context: true },
{ label: '视频', href: 'profile-video.html', pages: ['profile-video-edit.html'], context: true },
{ label: '祭祀活动', href: 'profile-ceremony.html', pages: ['profile-ceremony-detail.html', 'profile-gift-edit.html'], context: true },
{ label: '贺礼邀请', href: 'profile-gift.html', context: true },
{ label: '成长记录', href: 'profile-growth.html', pages: ['profile-growth-edit.html'], context: true },
{ label: '功德录', href: 'profile-merit.html', pages: ['profile-merit-edit.html'], context: true },
{ label: '备忘录', href: 'profile-memo.html', pages: ['profile-memo-edit.html'], context: true },
{ label: '亲友记录', href: 'profile-relative.html', pages: ['profile-relative-edit.html'], context: true },
{ label: '重要证件', href: 'profile-documents.html', context: true }
] },
{ label: '家族管理', items: [
{ label: '成员管理', href: 'profile-family-admin.html', context: true },
{ label: '入谱审核', href: 'profile-join-review.html', context: true },
{ label: '邀请家人', href: 'profile-invite.html', context: true },
{ label: '家谱维护', href: 'profile-family-settings.html', context: true },
{ label: '权限说明', href: 'profile-admin-permissions.html', context: true }
] },
{ label: '消息中心', href: 'profile-messages.html' }
];
var accountWorkspaceNavigation = [
{ label: '个人中心', href: 'profile.html' },
{ label: '我的家谱', items: [
{ label: '家谱列表', href: 'profile-families.html' },
{ label: '创建家谱', href: 'profile-create-family.html' },
{ label: '加入家谱', href: 'join-genealogy.html' },
{ label: '我的申请', href: 'profile-join-family.html' }
] },
{ label: '账号资料', items: [
{ label: '个人资料', href: 'profile-data.html' },
{ label: '账号安全', href: 'profile-security.html' }
] },
{ label: '服务与帮助', items: [
{ label: '帮助与服务', href: 'profile-services.html' },
{ label: '意见反馈', href: 'profile-feedback.html', pages: ['my-tickets.html', 'submit-ticket.html', 'ticket-detail.html'] },
{ label: '推广收益', href: 'profile-earnings.html' },
{ label: '分享与邀请', href: 'profile-share.html' }
] },
{ label: '消息中心', href: 'profile-messages.html' }
];
function escapeHtml(value) {
return String(value === undefined || value === null ? '' : value)
@@ -33,8 +96,20 @@
element.innerHTML = renderApiState(type, message);
}
function revealDetail(element) {
var reduceMotion;
if (!element) return;
reduceMotion = window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches;
if (typeof element.scrollIntoView === 'function') {
element.scrollIntoView({ behavior: reduceMotion ? 'auto' : 'smooth', block: 'start' });
}
if (typeof element.focus === 'function') element.focus({ preventScroll: true });
}
profileUI.renderApiState = renderApiState;
profileUI.setApiState = setApiState;
profileUI.revealDetail = revealDetail;
window.ProfileUI = profileUI;
if (!$) return;
@@ -105,21 +180,22 @@
var genealogyId = getGenealogyId();
var context = getStoredGenealogyContext();
return context && context.genealogyId === genealogyId ? context : null;
if (!context) return null;
return !genealogyId || context.genealogyId === genealogyId ? context : null;
}
function openLegacyLogout() {
var $modal = $('#logoutModal');
if (!$modal.length) return;
$modal.addClass('show').attr('aria-hidden', 'false');
$modal.prop('hidden', false).addClass('show').attr('aria-hidden', 'false');
$('body').addClass('logout-modal-open');
}
function closeLegacyLogout() {
var $modal = $('#logoutModal');
$modal.removeClass('show').attr('aria-hidden', 'true');
$modal.removeClass('show').attr('aria-hidden', 'true').prop('hidden', true);
$('body').removeClass('logout-modal-open');
}
@@ -129,7 +205,8 @@
content: '确定继续吗?',
confirmText: '确定',
cancelText: '取消',
onConfirm: $.noop
onConfirm: $.noop,
onCancel: $.noop
}, options || {});
if (layerApi) {
@@ -140,11 +217,26 @@
}, function (index) {
settings.onConfirm();
layerApi.close(index);
}, function () {
settings.onCancel();
});
return;
}
if (window.confirm(settings.content)) settings.onConfirm();
else settings.onCancel();
}
function confirmAction(content, options) {
var settings = typeof content === 'string'
? $.extend({}, options || {}, { content: content })
: $.extend({}, content || {});
return new Promise(function (resolve) {
settings.onConfirm = function () { resolve(true); };
settings.onCancel = function () { resolve(false); };
openConfirm(settings);
});
}
function initLayui() {
@@ -274,7 +366,8 @@
}
function syncGenealogyContextLinks() {
var genealogyId = getGenealogyId();
var context = getCurrentGenealogyContext();
var genealogyId = getGenealogyId() || (context && context.genealogyId);
$('[data-genealogy-context-link], a[href]').filter(function () {
var $link = $(this);
@@ -315,7 +408,8 @@
}
function initCurrentGenealogyContext() {
var genealogyId = getGenealogyId();
var context = getCurrentGenealogyContext();
var genealogyId = getGenealogyId() || (context && context.genealogyId);
var $nav;
var $actions;
var $context;
@@ -332,6 +426,94 @@
refreshCurrentGenealogyContext();
}
function getCurrentPageName() {
return (window.location.pathname.split('/').pop() || 'profile.html').split('?')[0];
}
function isWorkspaceItemCurrent(item, currentPage) {
return item.href === currentPage || (Array.isArray(item.pages) && item.pages.indexOf(currentPage) >= 0);
}
function renderWorkspaceLink(item, currentPage) {
var isCurrent = isWorkspaceItemCurrent(item, currentPage);
return '<a' + (isCurrent ? ' class="active" aria-current="page"' : '') +
' href="' + escapeHtml(item.href) + '"' + (item.context ? ' data-genealogy-context-link' : '') + '>' +
escapeHtml(item.label) + '</a>';
}
function renderWorkspaceNavigation(items, currentPage) {
return items.map(function (item) {
var isOpen;
if (!item.items) return renderWorkspaceLink(item, currentPage);
isOpen = item.items.some(function (child) { return isWorkspaceItemCurrent(child, currentPage); });
return '<details class="workspace-nav-group' + (isOpen ? ' is-open' : '') +
'" data-workspace-nav-group' + (isOpen ? ' open' : '') + '>' +
'<summary>' + escapeHtml(item.label) + '</summary>' +
'<div class="workspace-nav-items">' + item.items.map(function (child) {
return renderWorkspaceLink(child, currentPage);
}).join('') + '</div></details>';
}).join('');
}
function getHeaderSection(currentPage) {
if (['profile-families.html', 'profile-create-family.html', 'join-genealogy.html', 'profile-join-family.html', 'profile-family-home.html'].indexOf(currentPage) >= 0) {
return 'profile-families.html';
}
if ([
'profile-tree.html', 'profile-generation.html', 'profile-family-admin.html',
'profile-admin-permissions.html', 'profile-join-review.html', 'profile-invite.html',
'profile-data-reminders.html', 'profile-documents.html', 'profile-family-settings.html'
].indexOf(currentPage) >= 0) return 'profile-family-admin.html';
if (familyWorkspacePages.indexOf(currentPage) >= 0) return 'profile-content.html';
if (['profile-data.html', 'profile-security.html'].indexOf(currentPage) >= 0) return 'profile-data.html';
if (['profile-services.html', 'profile-feedback.html', 'my-tickets.html', 'submit-ticket.html', 'ticket-detail.html', 'profile-earnings.html', 'profile-share.html'].indexOf(currentPage) >= 0) {
return 'profile-services.html';
}
return '';
}
function renderHeaderLink(item, currentSection) {
var isCurrent = item.href === currentSection;
return '<a' + (isCurrent ? ' class="active" aria-current="page"' : '') +
' href="' + escapeHtml(item.href) + '"' + (item.context ? ' data-genealogy-context-link' : '') + '>' +
escapeHtml(item.label) + '</a>';
}
function initWorkspaceNavigation() {
var currentPage = getCurrentPageName();
var isFamilyWorkspace = familyWorkspacePages.indexOf(currentPage) >= 0;
var navigation = isFamilyWorkspace ? familyWorkspaceNavigation : accountWorkspaceNavigation;
var $sidebar = $('.module-nav').first();
var $header = $('.site-header').first();
var headerItems = [
{ label: '我的家谱', href: 'profile-families.html' },
{ label: '家族管理', href: 'profile-family-admin.html', context: true },
{ label: '内容发布', href: 'profile-content.html', context: true },
{ label: '个人资料', href: 'profile-data.html' },
{ label: '帮助与服务', href: 'profile-services.html' }
];
var currentSection = getHeaderSection(currentPage);
if ($header.length) {
$header.find('.brand').first().attr('href', 'profile.html').html(
'<img class="brand-logo brand-logo-mark" src="public/images/logo-mark.png" alt="" />' +
'<span class="brand-text">个人中心</span>'
);
$header.find('.nav-links').first().attr('aria-label', '个人中心主导航').html(headerItems.map(function (item) {
return renderHeaderLink(item, currentSection);
}).join(''));
}
if (!$sidebar.length) return;
$sidebar
.attr('aria-label', isFamilyWorkspace ? '当前家谱功能导航' : '个人中心功能导航')
.attr('data-workspace-navigation', isFamilyWorkspace ? 'family' : 'account')
.html(renderWorkspaceNavigation(navigation, currentPage));
$('body').addClass('has-workspace-navigation');
}
function setMobileMenuOpen(isOpen) {
var $menu = $('[data-profile-mobile-menu]').first();
var $toggle = $('[data-profile-mobile-menu-toggle]').first();
@@ -345,26 +527,28 @@
var $header = $('.site-header').first();
var $nav;
var currentPage;
var isFamilyWorkspace;
var navigation;
var workspaceLabel;
if (!$('body').is('.page-profile, .page-profile-module')) return;
if (!$header.length || $header.find('[data-profile-mobile-menu]').length) return;
$nav = $header.find('.nav').first();
if (!$nav.length) return;
$nav.append('<button class="profile-mobile-menu-toggle" type="button" data-profile-mobile-menu-toggle ' +
'aria-expanded="false" aria-controls="' + mobileMenuId + '">菜单</button>');
currentPage = getCurrentPageName();
isFamilyWorkspace = familyWorkspacePages.indexOf(currentPage) >= 0;
navigation = isFamilyWorkspace ? familyWorkspaceNavigation : accountWorkspaceNavigation;
workspaceLabel = isFamilyWorkspace ? '当前家谱功能导航' : '个人中心功能导航';
$header.append('<div class="profile-mobile-menu" id="' + mobileMenuId + '" data-profile-mobile-menu hidden aria-hidden="true">' +
'<div class="container profile-mobile-menu-inner">' +
'<a href="profile.html">个人中心</a>' +
'<a href="profile-families.html">我的家谱</a>' +
'<a href="profile-create-family.html">创建家谱</a>' +
'<a href="profile-family-home.html" data-genealogy-context-link>家谱主页</a>' +
'<a href="profile-content.html" data-genealogy-context-link>内容发布</a>' +
'<a href="profile-family-admin.html" data-genealogy-context-link>家族管理</a>' +
'<a href="profile-data.html">个人资料</a>' +
'<a href="profile-messages.html">消息中心</a>' +
'<a href="profile-services.html">帮助与服务</a>' +
'<button type="button" data-logout-open data-logout-url="index.html">退出登录</button>' +
'<nav class="profile-mobile-workspace" aria-label="' + workspaceLabel + '">' +
renderWorkspaceNavigation(navigation, currentPage) + '</nav>' +
'<div class="profile-mobile-account-actions">' +
(isFamilyWorkspace ? '<a href="profile-families.html">切换家谱</a>' : '') +
'<button type="button" data-logout-open data-logout-url="index.html">退出登录</button></div>' +
'</div></div>');
currentPage = (window.location.pathname.split('/').pop() || 'profile.html').split('?')[0];
$header.find('[data-profile-mobile-menu] a').each(function () {
var $link = $(this);
var target = ($link.attr('href') || '').split('?')[0];
@@ -390,7 +574,13 @@
if (!$(event.target).closest('.site-header').length) setMobileMenuOpen(false);
});
$(document).on('keydown', function (event) {
if (event.key === 'Escape') setMobileMenuOpen(false);
var $menu;
if (event.key !== 'Escape') return;
$menu = $('[data-profile-mobile-menu]').first();
if (!$menu.length || $menu.prop('hidden')) return;
setMobileMenuOpen(false);
$('[data-profile-mobile-menu-toggle]').first().trigger('focus');
});
}
@@ -411,6 +601,33 @@
}
}
function promptAction(options) {
var settings = $.extend({
title: '填写内容',
value: '',
formType: 1,
maxlength: 200
}, options || {});
return new Promise(function (resolve) {
if (!layerApi) {
resolve(window.prompt(settings.title, settings.value) || null);
return;
}
layerApi.prompt({
title: settings.title,
value: settings.value,
formType: settings.formType,
maxlength: settings.maxlength,
cancel: function () { resolve(null); }
}, function (value, index) {
resolve(value);
layerApi.close(index);
});
});
}
function bindPromptActions() {
$(document).on('click', '[data-layer-prompt]', function (event) {
var $item = $(this);
@@ -493,6 +710,7 @@
$(function () {
initLayui();
initWorkspaceNavigation();
bindLogout();
bindConfirmActions();
bindPromptActions();
@@ -508,6 +726,8 @@
Object.assign(profileUI, {
confirm: openConfirm,
confirmAction: confirmAction,
promptAction: promptAction,
closeLogout: closeLegacyLogout,
initLayui: initLayui,
getGenealogyId: getGenealogyId,
@@ -521,6 +741,7 @@
refreshCurrentGenealogyContext: refreshCurrentGenealogyContext,
syncGenealogyContextLinks: syncGenealogyContextLinks,
renderApiState: renderApiState,
setApiState: setApiState
setApiState: setApiState,
revealDetail: revealDetail
});
})(window, window.jQuery || (window.layui && window.layui.$));