@pnt-team/pnt-component-frontend 0.0.43 → 0.0.47

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 (35) hide show
  1. package/lib/cjs/api/index.d.ts +4 -0
  2. package/lib/cjs/api/index.js +46 -0
  3. package/lib/cjs/api/types/index.d.ts +80 -0
  4. package/lib/cjs/api/types/index.js +17 -0
  5. package/lib/cjs/components/PntBusinessSelect/index.d.ts +152 -0
  6. package/lib/cjs/components/PntBusinessSelect/index.js +242 -0
  7. package/lib/cjs/components/PntBusinessSelect/index.scss +3 -0
  8. package/lib/cjs/components/PntGeneralLayout/index.d.ts +1 -1
  9. package/lib/cjs/components/PntSecureBox/index.d.ts +5 -12
  10. package/lib/cjs/components/PntSecureBox/index.js +3 -3
  11. package/lib/cjs/hooks/useHighSecurity.d.ts +8 -9
  12. package/lib/cjs/hooks/useHighSecurity.js +14 -7
  13. package/lib/cjs/index.d.ts +1 -0
  14. package/lib/cjs/index.js +3 -0
  15. package/lib/cjs/utils/request.d.ts +8 -0
  16. package/lib/cjs/utils/request.js +82 -0
  17. package/lib/esm/api/index.d.ts +4 -0
  18. package/lib/esm/api/index.js +11 -0
  19. package/lib/esm/api/types/index.d.ts +80 -0
  20. package/lib/esm/api/types/index.js +0 -0
  21. package/lib/esm/components/PntBusinessSelect/index.d.ts +152 -0
  22. package/lib/esm/components/PntBusinessSelect/index.js +228 -0
  23. package/lib/esm/components/PntBusinessSelect/index.scss +3 -0
  24. package/lib/esm/components/PntGeneralLayout/index.d.ts +1 -1
  25. package/lib/esm/components/PntSecureBox/index.d.ts +5 -12
  26. package/lib/esm/components/PntSecureBox/index.js +4 -6
  27. package/lib/esm/hooks/useHighSecurity.d.ts +8 -9
  28. package/lib/esm/hooks/useHighSecurity.js +14 -7
  29. package/lib/esm/index.d.ts +1 -0
  30. package/lib/esm/index.js +6 -4
  31. package/lib/esm/utils/request.d.ts +8 -0
  32. package/lib/esm/utils/request.js +52 -0
  33. package/lib/umd/pnt-component-frontend.min.css +1 -1
  34. package/lib/umd/pnt-component-frontend.min.js +1 -1
  35. package/package.json +2 -1
