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

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,479 @@
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
+ data: dataMode === 'client' ? clientData ?? [] : [],
132
+ total: dataMode === 'client' ? clientTotal ?? clientData?.length ?? 0 : 0,
133
+ status: dataMode === 'client' ? 'normal' : 'loading',
134
+ error: null,
135
+ sort: null,
136
+ appliedFilters: {},
137
+ page: initialPage,
138
+ pageSize: initialPageSize,
139
+ selection: new Set()
140
+ }));
141
+ const setStatePartial = useCallback(patch => {
142
+ setState(prev => ({
143
+ ...prev,
144
+ ...patch
145
+ }));
146
+ }, []);
147
+
148
+ // ============================================================
149
+ // 数据获取
150
+ // ============================================================
151
+
152
+ const triggerFetch = useCallback(async (trigger, snapshot) => {
153
+ if (dataMode !== 'server' || !fetcher) return;
154
+ const thisReqId = reqMgrRef.current.nextId();
155
+ const query = {
156
+ query: {},
157
+ // 独立查询区(组件不维护,由业务项目维护并透传)
158
+ filters: snapshot.appliedFilters,
159
+ sort: snapshot.sort,
160
+ page: snapshot.page,
161
+ pageSize: snapshot.pageSize,
162
+ businessId,
163
+ env,
164
+ timezone
165
+ };
166
+ onQueryChange?.(query, {
167
+ tableId,
168
+ trigger,
169
+ requestId: thisReqId
170
+ });
171
+ setStatePartial({
172
+ status: snapshot.page > 1 || requestId > 0 ? 'refreshing' : 'loading'
173
+ });
174
+ try {
175
+ const res = await fetcher(query);
176
+
177
+ // 旧请求晚到 → 丢弃(TBL-09.06)
178
+ if (!reqMgrRef.current.isLatest(thisReqId)) return;
179
+ if (res.noPermission) {
180
+ setStatePartial({
181
+ status: 'no-permission',
182
+ error: null,
183
+ data: [],
184
+ total: 0
185
+ });
186
+ setRequestId(thisReqId);
187
+ return;
188
+ }
189
+ if (res.code !== undefined && res.code !== 0) {
190
+ setStatePartial({
191
+ status: 'error',
192
+ error: res.msg || '加载失败'
193
+ });
194
+ setRequestId(thisReqId);
195
+ return;
196
+ }
197
+ const rows = res.rows ?? [];
198
+ setStatePartial({
199
+ data: rows,
200
+ total: res.total ?? rows.length,
201
+ status: rows.length === 0 ? Object.values(snapshot.appliedFilters).some(v => v !== undefined && v !== null && v !== '') ? 'empty-with-filter' : 'empty' : 'normal',
202
+ error: null
203
+ });
204
+ setRequestId(thisReqId);
205
+ } catch (err) {
206
+ if (!reqMgrRef.current.isLatest(thisReqId)) return;
207
+ if (err?.name === 'AbortError') return;
208
+ setStatePartial({
209
+ status: 'error',
210
+ error: err?.message || '加载失败'
211
+ });
212
+ setRequestId(thisReqId);
213
+ }
214
+ }, [dataMode, fetcher, tableId, businessId, env, timezone, onQueryChange, requestId, setStatePartial]);
215
+
216
+ // 初始加载
217
+ useEffect(() => {
218
+ if (dataMode === 'server' && fetcher) {
219
+ const page = initialPage;
220
+ const pageSize = state.pageSize;
221
+ setStatePartial({
222
+ page,
223
+ pageSize
224
+ });
225
+ triggerFetch('initial', {
226
+ sort: null,
227
+ appliedFilters: {},
228
+ page,
229
+ pageSize
230
+ });
231
+ }
232
+ // eslint-disable-next-line react-hooks/exhaustive-deps
233
+ }, [tableId, dataMode]);
234
+
235
+ // ============================================================
236
+ // 排序
237
+ // ============================================================
238
+
239
+ const toggleSort = useCallback(field => {
240
+ if (dataMode !== 'server') return;
241
+ const col = columns.find(c => c.key === field);
242
+ if (!col || col.sort === false) return;
243
+ setState(prev => {
244
+ const newSort = cycleSort(prev.sort?.field ?? null, prev.sort?.direction, field);
245
+ const clearedSelection = currentPageOnly ? new Set() : prev.selection;
246
+ const clearedPage = prev.sort?.field !== field ? prev.page : prev.page; // 换字段才回 1
247
+ const newPage = newSort ? 1 : clearedPage; // 有排序就回 1(TBL-04.05)
248
+
249
+ // 翻页/排序变更回 1 页 + 清勾选
250
+ const next = {
251
+ ...prev,
252
+ sort: newSort,
253
+ page: newPage,
254
+ selection: clearedSelection
255
+ };
256
+ if (newSort) {
257
+ triggerFetch('sort', {
258
+ sort: newSort,
259
+ appliedFilters: next.appliedFilters,
260
+ page: newPage,
261
+ pageSize: next.pageSize
262
+ });
263
+ } else if (prev.sort) {
264
+ // 第三态清除排序
265
+ triggerFetch('sort', {
266
+ sort: null,
267
+ appliedFilters: next.appliedFilters,
268
+ page: newPage,
269
+ pageSize: next.pageSize
270
+ });
271
+ }
272
+ return next;
273
+ });
274
+ }, [dataMode, columns, triggerFetch, currentPageOnly]);
275
+
276
+ // ============================================================
277
+ // 筛选(草稿/生效分离)
278
+ // ============================================================
279
+
280
+ const applyFilters = useCallback(filters => {
281
+ // 归一化:空多选归一为不限(TBL-05.03)
282
+ const normalized = {};
283
+ Object.entries(filters).forEach(([k, v]) => {
284
+ if (Array.isArray(v) && v.length === 0) return;
285
+ if (v === undefined || v === null || v === '') return;
286
+ normalized[k] = v;
287
+ });
288
+ setState(prev => {
289
+ const clearedSelection = currentPageOnly ? new Set() : prev.selection;
290
+ const next = {
291
+ ...prev,
292
+ appliedFilters: normalized,
293
+ page: 1,
294
+ // 筛选变更回 1 页(TBL-04.05)
295
+ selection: clearedSelection
296
+ };
297
+ triggerFetch('filter', {
298
+ sort: next.sort,
299
+ appliedFilters: normalized,
300
+ page: 1,
301
+ pageSize: next.pageSize
302
+ });
303
+ return next;
304
+ });
305
+ }, [triggerFetch, currentPageOnly]);
306
+ const resetFilters = useCallback(() => {
307
+ setState(prev => {
308
+ const clearedSelection = currentPageOnly ? new Set() : prev.selection;
309
+ const next = {
310
+ ...prev,
311
+ appliedFilters: {},
312
+ page: 1,
313
+ selection: clearedSelection
314
+ };
315
+ triggerFetch('reset', {
316
+ sort: next.sort,
317
+ appliedFilters: {},
318
+ page: 1,
319
+ pageSize: next.pageSize
320
+ });
321
+ return next;
322
+ });
323
+ }, [triggerFetch, currentPageOnly]);
324
+
325
+ // ============================================================
326
+ // 分页
327
+ // ============================================================
328
+
329
+ const setPage = useCallback(page => {
330
+ if (dataMode !== 'server') return;
331
+ setState(prev => {
332
+ const validated = clampPage(page, prev.total, prev.pageSize);
333
+ if (validated === prev.page) return prev;
334
+ const clearedSelection = currentPageOnly ? new Set() : prev.selection;
335
+ const next = {
336
+ ...prev,
337
+ page: validated,
338
+ selection: clearedSelection
339
+ };
340
+ triggerFetch('pagination', {
341
+ sort: next.sort,
342
+ appliedFilters: next.appliedFilters,
343
+ page: validated,
344
+ pageSize: next.pageSize
345
+ });
346
+ return next;
347
+ });
348
+ }, [dataMode, triggerFetch, currentPageOnly]);
349
+ const setPageSize = useCallback(size => {
350
+ if (dataMode !== 'server') return;
351
+ setState(prev => {
352
+ if (size === prev.pageSize) return prev;
353
+ const clearedSelection = currentPageOnly ? new Set() : prev.selection;
354
+ // pageSize 变更回 1 页(TBL-07.02)
355
+ const next = {
356
+ ...prev,
357
+ pageSize: size,
358
+ page: 1,
359
+ selection: clearedSelection
360
+ };
361
+ triggerFetch('page-size', {
362
+ sort: next.sort,
363
+ appliedFilters: next.appliedFilters,
364
+ page: 1,
365
+ pageSize: size
366
+ });
367
+ return next;
368
+ });
369
+ }, [dataMode, triggerFetch, currentPageOnly]);
370
+
371
+ // ============================================================
372
+ // 多选(三态)
373
+ // ============================================================
374
+
375
+ const toggleRow = useCallback((key, selected) => {
376
+ if (!selectable) return;
377
+ setState(prev => {
378
+ const next = new Set(prev.selection);
379
+ if (selected) next.add(key);else next.delete(key);
380
+ const selArr = Array.from(next);
381
+ onSelectionChange?.(selArr, {
382
+ tableId,
383
+ pageKeys: prev.data.map(r => String(r[rowKey])),
384
+ disabledKeys: [],
385
+ trigger: 'select'
386
+ });
387
+ return {
388
+ ...prev,
389
+ selection: next
390
+ };
391
+ });
392
+ }, [selectable, onSelectionChange, tableId, rowKey]);
393
+ const selectAllOnPage = useCallback((rowKeys, disabledKeys) => {
394
+ if (!selectable) return;
395
+ const selectableKeys = rowKeys.filter(k => !disabledKeys.includes(k));
396
+ setState(prev => {
397
+ const allSelected = selectableKeys.every(k => prev.selection.has(k));
398
+ const next = new Set(prev.selection);
399
+ if (allSelected) {
400
+ selectableKeys.forEach(k => next.delete(k));
401
+ } else {
402
+ selectableKeys.forEach(k => next.add(k));
403
+ }
404
+ const selArr = Array.from(next);
405
+ onSelectionChange?.(selArr, {
406
+ tableId,
407
+ pageKeys: rowKeys,
408
+ disabledKeys,
409
+ trigger: allSelected ? 'select-all' : 'select-all'
410
+ });
411
+ return {
412
+ ...prev,
413
+ selection: next
414
+ };
415
+ });
416
+ }, [selectable, onSelectionChange, tableId]);
417
+ const clearSelection = useCallback(() => {
418
+ setState(prev => ({
419
+ ...prev,
420
+ selection: new Set()
421
+ }));
422
+ onSelectionChange?.([], {
423
+ tableId,
424
+ pageKeys: [],
425
+ disabledKeys: [],
426
+ trigger: 'reset'
427
+ });
428
+ }, [onSelectionChange, tableId]);
429
+ const isAllSelectedOnPage = useCallback((rowKeys, disabledKeys) => {
430
+ const selectableKeys = rowKeys.filter(k => !disabledKeys.includes(k));
431
+ if (selectableKeys.length === 0) return false;
432
+ return selectableKeys.every(k => state.selection.has(k));
433
+ }, [state.selection]);
434
+ const isIndeterminateOnPage = useCallback((rowKeys, disabledKeys) => {
435
+ const selectableKeys = rowKeys.filter(k => !disabledKeys.includes(k));
436
+ if (selectableKeys.length === 0) return false;
437
+ const selectedCount = selectableKeys.filter(k => state.selection.has(k)).length;
438
+ return selectedCount > 0 && selectedCount < selectableKeys.length;
439
+ }, [state.selection]);
440
+ const refresh = useCallback(() => {
441
+ setState(prev => {
442
+ const clearedSelection = currentPageOnly ? new Set() : prev.selection;
443
+ const next = {
444
+ ...prev,
445
+ selection: clearedSelection
446
+ };
447
+ triggerFetch('reset', {
448
+ sort: next.sort,
449
+ appliedFilters: next.appliedFilters,
450
+ page: next.page,
451
+ pageSize: next.pageSize
452
+ });
453
+ return next;
454
+ });
455
+ }, [triggerFetch, currentPageOnly]);
456
+ return useMemo(() => ({
457
+ data: state.data,
458
+ total: state.total,
459
+ status: state.status,
460
+ error: state.error,
461
+ sort: state.sort,
462
+ appliedFilters: state.appliedFilters,
463
+ page: state.page,
464
+ pageSize: state.pageSize,
465
+ selection: Array.from(state.selection),
466
+ requestId,
467
+ toggleSort,
468
+ applyFilters,
469
+ resetFilters,
470
+ setPage,
471
+ setPageSize,
472
+ toggleRow,
473
+ selectAllOnPage,
474
+ clearSelection,
475
+ refresh,
476
+ isAllSelectedOnPage,
477
+ isIndeterminateOnPage
478
+ }), [state, requestId, toggleSort, applyFilters, resetFilters, setPage, setPageSize, toggleRow, selectAllOnPage, clearSelection, refresh, isAllSelectedOnPage, isIndeterminateOnPage]);
479
+ }
@@ -1,5 +1,7 @@
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, PntTableProps, PntTableQuery, PntTableQueryMeta, PntTableQueryTrigger, PntTableRef, PntTableResponse, PntTableSelectConfig, PntTableSelectionMeta, PntTableStatus, PntTableTheme, } from './components/PntTable/types';
3
5
  export { default as PntBusinessSelect } from './components/PntBusinessSelect';
