@nokecy/qc-ui 1.1.11 → 1.1.13

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.
@@ -37,6 +37,23 @@ export declare class BackendApiSchemeAdapter implements SchemeStorageAdapter {
37
37
  * 日志输出
38
38
  */
39
39
  private log;
40
+ /**
41
+ * 【修复】将 JavaScript 时间戳转换为 ISO 字符串
42
+ *
43
+ * JavaScript Date.now() 返回毫秒时间戳(如 1699344567890)
44
+ * .NET DateTimeOffset 需要 ISO 8601 格式字符串(如 "2023-11-07T08:36:07.890Z")
45
+ *
46
+ * @param timestamp 毫秒时间戳
47
+ * @returns ISO 8601 格式字符串
48
+ */
49
+ private toIsoString;
50
+ /**
51
+ * 【修复】将 ISO 字符串转换为 JavaScript 时间戳
52
+ *
53
+ * @param isoString ISO 8601 格式字符串
54
+ * @returns 毫秒时间戳
55
+ */
56
+ private fromIsoString;
40
57
  /**
41
58
  * 生成请求头
42
59
  */
@@ -82,6 +82,39 @@ var BackendApiSchemeAdapter = exports.BackendApiSchemeAdapter = /*#__PURE__*/fun
82
82
  }
83
83
  }
84
84
 
85
+ /**
86
+ * 【修复】将 JavaScript 时间戳转换为 ISO 字符串
87
+ *
88
+ * JavaScript Date.now() 返回毫秒时间戳(如 1699344567890)
89
+ * .NET DateTimeOffset 需要 ISO 8601 格式字符串(如 "2023-11-07T08:36:07.890Z")
90
+ *
91
+ * @param timestamp 毫秒时间戳
92
+ * @returns ISO 8601 格式字符串
93
+ */
94
+ }, {
95
+ key: "toIsoString",
96
+ value: function toIsoString(timestamp) {
97
+ if (timestamp === undefined || timestamp === null) {
98
+ return undefined;
99
+ }
100
+ return new Date(timestamp).toISOString();
101
+ }
102
+
103
+ /**
104
+ * 【修复】将 ISO 字符串转换为 JavaScript 时间戳
105
+ *
106
+ * @param isoString ISO 8601 格式字符串
107
+ * @returns 毫秒时间戳
108
+ */
109
+ }, {
110
+ key: "fromIsoString",
111
+ value: function fromIsoString(isoString) {
112
+ if (!isoString) {
113
+ return undefined;
114
+ }
115
+ return new Date(isoString).getTime();
116
+ }
117
+
85
118
  /**
86
119
  * 生成请求头
87
120
  */
@@ -256,9 +289,11 @@ var BackendApiSchemeAdapter = exports.BackendApiSchemeAdapter = /*#__PURE__*/fun
256
289
  _context3.prev = 0;
257
290
  this.log("\u4FDD\u5B58\u5217\u65B9\u6848: ".concat(gridId, " - ").concat(scheme.name));
258
291
 
259
- // 将 columnConfig 转换为 JSON 字符串
292
+ // 【修复】将时间戳转换为 ISO 字符串,并将 columnConfig 转换为 JSON 字符串
260
293
  schemeForBackend = _objectSpread(_objectSpread({}, scheme), {}, {
261
- columnConfig: JSON.stringify(scheme.columnConfig)
294
+ columnConfig: JSON.stringify(scheme.columnConfig),
295
+ createdAt: this.toIsoString(scheme.createdAt),
296
+ updatedAt: this.toIsoString(scheme.updatedAt)
262
297
  });
263
298
  url = "".concat(this.config.apiBaseUrl, "/api/extra-object/table-scheme/save-column-scheme");
264
299
  _context3.next = 6;
@@ -277,10 +312,20 @@ var BackendApiSchemeAdapter = exports.BackendApiSchemeAdapter = /*#__PURE__*/fun
277
312
  }
278
313
  throw new Error(response.message || '保存失败');
279
314
  case 9:
280
- // 将返回的 columnConfig 从字符串解析为对象数组
315
+ // 【修复】将返回的数据转换回前端格式
281
316
  savedScheme = response.scheme;
