Explorar o código

update:0316更新

apple hai 3 días
pai
achega
7a25dd73f5

+ 128 - 31
js/vue/ss-components.js

@@ -7514,6 +7514,7 @@ import { EVEN_VAR } from "./EventBus.js";
         sectionHeights: [],
         sectionCollapsed: [], // 功能说明:面板折叠状态(sectionPanels 索引) by xu 20260116
         sectionHeightsExpanded: [], // 功能说明:面板展开高度缓存(用于折叠后恢复) by xu 20260116
+        sectionLastItemCounts: [], // 功能说明:记录栏目数据量,供“无数据默认关闭/已选自动展开”规则复用 by xu 20260313
         chartCollapsed: [], // 功能说明:图表面板折叠状态(chartPanels 索引) by xu 20260116
         chartHeaderTitleDownAt: [], // 功能说明:双击检测绑定到 chart 标题区 by xu 20260116
         reportCollapsed: [], // 功能说明:报表面板折叠状态(reportPanels 索引) by xu 20260116
@@ -7549,6 +7550,93 @@ import { EVEN_VAR } from "./EventBus.js";
           { length: sectionCount },
           (_, i) => this.sectionHeightsExpanded?.[i] ?? null
         );
+        this.sectionLastItemCounts = Array.from(
+          { length: sectionCount },
+          (_, i) => Number(this.sectionLastItemCounts?.[i] ?? 0) || 0
+        );
+      },
+      __getPanelsForSectionState(panelsInput) {
+        return (panelsInput || []).length
+          ? panelsInput
+          : this.list?.length
+          ? [
+              {
+                type: "list",
+                title: "已选",
+                icon: "",
+                mode: this.listMode,
+                items: this.list,
+              },
+            ]
+          : [];
+      },
+      __getSectionPanelsForState(panelsInput) {
+        return this.__getPanelsForSectionState(panelsInput)
+          .filter((p) => {
+            const k = String(p?._tabKey ?? "")
+              .trim()
+              .toLowerCase();
+            const t = String(p?.title ?? "").trim();
+            if (k === "rbarobj") return false;
+            if (t === "对象") return false;
+            return true;
+          })
+          .filter((p) => p?.type !== "chart" && p?.type !== "report-table");
+      },
+      __getSectionPanelCount(panel) {
+        const explicitCount = Number(panel?.count);
+        if (Number.isFinite(explicitCount)) return explicitCount;
+        return Array.isArray(panel?.items) ? panel.items.length : 0;
+      },
+      __setSectionCollapsedState(index, collapsed) {
+        const i = Number(index);
+        if (isNaN(i) || i < 0) return;
+        const nextCollapsed = !!collapsed;
+        const collapsedHeight = 37;
+        const cur = !!this.sectionCollapsed?.[i];
+        const currentHeight = Number(this.sectionHeights?.[i] ?? 190) || 190;
+        if (nextCollapsed === cur) {
+          if (nextCollapsed && currentHeight !== collapsedHeight) {
+            this.sectionHeights.splice(i, 1, collapsedHeight);
+          }
+          return;
+        }
+        if (nextCollapsed) {
+          this.sectionHeightsExpanded[i] =
+            currentHeight > collapsedHeight
+              ? currentHeight
+              : Number(this.sectionHeightsExpanded?.[i] ?? 190) || 190;
+          this.sectionHeights.splice(i, 1, collapsedHeight);
+        } else {
+          const restore =
+            Number(this.sectionHeightsExpanded?.[i] ?? 190) || 190;
+          this.sectionHeights.splice(i, 1, restore);
+        }
+        this.sectionCollapsed.splice(i, 1, nextCollapsed);
+      },
+      __syncSectionAutoCollapse(panelsInput) {
+        const sectionPanels = this.__getSectionPanelsForState(panelsInput);
+        const sectionCount = sectionPanels.length;
+        this.ensureSectionHeights(sectionCount);
+        const prevCounts = Array.isArray(this.sectionLastItemCounts)
+          ? this.sectionLastItemCounts.slice()
+          : [];
+        const nextCounts = Array.from({ length: sectionCount }, (_, i) =>
+          this.__getSectionPanelCount(sectionPanels[i])
+        );
+        this.sectionLastItemCounts = nextCounts;
+        sectionPanels.forEach((panel, index) => {
+          const count = Number(nextCounts[index] ?? 0) || 0;
+          const prevCount = Number(prevCounts[index] ?? 0) || 0;
+          const title = String(panel?.title ?? "").trim();
+          if (count <= 0) {
+            this.__setSectionCollapsedState(index, true);
+            return;
+          }
+          if (title === "已选" && count > prevCount) {
+            this.__setSectionCollapsedState(index, false);
+          }
+        });
       },
       toggleSectionCollapse(index) {
         // 功能说明:双击 header 折叠/展开 section 面板(仅控制高度与内容渲染) by xu 20260116
@@ -7812,6 +7900,23 @@ import { EVEN_VAR } from "./EventBus.js";
         ); // 功能说明:清理 cancel 监听,避免残留 by xu 20260122
       },
     },