@@ -0,0 +1,4 @@
1
+ import { commonEesType } from "../utils/request";
2
+ import { BusinessGameInfoHighSecurityDecryptBody, BusinessGameInfoHighSecurityDecryptResponse, BusinessSelectListBody, BusinessSelectListResponse } from './types/index';
3
+ export declare const businessGameInfoHighSecurityDecrypt: (data: BusinessGameInfoHighSecurityDecryptBody) => Promise<commonEesType<BusinessGameInfoHighSecurityDecryptResponse>>;
4
+ export declare const businessSelectList: (data: BusinessSelectListBody) => Promise<commonEesType<BusinessSelectListResponse>>;
@@ -0,0 +1,46 @@
1
+ var __create = Object.create;
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __getProtoOf = Object.getPrototypeOf;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __export = (target, all) => {
8
+ for (var name in all)
9
+ __defProp(target, name, { get: all[name], enumerable: true });
10
+ };
11
+ var __copyProps = (to, from, except, desc) => {
12
+ if (from && typeof from === "object" || typeof from === "function") {
13
+ for (let key of __getOwnPropNames(from))
14
+ if (!__hasOwnProp.call(to, key) && key !== except)
15
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
16
+ }
17
+ return to;
18
+ };
19
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
20
+ // If the importer is in node compatibility mode or this is not an ESM
21
+ // file that has been converted to a CommonJS file using a Babel-
22
+ // compatible transform (i.e. "__esModule" has not been set), then set
23
+ // "default" to the CommonJS "module.exports" for node compatibility.
24
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
25
+ mod
26
+ ));
27
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
28
+
29
+ // src/api/index.ts
30
+ var api_exports = {};
31
+ __export(api_exports, {
32
+ businessGameInfoHighSecurityDecrypt: () => businessGameInfoHighSecurityDecrypt,
33
+ businessSelectList: () => businessSelectList
34
+ });
35
+ module.exports = __toCommonJS(api_exports);
36
+ var import_request = __toESM(require("../utils/request"));
37
+ var businessGameInfoHighSecurityDecrypt = (data) => import_request.default.post(
38
+ "/api/v3/business/game_info/high-security-decrypt?audience=/laas-pnt",
39
+ data
40
+ );
41
+ var businessSelectList = (data) => import_request.default.post("/api/business/select/list", data);
42
+ // Annotate the CommonJS export names for ESM import in node:
43
+ 0 && (module.exports = {
44
+ businessGameInfoHighSecurityDecrypt,
45
+ businessSelectList
46
+ });
@@ -0,0 +1,80 @@
1
+ /**
2
+ * 本文件由 yapi-gen 自动生成,请勿手动修改
3
+ * 生成时间: 2026/9/10 11:19:01
4
+ * 数据来源: https://api-pnt.intlgame.com
5
+ */
6
+ export interface BusinessSelectListBody {
7
+ /** 业务接入类型:1-纯SDK,2-LI PASS,3-工作室品牌账号 */
8
+ business_access_method?: number;
9
+ /** 业务类型列表:1-正式业务,2-测试业务;SmartLink业务始终不返回 */
10
+ business_types?: number[];
11
+ /** 需要返回的字段;未传时使用场景默认字段,仅支持服务端白名单字段 */
12
+ fields?: string[];
13
+ /** 指定业务ID列表;与 Keyword 同时传���时取交集 */
14
+ game_ids?: string[];
15
+ /** 业务ID、中文名称或英文名称的模糊匹配关键字 */
16
+ keyword?: string;
17
+ /** 当前页 */
18
+ pageNum?: number;
19
+ /** 每页条数 */
20
+ pageSize?: number;
21
+ /** 下拉场景:default-通用业务,sdk-SDK定制,compliance_age-合规年龄,custom_region-自定义合规地域 */
22
+ scene?: string;
23
+ /** 业务状态列表:3-线上运营,4-接入中,5-中途结项,6-已下线 */
24
+ statuses?: number[];
25
+ /** 总条数 */
26
+ total?: number;
27
+ /** 总页数 */
28
+ totalPage?: number;
29
+ }
30
+ export interface BusinessSelectListResponseListItem {
31
+ /** 业务接入类型:1-纯SDK,2-LI PASS,3-工作室品牌账号 */
32
+ business_access_method?: number;
33
+ /** 业务类型:1-正式业务,2-测试业务 */
34
+ business_type?: number;
35
+ /** 当前场景是否可创建;仅 compliance_age、custom_region 场景有意义 */
36
+ creatable?: boolean;
37
+ /** 业务ID */
38
+ game_id?: string;
39
+ /** 业务接口开发负责人;SDK场景可返回 */
40
+ interface_developer_name?: string;
41
+ /** 业务中文名称 */
42
+ name?: string;
43
+ /** 业务英文名称 */
44
+ name_en?: string;
45
+ /** SDK定制版本通知人;SDK场景可返回 */
46
+ sdk_customize_notifier?: string;
47
+ /** 业务状态:3-线上运营,4-接入中,5-中途结项,6-已下线 */
48
+ state?: number;
49
+ }
50
+ export interface BusinessSelectListResponsePagination {
51
+ /** 当前页 */
52
+ pageNum?: number;
53
+ /** 每页条数 */
54
+ pageSize?: number;
55
+ /** 总条数 */
56
+ total?: number;
57
+ /** 总页数 */
58
+ totalPage?: number;
59
+ }
60
+ export interface BusinessSelectListResponse {
61
+ /** 业务列表;字段由请求 Fields 或场景默认字段决定 */
62
+ list?: BusinessSelectListResponseListItem[];
63
+ /** 分页信息;未分页时统计字段均为零值 */
64
+ pagination?: BusinessSelectListResponsePagination;
65
+ }
66
+ export interface BusinessGameInfoHighSecurityDecryptBodyParamItem {
67
+ /** 参数字段 */
68
+ key: string;
69
+ /** 参数密文 */
70
+ value: string;
71
+ }
72
+ export interface BusinessGameInfoHighSecurityDecryptBody {
73
+ param: BusinessGameInfoHighSecurityDecryptBodyParamItem[];
74
+ /** 页面ID */
75
+ page_id: string;
76
+ /** 请求环境 */
77
+ env: number;
78
+ game_id: number;
79
+ }
80
+ export type BusinessGameInfoHighSecurityDecryptResponse = Record<string, unknown>[];
@@ -0,0 +1,17 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
+ var __getOwnPropNames = Object.getOwnPropertyNames;
4
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
5
+ var __copyProps = (to, from, except, desc) => {
6
+ if (from && typeof from === "object" || typeof from === "function") {
7
+ for (let key of __getOwnPropNames(from))
8
+ if (!__hasOwnProp.call(to, key) && key !== except)
9
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
10
+ }
11
+ return to;
12
+ };
13
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
14
+
15
+ // src/api/types/index.ts
16
+ var types_exports = {};
17
+ module.exports = __toCommonJS(types_exports);
@@ -0,0 +1,152 @@
1
+ import React, { FC } from 'react';
2
+ import type { SelectValue, TdSelectProps } from 'tdesign-react/es/select/type';
3
+ import './index.scss';
4
+ /** 下拉场景 */
5
+ type Scene = 'default' | 'sdk' | 'compliance_age' | 'custom_region';
6
+ /** 标签格式 */
7
+ type LabelFormat = 'name' | 'name_en' | 'name_id' | 'name_en_id';
8
+ interface PntBusinessSelectProps {
9
+ /**
10
+ * 当前选中值
11
+ * @description 单选为 string,多选为 string[]
12
+ */
13
+ value?: SelectValue;
14
+ /**
15
+ * 值变化回调
16
+ */
17
+ onChange?: TdSelectProps['onChange'];
18
+ /**
19
+ * 是否多选
20
+ * @default false
21
+ */
22
+ multiple?: boolean;
23
+ /**
24
+ * 下拉场景
25
+ * @description 后端按场景返回默认字段集
26
+ * @default 'default'
27
+ */
28
+ scene?: Scene;
29
+ /**
30
+ * 业务状态筛选
31
+ * @description 3-线上运营,4-接入中,5-中途结项,6-已下线
32
+ */
33
+ statuses?: number[];
34
+ /**
35
+ * 业务类型筛选
36
+ * @description 1-正式业务,2-测试业务
37
+ */
38
+ businessTypes?: number[];
39
+ /**
40
+ * 业务接入类型筛选
41
+ * @description 1-纯SDK,2-LI PASS,3-工作室品牌账号
42
+ */
43
+ businessAccessMethod?: number;
44
+ /**
45
+ * 标签格式
46
+ * @description name-中文名,name_en-英文名,name_id-中文名(ID),name_en_id-英文名(ID)
47
+ * @default 'name'
48
+ */
49
+ labelFormat?: LabelFormat;
50
+ /**
51
+ * 占位提示文案
52
+ */
53
+ placeholder?: string;
54
+ /**
55
+ * 是否禁用整个选择器
56
+ * @default false
57
+ */
58
+ disabled?: boolean;
59
+ /**
60
+ * 是否可清除
61
+ * @default true
62
+ */
63
+ clearable?: boolean;
64
+ /**
65
+ * 是否可远程搜索
66
+ * @default true
67
+ */
68
+ filterable?: boolean;
69
+ /**
70
+ * 多选时最大可选数量
71
+ */
72
+ max?: number;
73
+ /**
74
+ * 每页条数
75
+ * @default 20
76
+ */
77
+ pageSize?: number;
78
+ /**
79
+ * 搜索防抖延迟(毫秒)
80
+ * @default 400
81
+ */
82
+ searchDebounce?: number;
83
+ /**
84
+ * 多选时最少折叠数量
85
+ * @description 超过此数量的选中项将折叠显示,透传至 TDesign Select
86
+ */
87
+ minCollapsedNum?: number;
88
+ /**
89
+ * 折叠项自定义渲染
90
+ * @description 透传至 TDesign Select collapsedItems
91
+ */
92
+ collapsedItems?: TdSelectProps['collapsedItems'];
93
+ /**
94
+ * 弹层属性透传
95
+ * @description 会与组件内部 onScrollToBottom 合并;常用 attach(挂载容器)、overlayClassName 等
96
+ */
97
+ popupProps?: Partial<TdSelectProps['popupProps']>;
98
+ /**
99
+ * 自定义类名
100
+ */
101
+ className?: string;
102
+ /**
103
+ * 自定义样式
104
+ */
105
+ style?: React.CSSProperties;
106
+ }
107
+ /**
108
+ * 业务选择器组件
109
+ * @description 统一业务下拉选择器,内置对接后端通用接口 `/api/business/select/list`,
110
+ * 支持远程搜索、滚动分页加载、多选、场景化禁用(合规场景 creatable 字段)。
111
+ *
112
+ * @param {PntBusinessSelectProps} props - 组件属性
113
+ *
114
+ * @example
115
+ * ```tsx
116
+ * import { PntBusinessSelect } from '@pnt-team/pnt-component-frontend';
117
+ *
118
+ * // 最简用法
119
+ * <PntBusinessSelect
120
+ * value={gameId}
121
+ * onChange={(v) => setGameId(v as string)}
122
+ * />
123
+ *
124
+ * // SDK 定制场景 + 名称带 ID
125
+ * <PntBusinessSelect
126
+ * scene="sdk"
127
+ * labelFormat="name_id"
128
+ * value={gameId}
129
+ * onChange={(v) => setGameId(v as string)}
130
+ * />
131
+ *
132
+ * // 合规年龄场景(自动禁用 creatable=false 的业务)
133
+ * <PntBusinessSelect
134
+ * scene="compliance_age"
135
+ * value={gameId}
136
+ * onChange={(v) => setGameId(v as string)}
137
+ * />
138
+ *
139
+ * // 多选 + 状态过滤
140
+ * <PntBusinessSelect
141
+ * multiple
142
+ * statuses={[3, 4]}
143
+ * labelFormat="name_id"
144
+ * value={gameIds}
145
+ * onChange={(v) => setGameIds(v as string[])}
146
+ * />
147
+ * ```
148
+ *
149
+ * @returns {ReactElement} 业务选择器组件
150
+ */
151
+ declare const PntBusinessSelect: FC<PntBusinessSelectProps>;
152
+ export default PntBusinessSelect;
@@ -0,0 +1,242 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
+ var __getOwnPropNames = Object.getOwnPropertyNames;
4
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
5
+ var __export = (target, all) => {
6
+ for (var name in all)
7
+ __defProp(target, name, { get: all[name], enumerable: true });
8
+ };
9
+ var __copyProps = (to, from, except, desc) => {
10
+ if (from && typeof from === "object" || typeof from === "function") {
11
+ for (let key of __getOwnPropNames(from))
12
+ if (!__hasOwnProp.call(to, key) && key !== except)
13
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
14
+ }
15
+ return to;
16
+ };
17
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
18
+
19
+ // src/components/PntBusinessSelect/index.tsx
20
+ var PntBusinessSelect_exports = {};
21
+ __export(PntBusinessSelect_exports, {
22
+ default: () => PntBusinessSelect_default
23
+ });
24
+ module.exports = __toCommonJS(PntBusinessSelect_exports);
25
+ var import_api = require("../../api");
26
+ var import_react = require("react");
27
+ var import_tdesign_react = require("tdesign-react");
28
+ var import_index = require("./index.scss");
29
+ var import_jsx_runtime = require("react/jsx-runtime");
30
+ var PntBusinessSelect = (props) => {
31
+ const {
32
+ value,
33
+ onChange,
34
+ multiple = false,
35
+ scene = "default",
36
+ statuses,
37
+ businessTypes,
38
+ businessAccessMethod,
39
+ labelFormat = "name",
40
+ placeholder,
41
+ disabled,
42
+ clearable = true,
43
+ filterable = true,
44
+ max,
45
+ pageSize = 20,
46
+ searchDebounce = 400,
47
+ minCollapsedNum,
48
+ collapsedItems,
49
+ popupProps,
50
+ className,
51
+ style
52
+ } = props;
53
+ const requestFn = (0, import_react.useCallback)(
54
+ (params) => (0, import_api.businessSelectList)(params),
55
+ []
56
+ );
57
+ const [options, setOptions] = (0, import_react.useState)(
58
+ []
59
+ );
60
+ const [loading, setLoading] = (0, import_react.useState)(false);
61
+ const [keyword, setKeyword] = (0, import_react.useState)("");
62
+ const [pageNum, setPageNum] = (0, import_react.useState)(1);
63
+ const [total, setTotal] = (0, import_react.useState)(0);
64
+ const debounceRef = (0, import_react.useRef)();
65
+ const loadingRef = (0, import_react.useRef)(false);
66
+ const selectedItemsRef = (0, import_react.useRef)(/* @__PURE__ */ new Map());
67
+ const buildParams = (0, import_react.useCallback)(
68
+ (kw, page) => ({
69
+ keyword: kw || void 0,
70
+ pageNum: page,
71
+ pageSize,
72
+ scene,
73
+ statuses,
74
+ business_types: businessTypes,
75
+ business_access_method: businessAccessMethod
76
+ }),
77
+ [scene, statuses, businessTypes, businessAccessMethod, pageSize]
78
+ );
79
+ const fetchData = (0, import_react.useCallback)(
80
+ async (kw, page, append) => {
81
+ var _a;
82
+ if (loadingRef.current)
83
+ return;
84
+ loadingRef.current = true;
85
+ setLoading(true);
86
+ try {
87
+ const res = await requestFn(buildParams(kw, page));
88
+ if (res.code === 0 && res.data) {
89
+ const newList = res.data.list || [];
90
+ setOptions((prev) => append ? [...prev, ...newList] : newList);
91
+ setTotal(((_a = res.data.pagination) == null ? void 0 : _a.total) || 0);
92
+ setPageNum(page);
93
+ }
94
+ } finally {
95
+ loadingRef.current = false;
96
+ setLoading(false);
97
+ }
98
+ },
99
+ [requestFn, buildParams]
100
+ );
101
+ const handleSearch = (0, import_react.useCallback)(
102
+ (val) => {
103
+ setKeyword(val);
104
+ if (debounceRef.current)
105
+ clearTimeout(debounceRef.current);
106
+ debounceRef.current = setTimeout(() => {
107
+ fetchData(val, 1, false);
108
+ }, searchDebounce);
109
+ },
110
+ [fetchData, searchDebounce]
111
+ );
112
+ const handleScrollToBottom = (0, import_react.useCallback)(() => {
113
+ if (!loadingRef.current && options.length < total) {
114
+ fetchData(keyword, pageNum + 1, true);
115
+ }
116
+ }, [options.length, total, keyword, pageNum, fetchData]);
117
+ const handlePopupVisibleChange = (0, import_react.useCallback)(
118
+ (visible) => {
119
+ if (!visible && keyword) {
120
+ setKeyword("");
121
+ fetchData("", 1, false);
122
+ }
123
+ },
124
+ [keyword, fetchData]
125
+ );
126
+ (0, import_react.useEffect)(() => {
127
+ fetchData("", 1, false);
128
+ }, [fetchData]);
129
+ (0, import_react.useEffect)(() => {
130
+ const selectedValues = Array.isArray(value) ? value : value ? [value] : [];
131
+ options.forEach((item) => {
132
+ if (item.game_id && selectedValues.includes(item.game_id)) {
133
+ selectedItemsRef.current.set(item.game_id, item);
134
+ }
135
+ });
136
+ }, [options, value]);
137
+ (0, import_react.useEffect)(() => {
138
+ return () => {
139
+ if (debounceRef.current)
140
+ clearTimeout(debounceRef.current);
141
+ };
142
+ }, []);
143
+ const formatLabel = (0, import_react.useCallback)(
144
+ (item) => {
145
+ const name = item.name || "";
146
+ const nameEn = item.name_en || "";
147
+ const gameId = item.game_id || "";
148
+ switch (labelFormat) {
149
+ case "name_en":
150
+ return nameEn || name;
151
+ case "name_id":
152
+ return `${name}(${gameId})`;
153
+ case "name_en_id":
154
+ return `${nameEn}(${gameId})`;
155
+ default:
156
+ return name;
157
+ }
158
+ },
159
+ [labelFormat]
160
+ );
161
+ const isOptionDisabled = (0, import_react.useCallback)(
162
+ (item) => {
163
+ if (scene === "compliance_age" || scene === "custom_region") {
164
+ return !item.creatable;
165
+ }
166
+ return false;
167
+ },
168
+ [scene]
169
+ );
170
+ const selectOptions = (0, import_react.useMemo)(() => {
171
+ const map = /* @__PURE__ */ new Map();
172
+ options.forEach((item) => {
173
+ if (item.game_id) {
174
+ map.set(item.game_id, {
175
+ label: formatLabel(item),
176
+ value: item.game_id,
177
+ disabled: isOptionDisabled(item),
178
+ name: item.name,
179
+ name_en: item.name_en,
180
+ game_id: item.game_id
181
+ });
182
+ }
183
+ });
184
+ const selectedValues = Array.isArray(value) ? value : value ? [value] : [];
185
+ selectedValues.forEach((id) => {
186
+ if (!map.has(id)) {
187
+ const item = selectedItemsRef.current.get(id);
188
+ if (item) {
189
+ map.set(id, {
190
+ label: formatLabel(item),
191
+ value: id,
192
+ disabled: isOptionDisabled(item),
193
+ name: item.name,
194
+ name_en: item.name_en,
195
+ game_id: item.game_id
196
+ });
197
+ } else {
198
+ map.set(id, { label: id, value: id, disabled: false });
199
+ }
200
+ }
201
+ });
202
+ return Array.from(map.values());
203
+ }, [options, value, formatLabel, isOptionDisabled]);
204
+ const localFilter = (0, import_react.useCallback)(
205
+ (filterWord, option) => {
206
+ if (!filterWord)
207
+ return true;
208
+ const kw = filterWord.toLowerCase();
209
+ const opt = option;
210
+ return ((opt == null ? void 0 : opt.name) || "").toLowerCase().includes(kw) || ((opt == null ? void 0 : opt.name_en) || "").toLowerCase().includes(kw) || ((opt == null ? void 0 : opt.game_id) || "").includes(kw);
211
+ },
212
+ []
213
+ );
214
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
215
+ import_tdesign_react.Select,
216
+ {
217
+ value,
218
+ onChange,
219
+ options: selectOptions,
220
+ filterable,
221
+ filter: filterable ? localFilter : void 0,
222
+ onSearch: filterable ? handleSearch : void 0,
223
+ loading: loading && options.length === 0,
224
+ multiple,
225
+ max,
226
+ clearable,
227
+ disabled,
228
+ placeholder,
229
+ minCollapsedNum,
230
+ collapsedItems,
231
+ onPopupVisibleChange: handlePopupVisibleChange,
232
+ panelBottomContent: options.length > 0 && loading ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_tdesign_react.Loading, { loading: true, size: "small" }) : null,
233
+ popupProps: {
234
+ ...popupProps,
235
+ onScrollToBottom: handleScrollToBottom
236
+ },
237
+ className: className ? `pnt-business-select ${className}` : "pnt-business-select",
238
+ style
239
+ }
240
+ );
241
+ };
242
+ var PntBusinessSelect_default = PntBusinessSelect;
@@ -0,0 +1,3 @@
1
+ .pnt-business-select {
2
+ width: 100%;
3
+ }
@@ -48,7 +48,7 @@ interface PntGeneralLayoutProps {
48
48
  footer?: ReactNode;
49
49
  }
