@pnt-team/pnt-component-frontend 0.0.132 → 0.0.134

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.
@@ -0,0 +1,499 @@
1
+ /**
2
+ * useTableCore — PntTable 核心逻辑
3
+ *
4
+ * 负责:请求顺序控制、排序三态、筛选草稿/生效分离、多选三态、分页越界校验、7 种状态管理。
5
+ * 纯 React Hook,不依赖 TDesign DOM,方便单测和版本降级。
6
+ */
7
+
8
+ import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
9
+
10
+ // ============================================================
11
+ // 内部类型
12
+ // ============================================================
13
+
14
+ // ============================================================
15
+ // 请求顺序控制
16
+ // ============================================================
17
+
18
+ class RequestManager {
19
+ requestIdCounter = 0;
20
+ abortController = null;
21
+ nextId() {
22
+ // 取消上一请求
23
+ if (this.abortController) {
24
+ try {
25
+ this.abortController.abort();
26
+ } catch {
27
+ /* noop */
28
+ }
29
+ }
30
+ this.abortController = new AbortController();
31
+ return ++this.requestIdCounter;
32
+ }
33
+ isLatest(id) {
34
+ return id === this.requestIdCounter;
35
+ }
36
+ abortCurrent() {
37
+ if (this.abortController) {
38
+ try {
39
+ this.abortController.abort();
40
+ } catch {
41
+ /* noop */
42
+ }
43
+ this.abortController = null;
44
+ }
45
+ }
46
+ }
47
+
48
+ // ============================================================
49
+ // 排序三态循环(TBL-04.01)
50
+ // ============================================================
51
+
52
+ export function cycleSort(currentField, currentDir, targetField) {
53
+ if (currentField !== targetField) {
54
+ // 切换字段:从升序开始,清上一列
55
+ return {
56
+ field: targetField,
57
+ direction: 'asc'
58
+ };
59
+ }
60
+ // 同字段:三态循环
61
+ if (currentDir === undefined || currentDir === null) return {
62
+ field: targetField,
63
+ direction: 'asc'
64
+ };
65
+ if (currentDir === 'asc') return {
66
+ field: targetField,
67
+ direction: 'desc'
68
+ };
69
+ // 第三态:清除排序
70
+ return null;
71
+ }
72
+
73
+ // ============================================================
74
+ // 分页越界校验(TBL-07.04)
75
+ // ============================================================
76
+
77
+ export function clampPage(page, total, pageSize) {
78
+ const maxPage = Math.max(1, Math.ceil(total / pageSize));
79
+ if (page < 1) return 1;
80
+ if (page > maxPage) return maxPage;
81
+ return page;
82
+ }
83
+ export function validateJumpPage(page, total, pageSize) {
84
+ const maxPage = Math.max(1, Math.ceil(total / pageSize));
85
+ if (!Number.isInteger(page) || page < 1 || page > maxPage) {
86
+ return `请输入 1–${maxPage} 的整数页码`;
87
+ }
88
+ return null;
89
+ }
90
+
91
+ // ============================================================
92
+ // 互斥校验(TBL-01.03)
93
+ // ============================================================
94
+
95
+ export function validateColumnConflicts(columns) {
96
+ const errors = [];
97
+ columns.forEach(col => {
98
+ if (col.sort && col.headerFilter) {
99
+ errors.push(`[PntTable] 列 "${col.key}" 同时配置了 sort 和 headerFilter,违反 TBL-01.03 互斥规则。` + ` 如需该字段同时排序+筛选,表头保留 sort,筛选移至 externalFilter(独立查询区)。`);
100
+ }
101
+ });
102
+ return errors;
103
+ }
104
+
105
+ // ============================================================
106
+ // 核心 Hook
107
+ // ============================================================
108
+
109
+ export function useTableCore(props) {
110
+ const {
111
+ tableId,
112
+ rowKey,
113
+ columns,
114
+ dataMode,
115
+ fetcher,
116
+ data: clientData,
117
+ total: clientTotal,
118
+ initialPage = 1,
119
+ pageSize: initialPageSize = 10,
120
+ businessId,
121
+ env,
122
+ timezone,
123
+ onQueryChange,
124
+ onSelectionChange,
125
+ selectable = false,
126
+ currentPageOnly = true
127
+ } = props;
128
+ const reqMgrRef = useRef(new RequestManager());
129
+ const [requestId, setRequestId] = useState(0);
130
+ const [state, setState] = useState(() => {
131
+ const initialRows = dataMode === 'client' ? clientData ?? [] : [];
132
+ return {
133
+ data: initialRows,
134
+ total: dataMode === 'client' ? clientTotal ?? clientData?.length ?? 0 : 0,
135
+ status: dataMode === 'client' ? initialRows.length === 0 ? 'empty' : 'normal' : 'loading',
136
+ error: null,
137
+ sort: null,
138
+ appliedFilters: {},
139
+ page: initialPage,
140
+ pageSize: initialPageSize,
141
+ selection: new Set()
142
+ };
143
+ });
144
+
145
+ // client 模式:props.data 变化时同步行数据,并重算空态
146
+ useEffect(() => {
147
+ if (dataMode !== 'client') return;
148
+ const rows = clientData ?? [];
149
+ setState(prev => {
150
+ const hasAppliedFilter = Object.values(prev.appliedFilters).some(v => v !== undefined && v !== null && v !== '');
151
+ return {
152
+ ...prev,
153
+ data: rows,
154
+ total: clientTotal ?? rows.length,
155
+ status: rows.length === 0 ? hasAppliedFilter ? 'empty-with-filter' : 'empty' : 'normal',
156
+ error: null
157
+ };
158
+ });
159
+ }, [dataMode, clientData, clientTotal]);
160
+ const setStatePartial = useCallback(patch => {
161
+ setState(prev => ({
162
+ ...prev,
163
+ ...patch
164
+ }));
165
+ }, []);
166
+
167
+ // ============================================================
168
+ // 数据获取
169
+ // ============================================================
170
+
171
+ const triggerFetch = useCallback(async (trigger, snapshot) => {
172
+ if (dataMode !== 'server' || !fetcher) return;
173
+ const thisReqId = reqMgrRef.current.nextId();
174
+ const query = {
175
+ query: {},
176
+ // 独立查询区(组件不维护,由业务项目维护并透传)
177
+ filters: snapshot.appliedFilters,
178
+ sort: snapshot.sort,
179
+ page: snapshot.page,
180
+ pageSize: snapshot.pageSize,
181
+ businessId,
182
+ env,
183
+ timezone
184
+ };
185
+ onQueryChange?.(query, {
186
+ tableId,
187
+ trigger,
188
+ requestId: thisReqId
189
+ });
190
+ setStatePartial({
191
+ status: snapshot.page > 1 || requestId > 0 ? 'refreshing' : 'loading'
192
+ });
193
+ try {
194
+ const res = await fetcher(query);
195
+
196
+ // 旧请求晚到 → 丢弃(TBL-09.06)
197
+ if (!reqMgrRef.current.isLatest(thisReqId)) return;
198
+ if (res.noPermission) {
199
+ setStatePartial({
200
+ status: 'no-permission',
201
+ error: null,
202
+ data: [],
203
+ total: 0
204
+ });
205
+ setRequestId(thisReqId);
206
+ return;
207
+ }
208
+ if (res.code !== undefined && res.code !== 0) {
209
+ // 文案由组件层按 locale/texts 兜底,core 只透传原始错误信息
210
+ setStatePartial({
211
+ status: 'error',
212
+ error: res.msg || ''
213
+ });
214
+ setRequestId(thisReqId);
215
+ return;
216
+ }
217
+ const rows = res.rows ?? [];
218
+ setStatePartial({
219
+ data: rows,
220
+ total: res.total ?? rows.length,
221
+ status: rows.length === 0 ? Object.values(snapshot.appliedFilters).some(v => v !== undefined && v !== null && v !== '') ? 'empty-with-filter' : 'empty' : 'normal',
222
+ error: null
223
+ });
224
+ setRequestId(thisReqId);
225
+ } catch (err) {
226
+ if (!reqMgrRef.current.isLatest(thisReqId)) return;
227
+ if (err?.name === 'AbortError') return;
228
+ setStatePartial({
229
+ status: 'error',
230
+ error: err?.message || ''
231
+ });
232
+ setRequestId(thisReqId);
233
+ }
234
+ }, [dataMode, fetcher, tableId, businessId, env, timezone, onQueryChange, requestId, setStatePartial]);
235
+
236
+ // 初始加载
237
+ useEffect(() => {
238
+ if (dataMode === 'server' && fetcher) {
239
+ const page = initialPage;
240
+ const pageSize = state.pageSize;
241
+ setStatePartial({
242
+ page,
243
+ pageSize
244
+ });
245
+ triggerFetch('initial', {
246
+ sort: null,
247
+ appliedFilters: {},
248
+ page,
249
+ pageSize
250
+ });
251
+ }
252
+ // eslint-disable-next-line react-hooks/exhaustive-deps
253
+ }, [tableId, dataMode]);
254
+
255
+ // ============================================================
256
+ // 排序
257
+ // ============================================================
258
+
259
+ const toggleSort = useCallback(field => {
260
+ if (dataMode !== 'server') return;
261
+ const col = columns.find(c => c.key === field);
262
+ if (!col || col.sort === false) return;
263
+ setState(prev => {
264
+ const newSort = cycleSort(prev.sort?.field ?? null, prev.sort?.direction, field);
265
+ const clearedSelection = currentPageOnly ? new Set() : prev.selection;
266
+ const clearedPage = prev.sort?.field !== field ? prev.page : prev.page; // 换字段才回 1
267
+ const newPage = newSort ? 1 : clearedPage; // 有排序就回 1(TBL-04.05)
268
+
269
+ // 翻页/排序变更回 1 页 + 清勾选
270
+ const next = {
271
+ ...prev,
272
+ sort: newSort,
273
+ page: newPage,
274
+ selection: clearedSelection
275
+ };
276
+ if (newSort) {
277
+ triggerFetch('sort', {
278
+ sort: newSort,
279
+ appliedFilters: next.appliedFilters,
280
+ page: newPage,
281
+ pageSize: next.pageSize
282
+ });
283
+ } else if (prev.sort) {
284
+ // 第三态清除排序
285
+ triggerFetch('sort', {
286
+ sort: null,
287
+ appliedFilters: next.appliedFilters,
288
+ page: newPage,
289
+ pageSize: next.pageSize
290
+ });
291
+ }
292
+ return next;
293
+ });
294
+ }, [dataMode, columns, triggerFetch, currentPageOnly]);
295
+
296
+ // ============================================================
297
+ // 筛选(草稿/生效分离)
298
+ // ============================================================
299
+
300
+ const applyFilters = useCallback(filters => {
301
+ // 归一化:空多选归一为不限(TBL-05.03)
302
+ const normalized = {};
303
+ Object.entries(filters).forEach(([k, v]) => {
304
+ if (Array.isArray(v) && v.length === 0) return;
305
+ if (v === undefined || v === null || v === '') return;
306
+ normalized[k] = v;
307
+ });
308
+ setState(prev => {
309
+ const clearedSelection = currentPageOnly ? new Set() : prev.selection;
310
+ const next = {
311
+ ...prev,
312
+ appliedFilters: normalized,
313
+ page: 1,
314
+ // 筛选变更回 1 页(TBL-04.05)
315
+ selection: clearedSelection
316
+ };
317
+ triggerFetch('filter', {
318
+ sort: next.sort,
319
+ appliedFilters: normalized,
320
+ page: 1,
321
+ pageSize: next.pageSize
322
+ });
323
+ return next;
324
+ });
325
+ }, [triggerFetch, currentPageOnly]);
326
+ const resetFilters = useCallback(() => {
327
+ setState(prev => {
328
+ const clearedSelection = currentPageOnly ? new Set() : prev.selection;
329
+ const next = {
330
+ ...prev,
331
+ appliedFilters: {},
332
+ page: 1,
333
+ selection: clearedSelection
334
+ };
335
+ triggerFetch('reset', {
336
+ sort: next.sort,
337
+ appliedFilters: {},
338
+ page: 1,
339
+ pageSize: next.pageSize
340
+ });
341
+ return next;
342
+ });
343
+ }, [triggerFetch, currentPageOnly]);
344
+
345
+ // ============================================================
346
+ // 分页
347
+ // ============================================================
348
+
349
+ const setPage = useCallback(page => {
350
+ if (dataMode !== 'server') return;
351
+ setState(prev => {
352
+ const validated = clampPage(page, prev.total, prev.pageSize);
353
+ if (validated === prev.page) return prev;
354
+ const clearedSelection = currentPageOnly ? new Set() : prev.selection;
355
+ const next = {
356
+ ...prev,
357
+ page: validated,
358
+ selection: clearedSelection
359
+ };
360
+ triggerFetch('pagination', {
361
+ sort: next.sort,
362
+ appliedFilters: next.appliedFilters,
363
+ page: validated,
364
+ pageSize: next.pageSize
365
+ });
366
+ return next;
367
+ });
368
+ }, [dataMode, triggerFetch, currentPageOnly]);
369
+ const setPageSize = useCallback(size => {
370
+ if (dataMode !== 'server') return;
371
+ setState(prev => {
372
+ if (size === prev.pageSize) return prev;
373
+ const clearedSelection = currentPageOnly ? new Set() : prev.selection;
374
+ // pageSize 变更回 1 页(TBL-07.02)
375
+ const next = {
376
+ ...prev,
377
+ pageSize: size,
378
+ page: 1,
379
+ selection: clearedSelection
380
+ };
381
+ triggerFetch('page-size', {
382
+ sort: next.sort,
383
+ appliedFilters: next.appliedFilters,
384
+ page: 1,
385
+ pageSize: size
386
+ });
387
+ return next;
388
+ });
389
+ }, [dataMode, triggerFetch, currentPageOnly]);
390
+
391
+ // ============================================================
392
+ // 多选(三态)
393
+ // ============================================================
394
+
395
+ const toggleRow = useCallback((key, selected) => {
396
+ if (!selectable) return;
397
+ setState(prev => {
398
+ const next = new Set(prev.selection);
399
+ if (selected) next.add(key);else next.delete(key);
400
+ const selArr = Array.from(next);
401
+ onSelectionChange?.(selArr, {
402
+ tableId,
403
+ pageKeys: prev.data.map(r => String(r[rowKey])),
404
+ disabledKeys: [],
405
+ trigger: 'select'
406
+ });
407
+ return {
408
+ ...prev,
409
+ selection: next
410
+ };
411
+ });
412
+ }, [selectable, onSelectionChange, tableId, rowKey]);
413
+ const selectAllOnPage = useCallback((rowKeys, disabledKeys) => {
414
+ if (!selectable) return;
415
+ const selectableKeys = rowKeys.filter(k => !disabledKeys.includes(k));
416
+ setState(prev => {
417
+ const allSelected = selectableKeys.every(k => prev.selection.has(k));
418
+ const next = new Set(prev.selection);
419
+ if (allSelected) {
420
+ selectableKeys.forEach(k => next.delete(k));
421
+ } else {
422
+ selectableKeys.forEach(k => next.add(k));
423
+ }
424
+ const selArr = Array.from(next);
425
+ onSelectionChange?.(selArr, {
426
+ tableId,
427
+ pageKeys: rowKeys,
428
+ disabledKeys,
429
+ trigger: allSelected ? 'select-all' : 'select-all'
430
+ });
431
+ return {
432
+ ...prev,
433
+ selection: next
434
+ };
435
+ });
436
+ }, [selectable, onSelectionChange, tableId]);
437
+ const clearSelection = useCallback(() => {
438
+ setState(prev => ({
439
+ ...prev,
440
+ selection: new Set()
441
+ }));
442
+ onSelectionChange?.([], {
443
+ tableId,
444
+ pageKeys: [],
445
+ disabledKeys: [],
446
+ trigger: 'reset'
447
+ });
448
+ }, [onSelectionChange, tableId]);
449
+ const isAllSelectedOnPage = useCallback((rowKeys, disabledKeys) => {
450
+ const selectableKeys = rowKeys.filter(k => !disabledKeys.includes(k));
451
+ if (selectableKeys.length === 0) return false;
452
+ return selectableKeys.every(k => state.selection.has(k));
453
+ }, [state.selection]);
454
+ const isIndeterminateOnPage = useCallback((rowKeys, disabledKeys) => {
455
+ const selectableKeys = rowKeys.filter(k => !disabledKeys.includes(k));
456
+ if (selectableKeys.length === 0) return false;
457
+ const selectedCount = selectableKeys.filter(k => state.selection.has(k)).length;
458
+ return selectedCount > 0 && selectedCount < selectableKeys.length;
459
+ }, [state.selection]);
460
+ const refresh = useCallback(() => {
461
+ setState(prev => {
462
+ const clearedSelection = currentPageOnly ? new Set() : prev.selection;
463
+ const next = {
464
+ ...prev,
465
+ selection: clearedSelection
466
+ };
467
+ triggerFetch('reset', {
468
+ sort: next.sort,
469
+ appliedFilters: next.appliedFilters,
470
+ page: next.page,
471
+ pageSize: next.pageSize
472
+ });
473
+ return next;
474
+ });
475
+ }, [triggerFetch, currentPageOnly]);
476
+ return useMemo(() => ({
477
+ data: state.data,
478
+ total: state.total,
479
+ status: state.status,
480
+ error: state.error,
481
+ sort: state.sort,
482
+ appliedFilters: state.appliedFilters,
483
+ page: state.page,
484
+ pageSize: state.pageSize,
485
+ selection: Array.from(state.selection),
486
+ requestId,
487
+ toggleSort,
488
+ applyFilters,
489
+ resetFilters,
490
+ setPage,
491
+ setPageSize,
492
+ toggleRow,
493
+ selectAllOnPage,
494
+ clearSelection,
495
+ refresh,
496
+ isAllSelectedOnPage,
497
+ isIndeterminateOnPage
498
+ }), [state, requestId, toggleSort, applyFilters, resetFilters, setPage, setPageSize, toggleRow, selectAllOnPage, clearSelection, refresh, isAllSelectedOnPage, isIndeterminateOnPage]);
499
+ }
@@ -1,5 +1,8 @@
1
1
  export { PntProvider, usePntConfig, type PntConfig, type PntHighSecurityConfig, type PntHttpLike, type PntRegionQueryConfig, type commonEesType, } from './config';
