bl-common-vue3 3.8.118 → 3.8.120

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bl-common-vue3",
3
- "version": "3.8.118",
3
+ "version": "3.8.120",
4
4
  "main": "index.js",
5
5
  "module": "index.js",
6
6
  "description": "bailing vue3 common components lib",
@@ -18,6 +18,7 @@ const utils = {
18
18
  basicConfigI18n: {}, // config 接口返回的i18n 配置信息
19
19
  dictData: {}, // 字典
20
20
  dictMenuData: {}, // 菜单字典
21
+ preferences: {}, // 用户使用偏好
21
22
  /**
22
23
  * 表单验证为数字
23
24
  */
@@ -91,6 +92,12 @@ const utils = {
91
92
  }else {
92
93
  localData[key] = value;
93
94
  }
95
+ if (key == 'preferences') {
96
+ utils.preferences = localData[key];
97
+ let setBLPreferences = new Event('setBLPreferences');
98
+ setBLPreferences.newValue = utils.preferences;
99
+ window.dispatchEvent(setBLPreferences);
100
+ }
94
101
  localStorage.setItem(utils.blCommonKey, JSON.stringify(localData));
95
102
  if (key && key.includes('locale_')) {
96
103
  // 修改的语言
@@ -5,6 +5,7 @@ const DEFAULT_COLUMN_WIDTH = 16;
5
5
  const MAX_COLUMN_WIDTH = 36;
6
6
  const HEADER_ROW_HEIGHT = 30;
7
7
  const DATA_ROW_HEIGHT = 24;
8
+ const DEFAULT_BODY_FONT_COLOR = "FF333333";
8
9
  const XLSX_MIME_TYPE =
9
10
  "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8";
10
11
  const INVALID_FILE_NAME_REG = /[\\/:*?"<>|]/g;
@@ -68,6 +69,8 @@ const getStyledExportOptions = (options = {}) => {
68
69
  detailFields = [],
69
70
  fieldAlignments = {},
70
71
  columnWidths = {},
72
+ fieldStyles = {},
73
+ fieldValueColors = {},
71
74
  } = options;
72
75
 
73
76
  return {
@@ -79,9 +82,78 @@ const getStyledExportOptions = (options = {}) => {
79
82
  : {},
80
83
  columnWidths:
81
84
  columnWidths && typeof columnWidths === "object" ? columnWidths : {},
85
+ fieldStyles:
86
+ fieldStyles && typeof fieldStyles === "object" ? fieldStyles : {},
87
+ fieldValueColors:
88
+ fieldValueColors && typeof fieldValueColors === "object"
89
+ ? fieldValueColors
90
+ : {},
82
91
  };
83
92
  };
84
93
 
94
+ const normalizeArgbColor = (color, fallbackColor = DEFAULT_BODY_FONT_COLOR) => {
95
+ const normalizedColor = String(color || "")
96
+ .replace(/^#/, "")
97
+ .toUpperCase();
98
+ if (/^[0-9A-F]{8}$/.test(normalizedColor)) {
99
+ return normalizedColor;
100
+ }
101
+ if (/^[0-9A-F]{6}$/.test(normalizedColor)) {
102
+ return `FF${normalizedColor}`;
103
+ }
104
+ return fallbackColor;
105
+ };
106
+
107
+ const getFieldValueFontColor = (
108
+ item,
109
+ field,
110
+ fieldValueColors,
111
+ defaultColor
112
+ ) => {
113
+ const colorConfig = fieldValueColors[field];
114
+ if (!colorConfig || typeof colorConfig !== "object") {
115
+ return defaultColor;
116
+ }
117
+
118
+ const sourceField = colorConfig.sourceField || field;
119
+ const valueColors = colorConfig.colors;
120
+ if (!valueColors || typeof valueColors !== "object") {
121
+ return defaultColor;
122
+ }
123
+
124
+ return normalizeArgbColor(
125
+ valueColors[String(item?.[sourceField] ?? "")],
126
+ defaultColor
127
+ );
128
+ };
129
+
130
+ const getFieldStyle = (field, isDetailField, fieldStyles) => {
131
+ const defaultStyle = isDetailField
132
+ ? {
133
+ headerFontColor: "FF1F4E78",
134
+ headerFillColor: "FFDCE6F1",
135
+ bodyFontColor: DEFAULT_BODY_FONT_COLOR,
136
+ bodyFillColor: "FFF7FAFD",
137
+ }
138
+ : {
139
+ headerFontColor: "FFFFFFFF",
140
+ headerFillColor: "FF4472C4",
141
+ bodyFontColor: DEFAULT_BODY_FONT_COLOR,
142
+ bodyFillColor: "FFFFFFFF",
143
+ };
144
+ const configuredStyle = fieldStyles[field];
145
+ if (!configuredStyle || typeof configuredStyle !== "object") {
146
+ return defaultStyle;
147
+ }
148
+
149
+ return Object.fromEntries(
150
+ Object.entries(defaultStyle).map(([key, defaultColor]) => [
151
+ key,
152
+ normalizeArgbColor(configuredStyle[key], defaultColor),
153
+ ])
154
+ );
155
+ };
156
+
85
157
  export function getVerticalMergeCells(json, fields, options = {}) {
86
158
  const { groupField, mergeFields = [] } = options;
87
159
  if (!groupField || !Array.isArray(mergeFields) || !mergeFields.length) {
@@ -160,18 +232,23 @@ const applyStyledExport = (XLSX, ws, json, fields, options) => {
160
232
 
161
233
  fieldKeys.forEach((field, columnIndex) => {
162
234
  const headerCell = ws[XLSX.utils.encode_cell({ r: 0, c: columnIndex })];
235
+ const isDetailField = detailFieldSet.has(field);
236
+ const fieldStyle = getFieldStyle(
237
+ field,
238
+ isDetailField,
239
+ options.fieldStyles
240
+ );
163
241
  if (headerCell) {
164
- const isDetailField = detailFieldSet.has(field);
165
242
  headerCell.s = {
166
243
  font: {
167
244
  name: "Microsoft YaHei",
168
245
  sz: 11,
169
246
  bold: true,
170
- color: { rgb: isDetailField ? "FF1F4E78" : "FFFFFFFF" },
247
+ color: { rgb: fieldStyle.headerFontColor },
171
248
  },
172
249
  fill: {
173
250
  patternType: "solid",
174
- fgColor: { rgb: isDetailField ? "FFDCE6F1" : "FF4472C4" },
251
+ fgColor: { rgb: fieldStyle.headerFillColor },
175
252
  },
176
253
  alignment: {
177
254
  horizontal: "center",
@@ -190,16 +267,21 @@ const applyStyledExport = (XLSX, ws, json, fields, options) => {
190
267
  return;
191
268
  }
192
269
 
193
- const isDetailField = detailFieldSet.has(field);
270
+ const fontColor = getFieldValueFontColor(
271
+ item,
272
+ field,
273
+ options.fieldValueColors,
274
+ fieldStyle.bodyFontColor
275
+ );
194
276
  cell.s = {
195
277
  font: {
196
278
  name: "Microsoft YaHei",
197
279
  sz: 10,
198
- color: { rgb: "FF333333" },
280
+ color: { rgb: fontColor },
199
281
  },
200
282
  fill: {
201
283
  patternType: "solid",
202
- fgColor: { rgb: isDetailField ? "FFF7FAFD" : "FFFFFFFF" },
284
+ fgColor: { rgb: fieldStyle.bodyFillColor },
203
285
  },
204
286
  alignment: {
205
287
  horizontal: options.fieldAlignments[field] || "left",
@@ -1,5 +1,5 @@
1
1
  <template>
2
- <div ref="tableWarpRef" class="table-warp">
2
+ <div ref="tableWarpRef" class="table-warp" :class="{'antd-pagination-no-mb': useUserPreferences}">
3
3
  <template v-if="displayTitleCollapsed && filterList?.length">
4
4
  <div
5
5
  ref="titleHeaderRef"
@@ -659,6 +659,7 @@
659
659
  ? { x: 'max-content', y: tableScrollHeight }
660
660
  : { x: 'max-content' },
661
661
  ...$attrs,
662
+ sticky: resolvedSticky,
662
663
  }"
663
664
  :dataSource="newDataSource"
664
665
  :size="$attrs?.size || isInDrawer ? 'small' : tableConfig?.size"
@@ -1344,6 +1345,8 @@
1344
1345
  :params="listParams"
1345
1346
  :limit="exportLimit"
1346
1347
  :columnstitle="exportColumnsTitle"
1348
+ :merge_options="exportMergeOptions"
1349
+ :style_options="exportStyleOptions"
1347
1350
  :custom_result="exportResultData"
1348
1351
  :custom_data="dictionaryFilling"
1349
1352
  @customDataFunc="handleExportData"
@@ -1576,6 +1579,16 @@ export default defineComponent({
1576
1579
  type: Number,
1577
1580
  default: 500,
1578
1581
  },
1582
+ /* 导出表格纵向合并配置 */
1583
+ exportMergeOptions: {
1584
+ type: Object,
1585
+ default: () => ({}),
1586
+ },
1587
+ /* 导出表格样式配置 */
1588
+ exportStyleOptions: {
1589
+ type: Object,
1590
+ default: () => ({}),
1591
+ },
1579
1592
  /* 自定义导出的方法 */
1580
1593
  customImport: {
1581
1594
  type: [Function, undefined],
@@ -1615,14 +1628,14 @@ export default defineComponent({
1615
1628
  };
1616
1629
  },
1617
1630
  },
1618
- tableHeight: {
1619
- type: Number,
1620
- default: 0,
1621
- },
1622
- autoTableHeight: {
1631
+ useUserPreferences: {
1623
1632
  type: Boolean,
1624
1633
  default: false,
1625
1634
  },
1635
+ autoTableHeightBottomOffset: {
1636
+ type: Number,
1637
+ default: 11,
1638
+ },
1626
1639
  maximized: {
1627
1640
  type: Boolean,
1628
1641
  default: false,
@@ -1928,9 +1941,25 @@ export default defineComponent({
1928
1941
  const autoTableHeightRaf = ref(0);
1929
1942
  const tableHeightTimer = ref(0);
1930
1943
  const autoTableHeightObserver = ref(null);
1931
- const autoTableHeightBottomOffset = 11;
1932
1944
  const autoTableHeightMinBody = 80;
1933
1945
  const showTableMaximizedButton = computed(() => props.showMaximizeButton);
1946
+ const getUserTableHeightMode = () => {
1947
+ return (
1948
+ utils.preferences?.table?.heightMode ||
1949
+ utils.getCommonLocal("preferences")?.table?.heightMode ||
1950
+ ""
1951
+ );
1952
+ };
1953
+ const userTableHeightMode = ref(getUserTableHeightMode());
1954
+ const shouldUseAutoTableHeight = computed(() => {
1955
+ return props.useUserPreferences && userTableHeightMode.value === "fixed";
1956
+ });
1957
+ const resolvedSticky = computed(() => {
1958
+ if (props.useUserPreferences && userTableHeightMode.value !== "fixed") {
1959
+ return true;
1960
+ }
1961
+ return attrs.sticky;
1962
+ });
1934
1963
  const tableMaximizedText = computed(() =>
1935
1964
  isTableMaximized.value
1936
1965
  ? t("CustomTable.index.074786-34")
@@ -1948,6 +1977,17 @@ export default defineComponent({
1948
1977
  scheduleTableHeightRecalc();
1949
1978
  });
1950
1979
  };
1980
+ const handleLangChange = (event) => {
1981
+ const newLang = event.newValue;
1982
+ loadLanguageAsync(newLang);
1983
+ };
1984
+ const handlePreferencesChange = () => {
1985
+ userTableHeightMode.value = getUserTableHeightMode();
1986
+ nextTick(() => {
1987
+ setupAutoTableHeightObserver();
1988
+ scheduleTableHeightRecalc();
1989
+ });
1990
+ };
1951
1991
 
1952
1992
  const isVisibleFlowElement = (el) => {
1953
1993
  if (!el || el.nodeType !== 1) {
@@ -2004,7 +2044,7 @@ export default defineComponent({
2004
2044
  };
2005
2045
 
2006
2046
  const isAutoTableHeightSafe = () => {
2007
- if (!props.autoTableHeight || props.tableHeight) {
2047
+ if (!shouldUseAutoTableHeight.value) {
2008
2048
  return false;
2009
2049
  }
2010
2050
  const rootEl = tableWarpRef.value;
@@ -2080,13 +2120,17 @@ export default defineComponent({
2080
2120
  };
2081
2121
 
2082
2122
  const getTablePaginationHeight = () => {
2083
- let pagHeight =
2084
- tableRef.value?.$el.getElementsByClassName("ant-pagination")[0]
2085
- ?.offsetHeight || 0;
2086
- if (pagHeight) {
2087
- pagHeight += 32;
2123
+ const paginationEl =
2124
+ tableRef.value?.$el.getElementsByClassName("ant-pagination")[0];
2125
+ if (!paginationEl) {
2126
+ return 0;
2088
2127
  }
2089
- return pagHeight;
2128
+ const style = window.getComputedStyle(paginationEl);
2129
+ return (
2130
+ paginationEl.offsetHeight +
2131
+ parseFloat(style.marginTop || 0) +
2132
+ parseFloat(style.marginBottom || 0)
2133
+ );
2090
2134
  };
2091
2135
 
2092
2136
  const getFilterHeight = () => {
@@ -3036,34 +3080,7 @@ export default defineComponent({
3036
3080
  if (!tableEl) {
3037
3081
  return;
3038
3082
  }
3039
- if (props.tableHeight) {
3040
- let tTitleHeight = getTableTitleHeight();
3041
- let tHeaderHeight = getTableHeaderHeight();
3042
- let tPagHeight = getTablePaginationHeight();
3043
- let filterHeight = getFilterHeight();
3044
- if (utils.isEnv()) {
3045
- console.log(
3046
- props.tableHeight,
3047
- tTitleHeight,
3048
- tHeaderHeight,
3049
- tPagHeight,
3050
- tableEl.getElementsByClassName("ant-table-thead")[0],
3051
- "0000000000000000000"
3052
- );
3053
- }
3054
- let tableScrollHeight =
3055
- props.tableHeight -
3056
- tTitleHeight -
3057
- tHeaderHeight -
3058
- tPagHeight -
3059
- filterHeight;
3060
- tableScrollHeight = Math.max(0, Math.floor(tableScrollHeight));
3061
- if (state.tableScrollHeight !== tableScrollHeight) {
3062
- state.tableScrollHeight = tableScrollHeight;
3063
- }
3064
- return;
3065
- }
3066
- if (props.autoTableHeight && isAutoTableHeightSafe()) {
3083
+ if (shouldUseAutoTableHeight.value && isAutoTableHeightSafe()) {
3067
3084
  const tableTop = tableEl.getBoundingClientRect()?.top || 0;
3068
3085
  const boundaryBottom = getAutoTableHeightBoundaryBottom(tableEl);
3069
3086
  let tableScrollHeight =
@@ -3072,7 +3089,7 @@ export default defineComponent({
3072
3089
  getTableTitleHeight() -
3073
3090
  getTableHeaderHeight() -
3074
3091
  getTablePaginationHeight() -
3075
- autoTableHeightBottomOffset;
3092
+ props.autoTableHeightBottomOffset;
3076
3093
  tableScrollHeight = Math.max(
3077
3094
  autoTableHeightMinBody,
3078
3095
  Math.ceil(tableScrollHeight)
@@ -4044,22 +4061,6 @@ export default defineComponent({
4044
4061
  return utils.i18nMapShow;
4045
4062
  });
4046
4063
 
4047
- watch(
4048
- () => props.tableHeight,
4049
- () => {
4050
- setupAutoTableHeightObserver();
4051
- getTableHeight();
4052
- }
4053
- );
4054
-
4055
- watch(
4056
- () => props.autoTableHeight,
4057
- () => {
4058
- setupAutoTableHeightObserver();
4059
- scheduleTableHeightRecalc();
4060
- }
4061
- );
4062
-
4063
4064
  watch(
4064
4065
  () => [state.filterList.length, isTitleCollapsed.value],
4065
4066
  () => {
@@ -4074,6 +4075,8 @@ export default defineComponent({
4074
4075
  createColumnSlots();
4075
4076
  createButtonIconSlots();
4076
4077
  window.addEventListener("resize", handleResize);
4078
+ window.addEventListener("setBLLang", handleLangChange);
4079
+ window.addEventListener("setBLPreferences", handlePreferencesChange);
4077
4080
  handleResize();
4078
4081
  setupAutoTableHeightObserver();
4079
4082
  scheduleTableHeightRecalc();
@@ -4082,6 +4085,8 @@ export default defineComponent({
4082
4085
 
4083
4086
  onBeforeUnmount(() => {
4084
4087
  window.removeEventListener("resize", handleResize);
4088
+ window.removeEventListener("setBLLang", handleLangChange);
4089
+ window.removeEventListener("setBLPreferences", handlePreferencesChange);
4085
4090
  clearAutoTableHeightObserver();
4086
4091
  if (autoTableHeightRaf.value) {
4087
4092
  cancelAnimationFrame(autoTableHeightRaf.value);
@@ -4147,11 +4152,6 @@ export default defineComponent({
4147
4152
  };*/
4148
4153
  loadLanguageAsync(utils.getLang());
4149
4154
 
4150
- window.addEventListener("setBLLang", (event) => {
4151
- const newLang = event.newValue; // 获取新的语言值
4152
- loadLanguageAsync(newLang);
4153
- });
4154
-
4155
4155
  const checkOverflow = (e) => {
4156
4156
  const ev = window.event || e;
4157
4157
  const textContent = ev.target;
@@ -4440,6 +4440,7 @@ export default defineComponent({
4440
4440
  shouldShowSecurityHeaderBtn,
4441
4441
  formatFilterTagValueShow,
4442
4442
  isFormatFilterTagValueShow,
4443
+ resolvedSticky,
4443
4444
  };
4444
4445
  },
4445
4446
  });
@@ -4538,4 +4539,12 @@ export default defineComponent({
4538
4539
  text-align: right;
4539
4540
  }
4540
4541
  }
4542
+
4543
+ .table-warp {
4544
+ &.antd-pagination-no-mb {
4545
+ :deep(.ant-table-pagination.ant-pagination) {
4546
+ margin-bottom: 0 !important;
4547
+ }
4548
+ }
4549
+ }
4541
4550
  </style>