4
6
  export { default as PntRegionSelect, normalizeRegionCode, } from './components/PntRegionSelect';
5
7
  export { DEFAULT_TEXTS, EN_TEXTS, getTextsByLocale, } from './components/PntRegionSelect/types';
package/lib/esm/index.js CHANGED
@@ -10,7 +10,7 @@ export { PntProvider, usePntConfig } from "./config";
10
10
 
11
11
  // ---------- L1 基础展示组件 ----------
12
12
  export { default as PntImage } from "./components/PntImage";
13
-
13
+ export { default as PntTable } from "./components/PntTable";
14
14
  // ---------- L2 业务复合组件 ----------
15
15
  export { default as PntBusinessSelect } from "./components/PntBusinessSelect";
16
16
  export { default as PntRegionSelect, normalizeRegionCode } from "./components/PntRegionSelect";
@@ -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__cell--fixed-left,.pnt-table .t-table__cell--fixed-right{background-color:var(--pnt-table-bg);box-shadow:none}.pnt-table .t-table__cell--fixed-left:after,.pnt-table .t-table__cell--fixed-right:after{bottom:0;content:"";pointer-events:none;position:absolute;top:0;width:.5rem}.pnt-table .t-table__cell--fixed-left:after{box-shadow:inset -.5rem 0 .25rem -.25rem rgba(0,0,0,.06);right:-.5rem}.pnt-table .t-table__cell--fixed-right:after{box-shadow:inset .5rem 0 .25rem -.25rem rgba(0,0,0,.06);left:-.5rem}.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}