+    watch: {
+      panels: {
+        handler(nextPanels) {
+          this.__syncSectionAutoCollapse(nextPanels);
+        },
+        deep: true,
+        immediate: true,
+      },
+      list: {
+        handler(nextList) {
+          if ((this.panels || []).length) return;
+          this.__syncSectionAutoCollapse(nextList);
+        },
+        deep: true,
+        immediate: true,
+      },
+    },
     mounted() {
       clearTimeout(this.resizeTimer);
       this.resizeTimer = null;
@@ -7916,15 +8021,14 @@ import { EVEN_VAR } from "./EventBus.js";
             // 可拖拽的业务面板容器 by xu 20260106
             Vue.h(
               "div",
-              { class: "ss-sidebar-sections", style: { flex: "0 0 auto" } }, // 功能说明:禁止 flex shrink,避免面板很多时 header 被压缩成一条线 by xu 20260116
+              { class: "ss-sidebar-sections", style: { flex: "0 0 auto" } },
               sectionPanels.flatMap((p, idx) => {
-                // 功能说明:section 面板支持 list / report-table 两种渲染 by xu 20260115
                 const panelContent =
                   p?.type === "report-table"
                     ? Vue.h(SsSidebarReportTableComp, {
                         key: `ss-sidebar-report-in-section-${idx}-${
                           p?.title ?? ""
-                        }`, // 功能说明:加 key 防止多面板时组件实例复用导致折叠态不更新 by xu 20260116
+                        }`,
                         title: p?.title ?? "",
                         icon: p?.icon ?? "",
                         iconClass: p?.iconClass ?? "",
@@ -7932,7 +8036,7 @@ import { EVEN_VAR } from "./EventBus.js";
                         onOpen: (srv, ctx) => p?.onOpen?.(srv, ctx),
                       })
                     : Vue.h(SsSidebarListComp, {
-                        key: `ss-sidebar-list-${idx}-${p?.title ?? ""}`, // 功能说明:加 key 防止多面板时组件实例复用导致折叠态不更新 by xu 20260116
+                        key: `ss-sidebar-list-${idx}-${p?.title ?? ""}`,
                         title: p?.title ?? "",
                         icon: p?.icon ?? "",
                         count: p?.count ?? p?.items?.length ?? "",
@@ -7943,17 +8047,16 @@ import { EVEN_VAR } from "./EventBus.js";
                         headerSearchButton: !!p?.headerSearchButton,
                         searchPlaceholder: p?.searchPlaceholder ?? "搜索",
                         itemLayout: p?.itemLayout ?? "simple",
-                        itemAction: p?.itemAction ?? true, // 功能说明:面板可配置是否显示 hover 操作按钮(之前未透传导致总显示) by xu 20260114
-                        collapsible: true, // 功能说明:双击 header 可折叠/展开 by xu 20260116
-                        collapsed: !!this.sectionCollapsed?.[idx], // 功能说明:折叠态仅展示 header by xu 20260116
+                        itemAction: p?.itemAction ?? true,
+                        collapsible: true,
+                        collapsed: !!this.sectionCollapsed?.[idx],
                         onToggleCollapse: () =>
-                          this.toggleSectionCollapse?.(idx), // 功能说明:折叠事件回调 by xu 20260116
+                          this.toggleSectionCollapse?.(idx),
                         iconClass: p?.iconClass ?? "",
                         items: p?.items || [],
                         mode: p?.mode || "search",
                         onSelect: (item) => this.$emit("select", item),
                         onRemove: (item) => this.$emit("remove", item),
-                        // closable = 清空分区数据 by xu 20260106
                         onClear: () => p?.onClear?.(),
                         onSearch: (payload) => p?.onSearch?.(payload),
                       });
@@ -7964,14 +8067,14 @@ import { EVEN_VAR } from "./EventBus.js";
                     class: {
                       "ss-sidebar-section": true,
                       "is-collapsed": !!this.sectionCollapsed?.[idx],
-                    }, // 功能说明:折叠态加 class,配合 CSS 裁剪溢出(否则高度变了内容仍 overflow visible) by xu 20260116
+                    },
                     key: `ss-sidebar-section-${idx}-${p?.type ?? "list"}-${
                       p?.title ?? ""
-                    }`, // 功能说明:加 key 保证 section 节点稳定更新 by xu 20260116
+                    }`,
                     style: {
                       height: (this.sectionHeights[idx] ?? 190) + "px",
                       flex: "0 0 auto",
-                    }, // 功能说明:禁止 flex shrink,避免折叠/展开后 header 高度被挤压 by xu 20260116
+                    },
                   },
                   [
                     Vue.h("div", { class: "ss-sidebar-section__content" }, [
@@ -8000,10 +8103,10 @@ import { EVEN_VAR } from "./EventBus.js";
                     "ss-sidebar-panel": true,
                     "ss-sidebar-chart-panel": true,
                     "is-collapsed": !!this.chartCollapsed?.[chartIdx],
-                  }, // 功能说明:图表折叠态加 class,DOM 兜底隐藏内容 by xu 20260116
-                  style: { flex: "0 0 auto", minHeight: "37px" }, // 功能说明:禁止 flex shrink + 折叠态最小高度兜底,避免 header 被压扁 by xu 20260116
-                  "data-chart-idx": chartIdx, // 功能说明:便于 toggleChartCollapse nextTick 精确定位 DOM by xu 20260116
-                  key: `ss-sidebar-chart-${chartIdx}-${p?.title ?? ""}`, // 功能说明:加 key 防止多图表时实例复用 by xu 20260116
+                  },
+                  style: { flex: "0 0 auto", minHeight: "37px" },
+                  "data-chart-idx": chartIdx,
+                  key: `ss-sidebar-chart-${chartIdx}-${p?.title ?? ""}`,
                 },
                 [
                   p?.title
@@ -8011,17 +8114,15 @@ import { EVEN_VAR } from "./EventBus.js";
                         "div",
                         {
                           class: "ss-sidebar-panel__header",
-                          // 功能说明:折叠触发绑定到整个 header(仅 dblclick,避免双击触发两次) by xu 20260116
                           onDblclick: (e) => {
                             e?.preventDefault?.();
                             e?.stopPropagation?.();
                             console.log("[SsSidebar] chart header dblclick", {
                               idx: chartIdx,
                               title: p?.title,
-                            }); // 功能说明:直接打印用于排查多面板不生效 by xu 20260116
+                            });
                             this.toggleChartCollapse?.(chartIdx);
                           },
-                          // 功能说明:移除 click.detail==2 兜底,避免双击同时触发 click+dblclick 导致“折叠又立刻展开” by xu 20260116
                         },
                         [
                           Vue.h("div", { class: "ss-sidebar-panel__title" }, [
@@ -8043,7 +8144,6 @@ import { EVEN_VAR } from "./EventBus.js";
                         ]
                       )
                     : null,
-                  // hover 大图也展示与 header 一致的图标/标题 by xu 20260108
                   this.chartCollapsed?.[chartIdx]
                     ? null
                     : Vue.h(Vue.resolveComponent("ss-sidebar-chart-hover"), {
@@ -8056,9 +8156,7 @@ import { EVEN_VAR } from "./EventBus.js";
                 ]
               )
             ),
-            // 功能说明:统计表(report-table)放在统计图下面,统一走 ss-sidebar-report-table 渲染 by xu 20260115
             ...reportPanels.map((p, reportIdx) =>
-              // 功能说明:report-table 顶部也需要折叠态 class/定位属性,DOM 兜底隐藏内容 by xu 20260116
               Vue.h(
                 "div",
                 {
@@ -8066,23 +8164,22 @@ import { EVEN_VAR } from "./EventBus.js";
                     "ss-sidebar-report-panel-wrap": true,
                     "ss-sidebar-report-panel": true,
                     "is-collapsed": !!this.reportCollapsed?.[reportIdx],
-                  }, // 功能说明:报表折叠态加 class,DOM 兜底隐藏内容 by xu 20260116
-                  style: { flex: "0 0 auto", minHeight: "37px" }, // 功能说明:禁止 flex shrink + 折叠态最小高度兜底,避免 header 被压扁 by xu 20260116
-                  "data-report-idx": reportIdx, // 功能说明:便于 toggleReportCollapse nextTick 精确定位 DOM by xu 20260116
-                  key: `ss-sidebar-report-wrap-${reportIdx}-${p?.title ?? ""}`, // 功能说明:加 key 防止多面板时实例复用导致折叠态不更新 by xu 20260116
+                  },
+                  style: { flex: "0 0 auto", minHeight: "37px" },
+                  "data-report-idx": reportIdx,
+                  key: `ss-sidebar-report-wrap-${reportIdx}-${p?.title ?? ""}`,
                 },
                 [
-                  // 功能说明:ss-sidebar-report-table 自带 ss-sidebar-panel 外壳,这里不重复包裹 by xu 20260115
                   Vue.h(SsSidebarReportTableComp, {
-                    key: `ss-sidebar-report-${reportIdx}-${p?.title ?? ""}`, // 功能说明:加 key 防止多面板时实例复用导致折叠态不更新 by xu 20260116
+                    key: `ss-sidebar-report-${reportIdx}-${p?.title ?? ""}`,
                     title: p?.title ?? "",
                     icon: p?.icon ?? "",
                     iconClass: p?.iconClass ?? "",
                     items: p?.items || [],
-                    collapsible: true, // 功能说明:允许双击 header 折叠/展开 by xu 20260116
-                    collapsed: !!this.reportCollapsed?.[reportIdx], // 功能说明:折叠态隐藏表格 by xu 20260116
+                    collapsible: true,
+                    collapsed: !!this.reportCollapsed?.[reportIdx],
                     onToggleCollapse: () =>
-                      this.toggleReportCollapse?.(reportIdx), // 功能说明:报表折叠事件回调 by xu 20260116
+                      this.toggleReportCollapse?.(reportIdx),
                     onOpen: (srv, ctx) => p?.onOpen?.(srv, ctx),
                   }),
                 ]

+ 25 - 0
skin/easy/css/icon-biz/iconfont.css

@@ -4,6 +4,7 @@
        url('../../fonts/icon-biz/iconfont.woff') format('woff'),
        url('../../fonts/icon-biz/iconfont.ttf') format('truetype');
 }
+
 .icon-biz {
   font-family: "icon-biz" !important;
   font-size: 16px;
@@ -12,6 +13,30 @@
   -moz-osx-font-smoothing: grayscale;
 }
 
+.icon-obj-ka:before {
+  content: "\e68b";
+}
+
+.icon-obj-txjl:before {
+  content: "\e68a";
+}
+
+.icon-obj-ryGrxf:before {
+  content: "\e689";
+}
+
+.icon-guashi:before {
+  content: "\e688";
+}
+
+.icon-obj-tk:before {
+  content: "\e687";
+}
+
+.icon-dianming:before {
+  content: "\e686";
+}
+
 .icon-obj-dy:before {
   content: "\e685";
 }

BIN=BIN
skin/easy/fonts/icon-biz/iconfont.ttf


BIN=BIN
skin/easy/fonts/icon-biz/iconfont.woff


BIN=BIN
skin/easy/fonts/icon-biz/iconfont.woff2