@pnt-team/pnt-component-frontend 0.0.136 → 0.0.138

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.
Files changed (68) hide show
  1. package/lib/cjs/components/PntRegionSelect/index.scss +14 -10
  2. package/package.json +1 -1
  3. package/lib/cjs/api/cos.d.ts +0 -103
  4. package/lib/cjs/api/cos.js +0 -146
  5. package/lib/cjs/api/index.d.ts +0 -23
  6. package/lib/cjs/api/index.js +0 -38
  7. package/lib/cjs/api/types/index.d.ts +0 -117
  8. package/lib/cjs/api/types/index.js +0 -17
  9. package/lib/cjs/assets/css/tdesign-theme.css +0 -584
  10. package/lib/cjs/assets/images/uploadImg.png +0 -0
  11. package/lib/cjs/assets/svg/inputSearch.svg +0 -4
  12. package/lib/cjs/assets/svg/inputTip.svg +0 -5
  13. package/lib/esm/api/cos.d.ts +0 -103
  14. package/lib/esm/api/cos.js +0 -189
  15. package/lib/esm/api/index.d.ts +0 -23
  16. package/lib/esm/api/index.js +0 -23
  17. package/lib/esm/api/types/index.d.ts +0 -117
  18. package/lib/esm/api/types/index.js +0 -1
  19. package/lib/esm/assets/css/tdesign-theme.css +0 -584
  20. package/lib/esm/assets/images/uploadImg.png +0 -0
  21. package/lib/esm/assets/svg/inputSearch.svg +0 -4
  22. package/lib/esm/assets/svg/inputTip.svg +0 -5
  23. package/lib/esm/assets/svg/inputWarnTip.svg +0 -5
  24. package/lib/esm/components/PntBusinessSelect/index.d.ts +0 -192
  25. package/lib/esm/components/PntBusinessSelect/index.js +0 -513
  26. package/lib/esm/components/PntBusinessSelect/index.scss +0 -27
  27. package/lib/esm/components/PntCosUploader/index.d.ts +0 -134
  28. package/lib/esm/components/PntCosUploader/index.js +0 -300
  29. package/lib/esm/components/PntGeneralLayout/index.d.ts +0 -114
  30. package/lib/esm/components/PntGeneralLayout/index.js +0 -103
  31. package/lib/esm/components/PntGeneralLayout/index.scss +0 -121
  32. package/lib/esm/components/PntImage/index.d.ts +0 -93
  33. package/lib/esm/components/PntImage/index.js +0 -200
  34. package/lib/esm/components/PntImage/index.scss +0 -61
  35. package/lib/esm/components/PntRegionSelect/ImportDialog.d.ts +0 -29
  36. package/lib/esm/components/PntRegionSelect/ImportDialog.js +0 -244
  37. package/lib/esm/components/PntRegionSelect/index.d.ts +0 -39
  38. package/lib/esm/components/PntRegionSelect/index.js +0 -471
  39. package/lib/esm/components/PntRegionSelect/index.scss +0 -170
  40. package/lib/esm/components/PntRegionSelect/types.d.ts +0 -181
  41. package/lib/esm/components/PntRegionSelect/types.js +0 -77
  42. package/lib/esm/components/PntSecureBox/index.d.ts +0 -122
  43. package/lib/esm/components/PntSecureBox/index.js +0 -166
  44. package/lib/esm/components/PntSecureBox/index.scss +0 -23
  45. package/lib/esm/components/PntTable/index.d.ts +0 -14
  46. package/lib/esm/components/PntTable/index.js +0 -404
  47. package/lib/esm/components/PntTable/index.scss +0 -290
  48. package/lib/esm/components/PntTable/types.d.ts +0 -250
  49. package/lib/esm/components/PntTable/types.js +0 -81
  50. package/lib/esm/components/PntTable/useTableCore.d.ts +0 -38
  51. package/lib/esm/components/PntTable/useTableCore.js +0 -499
  52. package/lib/esm/components/PntUpload/index.d.ts +0 -149
  53. package/lib/esm/components/PntUpload/index.js +0 -276
  54. package/lib/esm/components/PntUpload/index.scss +0 -101
  55. package/lib/esm/config.d.ts +0 -97
  56. package/lib/esm/config.js +0 -60
  57. package/lib/esm/global.css +0 -2
  58. package/lib/esm/global.d.ts +0 -39
  59. package/lib/esm/hooks/useHighSecurity.d.ts +0 -88
  60. package/lib/esm/hooks/useHighSecurity.js +0 -250
  61. package/lib/esm/index.d.ts +0 -16
  62. package/lib/esm/index.js +0 -33
  63. package/lib/esm/utils/const.d.ts +0 -13
  64. package/lib/esm/utils/const.js +0 -23
  65. package/lib/esm/utils/index.d.ts +0 -6
  66. package/lib/esm/utils/index.js +0 -22
  67. package/lib/umd/pnt-component-frontend.min.css +0 -1
  68. package/lib/umd/pnt-component-frontend.min.js +0 -1
