fantasy-ngzorro 2.1.58 → 2.1.59

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -35,6 +35,7 @@
35
35
  | MC | 2023-2-10 | Readme 创建;按钮、按钮组、通用表格、筛选器、状态、详情头、详情单头、详情明细文档 |
36
36
  | MC | 2023-2-13 | 表单、明细表单、间隔、小标题文档;组件字段增加必填说明 |
37
37
  | — | 2026-5-20 | 补充 hd-table、hd-detail-lines-page 等组件;完善公共子类型(SelectOption、FormItem 等)文档 |
38
+ | — | 2026-9-18 | `hd-detail-lines-page` 对齐 `hd-table` 支持虚拟滚动(`virtualScroll` / `virtualItemSize`);千行勾选时减少 DOM 卡顿 |
38
39
  | — | 2026-9-17 | hd-table / hd-detail-lines / hd-detail-lines-page 支持 `selectDisabledField` / `rowInvalidField`:按行字段控制勾选禁用、失效行样式 |
39
40
  | — | 2026-9-14 | 新增 `hd-accessory-list` 附件列表组件(分组 name + accessoryList,点击下载/查看) |
40
41
  | — | 2026-6-23 | hd-table 状态列支持 `stateField` 自定义取值字段、`isState` 按列名取值;hd-form Input 支持 `prefix` / `prefixIcon`;hd-detail-lines-page 支持 `isCrossPageSelect` 跨页勾选开关 |
@@ -706,7 +707,9 @@ onDetailLinesPageSizeChange(pageSize: number) {
706
707
  | tablePageIndexChange | EventEmitter | — | 页码变化 |
707
708
  | tablePageSizeChange | EventEmitter | — | 每页条数变化(组件内会重置到第 1 页) |
708
709
  | pageChange | EventEmitter | — | 任意分页变化 |
709
- | showSelected / allowDrop / showTotal / selectDisabledField / rowInvalidField 等 | — | — | 同 hd-detail-lines |
710
+ | showSelected / allowDrop / showTotal / selectDisabledField / rowInvalidField 等 | — | — | 同 hd-detail-lines;`allowDrop` 开启时虚拟滚动自动关闭 |
711
+ | virtualScroll | boolean | true | 与 hd-table 一致:当前页行数多(或已设 `scroll.y`)时自动虚拟滚动,减轻千行勾选卡顿 |
712
+ | virtualItemSize | number | — | 虚拟滚动行高;不传则默认/自动测量 |
710
713
  | isCrossPageSelect | boolean | — | 跨页勾选 |
711
714
 
712
715
  分页可选条数:`10 / 50 / 100 / 200 / 500 / 1000`。模板中 `index` 为**全局序号**:`(pageIndex - 1) * pageSize + 行号`。
@@ -1777,6 +1777,10 @@
1777
1777
  this.tableData = new Page();
1778
1778
  this.showSelected = false;
1779
1779
  this.allowDrop = false;
1780
+ /**
1781
+ * 与 hd-table 一致:行数多时自动虚拟滚动;拖拽排序开启时强制关闭
1782
+ */
1783
+ this.virtualScroll = true;
1780
1784
  /**
1781
1785
  * 不传则按列宽与容器宽度自动计算横向滚动
1782
1786
  */
@@ -1800,6 +1804,20 @@
1800
1804
  this.mapOfCheckedId = {};
1801
1805
  this.mapOfCheckList = {};
1802
1806
  this.isCrossPageSelectLocal = false;
1807
+ this.showTable = true;
1808
+ /**
1809
+ * 自动测量前的兜底行高
1810
+ */
1811
+ this.measuredVirtualItemSize = 47;
1812
+ this.virtualScrollActive = null;
1813
+ /**
1814
+ * 虚拟滚动按数组下标追踪,避免业务主键 trackBy 导致 CDK 行复用错位
1815
+ */
1816
+ this.virtualTrackByRow = (/**
1817
+ * @param {?} index
1818
+ * @return {?}
1819
+ */
1820
+ function (index) { return index; });
1803
1821
  }
1804
1822
  Object.defineProperty(HdDetailLinesPageComponent.prototype, "effectiveScroll", {
1805
1823
  get: /**
@@ -1811,6 +1829,79 @@
1811
1829
  enumerable: true,
1812
1830
  configurable: true
1813
1831
  });
1832
+ Object.defineProperty(HdDetailLinesPageComponent.prototype, "effectiveVirtualItemSize", {
1833
+ get: /**
1834
+ * @return {?}
1835
+ */
1836
+ function () {
1837
+ if (this.virtualItemSize != null && this.virtualItemSize > 0) {
1838
+ return this.virtualItemSize;
1839
+ }
1840
+ return this.measuredVirtualItemSize;
1841
+ },
1842
+ enumerable: true,
1843
+ configurable: true
1844
+ });
1845
+ Object.defineProperty(HdDetailLinesPageComponent.prototype, "needsVerticalScroll", {
1846
+ /** 当前页内容高度是否超出视口 / 已指定 scroll.y */
1847
+ get: /**
1848
+ * 当前页内容高度是否超出视口 / 已指定 scroll.y
1849
+ * @return {?}
1850
+ */
1851
+ function () {
1852
+ /** @type {?} */
1853
+ var rowCount = this.displayLines ? this.displayLines.length : 0;
1854
+ if (rowCount <= 0) {
1855
+ return false;
1856
+ }
1857
+ /** @type {?} */
1858
+ var base = this.effectiveScroll;
1859
+ if (base && base.y) {
1860
+ // 父级已定高(如弹窗),行稍多就开虚拟,避免千行 DOM
1861
+ return rowCount > 20;
1862
+ }
1863
+ /** @type {?} */
1864
+ var maxOffset = 200;
1865
+ /** @type {?} */
1866
+ var estimatedHeight = rowCount * this.effectiveVirtualItemSize;
1867
+ if (typeof window !== "undefined") {
1868
+ return estimatedHeight > window.innerHeight - maxOffset;
1869
+ }
1870
+ return rowCount > 100;
1871
+ },
1872
+ enumerable: true,
1873
+ configurable: true
1874
+ });
1875
+ Object.defineProperty(HdDetailLinesPageComponent.prototype, "useVirtualScroll", {
1876
+ get: /**
1877
+ * @return {?}
1878
+ */
1879
+ function () {
1880
+ if (!this.virtualScroll || this.allowDrop) {
1881
+ return false;
1882
+ }
1883
+ return this.needsVerticalScroll;
1884
+ },
1885
+ enumerable: true,
1886
+ configurable: true
1887
+ });
1888
+ Object.defineProperty(HdDetailLinesPageComponent.prototype, "resolvedScroll", {
1889
+ /** 虚拟滚动时保证有 scroll.y,否则 nzVirtualScroll 无效 */
1890
+ get: /**
1891
+ * 虚拟滚动时保证有 scroll.y,否则 nzVirtualScroll 无效
1892
+ * @return {?}
1893
+ */
1894
+ function () {
1895
+ /** @type {?} */
1896
+ var base = this.effectiveScroll ? __assign({}, this.effectiveScroll) : {};
1897
+ if (this.useVirtualScroll && !base.y) {
1898
+ base.y = "calc(100vh - 200px)";
1899
+ }
1900
+ return base;
1901
+ },
1902
+ enumerable: true,
1903
+ configurable: true
1904
+ });
1814
1905
  /**
1815
1906
  * @return {?}
1816
1907
  */
