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

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/api/cos.d.ts +103 -0
  2. package/lib/cjs/api/cos.js +146 -0
  3. package/lib/cjs/api/index.d.ts +23 -0
  4. package/lib/cjs/api/index.js +38 -0
  5. package/lib/cjs/api/types/index.d.ts +117 -0
  6. package/lib/cjs/api/types/index.js +17 -0
  7. package/lib/cjs/assets/css/tdesign-theme.css +584 -0
  8. package/lib/cjs/assets/images/uploadImg.png +0 -0
  9. package/lib/cjs/assets/svg/inputSearch.svg +4 -0
  10. package/lib/cjs/assets/svg/inputTip.svg +5 -0
  11. package/lib/cjs/components/PntRegionSelect/index.scss +1 -1
  12. package/lib/esm/api/cos.d.ts +103 -0
  13. package/lib/esm/api/cos.js +189 -0
  14. package/lib/esm/api/index.d.ts +23 -0
  15. package/lib/esm/api/index.js +23 -0
  16. package/lib/esm/api/types/index.d.ts +117 -0
  17. package/lib/esm/api/types/index.js +1 -0
  18. package/lib/esm/assets/css/tdesign-theme.css +584 -0
  19. package/lib/esm/assets/images/uploadImg.png +0 -0
  20. package/lib/esm/assets/svg/inputSearch.svg +4 -0
  21. package/lib/esm/assets/svg/inputTip.svg +5 -0
  22. package/lib/esm/assets/svg/inputWarnTip.svg +5 -0
  23. package/lib/esm/components/PntBusinessSelect/index.d.ts +192 -0
  24. package/lib/esm/components/PntBusinessSelect/index.js +513 -0
  25. package/lib/esm/components/PntBusinessSelect/index.scss +27 -0
  26. package/lib/esm/components/PntCosUploader/index.d.ts +134 -0
  27. package/lib/esm/components/PntCosUploader/index.js +300 -0
  28. package/lib/esm/components/PntGeneralLayout/index.d.ts +114 -0
  29. package/lib/esm/components/PntGeneralLayout/index.js +103 -0
  30. package/lib/esm/components/PntGeneralLayout/index.scss +121 -0
  31. package/lib/esm/components/PntImage/index.d.ts +93 -0
  32. package/lib/esm/components/PntImage/index.js +200 -0
  33. package/lib/esm/components/PntImage/index.scss +61 -0
  34. package/lib/esm/components/PntRegionSelect/ImportDialog.d.ts +29 -0
  35. package/lib/esm/components/PntRegionSelect/ImportDialog.js +244 -0
  36. package/lib/esm/components/PntRegionSelect/index.d.ts +39 -0
  37. package/lib/esm/components/PntRegionSelect/index.js +471 -0
  38. package/lib/esm/components/PntRegionSelect/index.scss +174 -0
  39. package/lib/esm/components/PntRegionSelect/types.d.ts +181 -0
  40. package/lib/esm/components/PntRegionSelect/types.js +77 -0
  41. package/lib/esm/components/PntSecureBox/index.d.ts +122 -0
  42. package/lib/esm/components/PntSecureBox/index.js +166 -0
  43. package/lib/esm/components/PntSecureBox/index.scss +23 -0
  44. package/lib/esm/components/PntTable/index.d.ts +14 -0
  45. package/lib/esm/components/PntTable/index.js +404 -0
  46. package/lib/esm/components/PntTable/index.scss +290 -0
  47. package/lib/esm/components/PntTable/types.d.ts +250 -0
  48. package/lib/esm/components/PntTable/types.js +81 -0
  49. package/lib/esm/components/PntTable/useTableCore.d.ts +38 -0
  50. package/lib/esm/components/PntTable/useTableCore.js +499 -0
  51. package/lib/esm/components/PntUpload/index.d.ts +149 -0
  52. package/lib/esm/components/PntUpload/index.js +276 -0
  53. package/lib/esm/components/PntUpload/index.scss +101 -0
  54. package/lib/esm/config.d.ts +97 -0
  55. package/lib/esm/config.js +60 -0
  56. package/lib/esm/global.css +2 -0
  57. package/lib/esm/global.d.ts +39 -0
  58. package/lib/esm/hooks/useHighSecurity.d.ts +88 -0
  59. package/lib/esm/hooks/useHighSecurity.js +250 -0
  60. package/lib/esm/index.d.ts +16 -0
  61. package/lib/esm/index.js +33 -0
  62. package/lib/esm/utils/const.d.ts +13 -0
  63. package/lib/esm/utils/const.js +23 -0
  64. package/lib/esm/utils/index.d.ts +6 -0
  65. package/lib/esm/utils/index.js +22 -0
  66. package/lib/umd/pnt-component-frontend.min.css +1 -0
  67. package/lib/umd/pnt-component-frontend.min.js +1 -0
  68. package/package.json +1 -1