2
2
  export { default as PntImage } from './components/PntImage';
3
+ export { default as PntTable } from './components/PntTable';
4
+ export type { PntSortDirection, PntSortInfo, PntTableColumn, PntTableDataMode, PntTableFetcher, PntTableFilterConfig as PntTableFilterConfigItem, PntTableLocale, PntTableProps, PntTableQuery, PntTableQueryMeta, PntTableQueryTrigger, PntTableRef, PntTableResponse, PntTableSelectConfig, PntTableSelectionMeta, PntTableStatus, PntTableTexts, PntTableTheme, PntFilterOption, } from './components/PntTable/types';
5
+ export { PNT_TABLE_DEFAULT_TEXTS, PNT_TABLE_EN_TEXTS, getPntTableTextsByLocale, } from './components/PntTable/types';
3
6
  export { default as PntBusinessSelect } from './components/PntBusinessSelect';
4
7
  export { default as PntRegionSelect, normalizeRegionCode, } from './components/PntRegionSelect';
5
8
  export { DEFAULT_TEXTS, EN_TEXTS, getTextsByLocale, } from './components/PntRegionSelect/types';
package/lib/esm/index.js CHANGED
@@ -10,6 +10,8 @@ export { PntProvider, usePntConfig } from "./config";
10
10
 
