重构 monorepo 并完善网页端订阅与首页体验

- 迁移为 frontend-web、frontend-electron、backend-web 与 docker 部署结构
- 网页端:订阅门禁二次弹窗、套餐/支付组件化、顶栏分组对齐
- 首页:最近文件与模板库布局优化,缩略图对齐,下载与删除操作
- 新增管理后台、支付与云端文件 API,更新 README 与项目规范

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
24kycj
2026-06-08 18:17:39 +08:00
parent 5814b7bc0e
commit 88c6ce8ccc
511 changed files with 189528 additions and 22804 deletions
+81
View File
@@ -0,0 +1,81 @@
(function () {
'use strict';
function showAuthedNav() {
var guest = document.getElementById('auth_guest');
var account = document.getElementById('auth_account');
var session = document.getElementById('auth_session');
if (guest) guest.style.display = 'none';
if (account) account.style.display = 'inline-flex';
if (session) session.style.display = 'inline-flex';
}
function clearSession() {
if (typeof window.soonClearAuthSession === 'function') {
window.soonClearAuthSession();
} else {
localStorage.removeItem('soon_access');
localStorage.removeItem('soon_refresh');
}
}
function initTopbar(options) {
options = options || {};
var tok = localStorage.getItem('soon_access') || '';
var login = document.getElementById('auth_login');
var reg = document.getElementById('auth_register');
var member = document.getElementById('auth_member');
var admin = document.getElementById('auth_admin');
var logout = document.getElementById('auth_logout');
var avatar = document.getElementById('auth_avatar');
if (!tok) return;
showAuthedNav();
if (login) login.style.display = 'none';
if (reg) reg.style.display = 'none';
if (member) member.style.display = 'inline-flex';
if (logout) logout.style.display = 'inline-flex';
var base = (window.SOON_DEPLOY_CONFIG && window.SOON_DEPLOY_CONFIG.api_v1_base) || '';
if (!base) return;
var meFetch = typeof window.soonAuthedFetch === 'function'
? window.soonAuthedFetch(base + '/auth/me', { headers: { Authorization: 'Bearer ' + tok } })
: fetch(base + '/auth/me', { headers: { Authorization: 'Bearer ' + tok } });
meFetch
.then(function (r) { return r.json(); })
.then(function (j) {
if (!j.ok || !j.data) {
clearSession();
location.reload();
return;
}
if (j.data.role === 'admin' && admin) admin.style.display = 'inline-flex';
if (avatar && j.data.email) {
avatar.style.display = 'inline-flex';
avatar.textContent = j.data.email.charAt(0).toUpperCase();
avatar.title = j.data.email;
}
if (typeof window.soonLoadMembership === 'function') {
window.soonLoadMembership().then(function () {
if (typeof window.soonRefreshPortalIdentity === 'function') {
window.soonRefreshPortalIdentity();
}
});
}
})
.catch(function () { /* keep authed shell */ });
if (logout) {
logout.addEventListener('click', function (e) {
e.preventDefault();
clearSession();
if (options.logoutReload !== false) location.reload();
else location.href = 'index.web.html';
});
}
}
window.soonPortalAuth = { init: initTopbar };
})();