永久会员与模板库后台化:预览门控、轻量首页与 Admin CRUD
- 会员改为永久激活方案;云端文件不再拦截非会员;预览弹窗内导出/打印才校验 - 首页最近文件支持本地记录,登录后与云端合并;移除独立会员页与订阅页 - 模板库入库管理:soon_templates 表、Admin 上传 CRUD、/templates 轻量列表与按需下载 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,152 @@
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
var _gate = { index: null, opts: null };
|
||||
|
||||
function esc(s) {
|
||||
if (s == null) return '';
|
||||
return String(s).replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>');
|
||||
}
|
||||
|
||||
function toast(msg, type) {
|
||||
if (typeof window.soonToast === 'function') window.soonToast(msg, type);
|
||||
}
|
||||
|
||||
function apiBase() {
|
||||
var cfg = window.SOON_DEPLOY_CONFIG && window.SOON_DEPLOY_CONFIG.api_v1_base;
|
||||
if (cfg) return String(cfg).replace(/\/+$/, '');
|
||||
if (window.location) return window.location.origin + '/api/v1';
|
||||
return '/api/v1';
|
||||
}
|
||||
|
||||
function ensureLayer(cb) {
|
||||
if (typeof layer !== 'undefined' && layer.open) {
|
||||
if (layer.config) layer.config({ skin: 'soon-layer' });
|
||||
cb();
|
||||
return;
|
||||
}
|
||||
if (typeof layui !== 'undefined') {
|
||||
layui.use(['layer'], function () {
|
||||
window.layer = layui.layer;
|
||||
layer.config({ skin: 'soon-layer' });
|
||||
cb();
|
||||
});
|
||||
return;
|
||||
}
|
||||
toast('登录功能暂不可用,请刷新页面后重试', 'warn');
|
||||
}
|
||||
|
||||
function shellHtml(reason) {
|
||||
return '<div class="soon-login-gate">' +
|
||||
'<header class="soon-subscribe-modal__head">' +
|
||||
'<span class="soon-subscribe-modal__eyebrow">登录</span>' +
|
||||
'<h3 class="soon-subscribe-modal__title">登录后继续</h3>' +
|
||||
'<p class="soon-subscribe-modal__desc">预览内' + esc(reason || '导出或打印') + '需先登录账号。</p>' +
|
||||
'</header>' +
|
||||
'<form class="soon-login-gate__form" data-role="login-form">' +
|
||||
'<div class="soon-input-wrap"><input type="email" name="email" required class="soon-input" placeholder="邮箱" autocomplete="email"></div>' +
|
||||
'<div class="soon-input-wrap"><input type="password" name="password" required class="soon-input" placeholder="密码" autocomplete="current-password"></div>' +
|
||||
'<p class="soon-login-gate__error" data-role="login-error" style="display:none"></p>' +
|
||||
'<button type="submit" class="soon-btn soon-btn--block">登录</button>' +
|
||||
'</form>' +
|
||||
'<p class="soon-login-gate__links">还没有账号?<a href="register.web.html" target="_blank" rel="noopener">立即注册</a></p>' +
|
||||
'<footer class="soon-subscribe-modal__foot">' +
|
||||
'<button type="button" class="soon-subscribe-modal__stay" data-action="stay">继续设计</button>' +
|
||||
'</footer></div>';
|
||||
}
|
||||
|
||||
function closeGate() {
|
||||
var idx = _gate.index;
|
||||
_gate = { index: null, opts: null };
|
||||
if (idx != null && typeof layer !== 'undefined') {
|
||||
try { layer.close(idx); } catch (e) { /* ignore */ }
|
||||
}
|
||||
}
|
||||
|
||||
function bindModal(modal) {
|
||||
var form = modal.querySelector('[data-role="login-form"]');
|
||||
var errEl = modal.querySelector('[data-role="login-error"]');
|
||||
modal.addEventListener('click', function (e) {
|
||||
var stay = e.target.closest('[data-action="stay"]');
|
||||
if (stay) {
|
||||
e.preventDefault();
|
||||
closeGate();
|
||||
}
|
||||
});
|
||||
if (!form) return;
|
||||
form.addEventListener('submit', function (e) {
|
||||
e.preventDefault();
|
||||
if (errEl) {
|
||||
errEl.style.display = 'none';
|
||||
errEl.textContent = '';
|
||||
}
|
||||
var email = (form.email && form.email.value || '').trim();
|
||||
var password = form.password ? form.password.value : '';
|
||||
fetch(apiBase() + '/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 || !j.data || !j.data.access_token) {
|
||||
if (errEl) {
|
||||
errEl.textContent = (j && j.message) || '登录失败';
|
||||
errEl.style.display = 'block';
|
||||
}
|
||||
return;
|
||||
}
|
||||
localStorage.setItem('soon_access', j.data.access_token);
|
||||
if (j.data.refresh_token) localStorage.setItem('soon_refresh', j.data.refresh_token);
|
||||
var opts = _gate.opts;
|
||||
closeGate();
|
||||
var load = typeof window.soonLoadMembership === 'function'
|
||||
? window.soonLoadMembership(true)
|
||||
: Promise.resolve();
|
||||
load.then(function () {
|
||||
if (typeof window.soonRefreshPortalIdentity === 'function') window.soonRefreshPortalIdentity();
|
||||
if (typeof window.soonReloadRecentFiles === 'function') window.soonReloadRecentFiles();
|
||||
if (opts && typeof opts.onSuccess === 'function') opts.onSuccess();
|
||||
});
|
||||
}).catch(function () {
|
||||
if (errEl) {
|
||||
errEl.textContent = '网络错误,请稍后重试';
|
||||
errEl.style.display = 'block';
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function soonShowLoginGate(opts) {
|
||||
opts = opts || {};
|
||||
ensureLayer(function () {
|
||||
if (_gate.index != null) {
|
||||
try { layer.close(_gate.index); } catch (e) { /* ignore */ }
|
||||
}
|
||||
_gate.opts = opts;
|
||||
var width = Math.min(420, window.innerWidth - 24);
|
||||
layer.open({
|
||||
type: 1,
|
||||
skin: 'soon-layer',
|
||||
title: false,
|
||||
closeBtn: 1,
|
||||
shadeClose: true,
|
||||
area: [width + 'px', 'auto'],
|
||||
content: shellHtml(opts.reason),
|
||||
success: function (layero, index) {
|
||||
var layerEl = layero && layero[0] ? layero[0] : layero;
|
||||
if (layerEl && layerEl.classList) layerEl.classList.add('soon-layer--subscribe');
|
||||
var content = layerEl && layerEl.querySelector ? layerEl.querySelector('.layui-layer-content') : null;
|
||||
if (content) content.style.padding = '0';
|
||||
var modal = layerEl.querySelector('.soon-login-gate');
|
||||
_gate.index = index;
|
||||
_gate.opts = opts;
|
||||
if (modal) bindModal(modal);
|
||||
},
|
||||
end: function () {
|
||||
_gate = { index: null, opts: null };
|
||||
},
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
window.soonShowLoginGate = soonShowLoginGate;
|
||||
})();
|
||||
Reference in New Issue
Block a user