@pnt-team/pnt-component-frontend 0.0.130 → 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
+ }
@@ -177,9 +177,12 @@ export const useHighSecurity = options => {
177
177
  const url = scope === 'platform' ? merged.decryptPlatUrl || '/v3/business/game_info/plat-high-security-decrypt?audience=/laas-pnt' : merged.decryptUrl || '/v3/business/game_info/high-security-decrypt?audience=/laas-pnt';
178
178
 
179
179
  // 请求级并发去重:同一业务+环境+参数列表指纹在途时复用
180
+ // forceRefresh 时跳过并发去重,强制发新请求(用户显式要求重新拉取)
180
181
  const requestKey = `${gid}:${eid}:${missing.map(item => `${item.key}\u0001${item.value}`).join('\u0002')}`;
181
- const existing = inflightRequests.get(requestKey);
182
- if (existing) return existing;
182
+ if (!forceRefresh) {
183
+ const existing = inflightRequests.get(requestKey);
184
+ if (existing) return existing;
185
+ }
183
186
  const promise = (async () => {
184
187
  try {
185
188
  const res = await businessGameInfoHighSecurityDecrypt(http, body, url);
@@ -221,11 +224,18 @@ export const useHighSecurity = options => {
221
224
  // eslint-disable-next-line no-console
222
225
  console.warn('[pnt-component-frontend] high-security-decrypt 请求异常', error);
223
226
  } finally {
224
- inflightRequests.delete(requestKey);
227
+ // 仅普通请求(注册了 inflight)需要清理;forceRefresh 请求不注册
228
+ if (!forceRefresh) {
229
+ inflightRequests.delete(requestKey);
230
+ }
225
231
  }
226
232
  return result.filter(item => item !== undefined);
227
233
  })();
228
- inflightRequests.set(requestKey, promise);
234
+
235
+ // forceRefresh 请求不注册到 inflightRequests,避免覆盖同 key 的普通在途请求
236
+ if (!forceRefresh) {
237
+ inflightRequests.set(requestKey, promise);
238
+ }
229
239
  return promise;
230
240
  }, [http, snapshot, globalHighSecurity, optionsScope]);
231
241
  const clearSecurityData = useCallback(filter => {
@@ -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}