Преглед изворни кода

调整一级对象页自适应 rowpagenum

apple пре 3 дана
родитељ
комит
4d9ed8646a
1 измењених фајлова са 56 додато и 15 уклоњено
  1. 56 15
      page/env/objList.jsp

+ 56 - 15
page/env/objList.jsp

@@ -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;