50
50
  /**
51
- * 通用页面布局组件(L4 布局组件)
51
+ * 通用页面布局组件(L3 布局组件)
52
52
  * @description 提供标准的「头部 + 子头部 + 内容区 + 底部」页面布局结构,
53
53
  * 基于 TDesign Layout 封装,适用于后台管理系统的详情页、表单页等场景。
54
54
  *
@@ -1,4 +1,3 @@
1
- import { type HighSecurityFetcher } from "../../hooks/useHighSecurity";
2
1
  import React, { FC } from 'react';
3
2
  import './index.scss';
4
3
  interface PntSecureBoxProps {
@@ -39,15 +38,12 @@ interface PntSecureBoxProps {
39
38
  * @description 用于记录操作日志和权限验证
40
39
  */
41
40
  pageId?: string;
42
- /**
43
- * 高敏数据请求函数
44
- * @description 通过外部注入请求函数,避免组件库内部依赖敏感配置
45
- */
46
- fetcher: HighSecurityFetcher;
47
41
  }
48
42
  /**
49
43
  * 高敏信息展示统一组件
50
- * @description 用于统一处理和展示高敏信息,支持脱敏显示和按需获取真实数据
44
+ * @description 用于统一处理和展示高敏信息,支持脱敏显示和按需获取真实数据。
45
+ * 内置对接组件库 `businessGameInfoHighSecurityDecrypt` API(`/api/v3/business/game_info/high-security-decrypt`)。
46
+ *
51
47
  * @param {PntSecureBoxProps} props - 组件属性
52
48
  * @param {string} props.dataKey - 高敏信息的唯一标识 key
53
49
  * @param {string} props.dataValue - 高敏信息的实际值
@@ -56,19 +52,16 @@ interface PntSecureBoxProps {
56
52
  * @param {(content: string) => React.ReactNode} props.renderDom - 自定义渲染函数
57
53
  * @param {string} [props.viewText] - 自定义查看按钮文案
58
54
  * @param {string} [props.pageId] - 页面 ID
59
- * @param {HighSecurityFetcher} props.fetcher - 高敏数据请求函数
60
55
  *
61
56
  * @example
62
57
  * ```tsx
63
- * import http from '@/utils/request';
64
58
  * import { PntSecureBox } from '@pnt-team/pnt-component-frontend';
65
59
  *
66
60
  * <PntSecureBox
67
61
  * dataKey="userPhone"
68
- * dataValue="138****8888"
69
- * env="production"
62
+ * dataValue="_high_security_:AAAA...:6542"
63
+ * env={2}
70
64
  * gameId={12345}
71
- * fetcher={(params) => http.post('/api/v3/business/game_info/high-security-decrypt', params).then(r => r.data)}
72
65
  * renderDom={(content) => <span>{content}</span>}
73
66
  * viewText="查看"
74
67
  * />
@@ -22,6 +22,7 @@ __export(PntSecureBox_exports, {
22
22
  default: () => PntSecureBox_default
23
23
  });
24
24
  module.exports = __toCommonJS(PntSecureBox_exports);
25
+ var import_api = require("../../api");
25
26
  var import_useHighSecurity = require("../../hooks/useHighSecurity");
26
27
  var import_utils = require("../../utils");
27
28
  var import_index = require("./index.scss");
@@ -34,10 +35,9 @@ var PntSecureBox = (prop) => {
34
35
  gameId,
35
36
  renderDom,
36
37
  viewText,
37
- pageId,
38
- fetcher
38
+ pageId
39
39
  } = prop;
40
- const { securityData, requestSecurityData } = (0, import_useHighSecurity.useHighSecurity)(fetcher);
40
+ const { securityData, requestSecurityData } = (0, import_useHighSecurity.useHighSecurity)(import_api.businessGameInfoHighSecurityDecrypt);
41
41
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "pnt-secure-box", children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
42
42
  renderDom(
43
43
  (0, import_utils.isSecurityData)(dataValue) ? securityData[dataKey] || "******" : dataValue
@@ -1,4 +1,6 @@
1
- /** 高敏数据请求参数 */
1
+ import type { BusinessGameInfoHighSecurityDecryptBody, BusinessGameInfoHighSecurityDecryptResponse } from "../api/types";
2
+ import type { commonEesType } from "../utils/request";
3
+ /** 高敏数据请求参数(组件层友好命名) */
2
4
  export interface HighSecurityRequestParams {
3
5
  /** 游戏 ID */
4
6
  gameId: string | number;
@@ -12,14 +14,11 @@ export interface HighSecurityRequestParams {
12
14
  value: string;
13
15
  }>;
14
16
  }