@@ -1,471 +0,0 @@
1
- import { businessRegionQuery } from "../../api";
2
- import { usePntConfigOptional } from "../../config";
3
- import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
4
- import { Button, Checkbox, Select } from 'tdesign-react';
5
- import ImportDialog from "./ImportDialog";
6
- import "./index.scss";
7
- import { getTextsByLocale } from "./types";
8
-
9
- /**
10
- * 归一化 region_code:纯数字字符串去掉前导零('012' -> '12'),非数字保持原样
11
- * @description 后端详情接口可能返回 '12',字典接口可能返回 '012',需统一格式才能匹配
12
- */
13
- import { jsx as _jsx } from "react/jsx-runtime";
14
- import { jsxs as _jsxs } from "react/jsx-runtime";
15
- import { Fragment as _Fragment } from "react/jsx-runtime";
16
- export const normalizeRegionCode = code => {
17
- if (code === null || code === undefined || code === '') return '';
18
- const str = String(code);
19
- return /^\d+$/.test(str) ? String(Number(str)) : str;
20
- };
21
-
22
- /**
23
- * 组件内部选项:region_code 为归一化码(用于匹配/选中),
24
- * rawRegionCode 保留数据源的原始码(如 '004',用于对外回传,避免前导零丢失)
25
- */
26
-
27
- /**
28
- * 将后端区域项归一化为组件内部的 RegionOption
29
- * @description 后端契约字段均为可选,此处补默认值;同时保留原始 region_code
30
- */
31
- const toRegionOptions = list => (list || []).map(item => ({
32
- ...item,
33
- region_code: normalizeRegionCode(item.region_code),
34
- rawRegionCode: item.region_code === null || item.region_code === undefined ? '' : String(item.region_code),
35
- region_ch: item.region_ch ?? '',
36
- region_en: item.region_en ?? ''
37
- }));
38
-
39
- /**
40
- * 构建标签文本
41
- */
42
- const getLabelText = (item, format) => {
43
- const {
44
- region_ch,
45
- region_en,
46
- region_code,
47
- rawRegionCode
48
- } = item;
49
- switch (format) {
50
- case 'name_en':
51
- return region_en || region_ch || rawRegionCode || region_code;
52
- case 'name_en_name':
53
- return region_en && region_ch ? `${region_en}(${region_ch})` : region_en || region_ch || rawRegionCode || region_code;
54
- case 'code':
55
- // 代码标签优先展示数据源原始码(保留前导零,如 '004')
56
- return rawRegionCode || region_code;
57
- default:
58
- return region_ch || region_en || rawRegionCode || region_code;
59
- }
60
- };
61
-
62
- /**
63
- * 地区选择器组件
64
- * @description 统一的国家/地区选择组件,支持单选/多选、批量选择、批量导入、自定义区域、合规区域
65
- *
66
- * @example
67
- * ```tsx
68
- * // 基础多选(内部拉取默认区域列表)
69
- * <PntRegionSelect
70
- * value={regions}
71
- * onChange={(v) => setRegions(v)}
72
- * />
73
- *
74
- * // 业务最终生效区域
75
- * <PntRegionSelect
76
- * dataSource="business"
77
- * gameId={gameId}
78
- * value={regions}
79
- * onChange={(v) => setRegions(v)}
80
- * />
81
- *
82
- * // 外部受控选项 + 批量导入
83
- * <PntRegionSelect
84
- * options={regionList}
85
- * importable
86
- * value={regions}
87
- * onChange={(v) => setRegions(v)}
88
- * />
89
- * ```
90
- */
91
- const PntRegionSelect = props => {
92
- const {
93
- value = [],
94
- onChange,
95
- multiple = true,
96
- dataSource = 'default',
97
- scope = 'business',
98
- gameId,
99
- options: externalOptions,
100
- disabled = false,
101
- placeholder,
102
- max,
103
- filterable = true,
104
- labelFormat = 'name',
105
- texts: customTexts,
106
- onLoaded,
107
- optionDisabled,
108
- optionFilter,
109
- optionTooltip,
110
- importable = false,
111
- invertible = false,
112
- preserveLeadingZero = true,
113
- minCollapsedNum,
114
- collapsedItems,
115
- onBlur,
116
- importDialogProps,
117
- className,
118
- style,
119
- popupProps,
120
- locale: propLocale
121
- } = props;
122
-
123
- // 外部受控模式下无需 http,因此使用可选版配置读取
124
- const config = usePntConfigOptional();
125
- const http = config?.http;
126
- const regionQuery = config?.regionQuery;
127
- // 优先级:prop locale > PntProvider locale > 默认 'zh'
128
- const locale = propLocale || config?.locale || 'zh';
129
- // 文案优先级:customTexts > locale 默认文案
130
- const texts = useMemo(() => ({
131
- ...getTextsByLocale(locale),
132
- ...customTexts
133
- }), [customTexts, locale]);
134
-
135
- // ---- 状态 ----
136
- const [innerOptions, setInnerOptions] = useState([]);
137
- const [loading, setLoading] = useState(false);
138
- const [searchKeyword, setSearchKeyword] = useState('');
139
- const [importVisible, setImportVisible] = useState(false);
140
-
141
- // ---- Refs ----
142
- const fetchSeqRef = useRef(0);
143
- const onLoadedRef = useRef(onLoaded);
144
- onLoadedRef.current = onLoaded;
145
-
146
- // ---- 外部受控模式:传入 options 时跳过内部请求 ----
147
- const isExternal = externalOptions !== undefined;
148
-
149
- // ---- 获取数据 ----
150
- const fetchData = useCallback(async () => {
151
- if (isExternal) return;
152
- if (!http) {
153
- console.warn('[PntRegionSelect] 未注入 PntProvider.http,无法内部拉取区域数据;请用 <PntProvider> 包裹,或改用外部 options 模式');
154
- return;
155
- }
156
- const seq = ++fetchSeqRef.current;
157
- setLoading(true);
158
- try {
159
- let list = [];
160
- const url = scope === 'platform' ? regionQuery?.queryPlatUrl || '/v5/business/region/plat-query?audience=/laas-pnt' : regionQuery?.queryUrl || '/v5/business/region/query?audience=/laas-pnt';
161
- if (dataSource === 'business') {
162
- if (!gameId) {
163
- console.warn('[PntRegionSelect] dataSource="business" 时必须传入 gameId');
164
- return;
165
- }
166
- const res = await businessRegionQuery(http, {
167
- game_id: Number(gameId)
168
- }, url);
169
- if (seq !== fetchSeqRef.current) return;
170
- if (res.code === 0 && res.data?.region_list) {
171
- list = toRegionOptions(res.data.region_list);
172
- }
173
- } else {
174
- const res = await businessRegionQuery(http, {}, url);
175
- if (seq !== fetchSeqRef.current) return;
176
- if (res.code === 0 && res.data?.region_list) {
177
- list = toRegionOptions(res.data.region_list);
178
- }
179
- }
180
- setInnerOptions(list);
181
- onLoadedRef.current?.(list);
182
- } catch {
183
- // 请求失败静默处理
184
- } finally {
185
- if (seq === fetchSeqRef.current) {
186
- setLoading(false);
187
- }
188
- }
189
- }, [http, dataSource, gameId, isExternal, scope, regionQuery]);
190
-
191
- // ---- 初始加载 ----
192
- useEffect(() => {
193
- fetchData();
194
- }, [fetchData]);
195
-
196
- // ---- 生效的选项列表 ----
197
- // region_code 统一归一化(去前导零)用于与 valueArr 匹配;
198
- // rawRegionCode 保留数据源原始码(内部拉取已有,外部 options 取其原始值)
199
- const options = useMemo(() => (isExternal ? externalOptions ?? [] : innerOptions).map(item => ({
200
- ...item,
201
- region_code: normalizeRegionCode(item.region_code),
202
- rawRegionCode: item.rawRegionCode ?? (item.region_code === null || item.region_code === undefined ? '' : String(item.region_code))
203
- })), [isExternal, externalOptions, innerOptions]);
204
-
205
- // ---- 归一化码 -> 数据源原始码(如 '4' -> '004'),以选项字典为权威来源 ----
206
- const rawCodeMap = useMemo(() => {
207
- const map = new Map();
208
- options.forEach(item => {
209
- map.set(item.region_code, item.rawRegionCode || item.region_code);
210
- });
211
- return map;
212
- }, [options]);
213
-
214
- // ---- 受控 value 中存在、但选项里缺失的码,兜底保留调用方传入的原始写法 ----
215
- const inputRawCodeMap = useMemo(() => {
216
- const map = new Map();
217
- if (value === undefined || value === null || value === '') return map;
218
- const arr = Array.isArray(value) ? value : [value];
219
- arr.forEach(item => {
220
- if (item === null || item === undefined || item === '') return;
221
- map.set(normalizeRegionCode(item), String(item));
222
- });
223
- return map;
224
- }, [value]);
225
-
226
- // ---- 将内部归一化码还原为应对外输出的原始码 ----
227
- // preserveLeadingZero=true(默认): 输出数据源原始码(保留前导零,如 '004')
228
- // preserveLeadingZero=false: 输出归一化码(去前导零,如 '4')
229
- const resolveRawCodes = useCallback(codes => codes.map(code => {
230
- const raw = rawCodeMap.get(code) ?? inputRawCodeMap.get(code) ?? code;
231
- return preserveLeadingZero ? raw : normalizeRegionCode(raw);
232
- }), [rawCodeMap, inputRawCodeMap, preserveLeadingZero]);
233
-
234
- // ---- 转为对外暴露的 RegionOption(region_code 根据 preserveLeadingZero 决定格式) ----
235
- const toPublicOption = useCallback(item => {
236
- const raw = rawCodeMap.get(item.region_code) ?? item.region_code;
237
- return {
238
- region_code: preserveLeadingZero ? raw : normalizeRegionCode(raw),
239
- region_ch: item.region_ch,
240
- region_en: item.region_en,
241
- region_a2_code: item.region_a2_code,
242
- region_a3_code: item.region_a3_code,
243
- disabled: item.disabled,
244
- disabledReason: item.disabledReason
245
- };
246
- }, [rawCodeMap, preserveLeadingZero]);
247
-
248
- // ---- 归一化选中值为数组(兼容单选字符串),并去掉前导零与 options 对齐 ----
249
- const valueArr = useMemo(() => {
250
- if (value === undefined || value === null || value === '') return [];
251
- const arr = Array.isArray(value) ? value : [value];
252
- return arr.map(v => normalizeRegionCode(v));
253
- }, [value]);
254
-
255
- // ---- 本地搜索过滤 + optionFilter 自定义过滤 ----
256
- const filteredOptions = useMemo(() => {
257
- let result = options;
258
- if (optionFilter) {
259
- result = result.filter(optionFilter);
260
- }
261
- if (!searchKeyword) return result;
262
- const kw = searchKeyword.toLowerCase();
263
- return result.filter(item => item.region_ch?.toLowerCase().includes(kw) || item.region_en?.toLowerCase().includes(kw) || item.region_code?.toLowerCase().includes(kw) || item.rawRegionCode?.toLowerCase().includes(kw));
264
- }, [options, searchKeyword, optionFilter]);
265
-
266
- // ---- 判断选项是否禁用 ----
267
- const isOptionDisabled = useCallback(item => {
268
- if (item.disabled) return true;
269
- return optionDisabled ? optionDisabled(item) : false;
270
- }, [optionDisabled]);
271
-
272
- // ---- 多选 onChange 统一出口 ----
273
- // 入参为内部归一化码,对外回传数据源原始码(保留前导零,如 '004')
274
- const emitMultiple = useCallback(nextValue => {
275
- const rawValues = resolveRawCodes(nextValue);
276
- const selectedOptions = options.filter(o => nextValue.includes(o.region_code)).map(toPublicOption);
277
- onChange?.(rawValues, selectedOptions);
278
- return rawValues;
279
- }, [onChange, options, resolveRawCodes, toPublicOption]);
280
-
281
- // ---- 全选/清空 ----
282
- const handleSelectAll = useCallback(() => {
283
- const allValues = filteredOptions.filter(item => !isOptionDisabled(item)).map(item => item.region_code);
284
- emitMultiple(Array.from(new Set([...valueArr, ...allValues])));
285
- }, [filteredOptions, valueArr, emitMultiple, isOptionDisabled]);
286
- const handleClearAll = useCallback(() => {
287
- emitMultiple([]);
288
- }, [emitMultiple]);
289
-
290
- // ---- 反选 ----
291
- const handleInvert = useCallback(() => {
292
- const selectedSet = new Set(valueArr);
293
- const nextValue = filteredOptions.filter(item => !isOptionDisabled(item)).map(item => item.region_code).filter(code => !selectedSet.has(code));
294
- emitMultiple(nextValue);
295
- }, [filteredOptions, valueArr, emitMultiple, isOptionDisabled]);
296
-
297
- // ---- 是否全选 ----
298
- const isAllSelected = useMemo(() => {
299
- const selectable = filteredOptions.filter(item => !isOptionDisabled(item));
300
- return selectable.length > 0 && selectable.every(item => valueArr.includes(item.region_code));
301
- }, [filteredOptions, valueArr, isOptionDisabled]);
302
-
303
- // ---- 是否半选 ----
304
- const isIndeterminate = useMemo(() => {
305
- const selectable = filteredOptions.filter(item => !isOptionDisabled(item));
306
- const selected = selectable.filter(item => valueArr.includes(item.region_code));
307
- return selected.length > 0 && selected.length < selectable.length;
308
- }, [filteredOptions, valueArr, isOptionDisabled]);
309
-
310
- // ---- 构建 Select options ----
311
- const selectOptions = useMemo(() => {
312
- return filteredOptions.map(item => {
313
- const label = getLabelText(item, labelFormat);
314
- const isDisabled = isOptionDisabled(item);
315
- const tooltip = optionTooltip ? optionTooltip(item) : undefined;
316
- return {
317
- label,
318
- value: item.region_code,
319
- disabled: isDisabled,
320
- tooltip,
321
- rawItem: item
322
- };
323
- });
324
- }, [filteredOptions, labelFormat, isOptionDisabled, optionTooltip]);
325
-
326
- // ---- Select onChange ----
327
- const handleChange = useCallback(val => {
328
- const values = Array.isArray(val) ? val : val ? [val] : [];
329
- // Select 回传的是 option 上的归一化码,仅用于匹配
330
- const strValues = values.map(normalizeRegionCode);
331
- const selectedOptions = options.filter(o => strValues.includes(o.region_code)).map(toPublicOption);
332
- // 对外输出还原为数据源原始码(保留前导零)
333
- const rawValues = resolveRawCodes(strValues);
334
- // 多选模式下勾选后清除搜索关键字,恢复完整列表
335
- if (multiple) {
336
- setSearchKeyword('');
337
- }
338
- if (multiple) {
339
- onChange?.(rawValues, selectedOptions);
340
- } else {
341
- onChange?.(rawValues[0] ?? '', selectedOptions[0] ?? undefined);
342
- }
343
- }, [onChange, options, multiple, resolveRawCodes, toPublicOption]);
344
-
345
- // ---- 批量导入确认 ----
346
- const handleImportConfirm = useCallback(nextValue => {
347
- // ImportDialog 回传归一化码,经 emitMultiple 还原为原始码
348
- const rawValues = emitMultiple(nextValue);
349
- // 兼容外部表单 onBlur 校验触发,同样回传原始码
350
- onBlur?.({
351
- value: rawValues
352
- });
353
- }, [emitMultiple, onBlur]);
354
-
355
- // ---- 面板顶部操作栏 ----
356
- const panelTopContent = useMemo(() => {
357
- if (!multiple) return null;
358
- return /*#__PURE__*/_jsxs("div", {
359
- className: "pnt-region-select__toolbar",
360
- children: [/*#__PURE__*/_jsx(Checkbox, {
361
- checked: isAllSelected,
362
- indeterminate: isIndeterminate,
363
- onChange: checked => {
364
- if (checked) {
365
- handleSelectAll();
366
- } else {
367
- handleClearAll();
368
- }
369
- },
370
- children: texts.selectAll
371
- }), invertible && /*#__PURE__*/_jsx("span", {
372
- role: "button",
373
- tabIndex: 0,
374
- className: "pnt-region-select__invert",
375
- onClick: event => {
376
- event.preventDefault();
377
- event.stopPropagation();
378
- handleInvert();
379
- },
380
- onKeyDown: event => {
381
- if (event.key === 'Enter' || event.key === ' ') {
382
- event.preventDefault();
383
- event.stopPropagation();
384
- handleInvert();
385
- }
386
- },
387
- children: texts.invertSelection
388
- }), /*#__PURE__*/_jsx("span", {
389
- className: "pnt-region-select__count",
390
- children: texts.selectedCount.replace('{count}', String(valueArr.length))
391
- })]
392
- });
393
- }, [multiple, isAllSelected, isIndeterminate, handleSelectAll, handleClearAll, invertible, handleInvert, texts, valueArr.length]);
394
-
395
- // ---- 空状态 ----
396
- const emptyContent = useMemo(() => {
397
- if (loading) return null;
398
- if (filteredOptions.length === 0) {
399
- return /*#__PURE__*/_jsx("div", {
400
- className: "pnt-region-select__empty",
401
- children: texts.noResult
402
- });
403
- }
404
- return null;
405
- }, [loading, filteredOptions.length, texts.noResult]);
406
-
407
- // 下拉框关闭时清除搜索关键字,避免下次打开仍显示过滤结果
408
- const handlePopupVisibleChange = useCallback(visible => {
409
- if (!visible) {
410
- setSearchKeyword('');
411
- }
412
- }, []);
413
- const selectNode = /*#__PURE__*/_jsx(Select, {
414
- value: multiple ? valueArr : valueArr[0],
415
- onChange: handleChange,
416
- filterable: filterable,
417
- onSearch: setSearchKeyword,
418
- onPopupVisibleChange: handlePopupVisibleChange,
419
- loading: loading && options.length === 0,
420
- multiple: multiple,
421
- max: max,
422
- clearable: true,
423
- disabled: disabled,
424
- placeholder: placeholder || texts.placeholder,
425
- panelTopContent: panelTopContent,
426
- empty: emptyContent,
427
- minCollapsedNum: minCollapsedNum,
428
- collapsedItems: collapsedItems,
429
- onBlur: onBlur,
430
- popupProps: {
431
- ...popupProps,
432
- overlayClassName: ['pnt-region-select-popup', popupProps?.overlayClassName].filter(Boolean).join(' ')
433
- },
434
- className: className ? `pnt-region-select ${className}` : 'pnt-region-select',
435
- style: style,
436
- children: selectOptions.map(opt => /*#__PURE__*/_jsx(Select.Option, {
437
- value: opt.value,
438
- label: opt.label,
439
- disabled: opt.disabled,
440
- title: opt.tooltip
441
- }, opt.value))
442
- });
443
-
444
- // ---- 批量导入模式:输入框右侧叠加导入按钮 ----
445
- if (importable && multiple) {
446
- return /*#__PURE__*/_jsxs(_Fragment, {
447
- children: [/*#__PURE__*/_jsxs("div", {
448
- className: "pnt-region-select__import-wrapper",
449
- children: [selectNode, /*#__PURE__*/_jsx(Button, {
450
- theme: "primary",
451
- size: "small",
452
- variant: "outline",
453
- disabled: disabled,
454
- className: "pnt-region-select__import-btn",
455
- onClick: () => setImportVisible(true),
456
- children: texts.importBtn
457
- })]
458
- }), /*#__PURE__*/_jsx(ImportDialog, {
459
- visible: importVisible,
460
- options: options,
461
- currentValue: valueArr,
462
- texts: texts,
463
- dialogProps: importDialogProps,
464
- onClose: () => setImportVisible(false),
465
- onConfirm: handleImportConfirm
466
- })]
467
- });
468
- }
469
- return selectNode;
470
- };
471
- export default PntRegionSelect;
@@ -1,170 +0,0 @@
1
- .pnt-region-select {
2
- width: 100%;
3
-
4
- &__toolbar {
5
- display: flex;
6
- align-items: center;
7
- justify-content: space-between;
8
- padding: 8px 12px;
9
- border-bottom: 1px solid var(--td-component-border, #e7e7e7);
10
- background: var(--td-bg-color-container, #fff);
11
- }
12
-
13
- &__invert {
14
- margin-left: 12px;
15
- margin-right: auto;
16
- font-size: 12px;
17
- color: var(--td-brand-color, #0052d9);
18
- cursor: pointer;
19
- user-select: none;
20
-
21
- &:hover {
22
- color: var(--td-brand-color-hover, #2667d4);
23
- }
24
- }
25
-
26
- &__count {
27
- margin-left: auto;
28
- font-size: 12px;
29
- color: var(--td-text-color-secondary, #999);
30
- }
31
-
32
- &__invert + &__count {
33
- margin-left: 0;
34
- }
35
-
36
- &__empty {
37
- padding: 16px;
38
- text-align: center;
39
- color: var(--td-text-color-secondary, #999);
40
- font-size: 14px;
41
- }
42
-
43
- // ---- 批量导入 ----
44
- // 布局调整:取消固定宽度 + 按钮绝对定位,改为 flex 兄弟布局
45
- // 避免选中大量地区时 Select 标签区域被按钮遮挡/挤压
46
- &__import-wrapper {
47
- display: flex;
48
- align-items: flex-start;
49
- gap: 8px;
50
- width: 100%;
51
-
52
- .pnt-region-select {
53
- flex: 1;
54
- min-width: 0;
55
- }
56
- }
57
-
58
- &__import-btn {
59
- flex-shrink: 0;
60
- // Button 默认 32px 高度,对齐 Select 输入框上边缘;
61
- // 当 Select 因多行标签变高时,按钮保持顶部对齐不居中
62
- margin-top: 2px;
63
- }
64
- }
65
-
66
- .pnt-region-select-popup {
67
- .t-select__list {
68
- padding-top: 0;
69
- }
70
- }
71
-
72
- // ---- 批量导入弹窗 ----
73
- .pnt-region-import {
74
- &__tip {
75
- margin-bottom: 8px;
76
- font-size: 12px;
77
- color: var(--td-text-color-secondary, #999);
78
- }
79
-
80
- &__result {
81
- margin-top: 12px;
82
- }
83
-
84
- &__summary {
85
- display: flex;
86
- align-items: center;
87
- gap: 4px;
88
- margin-bottom: 8px;
89
- font-size: 12px;
90
- }
91
-
92
- &__summary-item {
93
- &--unmatched {
94
- color: var(--td-error-color, #d54941);
95
- }
96
-
97
- &--pending {
98
- color: var(--td-success-color, #2ba471);
99
- }
100
-
101
- &--exists {
102
- color: var(--td-text-color-secondary, #999);
103
- }
104
- }
105
-
106
- &__summary-dot {
107
- color: var(--td-text-color-placeholder, #bbb);
108
- }
109
-
110
- &__copy-btn {
111
- padding: 0 4px;
112
- height: 20px;
113
- }
114
-
115
- &__table {
116
- border: 1px solid var(--td-component-border, #e7e7e7);
117
- border-radius: 4px;
118
- overflow: hidden;
119
- }
120
-
121
- &__table-head {
122
- display: flex;
123
- justify-content: space-between;
124
- padding: 6px 12px;
125
- background: var(--td-bg-color-secondarycontainer, #f3f3f3);
126
- font-size: 12px;
127
- color: var(--td-text-color-secondary, #999);
128
- }
129
-
130
- &__table-body {
131
- max-height: 200px;
132
- overflow-y: auto;
133
- }
134
-
135
- &__table-row {
136
- display: flex;
137
- justify-content: space-between;
138
- align-items: center;
139
- padding: 6px 12px;
140
- font-size: 12px;
141
-
142
- & + & {
143
- border-top: 1px solid var(--td-component-border, #e7e7e7);
144
- }
145
- }
146
-
147
- &__status {
148
- display: inline-flex;
149
- align-items: center;
150
- gap: 4px;
151
-
152
- &--unmatched {
153
- color: var(--td-error-color, #d54941);
154
- }
155
-
156
- &--pending {
157
- color: var(--td-success-color, #2ba471);
158
- }
159
-
160
- &--exists {
161
- color: var(--td-text-color-secondary, #999);
162
- }
163
- }
164
-
165
- &__empty {
166
- padding: 16px;
167
- text-align: center;
168
- color: var(--td-text-color-secondary, #999);
169
- }
170
- }