282
- if (savedScheme && typeof savedScheme.columnConfig === 'string') {
283
- savedScheme.columnConfig = JSON.parse(savedScheme.columnConfig);
317
+ if (savedScheme) {
318
+ // 解析 columnConfig
319
+ if (typeof savedScheme.columnConfig === 'string') {
320
+ savedScheme.columnConfig = JSON.parse(savedScheme.columnConfig);
321
+ }
322
+ // 将 ISO 字符串转换回时间戳
323
+ if (savedScheme.createdAt) {
324
+ savedScheme.createdAt = this.fromIsoString(savedScheme.createdAt);
325
+ }
326
+ if (savedScheme.updatedAt) {
327
+ savedScheme.updatedAt = this.fromIsoString(savedScheme.updatedAt);
328
+ }
284
329
  }
285
330
  this.log('保存成功', savedScheme);
286
331
  return _context3.abrupt("return", savedScheme);
@@ -16,9 +16,9 @@ var _arrayAddBtn = _interopRequireDefault(require("./arrayAddBtn"));
16
16
  var _preview = _interopRequireDefault(require("./preview"));
17
17
  var _antd = require("antd");
18
18
  var _setting = _interopRequireDefault(require("../ag-grid-plus/setting"));
19
- var _gridContext = require("../ag-grid-plus/context/gridContext");
20
19
  var _columnGroupUtils = require("../ag-grid-plus/setting/columnGroupUtils");
21
20
  var _theme = require("../ag-grid-plus/theme");
21
+ var _agGridPlus = require("../ag-grid-plus");
22
22
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
23
23
  function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(e) { return e ? t : r; })(e); }
24
24
  function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != _typeof(e) && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
