优化报销管理增加挂靠
This commit is contained in:
1 parent
7b1c94b5ff
commit
ee49ef15b5
24 files changed
+1267
-70
No files matched your search
+118
-3
@@ -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;
|
||||
|
||||
Reference in new issue
Block a user