@@ -1832,6 +1923,7 @@
1832
1923
  */
1833
1924
  function () {
1834
1925
  this.scheduleSyncHorizontalScroll();
1926
+ this.applyTableScrollMode(true);
1835
1927
  };
1836
1928
  /**
1837
1929
  * @param {?} changes
@@ -1852,6 +1944,7 @@
1852
1944
  changes["tableData"]["previousValue"]["pageNumber"]) {
1853
1945
  this.countSelected();
1854
1946
  this.calculateTotal();
1947
+ this.applyTableScrollMode(false);
1855
1948
  return;
1856
1949
  }
1857
1950
  if (!this.isCrossPageSelectLocal) {
@@ -1862,8 +1955,122 @@
1862
1955
  this.calculateTotal();
1863
1956
  if (changes["lines"] ||
1864
1957
  changes["tableData"] ||
1865
- changes["showSelected"]) {
1958
+ changes["showSelected"] ||
1959
+ changes["scroll"] ||
1960
+ changes["virtualScroll"] ||
1961
+ changes["allowDrop"]) {
1866
1962
  this.scheduleSyncHorizontalScroll();
1963
+ this.applyTableScrollMode(false);
1964
+ }
1965
+ };
1966
+ /** 虚拟/普通模式切换时重建表格,避免残留滚动容器 */
1967
+ /**
1968
+ * 虚拟/普通模式切换时重建表格,避免残留滚动容器
1969
+ * @param {?=} forceRemount
1970
+ * @return {?}
1971
+ */
1972
+ HdDetailLinesPageComponent.prototype.applyTableScrollMode = /**
1973
+ * 虚拟/普通模式切换时重建表格,避免残留滚动容器
1974
+ * @param {?=} forceRemount
1975
+ * @return {?}
1976
+ */
1977
+ function (forceRemount) {
1978
+ var _this = this;
1979
+ if (forceRemount === void 0) { forceRemount = false; }
1980
+ /** @type {?} */
1981
+ var useVirtual = this.useVirtualScroll;
1982
+ /** @type {?} */
1983
+ var modeChanged = this.virtualScrollActive !== null &&
1984
+ this.virtualScrollActive !== useVirtual;
1985
+ this.virtualScrollActive = useVirtual;
1986
+ if (forceRemount || modeChanged) {
1987
+ this.showTable = false;
1988
+ this.cdr.markForCheck();
1989
+ setTimeout((/**
1990
+ * @return {?}
1991
+ */
1992
+ function () {
1993
+ _this.showTable = true;
1994
+ _this.cdr.markForCheck();
1995
+ setTimeout((/**
1996
+ * @return {?}
1997
+ */
1998
+ function () {
1999
+ _this.afterTableRender(useVirtual);
2000
+ }));
2001
+ }));
2002
+ return;
2003
+ }
2004
+ this.cdr.markForCheck();
2005
+ this.afterTableRender(useVirtual);
2006
+ };
2007
+ /**
2008
+ * @private
2009
+ * @param {?} useVirtual
2010
+ * @return {?}
2011
+ */
2012
+ HdDetailLinesPageComponent.prototype.afterTableRender = /**
2013
+ * @private
2014
+ * @param {?} useVirtual
2015
+ * @return {?}
2016
+ */
2017
+ function (useVirtual) {
2018
+ this.scheduleSyncHorizontalScroll();
2019
+ if (useVirtual) {
2020
+ this.refreshVirtualScrollViewport(true);
2021
+ }
2022
+ };
2023
+ /**
2024
+ * @param {?=} forceMeasure
2025
+ * @return {?}
2026
+ */
2027
+ HdDetailLinesPageComponent.prototype.refreshVirtualScrollViewport = /**
2028
+ * @param {?=} forceMeasure
2029
+ * @return {?}
2030
+ */
2031
+ function (forceMeasure) {
2032
+ var _this = this;
2033
+ if (forceMeasure === void 0) { forceMeasure = false; }
2034
+ if (!this.useVirtualScroll) {
2035
+ return;
2036
+ }
2037
+ setTimeout((/**
2038
+ * @return {?}
2039
+ */
2040
+ function () {
2041
+ _this.measureVirtualItemSize(forceMeasure);
2042
+ /** @type {?} */
2043
+ var viewport = _this.nzTableComponent && _this.nzTableComponent.cdkVirtualScrollViewport;
2044
+ if (viewport) {
2045
+ viewport.checkViewportSize();
2046
+ }
2047
+ _this.cdr.markForCheck();
2048
+ }));
2049
+ };
2050
+ /**
2051
+ * @private
2052
+ * @param {?=} force
2053
+ * @return {?}
2054
+ */
2055
+ HdDetailLinesPageComponent.prototype.measureVirtualItemSize = /**
2056
+ * @private
2057
+ * @param {?=} force
2058
+ * @return {?}
2059
+ */
2060
+ function (force) {
2061
+ if (force === void 0) { force = false; }
2062
+ if (this.virtualItemSize != null && this.virtualItemSize > 0 && !force) {
2063
+ return;
2064
+ }
2065
+ /** @type {?} */
2066
+ var viewport = this.nzTableComponent && this.nzTableComponent.cdkVirtualScrollViewport;
2067
+ if (!viewport || !viewport.elementRef || !viewport.elementRef.nativeElement) {
2068
+ return;
2069
+ }
2070
+ /** @type {?} */
2071
+ var row = (/** @type {?} */ (viewport.elementRef.nativeElement.querySelector("tr.hd-detail-lines-page-virtual-row")));
2072
+ if (row && row.offsetHeight > 0) {
2073
+ this.measuredVirtualItemSize = row.offsetHeight;
1867
2074
  }
1868
2075
  };