11
11
  // ---------- L1 基础展示组件 ----------
12
12
  export { default as PntImage } from "./components/PntImage";
13
+ export { default as PntTable } from "./components/PntTable";
14
+ export { PNT_TABLE_DEFAULT_TEXTS, PNT_TABLE_EN_TEXTS, getPntTableTextsByLocale } from "./components/PntTable/types";
13
15
 
14
16
  // ---------- L2 业务复合组件 ----------
15
17
  export { default as PntBusinessSelect } from "./components/PntBusinessSelect";
@@ -1 +1 @@
1
- .pnt-image-wrapper{position:relative}.pnt-image-wrapper .pnt-image-progress,.pnt-image-wrapper .pnt-image-upload-progress{align-items:center;display:flex;height:8.5rem;justify-content:center;width:8.5rem}.pnt-image-wrapper .pnt-image-progress .pnt-image-loading,.pnt-image-wrapper .pnt-image-upload-progress .pnt-image-loading{align-items:center;background-color:#f7f8fa;border-radius:.25rem;display:flex;flex-direction:column;height:100%;justify-content:center;text-align:center;width:100%}.pnt-image-wrapper .pnt-image-progress .pnt-image-loading svg,.pnt-image-wrapper .pnt-image-upload-progress .pnt-image-loading svg{color:var(--td-brand-color);font-size:1.5rem}.pnt-image-wrapper .pnt-image-progress .pnt-image-loading p,.pnt-image-wrapper .pnt-image-upload-progress .pnt-image-loading p{color:#808191;font-size:.75rem;margin-top:.25rem}.pnt-image-wrapper .pnt-image{height:8.5rem;width:8.5rem}.pnt-image-wrapper .pnt-image .pnt-image-mask{align-items:center;background:rgba(0,0,0,.6);color:#fff;display:flex;height:100%;justify-content:center}.pnt-image-wrapper .pnt-image .pnt-image-mask--basic{cursor:pointer}.pnt-image-wrapper .pnt-image .pnt-image-mask .pnt-image-divider{border-left:.0625rem solid var(--td-text-color-anti);height:var(--td-comp-size-xxxs);margin:0 var(--td-comp-margin-l)}.pnt-business-select{width:100%}.pnt-business-select-option-label{display:block;width:100%}.pnt-business-select-popup .t-popup__content .t-loading,.pnt-business-select-popup .t-popup__content .total-wrapper{align-items:center;display:flex;font-weight:400;height:2.25rem;line-height:1.25rem;padding:0 .875rem}.pnt-business-select-popup .t-popup__content .total-wrapper{color:#808191;font-size:.875rem}.pnt-region-select{width:100%}.pnt-region-select__toolbar{align-items:center;background:#fff;background:var(--td-bg-color-container,#fff);border-bottom:.0625rem solid #e7e7e7;border-bottom:.0625rem solid var(--td-component-border,#e7e7e7);display:flex;justify-content:space-between;padding:.5rem .75rem}.pnt-region-select__invert{color:#0052d9;color:var(--td-brand-color,#0052d9);cursor:pointer;font-size:.75rem;margin-left:.75rem;margin-right:auto;-webkit-user-select:none;-moz-user-select:none;user-select:none}.pnt-region-select__invert:hover{color:#2667d4;color:var(--td-brand-color-hover,#2667d4)}.pnt-region-select__count{color:#999;color:var(--td-text-color-secondary,#999);font-size:.75rem;margin-left:auto}.pnt-region-select__invert+.pnt-region-select__count{margin-left:0}.pnt-region-select__empty{color:#999;color:var(--td-text-color-secondary,#999);font-size:.875rem;padding:1rem;text-align:center}.pnt-region-select__import-wrapper{align-items:center;display:flex;position:relative;width:22.5rem}.pnt-region-select__import-wrapper .pnt-region-select{flex:1 1}.pnt-region-select__import-btn{flex-shrink:0;position:absolute;right:2rem;z-index:1}.pnt-region-select-popup .t-select__list{padding-top:0}.pnt-region-import__tip{color:#999;color:var(--td-text-color-secondary,#999);font-size:.75rem;margin-bottom:.5rem}.pnt-region-import__result{margin-top:.75rem}.pnt-region-import__summary{align-items:center;display:flex;font-size:.75rem;gap:.25rem;margin-bottom:.5rem}.pnt-region-import__summary-item--unmatched{color:#d54941;color:var(--td-error-color,#d54941)}.pnt-region-import__summary-item--pending{color:#2ba471;color:var(--td-success-color,#2ba471)}.pnt-region-import__summary-item--exists{color:#999;color:var(--td-text-color-secondary,#999)}.pnt-region-import__summary-dot{color:#bbb;color:var(--td-text-color-placeholder,#bbb)}.pnt-region-import__copy-btn{height:1.25rem;padding:0 .25rem}.pnt-region-import__table{border:.0625rem solid #e7e7e7;border:.0625rem solid var(--td-component-border,#e7e7e7);border-radius:.25rem;overflow:hidden}.pnt-region-import__table-head{background:#f3f3f3;background:var(--td-bg-color-secondarycontainer,#f3f3f3);color:#999;color:var(--td-text-color-secondary,#999);display:flex;font-size:.75rem;justify-content:space-between;padding:.375rem .75rem}.pnt-region-import__table-body{max-height:12.5rem;overflow-y:auto}.pnt-region-import__table-row{align-items:center;display:flex;font-size:.75rem;justify-content:space-between;padding:.375rem .75rem}.pnt-region-import__table-row+.pnt-region-import__table-row{border-top:.0625rem solid #e7e7e7;border-top:.0625rem solid var(--td-component-border,#e7e7e7)}.pnt-region-import__status{align-items:center;display:inline-flex;gap:.25rem}.pnt-region-import__status--unmatched{color:#d54941;color:var(--td-error-color,#d54941)}.pnt-region-import__status--pending{color:#2ba471;color:var(--td-success-color,#2ba471)}.pnt-region-import__empty,.pnt-region-import__status--exists{color:#999;color:var(--td-text-color-secondary,#999)}.pnt-region-import__empty{padding:1rem;text-align:center}.pnt-secure-box{color:#333;max-width:-moz-fit-content;max-width:fit-content;position:relative}.pnt-secure-box .copy-icon,.pnt-secure-box .view-icon{color:#3f8cff!important;cursor:pointer;font-size:small;position:absolute;right:-1.875rem;top:.0625rem}.pnt-secure-box .copy-icon{right:-3.125rem}.pnt-secure-box .security-value{position:relative;top:.1875rem}.pnt-general-layout{--pnt-layout-body-padding:1.5rem;--pnt-layout-card-radius:0.25rem;background-color:transparent;height:100%}.pnt-general-layout .t-layout__header{align-items:stretch;border-bottom:.0625rem solid #f0f3f6;display:flex;flex-shrink:0;height:auto;justify-content:space-between}.pnt-general-layout .t-layout__header .header-title{align-items:center;display:inline-flex;padding:1.5rem}.pnt-general-layout .t-layout__header .header-title .goback-icon{color:#3f8cff;cursor:pointer;margin-right:.75rem}.pnt-general-layout .t-layout__header .header-title .title{font-size:1.25rem;font-weight:600;line-height:1.5rem}.pnt-general-layout .t-layout__header .header-operation{align-items:center;display:flex;padding-right:1.5rem}.pnt-general-layout .t-layout__header .header-operation .t-button+.t-button{margin-left:.75rem}.pnt-general-layout--borderless .t-layout__header{border-bottom:none}.pnt-general-layout .general-layout-sub-header{border-bottom:.0625rem solid #f0f3f6;flex-shrink:0}.pnt-general-layout .general-layout-body{background:#fafafa;flex:1 1 auto;min-height:0;overflow-y:auto;padding:var(--pnt-layout-body-padding)}.pnt-general-layout .general-layout-body>div.t-card,.pnt-general-layout .general-layout-body>div.t-loading__parent>div.t-card,.pnt-general-layout .general-layout-body>div.tea-card,.pnt-general-layout .general-layout-body>div[class*=-block],.pnt-general-layout .general-layout-body>div[class*=-wrapper]{border-radius:var(--pnt-layout-card-radius);box-shadow:none;margin-bottom:1.5rem}.pnt-general-layout .general-layout-body>div.t-card .t-card__body,.pnt-general-layout .general-layout-body>div.t-loading__parent>div.t-card .t-card__body,.pnt-general-layout .general-layout-body>div.tea-card .t-card__body,.pnt-general-layout .general-layout-body>div[class*=-block] .t-card__body,.pnt-general-layout .general-layout-body>div[class*=-wrapper] .t-card__body{border-radius:var(--pnt-layout-card-radius)}.pnt-general-layout .general-layout-body>div.t-loading__parent>div:last-child.t-card,.pnt-general-layout .general-layout-body>div:last-child,.pnt-general-layout .general-layout-body>div:last-child.t-card,.pnt-general-layout .general-layout-body>div:last-child.tea-card,.pnt-general-layout .general-layout-body>div:last-child[class*=-block],.pnt-general-layout .general-layout-body>div:last-child[class*=-wrapper]{margin-bottom:0}.pnt-general-layout .t-layout__footer{background:#fff;border-top:.0625rem solid #f0f3f6;flex-shrink:0;padding:1.125rem 1.5rem}.pnt-general-layout .t-layout__footer .t-button{font-size:.875rem;font-weight:600;height:2.25rem;min-width:5.75rem}.pnt-general-layout .t-layout__footer .t-button+.t-button{margin-left:.75rem}.pnt-general-layout--footer-auto .t-layout__footer .t-button{font-size:inherit;font-weight:inherit;height:auto;min-width:0}
1
+ .pnt-image-wrapper{position:relative}.pnt-image-wrapper .pnt-image-progress,.pnt-image-wrapper .pnt-image-upload-progress{align-items:center;display:flex;height:8.5rem;justify-content:center;width:8.5rem}.pnt-image-wrapper .pnt-image-progress .pnt-image-loading,.pnt-image-wrapper .pnt-image-upload-progress .pnt-image-loading{align-items:center;background-color:#f7f8fa;border-radius:.25rem;display:flex;flex-direction:column;height:100%;justify-content:center;text-align:center;width:100%}.pnt-image-wrapper .pnt-image-progress .pnt-image-loading svg,.pnt-image-wrapper .pnt-image-upload-progress .pnt-image-loading svg{color:var(--td-brand-color);font-size:1.5rem}.pnt-image-wrapper .pnt-image-progress .pnt-image-loading p,.pnt-image-wrapper .pnt-image-upload-progress .pnt-image-loading p{color:#808191;font-size:.75rem;margin-top:.25rem}.pnt-image-wrapper .pnt-image{height:8.5rem;width:8.5rem}.pnt-image-wrapper .pnt-image .pnt-image-mask{align-items:center;background:rgba(0,0,0,.6);color:#fff;display:flex;height:100%;justify-content:center}.pnt-image-wrapper .pnt-image .pnt-image-mask--basic{cursor:pointer}.pnt-image-wrapper .pnt-image .pnt-image-mask .pnt-image-divider{border-left:.0625rem solid var(--td-text-color-anti);height:var(--td-comp-size-xxxs);margin:0 var(--td-comp-margin-l)}.pnt-table{--pnt-table-brand:#3f8cff;--pnt-table-brand-hover:#2875e3;--pnt-table-brand-active:#1f65cc;--pnt-table-brand-soft:#eaf3ff;--pnt-table-danger:#d54941;--pnt-table-danger-soft:#fdecea;--pnt-table-success:#2ba471;--pnt-table-success-soft:#e3f6ee;--pnt-table-warning:#e37318;--pnt-table-warning-soft:#fef3e8;--pnt-table-bg:#fff;--pnt-table-bg-header:#f8fafd;--pnt-table-bg-hover:#f8fafd;--pnt-table-bg-selected:var(--pnt-table-brand-soft);--pnt-table-border:#e5e8ef;--pnt-table-text-primary:#1d2129;--pnt-table-text-secondary:#4e5969;--pnt-table-text-tertiary:#86909c;--pnt-table-text-placeholder:#bbbfc4;--pnt-table-header-height:3rem;--pnt-table-row-min-height:3rem;--pnt-table-cell-padding-v:0.75rem;--pnt-table-cell-padding-h:1rem}.pnt-table[data-theme=internal]{--pnt-table-brand:#624beb;--pnt-table-brand-hover:#503bd1;--pnt-table-brand-active:#412eb5;--pnt-table-brand-soft:#f0edff}.pnt-table .t-table__header{background-color:var(--pnt-table-bg-header);color:var(--pnt-table-text-primary);font-size:.875rem;font-weight:600;line-height:var(--pnt-table-header-height)}.pnt-table .t-table__header th{background-color:var(--pnt-table-bg-header);border-bottom:.0625rem solid var(--pnt-table-border);border-right:none;height:var(--pnt-table-header-height);overflow:hidden;padding:0 var(--pnt-table-cell-padding-h);text-overflow:ellipsis;white-space:nowrap}.pnt-table .t-table__header th.tdesign-table-td--left{text-align:left}.pnt-table .t-table__header th.tdesign-table-td--center,.pnt-table .t-table__header th.tdesign-table-td--middle{text-align:center}.pnt-table .t-table__header th.tdesign-table-td--right{text-align:right}.pnt-table .t-table__body td{border-bottom:.0625rem solid var(--pnt-table-border);color:var(--pnt-table-text-primary);font-size:.875rem;min-height:var(--pnt-table-row-min-height);padding:var(--pnt-table-cell-padding-v) var(--pnt-table-cell-padding-h)}.pnt-table .t-table__body tr:hover>td{background-color:var(--pnt-table-bg-hover)}.pnt-table .t-table__body tr.is-selected>td{background-color:var(--pnt-table-bg-selected)}.pnt-table .t-table__body tr.is-selected:hover>td{background-color:var(--pnt-table-bg-selected)}.pnt-table .tdesign-table-td--left,.pnt-table .tdesign-table-td--start{text-align:left}.pnt-table .tdesign-table-td--center,.pnt-table .tdesign-table-td--middle{text-align:center}.pnt-table .tdesign-table-td--end,.pnt-table .tdesign-table-td--right{text-align:right}.pnt-table-col-title{align-items:center;display:inline-flex;gap:.25rem}.pnt-table-col-title .pnt-table-help-icon{background:var(--pnt-table-border);border-radius:50%;color:var(--pnt-table-text-tertiary);cursor:help;display:inline-flex;flex-shrink:0;font-size:.625rem;height:.875rem;justify-content:center;line-height:.875rem;width:.875rem}.pnt-table-col-title .pnt-table-help-icon:hover{background:var(--pnt-table-brand);color:#fff}.pnt-table .t-empty,.pnt-table .t-table__empty{color:var(--pnt-table-text-tertiary);font-size:.875rem;padding:3rem 0}.pnt-table-empty-with-filter{display:flex;flex-direction:column;gap:.25rem}.pnt-table-empty-with-filter .pnt-table-empty-hint{color:var(--pnt-table-text-tertiary);font-size:.75rem}.pnt-table .t-pagination{color:var(--pnt-table-text-secondary);font-size:.875rem;gap:.75rem;justify-content:flex-end;padding:1rem 0}.pnt-table .t-pagination .t-pagination__btn{border:none;border-radius:.25rem;height:2rem;padding:0 .5rem}.pnt-table .t-pagination .t-pagination__btn:hover:not(.is-disabled){color:var(--pnt-table-brand)}.pnt-table .t-pagination .t-pagination__btn.is-active{background:var(--pnt-table-brand);color:#fff}.pnt-table .t-pagination .t-pagination__total{margin-right:auto}.pnt-table .t-pagination .t-pagination__jump,.pnt-table .t-pagination .t-pagination__size{align-items:center;display:flex;gap:.5rem}.pnt-table .t-table__loading{background:hsla(0,0%,100%,.6);inset:0;position:absolute;z-index:1}.pnt-table .t-table__loading .t-table__loading-text{color:var(--pnt-table-text-secondary);font-size:.875rem}.pnt-table .t-table__loading--skeleton .t-table__body tr td{height:var(--pnt-table-row-min-height)}.pnt-table .t-table__body tr:hover>td.t-table__cell--fixed-left,.pnt-table .t-table__body tr:hover>td.t-table__cell--fixed-right{background-color:var(--pnt-table-bg-hover)}.pnt-table .t-table__body tr.is-selected>td.t-table__cell--fixed-left,.pnt-table .t-table__body tr.is-selected>td.t-table__cell--fixed-right{background-color:var(--pnt-table-bg-selected)}.pnt-table .t-table__select{text-align:center;width:2.75rem}.pnt-table .t-table__select .t-checkbox{cursor:pointer}.pnt-table .t-table__body-wrapper::-webkit-scrollbar,.pnt-table .t-table__header-wrapper::-webkit-scrollbar{height:.5rem;width:.5rem}.pnt-table .t-table__body-wrapper::-webkit-scrollbar-thumb,.pnt-table .t-table__header-wrapper::-webkit-scrollbar-thumb{background:#c9cdd4;border-radius:.25rem}.pnt-table .t-table__body-wrapper::-webkit-scrollbar-thumb:hover,.pnt-table .t-table__header-wrapper::-webkit-scrollbar-thumb:hover{background:var(--pnt-table-brand)}.pnt-table .t-table__body-wrapper::-webkit-scrollbar-track,.pnt-table .t-table__header-wrapper::-webkit-scrollbar-track{background:transparent}.pnt-business-select{width:100%}.pnt-business-select-option-label{display:block;width:100%}.pnt-business-select-popup .t-popup__content .t-loading,.pnt-business-select-popup .t-popup__content .total-wrapper{align-items:center;display:flex;font-weight:400;height:2.25rem;line-height:1.25rem;padding:0 .875rem}.pnt-business-select-popup .t-popup__content .total-wrapper{color:#808191;font-size:.875rem}.pnt-region-select{width:100%}.pnt-region-select__toolbar{align-items:center;background:#fff;background:var(--td-bg-color-container,#fff);border-bottom:.0625rem solid #e7e7e7;border-bottom:.0625rem solid var(--td-component-border,#e7e7e7);display:flex;justify-content:space-between;padding:.5rem .75rem}.pnt-region-select__invert{color:#0052d9;color:var(--td-brand-color,#0052d9);cursor:pointer;font-size:.75rem;margin-left:.75rem;margin-right:auto;-webkit-user-select:none;-moz-user-select:none;user-select:none}.pnt-region-select__invert:hover{color:#2667d4;color:var(--td-brand-color-hover,#2667d4)}.pnt-region-select__count{color:#999;color:var(--td-text-color-secondary,#999);font-size:.75rem;margin-left:auto}.pnt-region-select__invert+.pnt-region-select__count{margin-left:0}.pnt-region-select__empty{color:#999;color:var(--td-text-color-secondary,#999);font-size:.875rem;padding:1rem;text-align:center}.pnt-region-select__import-wrapper{align-items:center;display:flex;position:relative;width:22.5rem}.pnt-region-select__import-wrapper .pnt-region-select{flex:1 1}.pnt-region-select__import-btn{flex-shrink:0;position:absolute;right:2rem;z-index:1}.pnt-region-select-popup .t-select__list{padding-top:0}.pnt-region-import__tip{color:#999;color:var(--td-text-color-secondary,#999);font-size:.75rem;margin-bottom:.5rem}.pnt-region-import__result{margin-top:.75rem}.pnt-region-import__summary{align-items:center;display:flex;font-size:.75rem;gap:.25rem;margin-bottom:.5rem}.pnt-region-import__summary-item--unmatched{color:#d54941;color:var(--td-error-color,#d54941)}.pnt-region-import__summary-item--pending{color:#2ba471;color:var(--td-success-color,#2ba471)}.pnt-region-import__summary-item--exists{color:#999;color:var(--td-text-color-secondary,#999)}.pnt-region-import__summary-dot{color:#bbb;color:var(--td-text-color-placeholder,#bbb)}.pnt-region-import__copy-btn{height:1.25rem;padding:0 .25rem}.pnt-region-import__table{border:.0625rem solid #e7e7e7;border:.0625rem solid var(--td-component-border,#e7e7e7);border-radius:.25rem;overflow:hidden}.pnt-region-import__table-head{background:#f3f3f3;background:var(--td-bg-color-secondarycontainer,#f3f3f3);color:#999;color:var(--td-text-color-secondary,#999);display:flex;font-size:.75rem;justify-content:space-between;padding:.375rem .75rem}.pnt-region-import__table-body{max-height:12.5rem;overflow-y:auto}.pnt-region-import__table-row{align-items:center;display:flex;font-size:.75rem;justify-content:space-between;padding:.375rem .75rem}.pnt-region-import__table-row+.pnt-region-import__table-row{border-top:.0625rem solid #e7e7e7;border-top:.0625rem solid var(--td-component-border,#e7e7e7)}.pnt-region-import__status{align-items:center;display:inline-flex;gap:.25rem}.pnt-region-import__status--unmatched{color:#d54941;color:var(--td-error-color,#d54941)}.pnt-region-import__status--pending{color:#2ba471;color:var(--td-success-color,#2ba471)}.pnt-region-import__empty,.pnt-region-import__status--exists{color:#999;color:var(--td-text-color-secondary,#999)}.pnt-region-import__empty{padding:1rem;text-align:center}.pnt-secure-box{color:#333;max-width:-moz-fit-content;max-width:fit-content;position:relative}.pnt-secure-box .copy-icon,.pnt-secure-box .view-icon{color:#3f8cff!important;cursor:pointer;font-size:small;position:absolute;right:-1.875rem;top:.0625rem}.pnt-secure-box .copy-icon{right:-3.125rem}.pnt-secure-box .security-value{position:relative;top:.1875rem}.pnt-general-layout{--pnt-layout-body-padding:1.5rem;--pnt-layout-card-radius:0.25rem;background-color:transparent;height:100%}.pnt-general-layout .t-layout__header{align-items:stretch;border-bottom:.0625rem solid #f0f3f6;display:flex;flex-shrink:0;height:auto;justify-content:space-between}.pnt-general-layout .t-layout__header .header-title{align-items:center;display:inline-flex;padding:1.5rem}.pnt-general-layout .t-layout__header .header-title .goback-icon{color:#3f8cff;cursor:pointer;margin-right:.75rem}.pnt-general-layout .t-layout__header .header-title .title{font-size:1.25rem;font-weight:600;line-height:1.5rem}.pnt-general-layout .t-layout__header .header-operation{align-items:center;display:flex;padding-right:1.5rem}.pnt-general-layout .t-layout__header .header-operation .t-button+.t-button{margin-left:.75rem}.pnt-general-layout--borderless .t-layout__header{border-bottom:none}.pnt-general-layout .general-layout-sub-header{border-bottom:.0625rem solid #f0f3f6;flex-shrink:0}.pnt-general-layout .general-layout-body{background:#fafafa;flex:1 1 auto;min-height:0;overflow-y:auto;padding:var(--pnt-layout-body-padding)}.pnt-general-layout .general-layout-body>div.t-card,.pnt-general-layout .general-layout-body>div.t-loading__parent>div.t-card,.pnt-general-layout .general-layout-body>div.tea-card,.pnt-general-layout .general-layout-body>div[class*=-block],.pnt-general-layout .general-layout-body>div[class*=-wrapper]{border-radius:var(--pnt-layout-card-radius);box-shadow:none;margin-bottom:1.5rem}.pnt-general-layout .general-layout-body>div.t-card .t-card__body,.pnt-general-layout .general-layout-body>div.t-loading__parent>div.t-card .t-card__body,.pnt-general-layout .general-layout-body>div.tea-card .t-card__body,.pnt-general-layout .general-layout-body>div[class*=-block] .t-card__body,.pnt-general-layout .general-layout-body>div[class*=-wrapper] .t-card__body{border-radius:var(--pnt-layout-card-radius)}.pnt-general-layout .general-layout-body>div.t-loading__parent>div:last-child.t-card,.pnt-general-layout .general-layout-body>div:last-child,.pnt-general-layout .general-layout-body>div:last-child.t-card,.pnt-general-layout .general-layout-body>div:last-child.tea-card,.pnt-general-layout .general-layout-body>div:last-child[class*=-block],.pnt-general-layout .general-layout-body>div:last-child[class*=-wrapper]{margin-bottom:0}.pnt-general-layout .t-layout__footer{background:#fff;border-top:.0625rem solid #f0f3f6;flex-shrink:0;padding:1.125rem 1.5rem}.pnt-general-layout .t-layout__footer .t-button{font-size:.875rem;font-weight:600;height:2.25rem;min-width:5.75rem}.pnt-general-layout .t-layout__footer .t-button+.t-button{margin-left:.75rem}.pnt-general-layout--footer-auto .t-layout__footer .t-button{font-size:inherit;font-weight:inherit;height:auto;min-width:0}