feat: 保持模块列表筛选和分页状态 (#156)

This commit is contained in:
chengma
2026-08-11 15:18:00 +08:00
parent d7e548a60f
commit cd1fc8ae68
4 changed files with 155 additions and 7 deletions
+82
View File
@@ -9,6 +9,87 @@
(function () {
"use strict";
/* ── 模块导航状态 ────────────────────────────
列表筛选和页码本来就在 URL 中。这里按账号、按浏览器标签页记住每个
主模块最后一次稳定 URL,让采购员切走再回来时不用重复筛选。
只接受已知主列表路径和查询参数;勾选、弹窗、临时提示及写操作状态
都不进入 sessionStorage。链接原始 href 保持模块根地址,因此脚本失效时
仍可正常导航。 */
var MODULE_QUERY_KEYS = {
"/shopee": ["goods_id", "status", "shop", "image", "page"],
"/pdd": ["q", "status", "page"],
"/syb": ["order_no", "shop", "stage", "page", "date_from", "date_to"],
"/tasks": ["type", "status", "creator", "q", "page"],
"/clients": ["name", "page"],
"/users": ["q", "status", "page"]
};
var MODULE_STATE_PREFIX = "cmautobuy:module-state:";
function moduleStateStorageKey(userID, moduleRoot) {
return MODULE_STATE_PREFIX + userID + ":" + moduleRoot;
}
function stableModuleURL(moduleRoot, rawURL) {
if (!Object.prototype.hasOwnProperty.call(MODULE_QUERY_KEYS, moduleRoot)) return moduleRoot;
if (!rawURL || rawURL.length > 2048) return moduleRoot;
var parsed;
try {
parsed = new URL(rawURL, window.location.origin);
} catch (error) {
return moduleRoot;
}
if (parsed.origin !== window.location.origin || parsed.pathname !== moduleRoot) return moduleRoot;
var allowed = MODULE_QUERY_KEYS[moduleRoot];
var stable = new URLSearchParams();
parsed.searchParams.forEach(function (value, key) {
if (allowed.indexOf(key) !== -1 && value !== "") stable.set(key, value);
});
var query = stable.toString();
return moduleRoot + (query ? "?" + query : "");
}
function setupModuleNavigationState() {
var nav = document.querySelector("[data-module-navigation]");
if (!nav) return;
var userID = nav.getAttribute("data-ui-state-user") || "";
if (!userID) return;
var currentRoot = Object.prototype.hasOwnProperty.call(MODULE_QUERY_KEYS, window.location.pathname)
? window.location.pathname
: "";
try {
if (currentRoot) {
sessionStorage.setItem(
moduleStateStorageKey(userID, currentRoot),
stableModuleURL(currentRoot, window.location.href)
);
}
nav.querySelectorAll("[data-module-root]").forEach(function (link) {
var moduleRoot = link.getAttribute("data-module-root") || "";
var saved = sessionStorage.getItem(moduleStateStorageKey(userID, moduleRoot));
link.href = stableModuleURL(moduleRoot, saved);
});
} catch (error) {
/* 隐私模式或浏览器策略可能禁用存储。默认 href 仍是安全回退。 */
}
var logoutForm = nav.querySelector(".nav-logout");
if (logoutForm) {
logoutForm.addEventListener("submit", function () {
try {
Object.keys(MODULE_QUERY_KEYS).forEach(function (moduleRoot) {
sessionStorage.removeItem(moduleStateStorageKey(userID, moduleRoot));
});
} catch (error) {
/* 登出不能因为清理界面状态失败而被阻止。 */
}
});
}
}
/* ── 全选 / 反选 ──────────────────────────────
表头的勾选框控制本表格所有行的勾选框。 */
function setupCheckAll(root) {
@@ -484,6 +565,7 @@
}
document.addEventListener("DOMContentLoaded", function () {
setupModuleNavigationState();
document.querySelectorAll("table").forEach(setupCheckAll);
setupConfirmDelete();
setupConfirmSubmit();