重构 monorepo 并完善网页端订阅与首页体验
- 迁移为 frontend-web、frontend-electron、backend-web 与 docker 部署结构 - 网页端:订阅门禁二次弹窗、套餐/支付组件化、顶栏分组对齐 - 首页:最近文件与模板库布局优化,缩略图对齐,下载与删除操作 - 新增管理后台、支付与云端文件 API,更新 README 与项目规范 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,116 @@
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
var TOKEN_KEY = 'soon_access';
|
||||
|
||||
function getV1Base() {
|
||||
var cfg = window.SOON_DEPLOY_CONFIG || {};
|
||||
return (cfg.api_v1_base || '/api/v1').replace(/\/+$/, '');
|
||||
}
|
||||
|
||||
function redirectTarget() {
|
||||
var p = new URLSearchParams(location.search);
|
||||
var r = p.get('redirect');
|
||||
if (r && typeof soonSafeRedirect === 'function') {
|
||||
return soonSafeRedirect(r, 'index.html');
|
||||
}
|
||||
return r || 'index.html';
|
||||
}
|
||||
|
||||
function clearTokens() {
|
||||
try {
|
||||
localStorage.removeItem(TOKEN_KEY);
|
||||
localStorage.removeItem('soon_refresh');
|
||||
} catch (e) { /* ignore */ }
|
||||
}
|
||||
|
||||
function showError(msg) {
|
||||
var err = document.getElementById('loginError');
|
||||
if (err) {
|
||||
err.textContent = msg;
|
||||
err.style.display = 'block';
|
||||
}
|
||||
}
|
||||
|
||||
async function verifyAdmin(token) {
|
||||
var r = await fetch(getV1Base() + '/auth/me', {
|
||||
headers: { Authorization: 'Bearer ' + token },
|
||||
});
|
||||
var j = await r.json();
|
||||
if (!j.ok || !j.data || j.data.role !== 'admin') return null;
|
||||
return j.data;
|
||||
}
|
||||
|
||||
function init() {
|
||||
if (localStorage.getItem(TOKEN_KEY)) {
|
||||
verifyAdmin(localStorage.getItem(TOKEN_KEY)).then(function (me) {
|
||||
if (me) location.href = redirectTarget();
|
||||
});
|
||||
}
|
||||
|
||||
var pwdToggle = document.getElementById('pwdToggle');
|
||||
if (pwdToggle) {
|
||||
pwdToggle.onclick = function () {
|
||||
var p = document.getElementById('password');
|
||||
var show = p.type === 'password';
|
||||
p.type = show ? 'text' : 'password';
|
||||
this.textContent = show ? '隐藏' : '显示';
|
||||
};
|
||||
}
|
||||
|
||||
var form = document.getElementById('loginForm');
|
||||
if (!form) return;
|
||||
|
||||
form.onsubmit = function (e) {
|
||||
e.preventDefault();
|
||||
var err = document.getElementById('loginError');
|
||||
if (err) { err.style.display = 'none'; err.textContent = ''; }
|
||||
|
||||
var email = document.getElementById('email').value.trim();
|
||||
var password = document.getElementById('password').value;
|
||||
|
||||
fetch(getV1Base() + '/auth/login', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ email: email, password: password }),
|
||||
}).then(function (r) { return r.json(); }).then(function (j) {
|
||||
if (!j.ok) {
|
||||
showError(j.message || '登录失败');
|
||||
return;
|
||||
}
|
||||
localStorage.setItem(TOKEN_KEY, j.data.access_token);
|
||||
localStorage.setItem('soon_refresh', j.data.refresh_token);
|
||||
return verifyAdmin(j.data.access_token);
|
||||
}).then(function (me) {
|
||||
if (me === undefined) return;
|
||||
if (!me) {
|
||||
clearTokens();
|
||||
showError('无管理员权限,请使用管理员账号登录');
|
||||
soonToast('无管理员权限', 'warn');
|
||||
return;
|
||||
}
|
||||
location.href = redirectTarget();
|
||||
}).catch(function () {
|
||||
showError('网络错误,请稍后重试');
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
function boot() {
|
||||
if (document.readyState === 'loading') {
|
||||
document.addEventListener('DOMContentLoaded', init);
|
||||
} else {
|
||||
init();
|
||||
}
|
||||
}
|
||||
|
||||
if (typeof layui !== 'undefined') {
|
||||
layui.use(['layer'], function () {
|
||||
window.layer = layui.layer;
|
||||
layer.config({ skin: 'soon-layer' });
|
||||
boot();
|
||||
});
|
||||
} else {
|
||||
boot();
|
||||
}
|
||||
})();
|
||||
Reference in New Issue
Block a user