15
- /** 高敏数据请求函数:返回 { ret, data } 结构且 ret === 0 视为成功 */
16
- export type HighSecurityFetcher = (params: HighSecurityRequestParams) => Promise<{
17
- ret: number;
18
- data?: Array<{
19
- key: string;
20
- value: string;
21
- }>;
22
- }>;
17
+ /**
18
+ * 高敏数据请求函数:返回 commonEesType 结构,code === 0 视为成功
19
+ * 不传时使用组件库内置的 `businessGameInfoHighSecurityDecrypt` API
20
+ */
21
+ export type HighSecurityFetcher = (params: BusinessGameInfoHighSecurityDecryptBody) => Promise<commonEesType<BusinessGameInfoHighSecurityDecryptResponse>>;
23
22
  /**
24
23
  * 高敏数据解锁 Hook(PntSecureBox 内部依赖)
25
24
  * @internal 不对外导出,归 PntSecureBox 组件内部使用
@@ -40,14 +40,21 @@ var useHighSecurity = (fetcher) => {
40
40
  env,
41
41
  pageId
42
42
  }) => {
43
- const result = await fetcher({
44
- gameId,
43
+ const body = {
44
+ game_id: Number(gameId),
45
45
  env: Number(env),
46
- pageId: pageId || location.pathname,
47
- param
48
- });
49
- if (result.ret === 0 && result.data) {
50
- result.data.forEach((item) => {
46
+ page_id: pageId || location.pathname,
47
+ param: param.map(
48
+ (i) => ({
49
+ key: i.key,
50
+ value: i.value
51
+ })
52
+ )
53
+ };
54
+ const result = await fetcher(body);
55
+ if (result.code === 0 && result.data) {
56
+ const data = result.data;
57
+ data.forEach((item) => {
51
58
  securityCache.set(item.key, item.value);
52
59
  });
53
60
  setSecurityData(Object.fromEntries(securityCache));