优化报销管理增加挂靠

This commit is contained in:
hero920103 committed 2026-11-06 01:13:28 +08:00
1 parent 7b1c94b5ff
commit ee49ef15b5
24 files changed
+1267 -70

No files matched your search

+118 -3
View File
@@ -202,10 +202,26 @@
.form-foot {
position: absolute;
left: 0; right: 0; bottom: 26px;
display: flex;
align-items: center;
justify-content: center;
gap: 12px;
text-align: center;
font-size: 12px;
color: #a3acbf;
}
/* 底部「清除缓存」文字按钮 */
.cache-clear-btn {
border: 0;
background: none;
padding: 0;
font: inherit;
color: var(--primary);
cursor: pointer;
transition: color .2s;
}
.cache-clear-btn:hover { color: var(--primary-dark); text-decoration: underline; }
.cache-clear-btn:disabled { opacity: .6; cursor: default; text-decoration: none; }
.error {
display: none;
@@ -737,7 +753,10 @@
</div>
<div class="form-foot">© 2026 云泽科技 版权所有</div>
<div class="form-foot">
<span>© 2026 云泽科技 版权所有</span>
<button id="cacheClearBtn" class="cache-clear-btn" type="button" onclick="clearSiteCache()" title="仅清除本站在当前浏览器中的缓存数据">清除缓存</button>
</div>
</main>
</div>
@@ -1075,7 +1094,9 @@
return;
}
if (res.redirect) { window.location.href = res.redirect; return; }
window.location.href = '/auth/login';
// 会话已建立但确实没有回跳地址:明确提示,绝不再跳回登录页造成死循环
showError('登录成功,但未获取到回跳地址,请从业务系统重新进入');
setBtnLoading(false);
})
.catch(function () {
showError('网络异常,请稍后重试');
@@ -1094,7 +1115,7 @@
.then(function (res) {
if (res.code !== 200) { showError(res.msg || '切换失败'); return; }
if (res.redirect) { window.location.href = res.redirect; return; }
window.location.href = '/auth/login';
showError('已进入所选企业,但未获取到回跳地址,请从业务系统重新进入');
})
.catch(function () { showError('网络异常,请稍后重试'); });
}
@@ -1105,6 +1126,100 @@
});
}
/**
* 清除本站在当前浏览器里的全部缓存数据。
*
* localStorage / sessionStorage / document.cookie / Cache Storage /
* IndexedDB / Service Worker 都受同源策略约束,只会作用于认证中心自己的
* origin,不会影响 back.yunzer.cn 等其它站点。
* HttpOnly 的 yz_sid 前端读不到,交给 /auth/clear-site-data 的
* Clear-Site-Data 响应头与 Set-Cookie 一起清除。
*/
function clearSiteCache() {
var btn = document.getElementById('cacheClearBtn');
if (btn) { btn.disabled = true; btn.textContent = '清除中...'; }
// 1. Web Storage(记住账号、各类前端状态)
try {
localStorage.clear();
sessionStorage.clear();
} catch (e) { /* 隐私模式下存储可能不可访问 */ }
// 2. 当前站点可写的 Cookie。只针对本站 host:不尝试 .yunzer.cn 等父域,
// 否则会连带清掉 back.yunzer.cn / platform.yunzer.cn 等兄弟站点的数据。
// 两次删除分别覆盖 host-only cookie 与显式 Domain=当前 host 的 cookie。
try {
var cookieNames = (document.cookie || '').split(';').map(function (item) {
return item.split('=')[0].trim();
}).filter(Boolean);
var host = window.location.hostname;
var expired = '=; Max-Age=0; Path=/; expires=Thu, 01 Jan 1970 00:00:00 GMT';
cookieNames.forEach(function (name) {
document.cookie = name + expired;
document.cookie = name + expired + '; Domain=' + host;
});
} catch (e) { /* ignore */ }
var tasks = [];
// 3. Cache Storage(离线资源 / 静态资源缓存)
if (window.caches && caches.keys) {
tasks.push(caches.keys().then(function (keys) {
return Promise.all((keys || []).map(function (key) { return caches.delete(key); }));
}).catch(function () {}));
}
// 4. Service Worker 注册
if (navigator.serviceWorker && navigator.serviceWorker.getRegistrations) {
tasks.push(navigator.serviceWorker.getRegistrations().then(function (regs) {
return Promise.all((regs || []).map(function (reg) { return reg.unregister(); }));
}).catch(function () {}));
}
// 5. IndexedDB(databases() 在部分浏览器不可用,跳过即可)
if (window.indexedDB && indexedDB.databases) {
tasks.push(indexedDB.databases().then(function (dbs) {
return Promise.all((dbs || []).map(function (db) {
return new Promise(function (resolve) {
if (!db || !db.name) { resolve(); return; }
var done = false;
var finish = function () { if (!done) { done = true; resolve(); } };
var req = indexedDB.deleteDatabase(db.name);
req.onsuccess = req.onerror = req.onblocked = finish;
// 其它标签页占用数据库时 onblocked 可能不触发,兜底避免卡住
setTimeout(finish, 1500);
});
}));
}).catch(function () {}));
}
// 6. 后端清 HttpOnly 会话 Cookie,并让浏览器按 origin 清 HTTP 缓存与存储;
// 服务尚未部署新端点(404)或接口异常时退回已有登出接口,
// 至少保证会话 Cookie 被清除;整体超时也不阻断前面的前端清理结果
var legacyClear = function () {
return fetch('/auth/logout', { method: 'POST', credentials: 'same-origin', cache: 'no-store' })
.catch(function () {});
};
var clearRequest = fetch('/auth/clear-site-data', {
method: 'POST',
credentials: 'same-origin',
cache: 'no-store'
}).then(function (res) {
if (res.ok) return;
return legacyClear();
}).catch(legacyClear);
tasks.push(Promise.race([
clearRequest,
new Promise(function (resolve) { setTimeout(resolve, 5000); })
]));
Promise.all(tasks).then(function () {
// 保留 client_id / redirect,清完直接从登录页重新开始
window.location.replace('/auth/login?client_id=' + encodeURIComponent(CLIENT_ID) +
(REDIRECT ? '&redirect=' + encodeURIComponent(REDIRECT) : ''));
});
}
// ==================== 微信扫码登录(扫码 → 小程序内确认;已接 scan/start、scan/status) ====================
var scanScene = '';
var scanExpireAt = 0;