@@ -77,11 +77,10 @@ var ArrayTableInner = (0, _react2.observer)(function (props) {
77
77
  handleRowDragMove = _useRowDrag.handleRowDragMove;
78
78
 
79
79
  // 直接使用 Context 获取方案管理状态
80
- // ArrayTable 外层已经提供了完整的 GridPlusContext.Provider
81
- var context = (0, _react.useContext)(_gridContext.GridPlusContext);
82
- var _ref = context || {},
83
- currentSchemes = _ref.currentSchemes,
84
- columnSchemes = _ref.columnSchemes;
80
+ var _useGridSchemes = (0, _agGridPlus.useGridSchemes)(),
81
+ columnSchemes = _useGridSchemes.columnSchemes,
82
+ querySchemes = _useGridSchemes.querySchemes,
83
+ currentSchemes = _useGridSchemes.currentSchemes;
85
84
 
86
85
  // 获取当前表格的激活方案
87
86
  var currentScheme = (0, _react.useMemo)(function () {
@@ -95,134 +94,94 @@ var ArrayTableInner = (0, _react2.observer)(function (props) {
95
94
  });
96
95
  }, [props.gridKey, currentSchemes, columnSchemes]);
97
96
 
98
- // 使用 ref 记录上次应用的方案 ID 和配置哈希,避免重复应用
99
- var lastAppliedRef = (0, _react.useRef)({
100
- schemeId: null,
101
- configHash: null
97
+ // 使用 ref 记录上次应用的方案状态,避免重复应用
98
+ var lastAppliedSchemeRef = (0, _react.useRef)({
99
+ id: null,
100
+ updatedAt: null
102
101
  });
103
102
 
104
103
  /**
105
- * 【关键修复】在页面刷新或切换方案时自动恢复列方案
104
+ * 方案自动加载
106
105
  *
107
- * 监听 currentScheme 和 gridApiState 的变化,当方案和 Grid API 都准备好时,
108
- * 自动应用方案中保存的列状态(列顺序、宽度、隐藏等)
109
- *
110
- * 关键优化:比较 Grid 当前状态和方案配置,只在真正不一致时才应用
106
+ * 参考 ag-gridPlus 优化方案:
107
+ * 1. 使用 Promise 链确保顺序执行,避免竞态条件
108
+ * 2. 使用双重 RAF 确保渲染完成
109
+ * 3. 完整的错误处理和清理机制
111
110
  */
112
111
  (0, _react.useEffect)(function () {
113
112
  // 检查必要条件
114
113
  if (!props.gridKey || !gridApiState || !currentScheme) return;
115
114
  if (!currentScheme.columnConfig || currentScheme.columnConfig.length === 0) return;
116
115
 
117
- // 【修复】计算方案配置的哈希
118
- var schemeConfigHash = JSON.stringify({
119
- id: currentScheme.id,
120
- columnCount: currentScheme.columnConfig.length,
121
- // 使用前3列的完整配置作为哈希的一部分(包含顺序、宽度、隐藏等)
122
- firstCols: currentScheme.columnConfig.slice(0, 3).map(function (col) {
123
- return {
124
- field: col.field,
125
- width: col.width,
126
- hide: col.hide,
127
- pinned: col.pinned
128
- };
129
- })
130
- });
116
+ // 【关键修复】检查方案是否真正变化(比对 ID 和 updatedAt)
117
+ // 只有当方案 ID 变化,或者同一方案但 updatedAt 变化时,才重新应用
118
+ var isSameScheme = currentScheme.id === lastAppliedSchemeRef.current.id;
119
+ var isSameVersion = currentScheme.updatedAt === lastAppliedSchemeRef.current.updatedAt;
120
+ if (isSameScheme && isSameVersion) {
121
+ return;
122
+ }
123
+ if (isSameScheme && !isSameVersion) {}
124
+ // 使用 Promise 链确保顺序执行,避免竞态条件
125
+ var cancelled = false;
126
+ Promise.resolve().then(function () {
127
+ if (cancelled || !gridApiState) return;
131
128
 
132
- // 【关键修复】比较方案配置和 Grid 当前状态
133
- // 检查前3列的关键属性是否一致(跳过字段名差异)
134
- var currentGridState = gridApiState.getColumnState();
135
- var isGridStateSameAsScheme = true;
136
- if (currentGridState.length !== currentScheme.columnConfig.length) {
137
- isGridStateSameAsScheme = false;
138
- } else {
139
- // 比较前3列的关键属性
140
- for (var i = 0; i < Math.min(3, currentGridState.length); i++) {
141
- var gridCol = currentGridState[i];
142
- var schemeCol = currentScheme.columnConfig[i];
143
- if (schemeCol.type !== 'column') continue;
129
+ // 1. 检查是否包含分组配置
130
+ var hasGroups = currentScheme.columnConfig.some(function (item) {
131
+ return item.type === 'group';
132
+ });
144
133
 
145
- // 比较关键属性(field/colId, width, hide, pinned)
146
- if (gridCol.colId !== schemeCol.field || Math.abs((gridCol.width || 0) - (schemeCol.width || 0)) > 5 ||
147
- // 允许5px误差
148
- gridCol.hide !== schemeCol.hide || gridCol.pinned !== schemeCol.pinned) {
149
- isGridStateSameAsScheme = false;
150
- break;
151
- }
134
+ // 如果包含分组,先更新 columnDefs
135
+ if (hasGroups) {
136
+ var gridColumnDefs = (0, _columnGroupUtils.flatConfigToGridState)(currentScheme.columnConfig);
137
+ gridApiState.setGridOption('columnDefs', gridColumnDefs);
152
138
  }
153
- }
154
- // 【关键】跳过应用的条件:
155
- // 1. Grid 当前状态与方案配置一致(说明已经应用过或刚保存)
156
- // 2. 方案配置与上次应用的相同(避免重复应用)
157
- if (isGridStateSameAsScheme || schemeConfigHash === lastAppliedRef.current.configHash) {
158
- // 更新记录,避免后续误判
159
- lastAppliedRef.current = {
160
- schemeId: currentScheme.id,
161
- configHash: schemeConfigHash
162
- };
163
- return;
164
- }
165
139
 
166
- // 【提取函数】应用列状态和过滤器
167
- var applyColumnStateAndFilter = function applyColumnStateAndFilter() {
168
- if (!currentScheme || !gridApiState) return;
140
+ // 2. 应用列状态(列顺序、宽度、隐藏、固定等)
169
141
 
170
- // 将扁平化的列配置转换为 AG-Grid 列状态
171
142
  var columnState = (0, _columnGroupUtils.flatConfigToColumnState)(currentScheme.columnConfig);
172
-
173
- // 应用列状态(包括列顺序、宽度、隐藏等)
174
143
  gridApiState.applyColumnState({
175
144
  state: columnState,
176
- applyOrder: true // 强制应用列顺序
145
+ applyOrder: true
177
146
  });
178
- // 如果方案中包含过滤器配置,也一并应用
147
+ }).then(function () {
148
+ // 等待 Grid 状态稳定(使用 requestAnimationFrame 而非固定延迟)
149
+ return new Promise(function (resolve) {
150
+ if (cancelled) {
151
+ resolve();
152
+ return;
153
+ }
154
+ requestAnimationFrame(function () {
155
+ // 双重 RAF 确保渲染完成
156
+ requestAnimationFrame(function () {
157
+ return resolve();
158
+ });
159
+ });
160
+ });
161
+ }).then(function () {
162
+ if (cancelled || !gridApiState) return;
163
+
164
+ // 3. 应用过滤器(在列状态稳定后执行)
179
165
  if (currentScheme.filterModel) {
180
166
  gridApiState.setFilterModel(currentScheme.filterModel);
181
167
  }
182
168
 
183
- // 记录本次应用的配置哈希
184
- lastAppliedRef.current = {
185
- schemeId: currentScheme.id,
186
- configHash: schemeConfigHash
169
+ // 【关键修复】记录已应用的方案状态(ID + updatedAt)
170
+ lastAppliedSchemeRef.current = {
171
+ id: currentScheme.id,
172
+ updatedAt: currentScheme.updatedAt
187
173
  };
188
- };
189
-
190
- // 使用 requestAnimationFrame 延迟应用
191
- var rafId = requestAnimationFrame(function () {
192
- try {
193
- // 【关键检测】检查是否包含分组配置
194
- var hasGroups = currentScheme.columnConfig.some(function (item) {
195
- return item.type === 'group';
196
- });
197
- // 【条件更新】只有在包含分组时才更新 columnDefs
198
- // 原因:array-table 的列是动态生成的,无分组时不应该覆盖动态列定义
199
- if (hasGroups) {
200
- var gridColumnDefs = (0, _columnGroupUtils.flatConfigToGridState)(currentScheme.columnConfig);
201
- gridApiState.setGridOption('columnDefs', gridColumnDefs);
202
-
203
- // 等待 columnDefs 更新完成后再应用列状态
204
- setTimeout(function () {
205
- try {
206
- applyColumnStateAndFilter();
207
- } catch (error) {
208
- console.error('[ArrayTable] 应用列状态失败:', error);
209
- }
210
- }, 100);
211
- } else {
212
- // 无分组时,直接应用列状态即可
213
-
214
- applyColumnStateAndFilter();
215
- }
216
- } catch (error) {
174
+ }).catch(function (error) {
175
+ if (!cancelled) {
217
176
  console.error('[ArrayTable] 应用方案失败:', error);
218
177
  }
219
178
  });
220
179
 
221
- // 清理函数:取消待执行的 RAF
180
+ // 清理函数:取消进行中的操作
222
181
  return function () {
223
- cancelAnimationFrame(rafId);
182
+ cancelled = true;
224
183
  };
225
- }, [props.gridKey, gridApiState, currentScheme === null || currentScheme === void 0 ? void 0 : currentScheme.id]);
184
+ }, [props.gridKey, gridApiState, currentScheme === null || currentScheme === void 0 ? void 0 : currentScheme.id, currentScheme === null || currentScheme === void 0 ? void 0 : currentScheme.updatedAt]);
226
185
 
227
186
  //@ts-ignore
228
187
  if (columns.length > 0) {
@@ -288,8 +247,6 @@ var ArrayTableInner = (0, _react2.observer)(function (props) {
288
247
  params.api.hidePopupMenu();
289
248
  apiRef.current = params.api;
290
249
  setGridApiState(params.api);
291
-
292
- // 恢复列状态将由 useEffect 处理(使用方案系统)
293
250
  },
294
251
  suppressColumnVirtualisation: true,
295
252
  gridOptions: {
@@ -337,8 +294,8 @@ var ArrayTableInner = (0, _react2.observer)(function (props) {
337
294
  ' <span data-ref="eSortAsc" class="ag-header-icon ag-sort-ascending-icon"></span>' + ' <span data-ref="eSortDesc" class="ag-header-icon ag-sort-descending-icon"></span>' + ' <span data-ref="eSortNone" class="ag-header-icon ag-sort-none-icon"></span>' + " </div>" + "</div>"
338
295
  }
339
296
  },
340
- getRowId: function getRowId(_ref2) {
341
- var data = _ref2.data;
297
+ getRowId: function getRowId(_ref) {
298
+ var data = _ref.data;
342
299
  return data._id || data.id;
343
300
  }
344
301
  // rowDragEntireRow={true}
@@ -37,6 +37,23 @@ export declare class BackendApiSchemeAdapter implements SchemeStorageAdapter {
37
37
  * 日志输出
38
38
  */
39
39
  private log;
40
+ /**
41
+ * 【修复】将 JavaScript 时间戳转换为 ISO 字符串
42
+ *
43
+ * JavaScript Date.now() 返回毫秒时间戳(如 1699344567890)
44
+ * .NET DateTimeOffset 需要 ISO 8601 格式字符串(如 "2023-11-07T08:36:07.890Z")
45
+ *
46
+ * @param timestamp 毫秒时间戳
47
+ * @returns ISO 8601 格式字符串
48
+ */
49
+ private toIsoString;
50
+ /**
51
+ * 【修复】将 ISO 字符串转换为 JavaScript 时间戳
52
+ *
53
+ * @param isoString ISO 8601 格式字符串
54
+ * @returns 毫秒时间戳
55
+ */
56
+ private fromIsoString;
40
57
  /**
41
58
  * 生成请求头
42
59
  */
@@ -83,6 +83,39 @@ export var BackendApiSchemeAdapter = /*#__PURE__*/function () {
83
83
  }
84
84
  }
85
85
 
86
+ /**
87
+ * 【修复】将 JavaScript 时间戳转换为 ISO 字符串
88
+ *
89
+ * JavaScript Date.now() 返回毫秒时间戳(如 1699344567890)
90
+ * .NET DateTimeOffset 需要 ISO 8601 格式字符串(如 "2023-11-07T08:36:07.890Z")
91
+ *
92
+ * @param timestamp 毫秒时间戳
93
+ * @returns ISO 8601 格式字符串
94
+ */
95
+ }, {
96
+ key: "toIsoString",
97
+ value: function toIsoString(timestamp) {
98
+ if (timestamp === undefined || timestamp === null) {
99
+ return undefined;
100
+ }
101
+ return new Date(timestamp).toISOString();
102
+ }
103
+
104
+ /**
105
+ * 【修复】将 ISO 字符串转换为 JavaScript 时间戳
106
+ *
107
+ * @param isoString ISO 8601 格式字符串
108
+ * @returns 毫秒时间戳
109
+ */
110
+ }, {
111
+ key: "fromIsoString",
112
+ value: function fromIsoString(isoString) {
113
+ if (!isoString) {
114
+ return undefined;
115
+ }
116
+ return new Date(isoString).getTime();
117
+ }
118
+
86
119
  /**
87
120
  * 生成请求头
88
121
  */
@@ -257,9 +290,11 @@ export var BackendApiSchemeAdapter = /*#__PURE__*/function () {
257
290
  _context3.prev = 0;
258
291
  this.log("\u4FDD\u5B58\u5217\u65B9\u6848: ".concat(gridId, " - ").concat(scheme.name));
259
292
 
260
- // 将 columnConfig 转换为 JSON 字符串
293
+ // 【修复】将时间戳转换为 ISO 字符串,并将 columnConfig 转换为 JSON 字符串
261
294
  schemeForBackend = _objectSpread(_objectSpread({}, scheme), {}, {
262
- columnConfig: JSON.stringify(scheme.columnConfig)
295
+ columnConfig: JSON.stringify(scheme.columnConfig),
296
+ createdAt: this.toIsoString(scheme.createdAt),
297
+ updatedAt: this.toIsoString(scheme.updatedAt)
263
298
  });
264
299
  url = "".concat(this.config.apiBaseUrl, "/api/extra-object/table-scheme/save-column-scheme");
265
300
  _context3.next = 6;
@@ -278,10 +313,20 @@ export var BackendApiSchemeAdapter = /*#__PURE__*/function () {
278
313
  }
279
314
  throw new Error(response.message || '保存失败');
280
315
  case 9:
281
- // 将返回的 columnConfig 从字符串解析为对象数组
316
+ // 【修复】将返回的数据转换回前端格式
282
317
  savedScheme = response.scheme;
283
- if (savedScheme && typeof savedScheme.columnConfig === 'string') {
284
- savedScheme.columnConfig = JSON.parse(savedScheme.columnConfig);
318
+ if (savedScheme) {
319
+ // 解析 columnConfig
320
+ if (typeof savedScheme.columnConfig === 'string') {
321
+ savedScheme.columnConfig = JSON.parse(savedScheme.columnConfig);
322
+ }
323
+ // 将 ISO 字符串转换回时间戳
324
+ if (savedScheme.createdAt) {
325
+ savedScheme.createdAt = this.fromIsoString(savedScheme.createdAt);
326
+ }
327
+ if (savedScheme.updatedAt) {
328
+ savedScheme.updatedAt = this.fromIsoString(savedScheme.updatedAt);
329
+ }
285
330
  }
286
331
  this.log('保存成功', savedScheme);
287
332
  return _context3.abrupt("return", savedScheme);