1869
2076
  /**
@@ -1918,10 +2125,18 @@
1918
2125
  var nextScroll = resolveAutoTableScroll(this.nzTableComponent, hasData);
1919
2126
  /** @type {?} */
1920
2127
  var nextX = nextScroll ? nextScroll.x : null;
1921
- if (this.tableScroll && this.tableScroll.x === nextX) {
2128
+ /** @type {?} */
2129
+ var currentY = this.tableScroll ? this.tableScroll.y : null;
2130
+ if (this.tableScroll &&
2131
+ this.tableScroll.x === nextX &&
2132
+ this.tableScroll.y === currentY) {
1922
2133
  return;
1923
2134
  }
1924
- this.tableScroll = nextScroll;
2135
+ this.tableScroll = nextScroll
2136
+ ? { x: nextScroll.x, y: currentY }
2137
+ : currentY
2138
+ ? { y: currentY }
2139
+ : null;
1925
2140
  this.cdr.markForCheck();
1926
2141
  };
1927
2142
  Object.defineProperty(HdDetailLinesPageComponent.prototype, "displayLines", {
@@ -1974,6 +2189,7 @@
1974
2189
  this.tablePageIndexChange.emit(this.tablePageIndex);
1975
2190
  this.pageChange.emit();
1976
2191
  this.scheduleSyncHorizontalScroll();
2192
+ this.applyTableScrollMode(false);
1977
2193
  };
1978
2194
  /**
1979
2195
  * @param {?} pageSize
@@ -1990,6 +2206,7 @@
1990
2206
  this.tablePageIndexChange.emit(this.tablePageIndex);
1991
2207
  this.pageChange.emit();
1992
2208
  this.scheduleSyncHorizontalScroll();
2209
+ this.applyTableScrollMode(true);
1993
2210
  };
1994
2211
  /**
1995
2212
  * @private
@@ -2130,7 +2347,11 @@
2130
2347
  }
2131
2348
  }
2132
2349
  /** @type {?} */
2133
- var selectableList = this.listOfDisplayData.filter((/**
2350
+ var sourceList = this.listOfDisplayData && this.listOfDisplayData.length
2351
+ ? this.listOfDisplayData
2352
+ : this.displayLines;
2353
+ /** @type {?} */
2354
+ var selectableList = (sourceList || []).filter((/**
2134
2355
  * @param {?} item
2135
2356
  * @return {?}
2136
2357
  */
@@ -2162,7 +2383,11 @@
2162
2383
  */
2163
2384
  function (value) {
2164
2385
  var _this = this;
2165
- this.listOfDisplayData.forEach((/**
2386
+ /** @type {?} */
2387
+ var sourceList = this.listOfDisplayData && this.listOfDisplayData.length
2388
+ ? this.listOfDisplayData
2389
+ : this.displayLines;
2390
+ (sourceList || []).forEach((/**
2166
2391
  * @param {?} item
2167
2392
  * @return {?}
2168
2393
  */
@@ -2217,8 +2442,8 @@
2217
2442
  HdDetailLinesPageComponent.decorators = [
2218
2443
  { type: core.Component, args: [{
2219
2444
  selector: "hd-detail-lines-page",
2220
- template: "<ng-container>\n <nz-table #hdTable [nzScroll]=\"effectiveScroll\" class=\"hd-table-container\" nzShowSizeChanger nzShowQuickJumper\n nzFrontPagination=\"false\" nzSize=\"middle\" [nzData]=\"displayLines\" [nzTotal]=\"totalCount\"\n [(nzPageIndex)]=\"tablePageIndex\" [(nzPageSize)]=\"tablePageSize\" [nzLoading]=\"tableLoading\"\n [nzPageSizeOptions]=\"[ 10, 50, 100, 200, 500, 1000 ]\" (nzPageIndexChange)=\"onPageIndexChange($event)\"\n (nzPageSizeChange)=\"onPageSizeChange($event)\" [nzShowTotal]=\"tableTotalTemplate\"\n (nzCurrentPageDataChange)=\"showSelected ? currentPageDataChange($event) : null\">\n <thead>\n <tr>\n <th *ngIf=\"showSelected\" nzWidth=\"40px\" nzLeft=\"0px\" nzShowCheckbox [(nzChecked)]=\"isAllDisplayDataChecked\"\n [nzIndeterminate]=\"isIndeterminate\" (nzCheckedChange)=\"checkAll($event)\"></th>\n <ng-container *ngTemplateOutlet=\"detailLineHead\"></ng-container>\n </tr>\n </thead>\n <tbody *ngIf=\"!allowDrop;else allowDropTemplate\">\n <tr *ngFor=\"let data of hdTable.data;index as i\" [class.hd-table-row-invalid]=\"isInvalidRow(data)\">\n <td *ngIf=\"showSelected\" nzWidth=\"40px\" nzLeft=\"0px\" nzShowCheckbox\n [nzChecked]=\"mapOfCheckedId[data[selectField]]\" [nzDisabled]=\"isSelectDisabled(data)\"\n (nzCheckedChange)=\"refreshStatus($event, data)\"></td>\n <ng-container\n *ngTemplateOutlet=\"detailLineBody;context:{$implicit: data, index: getRowIndex(i)}\"></ng-container>\n </tr>\n <tr *ngIf=\"showTotal\" class=\"hd-table-total\">\n <td *ngIf=\"showSelected\"></td>\n <td>\u5408\u8BA1</td>\n <ng-container *ngFor=\"let totalOption of totalOptionList\">\n <td *ngIf=\"!totalOption.isHide\" [nzAlign]=\"totalOption.align ? totalOption.align : 'left'\">{{\n (totalOption.value || totalOption.value ===\n 0) ? (((totalOption.value % 1 === 0) && !totalOption.showDecimal ) ? totalOption.value :\n LodashRound(totalOption.value, totalOption.preserveNumber).toFixed(totalOption.preserveNumber)) : '' }} </td>\n </ng-container>\n </tr>\n </tbody>\n <ng-template #allowDropTemplate>\n <tbody cdkDropList (cdkDropListDropped)=\"drop($event)\">\n <tr *ngFor=\"let data of hdTable.data;index as i\" cdkDrag [class.hd-table-row-invalid]=\"isInvalidRow(data)\">\n <td *ngIf=\"showSelected\" nzWidth=\"40px\" nzLeft=\"0px\" nzShowCheckbox\n [nzChecked]=\"mapOfCheckedId[data[selectField]]\" [nzDisabled]=\"isSelectDisabled(data)\"\n (nzCheckedChange)=\"refreshStatus($event, data)\"></td>\n <ng-container\n *ngTemplateOutlet=\"detailLineBody;context:{$implicit: data, index: getRowIndex(i)}\"></ng-container>\n </tr>\n <tr *ngIf=\"showTotal\" class=\"hd-table-total\">\n <td *ngIf=\"showSelected\"></td>\n <td>\u5408\u8BA1</td>\n <ng-container *ngFor=\"let totalOption of totalOptionList\">\n <td *ngIf=\"!totalOption.isHide\" [nzAlign]=\"totalOption.align ? totalOption.align : 'left'\">{{\n (totalOption.value || totalOption.value\n === 0) ? (((totalOption.value % 1 === 0) && !totalOption.showDecimal ) ? totalOption.value :\n LodashRound(totalOption.value, totalOption.preserveNumber).toFixed(totalOption.preserveNumber)) : '' }} </td>\n </ng-container>\n </tr>\n </tbody>\n </ng-template>\n <ng-template #tableTotalTemplate>\n \u5171 {{totalCount}} \u6761\u6570\u636E\n </ng-template>\n </nz-table>\n</ng-container>\n",
2221
- styles: ["::ng-deep .common-btn-group>a{font-size:14px;font-weight:400;color:#20b95d!important;white-space:nowrap}::ng-deep .common-btn-group .common-danger-btn:hover{color:#f05b24!important}::ng-deep .common-btn-group>a:hover{color:#20bd62!important}::ng-deep .common-btn-group>a:not(:last-child)::after{content:'';margin:0 2px}::ng-deep .common-billNumber>a{color:#3b77e3}button{box-shadow:unset;text-shadow:unset}::ng-deep .ant-form-item-label>label{color:#4b504e;font-size:14px}::ng-deep .ant-input-number-input{height:32px}::ng-deep .ant-input-number{height:32px}textarea.ant-input{height:auto;min-height:32px}::ng-deep .ant-select-selection--multiple{min-height:32px}::ng-deep .ant-select-selection__rendered>ul>li{height:26px!important;margin-top:3px!important;line-height:26px!important}::ng-deep .ant-advanced-search-form .ant-form-item{margin-bottom:0!important}::ng-deep .ant-select-selection--single{height:32px!important}::ng-deep .ant-input{height:32px}::ng-deep .ant-input[disabled]:hover{border-color:#d9d9d9!important}::ng-deep .ant-select-selection__rendered{line-height:32px!important}::ng-deep .ant-calendar-range-picker-input{text-align:left!important}::ng-deep .ant-calendar-picker{width:100%!important}::ng-deep .ant-row{margin-right:0!important;margin-left:0!important}::ng-deep .ant-col-6{padding-left:12px;padding-right:12px}::ng-deep .ant-col-12{padding-left:12px;padding-right:12px}::ng-deep .ant-col-18{padding-left:12px;padding-right:12px}::ng-deep .ant-col-24{padding-left:12px;padding-right:12px}::ng-deep .ant-alert-info{background-color:#f5f8f6;border:1px solid #cfe3d4}::ng-deep .hd-table-container .ant-table-td-left-sticky,::ng-deep .hd-table-container .ant-table-td-right-sticky,::ng-deep .hd-table-container .ant-table-th-left-sticky,::ng-deep .hd-table-container .ant-table-th-right-sticky{z-index:2;transform:translateZ(0)}::ng-deep .hd-table-container .ant-table-thead>tr>th.ant-table-th-left-sticky,::ng-deep .hd-table-container .ant-table-thead>tr>th.ant-table-th-right-sticky{background:#f5f8f6!important}::ng-deep .hd-table-container .ant-table-tbody>tr>td.ant-table-td-left-sticky,::ng-deep .hd-table-container .ant-table-tbody>tr>td.ant-table-td-right-sticky{background:#fff}::ng-deep .hd-table-container .ant-table-tbody>tr.ant-table-row-hover>td.ant-table-td-left-sticky,::ng-deep .hd-table-container .ant-table-tbody>tr.ant-table-row-hover>td.ant-table-td-right-sticky,::ng-deep .hd-table-container .ant-table-tbody>tr:hover>td.ant-table-td-left-sticky,::ng-deep .hd-table-container .ant-table-tbody>tr:hover>td.ant-table-td-right-sticky{background:#ecf8f1!important}::ng-deep .hd-table-container .ant-table-scroll-position-left .ant-table-td-right-sticky,::ng-deep .hd-table-container .ant-table-scroll-position-left .ant-table-th-right-sticky,::ng-deep .hd-table-container .ant-table-scroll-position-middle .ant-table-td-right-sticky,::ng-deep .hd-table-container .ant-table-scroll-position-middle .ant-table-th-right-sticky,::ng-deep .hd-table-container .ant-table-scroll-position-right .ant-table-td-right-sticky,::ng-deep .hd-table-container .ant-table-scroll-position-right .ant-table-th-right-sticky{box-shadow:none!important}::ng-deep .hd-table-container .ant-table-fixed-right{right:0!important}:host ::ng-deep th{background:#f5f8f6!important;font-weight:700!important;white-space:nowrap;font-size:14px;font-family:PingFangSC-Medium,PingFang SC;color:#2a3634;padding:8px!important;box-sizing:border-box}:host ::ng-deep td{font-weight:400;font-style:normal;font-size:14px;color:#2a3634;text-align:left;white-space:nowrap;padding:8px!important;box-sizing:border-box}::ng-deep .ant-pagination-options{display:inline-flex;align-items:center}::ng-deep .ant-pagination-options .ant-select,::ng-deep .ant-pagination-options .ant-select-selection--single{min-width:100px}::ng-deep .ant-pagination-options-size-changer.ant-select{min-width:100px}::ng-deep .ant-time-picker{width:100%}::ng-deep .cdk-overlay-pane .hd-cascader-menus.ant-cascader-menus>.ant-cascader-menu:only-child{width:-webkit-max-content!important;width:-moz-max-content!important;width:max-content!important;min-width:var(--hd-cascader-menu-min-width,auto);max-width:560px}::ng-deep .cdk-overlay-pane .hd-cascader-menus.ant-cascader-menus>.ant-cascader-menu:only-child .ant-cascader-menu-item{white-space:nowrap}.ant-input-number-disabled,.ant-input[disabled],.ant-select-disabled{color:#4b504e}.hd-table-container ::ng-deep .ant-pagination-options-quick-jumper input{border-radius:2px;border:1px solid #d9d9d9}.hd-table-container ::ng-deep .ant-pagination-options .ant-select-selection{border-radius:2px}.hd-table-container ::ng-deep .ant-table-thead>tr>th{border-bottom:1px solid #ecf1ed}.hd-table-container ::ng-deep .ant-table-tbody>tr>td{border-bottom:1px solid #ecf1ed}.hd-table-container ::ng-deep .ant-table-tbody>tr.hd-table-row-invalid.ant-table-row-hover>td,.hd-table-container ::ng-deep .ant-table-tbody>tr.hd-table-row-invalid.ant-table-row-hover>td.ant-table-td-left-sticky,.hd-table-container ::ng-deep .ant-table-tbody>tr.hd-table-row-invalid.ant-table-row-hover>td.ant-table-td-right-sticky,.hd-table-container ::ng-deep .ant-table-tbody>tr.hd-table-row-invalid:hover>td,.hd-table-container ::ng-deep .ant-table-tbody>tr.hd-table-row-invalid:hover>td.ant-table-td-left-sticky,.hd-table-container ::ng-deep .ant-table-tbody>tr.hd-table-row-invalid:hover>td.ant-table-td-right-sticky,.hd-table-container ::ng-deep .ant-table-tbody>tr.hd-table-row-invalid>td,.hd-table-container ::ng-deep .ant-table-tbody>tr.hd-table-row-invalid>td.ant-table-td-left-sticky,.hd-table-container ::ng-deep .ant-table-tbody>tr.hd-table-row-invalid>td.ant-table-td-right-sticky{background:#f7f8fa!important;color:#868a9c!important}.hd-table-container ::ng-deep .ant-table-tbody>tr.hd-table-row-invalid .common-btn-group>a{color:#20b95d!important}.hd-table-container ::ng-deep .ant-table-tbody>tr.hd-table-row-invalid .common-btn-group>a:hover{color:#20bd62!important}.hd-table-container ::ng-deep .ant-table-tbody>tr.hd-table-row-invalid .common-btn-group .common-danger-btn:hover{color:#f05b24!important}.hd-table-container ::ng-deep .ant-table-tbody>tr.hd-table-row-invalid .hd-table-cell-value>a,.hd-table-container ::ng-deep .ant-table-tbody>tr.hd-table-row-invalid>td>a{color:#20b95d}.hd-table-container ::ng-deep .ant-table-tbody>tr.hd-table-row-invalid .common-billNumber>a{color:#3b77e3}.hd-table-container ::ng-deep .ant-table-tbody>tr.hd-table-row-invalid .hd-status-text{color:#868a9c!important}.hd-table-container ::ng-deep .hd-table-total>td{border:0!important}"]
2445
+ template: "<ng-container>\n <nz-table\n *ngIf=\"showTable\"\n #hdTable\n class=\"hd-table-container\"\n [class.hd-detail-lines-page--virtual]=\"useVirtualScroll\"\n [class.hd-detail-lines-page--scroll-y]=\"!!(resolvedScroll && resolvedScroll.y)\"\n [class.hd-detail-lines-page--scroll-x]=\"!!(resolvedScroll && resolvedScroll.x)\"\n [nzScroll]=\"resolvedScroll\"\n nzShowSizeChanger\n nzShowQuickJumper\n nzFrontPagination=\"false\"\n nzSize=\"middle\"\n [nzData]=\"displayLines\"\n [nzTotal]=\"totalCount\"\n [(nzPageIndex)]=\"tablePageIndex\"\n [(nzPageSize)]=\"tablePageSize\"\n [nzLoading]=\"tableLoading\"\n [nzPageSizeOptions]=\"[ 10, 50, 100, 200, 500, 1000 ]\"\n (nzPageIndexChange)=\"onPageIndexChange($event)\"\n (nzPageSizeChange)=\"onPageSizeChange($event)\"\n [nzShowTotal]=\"tableTotalTemplate\"\n (nzCurrentPageDataChange)=\"showSelected ? currentPageDataChange($event) : null\"\n [nzVirtualScroll]=\"useVirtualScroll\"\n [nzVirtualItemSize]=\"useVirtualScroll ? effectiveVirtualItemSize : 0\"\n [nzVirtualForTrackBy]=\"virtualTrackByRow\"\n >\n <thead>\n <tr>\n <th *ngIf=\"showSelected\" nzWidth=\"40px\" nzLeft=\"0px\" nzShowCheckbox [(nzChecked)]=\"isAllDisplayDataChecked\"\n [nzIndeterminate]=\"isIndeterminate\" (nzCheckedChange)=\"checkAll($event)\"></th>\n <ng-container *ngTemplateOutlet=\"detailLineHead\"></ng-container>\n </tr>\n </thead>\n <tbody *ngIf=\"!allowDrop;else allowDropTemplate\">\n <ng-template *ngIf=\"useVirtualScroll\" nz-virtual-scroll let-data let-index=\"index\">\n <tr class=\"hd-detail-lines-page-virtual-row\" [class.hd-table-row-invalid]=\"isInvalidRow(data)\">\n <td *ngIf=\"showSelected\" nzWidth=\"40px\" nzLeft=\"0px\" nzShowCheckbox\n [nzChecked]=\"mapOfCheckedId[data[selectField]]\" [nzDisabled]=\"isSelectDisabled(data)\"\n (nzCheckedChange)=\"refreshStatus($event, data)\"></td>\n <ng-container\n *ngTemplateOutlet=\"detailLineBody;context:{$implicit: data, index: getRowIndex(index)}\"></ng-container>\n </tr>\n </ng-template>\n <ng-container *ngIf=\"!useVirtualScroll\">\n <tr *ngFor=\"let data of hdTable.data;index as i\" [class.hd-table-row-invalid]=\"isInvalidRow(data)\">\n <td *ngIf=\"showSelected\" nzWidth=\"40px\" nzLeft=\"0px\" nzShowCheckbox\n [nzChecked]=\"mapOfCheckedId[data[selectField]]\" [nzDisabled]=\"isSelectDisabled(data)\"\n (nzCheckedChange)=\"refreshStatus($event, data)\"></td>\n <ng-container\n *ngTemplateOutlet=\"detailLineBody;context:{$implicit: data, index: getRowIndex(i)}\"></ng-container>\n </tr>\n <tr *ngIf=\"showTotal\" class=\"hd-table-total\">\n <td *ngIf=\"showSelected\"></td>\n <td>\u5408\u8BA1</td>\n <ng-container *ngFor=\"let totalOption of totalOptionList\">\n <td *ngIf=\"!totalOption.isHide\" [nzAlign]=\"totalOption.align ? totalOption.align : 'left'\">{{\n (totalOption.value || totalOption.value ===\n 0) ? (((totalOption.value % 1 === 0) && !totalOption.showDecimal ) ? totalOption.value :\n LodashRound(totalOption.value, totalOption.preserveNumber).toFixed(totalOption.preserveNumber)) : '' }} </td>\n </ng-container>\n </tr>\n </ng-container>\n </tbody>\n <tfoot *ngIf=\"useVirtualScroll && showTotal\">\n <tr class=\"hd-table-total\">\n <td *ngIf=\"showSelected\"></td>\n <td>\u5408\u8BA1</td>\n <ng-container *ngFor=\"let totalOption of totalOptionList\">\n <td *ngIf=\"!totalOption.isHide\" [nzAlign]=\"totalOption.align ? totalOption.align : 'left'\">{{\n (totalOption.value || totalOption.value ===\n 0) ? (((totalOption.value % 1 === 0) && !totalOption.showDecimal ) ? totalOption.value :\n LodashRound(totalOption.value, totalOption.preserveNumber).toFixed(totalOption.preserveNumber)) : '' }} </td>\n </ng-container>\n </tr>\n </tfoot>\n <ng-template #allowDropTemplate>\n <tbody cdkDropList (cdkDropListDropped)=\"drop($event)\">\n <tr *ngFor=\"let data of hdTable.data;index as i\" cdkDrag [class.hd-table-row-invalid]=\"isInvalidRow(data)\">\n <td *ngIf=\"showSelected\" nzWidth=\"40px\" nzLeft=\"0px\" nzShowCheckbox\n [nzChecked]=\"mapOfCheckedId[data[selectField]]\" [nzDisabled]=\"isSelectDisabled(data)\"\n (nzCheckedChange)=\"refreshStatus($event, data)\"></td>\n <ng-container\n *ngTemplateOutlet=\"detailLineBody;context:{$implicit: data, index: getRowIndex(i)}\"></ng-container>\n </tr>\n <tr *ngIf=\"showTotal\" class=\"hd-table-total\">\n <td *ngIf=\"showSelected\"></td>\n <td>\u5408\u8BA1</td>\n <ng-container *ngFor=\"let totalOption of totalOptionList\">\n <td *ngIf=\"!totalOption.isHide\" [nzAlign]=\"totalOption.align ? totalOption.align : 'left'\">{{\n (totalOption.value || totalOption.value\n === 0) ? (((totalOption.value % 1 === 0) && !totalOption.showDecimal ) ? totalOption.value :\n LodashRound(totalOption.value, totalOption.preserveNumber).toFixed(totalOption.preserveNumber)) : '' }} </td>\n </ng-container>\n </tr>\n </tbody>\n </ng-template>\n <ng-template #tableTotalTemplate>\n \u5171 {{totalCount}} \u6761\u6570\u636E\n </ng-template>\n </nz-table>\n</ng-container>\n",
2446
+ styles: ["::ng-deep .common-btn-group>a{font-size:14px;font-weight:400;color:#20b95d!important;white-space:nowrap}::ng-deep .common-btn-group .common-danger-btn:hover{color:#f05b24!important}::ng-deep .common-btn-group>a:hover{color:#20bd62!important}::ng-deep .common-btn-group>a:not(:last-child)::after{content:'';margin:0 2px}::ng-deep .common-billNumber>a{color:#3b77e3}button{box-shadow:unset;text-shadow:unset}::ng-deep .ant-form-item-label>label{color:#4b504e;font-size:14px}::ng-deep .ant-input-number-input{height:32px}::ng-deep .ant-input-number{height:32px}textarea.ant-input{height:auto;min-height:32px}::ng-deep .ant-select-selection--multiple{min-height:32px}::ng-deep .ant-select-selection__rendered>ul>li{height:26px!important;margin-top:3px!important;line-height:26px!important}::ng-deep .ant-advanced-search-form .ant-form-item{margin-bottom:0!important}::ng-deep .ant-select-selection--single{height:32px!important}::ng-deep .ant-input{height:32px}::ng-deep .ant-input[disabled]:hover{border-color:#d9d9d9!important}::ng-deep .ant-select-selection__rendered{line-height:32px!important}::ng-deep .ant-calendar-range-picker-input{text-align:left!important}::ng-deep .ant-calendar-picker{width:100%!important}::ng-deep .ant-row{margin-right:0!important;margin-left:0!important}::ng-deep .ant-col-6{padding-left:12px;padding-right:12px}::ng-deep .ant-col-12{padding-left:12px;padding-right:12px}::ng-deep .ant-col-18{padding-left:12px;padding-right:12px}::ng-deep .ant-col-24{padding-left:12px;padding-right:12px}::ng-deep .ant-alert-info{background-color:#f5f8f6;border:1px solid #cfe3d4}::ng-deep .hd-table-container .ant-table-td-left-sticky,::ng-deep .hd-table-container .ant-table-td-right-sticky,::ng-deep .hd-table-container .ant-table-th-left-sticky,::ng-deep .hd-table-container .ant-table-th-right-sticky{z-index:2;transform:translateZ(0)}::ng-deep .hd-table-container .ant-table-thead>tr>th.ant-table-th-left-sticky,::ng-deep .hd-table-container .ant-table-thead>tr>th.ant-table-th-right-sticky{background:#f5f8f6!important}::ng-deep .hd-table-container .ant-table-tbody>tr>td.ant-table-td-left-sticky,::ng-deep .hd-table-container .ant-table-tbody>tr>td.ant-table-td-right-sticky{background:#fff}::ng-deep .hd-table-container .ant-table-tbody>tr.ant-table-row-hover>td.ant-table-td-left-sticky,::ng-deep .hd-table-container .ant-table-tbody>tr.ant-table-row-hover>td.ant-table-td-right-sticky,::ng-deep .hd-table-container .ant-table-tbody>tr:hover>td.ant-table-td-left-sticky,::ng-deep .hd-table-container .ant-table-tbody>tr:hover>td.ant-table-td-right-sticky{background:#ecf8f1!important}::ng-deep .hd-table-container .ant-table-scroll-position-left .ant-table-td-right-sticky,::ng-deep .hd-table-container .ant-table-scroll-position-left .ant-table-th-right-sticky,::ng-deep .hd-table-container .ant-table-scroll-position-middle .ant-table-td-right-sticky,::ng-deep .hd-table-container .ant-table-scroll-position-middle .ant-table-th-right-sticky,::ng-deep .hd-table-container .ant-table-scroll-position-right .ant-table-td-right-sticky,::ng-deep .hd-table-container .ant-table-scroll-position-right .ant-table-th-right-sticky{box-shadow:none!important}::ng-deep .hd-table-container .ant-table-fixed-right{right:0!important}:host ::ng-deep th{background:#f5f8f6!important;font-weight:700!important;white-space:nowrap;font-size:14px;font-family:PingFangSC-Medium,PingFang SC;color:#2a3634;padding:8px!important;box-sizing:border-box}:host ::ng-deep td{font-weight:400;font-style:normal;font-size:14px;color:#2a3634;text-align:left;white-space:nowrap;padding:8px!important;box-sizing:border-box}::ng-deep .ant-pagination-options{display:inline-flex;align-items:center}::ng-deep .ant-pagination-options .ant-select,::ng-deep .ant-pagination-options .ant-select-selection--single{min-width:100px}::ng-deep .ant-pagination-options-size-changer.ant-select{min-width:100px}::ng-deep .ant-time-picker{width:100%}::ng-deep .cdk-overlay-pane .hd-cascader-menus.ant-cascader-menus>.ant-cascader-menu:only-child{width:-webkit-max-content!important;width:-moz-max-content!important;width:max-content!important;min-width:var(--hd-cascader-menu-min-width,auto);max-width:560px}::ng-deep .cdk-overlay-pane .hd-cascader-menus.ant-cascader-menus>.ant-cascader-menu:only-child .ant-cascader-menu-item{white-space:nowrap}.ant-input-number-disabled,.ant-input[disabled],.ant-select-disabled{color:#4b504e}.hd-table-container ::ng-deep .ant-pagination-options-quick-jumper input{border-radius:2px;border:1px solid #d9d9d9}.hd-table-container ::ng-deep .ant-pagination-options .ant-select-selection{border-radius:2px}.hd-table-container ::ng-deep .ant-table-thead>tr>th{border-bottom:1px solid #ecf1ed}.hd-table-container ::ng-deep .ant-table-tbody>tr>td{border-bottom:1px solid #ecf1ed}.hd-table-container ::ng-deep .ant-table-tbody>tr.hd-table-row-invalid.ant-table-row-hover>td,.hd-table-container ::ng-deep .ant-table-tbody>tr.hd-table-row-invalid.ant-table-row-hover>td.ant-table-td-left-sticky,.hd-table-container ::ng-deep .ant-table-tbody>tr.hd-table-row-invalid.ant-table-row-hover>td.ant-table-td-right-sticky,.hd-table-container ::ng-deep .ant-table-tbody>tr.hd-table-row-invalid:hover>td,.hd-table-container ::ng-deep .ant-table-tbody>tr.hd-table-row-invalid:hover>td.ant-table-td-left-sticky,.hd-table-container ::ng-deep .ant-table-tbody>tr.hd-table-row-invalid:hover>td.ant-table-td-right-sticky,.hd-table-container ::ng-deep .ant-table-tbody>tr.hd-table-row-invalid>td,.hd-table-container ::ng-deep .ant-table-tbody>tr.hd-table-row-invalid>td.ant-table-td-left-sticky,.hd-table-container ::ng-deep .ant-table-tbody>tr.hd-table-row-invalid>td.ant-table-td-right-sticky{background:#f7f8fa!important;color:#868a9c!important}.hd-table-container ::ng-deep .ant-table-tbody>tr.hd-table-row-invalid .common-btn-group>a{color:#20b95d!important}.hd-table-container ::ng-deep .ant-table-tbody>tr.hd-table-row-invalid .common-btn-group>a:hover{color:#20bd62!important}.hd-table-container ::ng-deep .ant-table-tbody>tr.hd-table-row-invalid .common-btn-group .common-danger-btn:hover{color:#f05b24!important}.hd-table-container ::ng-deep .ant-table-tbody>tr.hd-table-row-invalid .hd-table-cell-value>a,.hd-table-container ::ng-deep .ant-table-tbody>tr.hd-table-row-invalid>td>a{color:#20b95d}.hd-table-container ::ng-deep .ant-table-tbody>tr.hd-table-row-invalid .common-billNumber>a{color:#3b77e3}.hd-table-container ::ng-deep .ant-table-tbody>tr.hd-table-row-invalid .hd-status-text{color:#868a9c!important}.hd-table-container ::ng-deep .hd-table-total>td{border:0!important}.hd-table-container ::ng-deep cdk-virtual-scroll-viewport.ant-table-body .hd-detail-lines-page-virtual-row>td{box-sizing:border-box}.hd-table-container:not(.hd-detail-lines-page--scroll-y):not(.hd-detail-lines-page--scroll-x) ::ng-deep .ant-table-body{max-height:none!important;overflow-y:visible!important}"]
2222
2447
  }] }
2223
2448
  ];
2224
2449
  /** @nocollapse */
@@ -2231,6 +2456,8 @@
2231
2456
  tableData: [{ type: core.Input }],
2232
2457
  showSelected: [{ type: core.Input }],
2233
2458
  allowDrop: [{ type: core.Input }],
2459
+ virtualScroll: [{ type: core.Input }],
2460
+ virtualItemSize: [{ type: core.Input }],
2234
2461
  scroll: [{ type: core.Input }],
2235
2462
  selectField: [{ type: core.Input }],
2236
2463
  selectedField: [{ type: core.Input }],
@@ -2258,6 +2485,10 @@
2258
2485
  core$1.InputBoolean(),
2259
2486
  __metadata("design:type", Boolean)
2260
2487
  ], HdDetailLinesPageComponent.prototype, "allowDrop", void 0);
2488
+ __decorate([
2489
+ core$1.InputBoolean(),
2490
+ __metadata("design:type", Boolean)
2491
+ ], HdDetailLinesPageComponent.prototype, "virtualScroll", void 0);
2261
2492
  __decorate([
2262
2493
  core$1.InputBoolean(),
2263
2494
  __metadata("design:type", Boolean)
@@ -2278,6 +2509,16 @@
2278
2509
  HdDetailLinesPageComponent.prototype.showSelected;
2279
2510
  /** @type {?} */
2280
2511
  HdDetailLinesPageComponent.prototype.allowDrop;
2512
+ /**
2513
+ * 与 hd-table 一致:行数多时自动虚拟滚动;拖拽排序开启时强制关闭
2514
+ * @type {?}
2515
+ */
2516
+ HdDetailLinesPageComponent.prototype.virtualScroll;
2517
+ /**
2518
+ * 手动指定行高;不传则用默认/测量值
2519
+ * @type {?}
2520
+ */
2521
+ HdDetailLinesPageComponent.prototype.virtualItemSize;
2281
2522
  /**
2282
2523
  * 不传则按列宽与容器宽度自动计算横向滚动
2283
2524
  * @type {?}
@@ -2341,6 +2582,23 @@
2341
2582
  HdDetailLinesPageComponent.prototype.mapOfCheckList;
2342
2583
  /** @type {?} */
2343
2584
  HdDetailLinesPageComponent.prototype.isCrossPageSelectLocal;
2585
+ /** @type {?} */
2586
+ HdDetailLinesPageComponent.prototype.showTable;
2587
+ /**
2588
+ * 自动测量前的兜底行高
2589
+ * @type {?}
2590
+ */
2591
+ HdDetailLinesPageComponent.prototype.measuredVirtualItemSize;
2592
+ /**
2593
+ * @type {?}
2594
+ * @private
2595
+ */
2596
+ HdDetailLinesPageComponent.prototype.virtualScrollActive;
2597
+ /**
2598
+ * 虚拟滚动按数组下标追踪,避免业务主键 trackBy 导致 CDK 行复用错位
2599
+ * @type {?}
2600
+ */
2601
+ HdDetailLinesPageComponent.prototype.virtualTrackByRow;
2344
2602
  /**
2345
2603
  * @type {?}
2346
2604
  * @private