|
|
@@ -99,8 +99,8 @@
|
|
|
<div class="pobj-spinner"></div>
|
|
|
</div>
|
|
|
<%-- 功能说明:移除 thnType 直出调试内容,避免进入页面即输出 by xu 20260123 --%>
|
|
|
- <%-- 功能说明:主布局容器(左侧表单 + 右侧 ss-sidebar) by xu 20260113 --%>
|
|
|
- <div style="display: flex; height: 100%; " v-show="homeReady">
|
|
|
+ <%-- 功能说明:主布局容器(左侧表单 + 右侧 ss-sidebar);为首屏 rowNumPer 自适应计算需要,避免用 homeReady 把容器 display:none(否则无法测量宽高) by xu 20260123 --%>
|
|
|
+ <div style="display: flex; height: 100%; ">
|
|
|
<%-- 功能说明:左侧表单区域在 flex 中占满剩余宽度(避免挤掉右侧 ss-sidebar) by xu 20260113 --%>
|
|
|
<form class="page-container" id="myForm" style="flex: 1; min-width: 0; width: auto;"
|
|
|
action="<ss:serv name='${currentService.servName}' dest='${currentService.dest}' parm='${currentService.parm}'/>"
|
|
|
@@ -1007,7 +1007,15 @@
|
|
|
rootFuncList: [], // 根功能
|
|
|
hasKeyword: false, // 是否有关键词
|
|
|
hasScope: false, // 是否带范围
|
|
|
- thnType: 0, // 缩略图类型:1横向 2竖向 3方形 4圆形(目前仅用 1/2,其他先不处理)
|
|
|
+ thnType: (() => { // 功能说明:首屏 thnType 优先从 JSP 注入(用于第一个接口前正确计算 rowNumPer);空/缺省回退 0 by xu 20260123
|
|
|
+ try {
|
|
|
+ const s = String("${thnType}" || "").trim();
|
|
|
+ const n = parseInt(s, 10);
|
|
|
+ return isNaN(n) ? 0 : n;
|
|
|
+ } catch (_) {
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ })(), // 缩略图类型:1横向 2竖向 3方形 4圆形(目前仅用 1/2,其他先不处理)
|
|
|
ssPaging: {pageNo: 1, rowNumPer: 12, rowNum: 0}, // 翻页信息 // 功能说明:分页默认每页12条(全文件仅此处兜底) by xu 20260123
|
|
|
rbarFuncList: [], // 右侧栏功能
|
|
|
rbarTabNameList: [], // 右侧栏选项卡
|
|
|
@@ -1020,14 +1028,23 @@
|
|
|
listConfig: window.ss.dom.listConfig || {draftbox: [], list: []},
|
|
|
formElemConfig: window.ss.dom.formElemConfig || {},
|
|
|
// 卡片区域:自动分列/宽度平分 by xu 20260109
|
|
|
- cardGridKind: '', // none/photo/thumbnail by xu 20260109
|
|
|
+ cardGridKind: (() => { // 功能说明:首屏按 thnType 预设网格类型(决定 --ss-card-min),避免缩略图业务第一个接口仍按 300px 计算 by xu 20260123
|
|
|
+ try {
|
|
|
+ const t = (() => { const s = String("${thnType}" || "").trim(); const n = parseInt(s, 10); return isNaN(n) ? 0 : n; })();
|
|
|
+ if (t === 1) return "thumbnail";
|
|
|
+ if (t === 2) return "photo";
|
|
|
+ return "none";
|
|
|
+ } catch (_) {
|
|
|
+ return "none";
|
|
|
+ }
|
|
|
+ })(), // none/photo/thumbnail by xu 20260109
|
|
|
// 卡片主体点击动作:view=查看(调用 item.onclick);single=单选互斥;角标仍多选 by xu 20260109
|
|
|
cardClickAction: "view", // 功能说明:默认先用 view,首页接口若返回预订面板则切到 single by xu 20260114
|
|
|
hasBookPanel: false, // 功能说明:是否存在预订面板(驱动 cardClickAction + 选中后联动 cxycl) by xu 20260116
|
|
|
hasServPanel: false, // 功能说明:是否存在服务面板(严格依赖首页 rbarTabNameList 是否返回 rbarServ) by xu 20260116
|
|
|
hasObjPanel: false, // 功能说明:是否存在对象面板(严格依赖首页 rbarTabNameList 是否返回 rbarObj;无则不显示“已选”且禁止选中) by xu 20260122
|
|
|
- showRightSidebar: true, // 功能说明:右侧栏显隐(临时按 rbarTabNameList/rbarFuncList/pstatList 是否为空判断) by xu 20260122
|
|
|
- rbar: null, // 功能说明:后端 0 服务新增右侧栏标识 rbar(true=展示;缺省=字段不存在) by xu 20260123
|
|
|
+ rbar: (String("${rbar}" || "").trim().toLowerCase() === "true") ? true : null, // 功能说明:JSP 注入 rbar:有字段且为 "true" 才展示;缺省/空串为 null,首页接口返回后会覆盖 by xu 20260123
|
|
|
+ showRightSidebar: (String("${rbar}" || "").trim().toLowerCase() === "true"), // 功能说明:首屏右侧栏显隐以 JSP rbar 为准(用于首屏测量口径) by xu 20260123
|
|
|
autoRowNumPer: 0, // 功能说明:动态计算的 rowNumPer(只记录,下次接口请求时生效;resize 不立即重拉) by xu 20260123
|
|
|
yclLoading: false, // 功能说明:已选对象联动(cxycl)加载状态 by xu 20260114
|
|
|
yclResp: null, // 功能说明:已选对象联动接口返回(调试/兜底) by xu 20260114
|
|
|
@@ -1900,16 +1917,29 @@
|
|
|
if (!W || !H) {
|
|
|
// 功能说明:首屏 homeReady=false 时容器 display:none,W/H 为 0;此处回退用 viewport 估算 by xu 20260123
|
|
|
const vw = Math.max(0, document.documentElement?.clientWidth || window.innerWidth || 0);
|
|
|
- const vh = Math.max(0, document.documentElement?.clientHeight || window.innerHeight || 0);
|
|
|
- // 右侧栏宽度:后端标识未到位前按 380 估算(未来可改为从 rbar 决定) by xu 20260123
|
|
|
- const sidebarW = this.showRightSidebar ? 380 : 0;
|
|
|
+ const vhRaw = Math.max(0, document.documentElement?.clientHeight || window.innerHeight || 0);
|
|
|
+ // 功能说明:首屏高度按 URL 上的 removeHigh 扣减(弹窗/iframe 会预留顶部/底部区域),否则 rows 会偏大 by xu 20260123
|
|
|
+ let removeHigh = 0;
|
|
|
+ try {
|
|
|
+ const qs = window.location && window.location.search ? window.location.search : "";
|
|
|
+ const m = String(qs).match(/(?:\\?|&)removeHigh=([^&]+)/);
|
|
|
+ if (m && m[1] != null) {
|
|
|
+ const v = parseFloat(decodeURIComponent(m[1]));
|
|
|
+ if (!isNaN(v) && v > 0) removeHigh = v;
|
|
|
+ }
|
|
|
+ } catch (_) {
|
|
|
+ }
|
|
|
+ const vh = Math.max(0, vhRaw - removeHigh);
|
|
|
+ // 功能说明:右侧栏宽度用 rbar 判定(JSP 注入已写入 this.rbar;首页接口返回后会覆盖) by xu 20260123
|
|
|
+ const rbarFlag = (this.rbar === true);
|
|
|
+ const sidebarW = rbarFlag ? 380 : 0;
|
|
|
const minW = (Number(this.thnType || 0) === 1) ? 400 : (Number(this.thnType || 0) === 2) ? 320 : 300;
|
|
|
const gap = 20;
|
|
|
const padLeft = 20;
|
|
|
const padRight = 20;
|
|
|
const padTop = 0;
|
|
|
const padBottom = 100;
|
|
|
- const pagerH = 80;
|
|
|
+ const pagerH = 32; // 功能说明:分页高度以 .pager-container .pager-content 的 32px 为准(首屏未渲染时用该值预留) by xu 20260123
|
|
|
let cardH = Number(this.__autoCardH || 0) || Number(this.measureAutoCardHeight?.() || 0);
|
|
|
if (cardH) this.__autoCardH = cardH;
|
|
|
if (!vw || !vh || !cardH) return { err: "zero_size", W, H, overlap, vw, vh, cardH, showRightSidebar: !!this.showRightSidebar };
|
|
|
@@ -1918,7 +1948,7 @@
|
|
|
const availH = Math.max(0, (vh - 75) - padTop - padBottom - pagerH); // 75=search/预留(与 CSS 对齐) by xu 20260123
|
|
|
const rows = Math.max(1, Math.floor((availH + gap) / (cardH + gap)));
|
|
|
const n = Math.max(1, cols * rows);
|
|
|
- return { n, cols, rows, W: 0, H: 0, overlap, gap, padTop, padBottom, padLeft, padRight, minW, pagerH, cardH, vw, vh, sidebarW, showRightSidebar: !!this.showRightSidebar, fallback: "viewport" };
|
|
|
+ return { n, cols, rows, W: 0, H: 0, overlap, gap, padTop, padBottom, padLeft, padRight, minW, pagerH, cardH, vw, vhRaw, vh, removeHigh, sidebarW, rbarFlag, fallback: "viewport" };
|
|
|
}
|
|
|
|
|
|
const gap = cs ? (parseFloat(cs.gap) || 0) : 0;
|
|
|
@@ -2084,10 +2114,17 @@
|
|
|
// 初始化:把 URL/form 上已有的参数合并到 form/ssPaging(支持回显 + ajax)
|
|
|
const curParams = this.getSearchFormParams();
|
|
|
this.form = {...this.form, ...curParams};
|
|
|
- // 功能说明:分页参数不再从表单读取/初始化(完全由 ssPaging 驱动,且页面不再输出分页隐藏域) by xu 20260123
|
|
|
- this.searchButtonConfigCheckId = String(this.form?.management || "99");
|
|
|
- // 初始化卡片网格类型(用于自动分列/宽度平分) by xu 20260109
|
|
|
- this.cardGridKind = this.detectCardGridKind();
|
|
|
+ // 功能说明:分页参数不再从表单读取/初始化(完全由 ssPaging 驱动,且页面不再输出分页隐藏域) by xu 20260123
|
|
|
+ this.searchButtonConfigCheckId = String(this.form?.management || "99");
|
|
|
+ // 功能说明:首屏在列表数据未到达前,按 thnType 预设 cardGridKind(决定 --ss-card-min),避免 detectCardGridKind 在空列表时把缩略图场景误判为 none by xu 20260123
|
|
|
+ try {
|
|
|
+ const t = Number(this.thnType || 0);
|
|
|
+ if (t === 1) this.cardGridKind = "thumbnail";
|
|
|
+ else if (t === 2) this.cardGridKind = "photo";
|
|
|
+ else this.cardGridKind = "none";
|
|
|
+ } catch (_) {
|
|
|
+ this.cardGridKind = "none";
|
|
|
+ }
|
|
|
// 初始化右侧边栏分区 by xu 20260113
|
|
|
this.initSidebarPanels();
|
|
|
// 功能说明:订阅系统编辑模式变化(来自 home 顶部按钮/菜单切换),用于业务页右下角“新增”入口显隐 by xu 20260123
|
|
|
@@ -2107,6 +2144,10 @@
|
|
|
this.userInteracted = false;
|
|
|
// 功能说明:首屏在第一个接口调用前,按当前容器尺寸预先计算 rowNumPer,并写入 ssPaging(使首页接口直接返回“刚好铺满”的条数) by xu 20260123
|
|
|
const startHome = () => {
|
|
|
+ // 功能说明:首屏以 JSP 注入的 rbar 作为右侧栏存在与否的唯一依据 by xu 20260123
|
|
|
+ try { this.showRightSidebar = (this.rbar === true); } catch (_) {}
|
|
|
+ // 功能说明:打印首屏关键输入(thnType/cardGridKind/rbar),排查“有缩略图首屏 rowNumPer 偏大” by xu 20260123
|
|
|
+ try { console.log("[objList][自适应分页] 首屏输入", { thnType: this.thnType, cardGridKind: this.cardGridKind, rbar: this.rbar, showRightSidebar: this.showRightSidebar }); } catch (_) {}
|
|
|
// 功能说明:首屏首次渲染时容器可能尚未有尺寸(W/H=0),用 rAF 重试几帧再发第一个接口,确保 rowNumPer 能在首屏生效 by xu 20260123
|
|
|
let tries = 0;
|
|
|
const maxTries = 20;
|