@@ -0,0 +1,244 @@
1
+ import { useMemo, useState } from 'react';
2
+ import { CheckIcon, CloseIcon, FileCopyIcon } from 'tdesign-icons-react';
3
+ import { Button, Dialog, MessagePlugin, Textarea, Tooltip } from 'tdesign-react';
4
+
5
+ /** 解析后单行状态 */
6
+
7
+ /** 组件内部选项额外携带数据源原始码(保留前导零) */
8
+ import { jsx as _jsx } from "react/jsx-runtime";
9
+ import { jsxs as _jsxs } from "react/jsx-runtime";
10
+ /** 分隔符:换行/逗号/分号(中英文) */
11
+ const SEPARATOR = /[\r?\n,,;;]+/;
12
+
13
+ /**
14
+ * 批量导入弹窗:
15
+ * 粘贴文本 → 按 代码/中文名/英文名(大小写不敏感)解析 → 分类展示 → 确认导入
16
+ */
17
+ const ImportDialog = ({
18
+ visible,
19
+ options,
20
+ currentValue,
21
+ texts,
22
+ dialogProps,
23
+ onClose,
24
+ onConfirm
25
+ }) => {
26
+ const [importText, setImportText] = useState('');
27
+ const [rows, setRows] = useState([]);
28
+ const [isParsed, setIsParsed] = useState(false);
29
+
30
+ // ---- 别名映射:原始码/归一化码/中文名/英文名(小写) -> 归一化 region_code ----
31
+ // 同时收录原始码(如 '004')与归一化码('4'),粘贴任一种代码都能匹配
32
+ const aliasMap = useMemo(() => {
33
+ const map = new Map();
34
+ options.filter(item => !item.disabled).forEach(item => {
35
+ [item.rawRegionCode, item.region_code, item.region_ch, item.region_en].filter(Boolean).map(alias => String(alias).trim().toLowerCase()).forEach(alias => {
36
+ if (alias) map.set(alias, item.region_code);
37
+ });
38
+ });
39
+ return map;
40
+ }, [options]);
41
+
42
+ // ---- 派生分类列表 ----
43
+ const {
44
+ pendingList,
45
+ existsList,
46
+ unmatchedList
47
+ } = useMemo(() => {
48
+ const selectedSet = new Set(currentValue);
49
+ const pending = [];
50
+ const exists = [];
51
+ const unmatched = [];
52
+ const seenPending = new Set();
53
+ const seenExists = new Set();
54
+ const seenUnmatched = new Set();
55
+ rows.forEach(row => {
56
+ if (row.status === 'unmatched') {
57
+ if (!seenUnmatched.has(row.region)) {
58
+ seenUnmatched.add(row.region);
59
+ unmatched.push(row.region);
60
+ }
61
+ return;
62
+ }
63
+ const code = aliasMap.get(row.region.toLowerCase());
64
+ if (!code) return;
65
+ if (row.status === 'exists' || selectedSet.has(code)) {
66
+ if (!seenExists.has(code)) {
67
+ seenExists.add(code);
68
+ exists.push(code);
69
+ }
70
+ } else if (!seenPending.has(code)) {
71
+ seenPending.add(code);
72
+ pending.push(code);
73
+ }
74
+ });
75
+ return {
76
+ pendingList: pending,
77
+ existsList: exists,
78
+ unmatchedList: unmatched
79
+ };
80
+ }, [rows, aliasMap, currentValue]);
81
+
82
+ // ---- 重置 ----
83
+ const reset = () => {
84
+ setImportText('');
85
+ setRows([]);
86
+ setIsParsed(false);
87
+ };
88
+ const handleClose = () => {
89
+ reset();
90
+ onClose();
91
+ };
92
+
93
+ // ---- 解析 ----
94
+ const parse = () => {
95
+ const uniqueInputs = Array.from(new Set(importText.split(SEPARATOR).map(item => item.trim()).filter(Boolean)));
96
+ const selectedSet = new Set(currentValue);
97
+ const nextRows = uniqueInputs.map(input => {
98
+ const code = aliasMap.get(input.toLowerCase());
99
+ if (!code) return {
100
+ region: input,
101
+ status: 'unmatched'
102
+ };
103
+ return {
104
+ region: input,
105
+ status: selectedSet.has(code) ? 'exists' : 'pending'
106
+ };
107
+ });
108
+
109
+ // 排序:未匹配 > 待导入 > 已存在,同级保持输入顺序
110
+ const priority = {
111
+ unmatched: 0,
112
+ pending: 1,
113
+ exists: 2
114
+ };
115
+ nextRows.sort((a, b) => priority[a.status] - priority[b.status]);
116
+ setRows(nextRows);
117
+ setIsParsed(true);
118
+ };
119
+
120
+ // ---- 复制未匹配项 ----
121
+ const copyUnmatched = async () => {
122
+ if (!unmatchedList.length) return;
123
+ const text = unmatchedList.join('\n');
124
+ try {
125
+ if (navigator.clipboard && window.isSecureContext) {
126
+ await navigator.clipboard.writeText(text);
127
+ } else {
128
+ const textArea = document.createElement('textarea');
129
+ textArea.value = text;
130
+ document.body.appendChild(textArea);
131
+ textArea.focus();
132
+ textArea.select();
133
+ document.execCommand('copy');
134
+ textArea.remove();
135
+ }
136
+ MessagePlugin.success(texts.copySuccess);
137
+ } catch {
138
+ // 复制失败静默
139
+ }
140
+ };
141
+
142
+ // ---- 确认 ----
143
+ const handleConfirm = () => {
144
+ if (!isParsed) {
145
+ parse();
146
+ return;
147
+ }
148
+ const nextSet = new Set(currentValue);
149
+ pendingList.forEach(code => nextSet.add(code));
150
+ const nextValue = Array.from(nextSet);
151
+ onConfirm(nextValue, pendingList);
152
+ handleClose();
153
+ };
154
+ return /*#__PURE__*/_jsxs(Dialog, {
155
+ visible: visible,
156
+ header: texts.importTitle,
157
+ width: 520,
158
+ closeOnOverlayClick: false,
159
+ confirmBtn: isParsed ? texts.importConfirmBtn : texts.parseBtn,
160
+ cancelBtn: texts.cancelBtn,
161
+ onConfirm: handleConfirm,
162
+ onClose: handleClose,
163
+ ...dialogProps,
164
+ children: [/*#__PURE__*/_jsx("div", {
165
+ className: "pnt-region-import__tip",
166
+ children: texts.importTip
167
+ }), /*#__PURE__*/_jsx(Textarea, {
168
+ value: importText,
169
+ onChange: next => {
170
+ setImportText(String(next ?? ''));
171
+ if (isParsed) {
172
+ setRows([]);
173
+ setIsParsed(false);
174
+ }
175
+ },
176
+ rows: 3,
177
+ placeholder: texts.importPlaceholder
178
+ }), isParsed ? /*#__PURE__*/_jsxs("div", {
179
+ className: "pnt-region-import__result",
180
+ children: [/*#__PURE__*/_jsxs("div", {
181
+ className: "pnt-region-import__summary",
182
+ children: [/*#__PURE__*/_jsxs("span", {
183
+ className: "pnt-region-import__summary-item pnt-region-import__summary-item--unmatched",
184
+ children: [texts.importUnmatched, "\uFF1A", unmatchedList.length]
185
+ }), /*#__PURE__*/_jsx(Tooltip, {
186
+ content: texts.copyUnmatchedTip,
187
+ children: /*#__PURE__*/_jsx(Button, {
188
+ theme: "primary",
189
+ variant: "text",
190
+ size: "small",
191
+ className: "pnt-region-import__copy-btn",
192
+ disabled: !unmatchedList.length,
193
+ onClick: copyUnmatched,
194
+ children: /*#__PURE__*/_jsx(FileCopyIcon, {
195
+ strokeWidth: 2
196
+ })
197
+ })
198
+ }), /*#__PURE__*/_jsx("span", {
199
+ className: "pnt-region-import__summary-dot",
200
+ children: "\xB7"
201
+ }), /*#__PURE__*/_jsxs("span", {
202
+ className: "pnt-region-import__summary-item pnt-region-import__summary-item--pending",
203
+ children: [texts.importPending, "\uFF1A", pendingList.length]
204
+ }), /*#__PURE__*/_jsx("span", {
205
+ className: "pnt-region-import__summary-dot",
206
+ children: "\xB7"
207
+ }), /*#__PURE__*/_jsxs("span", {
208
+ className: "pnt-region-import__summary-item pnt-region-import__summary-item--exists",
209
+ children: [texts.importExists, "\uFF1A", existsList.length]
210
+ })]
211
+ }), /*#__PURE__*/_jsxs("div", {
212
+ className: "pnt-region-import__table",
213
+ children: [/*#__PURE__*/_jsxs("div", {
214
+ className: "pnt-region-import__table-head",
215
+ children: [/*#__PURE__*/_jsx("span", {
216
+ children: texts.importRegionColumn
217
+ }), /*#__PURE__*/_jsx("span", {
218
+ children: texts.importStatusColumn
219
+ })]
220
+ }), /*#__PURE__*/_jsx("div", {
221
+ className: "pnt-region-import__table-body",
222
+ children: rows.length ? rows.map(row => /*#__PURE__*/_jsxs("div", {
223
+ className: "pnt-region-import__table-row",
224
+ children: [/*#__PURE__*/_jsx("span", {
225
+ className: "pnt-region-import__region",
226
+ children: row.region
227
+ }), /*#__PURE__*/_jsxs("span", {
228
+ className: `pnt-region-import__status pnt-region-import__status--${row.status}`,
229
+ children: [row.status === 'unmatched' ? /*#__PURE__*/_jsx(CloseIcon, {
230
+ strokeWidth: 2
231
+ }) : /*#__PURE__*/_jsx(CheckIcon, {
232
+ strokeWidth: 2
233
+ }), row.status === 'pending' ? texts.importPending : row.status === 'exists' ? texts.importExists : texts.importUnmatched]
234
+ })]
235
+ }, row.region)) : /*#__PURE__*/_jsx("div", {
236
+ className: "pnt-region-import__empty",
237
+ children: "-"
238
+ })
239
+ })]
240
+ })]
241
+ }) : null]
242
+ });
243
+ };
244
+ export default ImportDialog;
@@ -0,0 +1,39 @@
1
+ import { FC } from 'react';
2
+ import './index.scss';
3
+ import type { PntRegionSelectProps } from './types';
4
+ /**
5
+ * 归一化 region_code:纯数字字符串去掉前导零('012' -> '12'),非数字保持原样
6
+ * @description 后端详情接口可能返回 '12',字典接口可能返回 '012',需统一格式才能匹配
7
+ */
8
+ export declare const normalizeRegionCode: (code: string | number | undefined | null) => string;
9
+ /**
10
+ * 地区选择器组件
11
+ * @description 统一的国家/地区选择组件,支持单选/多选、批量选择、批量导入、自定义区域、合规区域
12
+ *
13
+ * @example
14
+ * ```tsx
15
+ * // 基础多选(内部拉取默认区域列表)
16
+ * <PntRegionSelect
17
+ * value={regions}
18
+ * onChange={(v) => setRegions(v)}
19
+ * />
20
+ *
21
+ * // 业务最终生效区域
22
+ * <PntRegionSelect
23
+ * dataSource="business"
24
+ * gameId={gameId}
25
+ * value={regions}
26
+ * onChange={(v) => setRegions(v)}
27
+ * />
28
+ *
29
+ * // 外部受控选项 + 批量导入
30
+ * <PntRegionSelect
31
+ * options={regionList}
32
+ * importable
33
+ * value={regions}
34
+ * onChange={(v) => setRegions(v)}
35
+ * />
36
+ * ```
37
+ */
38
+ declare const PntRegionSelect: FC<PntRegionSelectProps>;
39
+ export default PntRegionSelect;