@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
@@ -1,3 +1,4 @@
1
1
  export { default as PntImagePreview } from './components/PntImagePreview';
2
+ export { default as PntBusinessSelect } from './components/PntBusinessSelect';
2
3
  export { default as PntSecureBox } from './components/PntSecureBox';
3
4
  export { default as PntGeneralLayout } from './components/PntGeneralLayout';
package/lib/cjs/index.js CHANGED
@@ -29,16 +29,19 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
29
29
  // src/index.ts
30
30
  var src_exports = {};
31
31
  __export(src_exports, {
32
+ PntBusinessSelect: () => import_PntBusinessSelect.default,
32
33
  PntGeneralLayout: () => import_PntGeneralLayout.default,
33
34
  PntImagePreview: () => import_PntImagePreview.default,
34
35
  PntSecureBox: () => import_PntSecureBox.default
35
36
  });
36
37
  module.exports = __toCommonJS(src_exports);
37
38
  var import_PntImagePreview = __toESM(require("./components/PntImagePreview"));
39
+ var import_PntBusinessSelect = __toESM(require("./components/PntBusinessSelect"));
38
40
  var import_PntSecureBox = __toESM(require("./components/PntSecureBox"));
39
41
  var import_PntGeneralLayout = __toESM(require("./components/PntGeneralLayout"));
40
42
  // Annotate the CommonJS export names for ESM import in node:
41
43
  0 && (module.exports = {
44
+ PntBusinessSelect,
42
45
  PntGeneralLayout,
43
46
  PntImagePreview,
44
47
  PntSecureBox
@@ -0,0 +1,8 @@
1
+ export interface commonEesType<T> {
2
+ code: number;
3
+ msg: string;
4
+ data: T;
5
+ ret?: number;
6
+ }
7
+ declare const http: import("axios").AxiosInstance;
8
+ export default http;
@@ -0,0 +1,82 @@
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/utils/request.ts
30
+ var request_exports = {};
31
+ __export(request_exports, {
32
+ default: () => request_default
33
+ });
34
+ module.exports = __toCommonJS(request_exports);
35
+ var import_axios = __toESM(require("axios"));
36
+ var import_host = __toESM(require("../configs/host"));
37
+ var import_token = __toESM(require("../configs/token"));
38
+ var import_const = require("./const");
39
+ var env = process.env.MODE || "development";
40
+ var API_HOST = import_host.default[env].API;
41
+ var http = import_axios.default.create({
42
+ baseURL: API_HOST,
43
+ timeout: 100 * 1e3,
44
+ withCredentials: true
45
+ });
46
+ http.interceptors.request.use(
47
+ (config) => {
48
+ var _a;
49
+ const conf = { ...config };
50
+ const matchPath = Object.values(import_const.SUB_APP_PATHNAME).filter(
51
+ (path) => window.location.pathname.includes(path)
52
+ )[0] || "";
53
+ if (process.env.NODE_ENV === "development") {
54
+ conf.baseURL = matchPath ? "/subapi" : conf.baseURL;
55
+ conf.headers["X-Service-Type"] = ((_a = conf.headers) == null ? void 0 : _a["x-service-type"]) || "11";
56
+ conf.headers["X-User-Id"] = "us-104fe9b46fdf4534be663ec9eaa9ea2e";
57
+ conf.headers["X-User-Name"] = "v_bwweiwang";
58
+ conf.headers.authorization = import_token.default;
59
+ } else {
60
+ conf.baseURL = "/";
61
+ }
62
+ if (!conf.url.includes("audience=")) {
63
+ conf.url = `${conf.url}?audience=${matchPath ? import_const.AUDIENCE_MAPPING[matchPath] : "/player-network"}`;
64
+ }
65
+ return conf;
66
+ },
67
+ (err) => Promise.reject(err)
68
+ );
69
+ http.interceptors.response.use(
70
+ (response) => {
71
+ if (response.status === 200) {
72
+ const { data } = response;
73
+ if (data.code === 0) {
74
+ return Promise.resolve(data);
75
+ }
76
+ return Promise.resolve(data);
77
+ }
78
+ return Promise.reject(response == null ? void 0 : response.data);
79
+ },
80
+ (e) => Promise.reject(e)
81
+ );
82
+ var request_default = http;
@@ -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,11 @@
1
+ // src/api/index.ts
2
+ import axios from "../utils/request";
3
+ var businessGameInfoHighSecurityDecrypt = (data) => axios.post(
4
+ "/api/v3/business/game_info/high-security-decrypt?audience=/laas-pnt",
5
+ data
6
+ );
7
+ var businessSelectList = (data) => axios.post("/api/business/select/list", data);
8
+ export {
9
+ businessGameInfoHighSecurityDecrypt,
10
+ businessSelectList
11
+ };
@@ -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>[];
File without changes
@@ -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,228 @@
1
+ // src/components/PntBusinessSelect/index.tsx
2
+ import { businessSelectList } from "../../api";
3
+ import {
4
+ useCallback,
5
+ useEffect,
6
+ useMemo,
7
+ useRef,
8
+ useState
9
+ } from "react";
10
+ import { Loading, Select } from "tdesign-react";
11
+ import "./index.scss";
12
+ import { jsx } from "react/jsx-runtime";
13
+ var PntBusinessSelect = (props) => {
14
+ const {
15
+ value,
16
+ onChange,
17
+ multiple = false,
18
+ scene = "default",
19
+ statuses,
20
+ businessTypes,
21
+ businessAccessMethod,
22
+ labelFormat = "name",
23
+ placeholder,
24
+ disabled,
25
+ clearable = true,
26
+ filterable = true,
27
+ max,
28
+ pageSize = 20,
29
+ searchDebounce = 400,
30
+ minCollapsedNum,
31
+ collapsedItems,
32
+ popupProps,
33
+ className,
34
+ style
35
+ } = props;
36
+ const requestFn = useCallback(
37
+ (params) => businessSelectList(params),
38
+ []
39
+ );
40
+ const [options, setOptions] = useState(
41
+ []
42
+ );
43
+ const [loading, setLoading] = useState(false);
44
+ const [keyword, setKeyword] = useState("");
45
+ const [pageNum, setPageNum] = useState(1);
46
+ const [total, setTotal] = useState(0);
47
+ const debounceRef = useRef();
48
+ const loadingRef = useRef(false);
49
+ const selectedItemsRef = useRef(/* @__PURE__ */ new Map());
50
+ const buildParams = useCallback(
51
+ (kw, page) => ({
52
+ keyword: kw || void 0,
53
+ pageNum: page,
54
+ pageSize,
55
+ scene,
56
+ statuses,
57
+ business_types: businessTypes,
58
+ business_access_method: businessAccessMethod
59
+ }),
60
+ [scene, statuses, businessTypes, businessAccessMethod, pageSize]
61
+ );
62
+ const fetchData = useCallback(
63
+ async (kw, page, append) => {
64
+ var _a;
65
+ if (loadingRef.current)
66
+ return;
67
+ loadingRef.current = true;
68
+ setLoading(true);
69
+ try {
70
+ const res = await requestFn(buildParams(kw, page));
71
+ if (res.code === 0 && res.data) {
72
+ const newList = res.data.list || [];
73
+ setOptions((prev) => append ? [...prev, ...newList] : newList);
74
+ setTotal(((_a = res.data.pagination) == null ? void 0 : _a.total) || 0);
75
+ setPageNum(page);
76
+ }
77
+ } finally {
78
+ loadingRef.current = false;
79
+ setLoading(false);
80
+ }
81
+ },
82
+ [requestFn, buildParams]
83
+ );
84
+ const handleSearch = useCallback(
85
+ (val) => {
86
+ setKeyword(val);
87
+ if (debounceRef.current)
88
+ clearTimeout(debounceRef.current);
89
+ debounceRef.current = setTimeout(() => {
90
+ fetchData(val, 1, false);
91
+ }, searchDebounce);
92
+ },
93
+ [fetchData, searchDebounce]
94
+ );
95
+ const handleScrollToBottom = useCallback(() => {
96
+ if (!loadingRef.current && options.length < total) {
97
+ fetchData(keyword, pageNum + 1, true);
98
+ }
99
+ }, [options.length, total, keyword, pageNum, fetchData]);
100
+ const handlePopupVisibleChange = useCallback(
101
+ (visible) => {
102
+ if (!visible && keyword) {
103
+ setKeyword("");
104
+ fetchData("", 1, false);
105
+ }
106
+ },
107
+ [keyword, fetchData]
108
+ );
109
+ useEffect(() => {
110
+ fetchData("", 1, false);
111
+ }, [fetchData]);
112
+ useEffect(() => {
113
+ const selectedValues = Array.isArray(value) ? value : value ? [value] : [];
114
+ options.forEach((item) => {
115
+ if (item.game_id && selectedValues.includes(item.game_id)) {
116
+ selectedItemsRef.current.set(item.game_id, item);
117
+ }
118
+ });
119
+ }, [options, value]);
120
+ useEffect(() => {
121
+ return () => {
122
+ if (debounceRef.current)
123
+ clearTimeout(debounceRef.current);
124
+ };
125
+ }, []);
126
+ const formatLabel = useCallback(
127
+ (item) => {
128
+ const name = item.name || "";
129
+ const nameEn = item.name_en || "";
130
+ const gameId = item.game_id || "";
131
+ switch (labelFormat) {
132
+ case "name_en":
133
+ return nameEn || name;
134
+ case "name_id":
135
+ return `${name}(${gameId})`;
136
+ case "name_en_id":
137
+ return `${nameEn}(${gameId})`;
138
+ default:
139
+ return name;
140
+ }
141
+ },
142
+ [labelFormat]
143
+ );
144
+ const isOptionDisabled = useCallback(
145
+ (item) => {
146
+ if (scene === "compliance_age" || scene === "custom_region") {
147
+ return !item.creatable;
148
+ }
149
+ return false;
150
+ },
151
+ [scene]
152
+ );
153
+ const selectOptions = useMemo(() => {
154
+ const map = /* @__PURE__ */ new Map();
155
+ options.forEach((item) => {
156
+ if (item.game_id) {
157
+ map.set(item.game_id, {
158
+ label: formatLabel(item),
159
+ value: item.game_id,
160
+ disabled: isOptionDisabled(item),
161
+ name: item.name,
162
+ name_en: item.name_en,
163
+ game_id: item.game_id
164
+ });
165
+ }
166
+ });
167
+ const selectedValues = Array.isArray(value) ? value : value ? [value] : [];
168
+ selectedValues.forEach((id) => {
169
+ if (!map.has(id)) {
170
+ const item = selectedItemsRef.current.get(id);
171
+ if (item) {
172
+ map.set(id, {
173
+ label: formatLabel(item),
174
+ value: id,
175
+ disabled: isOptionDisabled(item),
176
+ name: item.name,
177
+ name_en: item.name_en,
178
+ game_id: item.game_id
179
+ });
180
+ } else {
181
+ map.set(id, { label: id, value: id, disabled: false });
182
+ }
183
+ }
184
+ });
185
+ return Array.from(map.values());
186
+ }, [options, value, formatLabel, isOptionDisabled]);
187
+ const localFilter = useCallback(
188
+ (filterWord, option) => {
189
+ if (!filterWord)
190
+ return true;
191
+ const kw = filterWord.toLowerCase();
192
+ const opt = option;
193
+ 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);
194
+ },
195
+ []
196
+ );
197
+ return /* @__PURE__ */ jsx(
198
+ Select,
199
+ {
200
+ value,
201
+ onChange,
202
+ options: selectOptions,
203
+ filterable,
204
+ filter: filterable ? localFilter : void 0,
205
+ onSearch: filterable ? handleSearch : void 0,
206
+ loading: loading && options.length === 0,
207
+ multiple,
208
+ max,
209
+ clearable,
210
+ disabled,
211
+ placeholder,
212
+ minCollapsedNum,
213
+ collapsedItems,
214
+ onPopupVisibleChange: handlePopupVisibleChange,
215
+ panelBottomContent: options.length > 0 && loading ? /* @__PURE__ */ jsx(Loading, { loading: true, size: "small" }) : null,
216
+ popupProps: {
217
+ ...popupProps,
218
+ onScrollToBottom: handleScrollToBottom
219
+ },
220
+ className: className ? `pnt-business-select ${className}` : "pnt-business-select",
221
+ style
222
+ }
223
+ );
224
+ };
225
+ var PntBusinessSelect_default = PntBusinessSelect;
226
+ export {
227
+ PntBusinessSelect_default as default
228
+ };
@@ -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
  * />
@@ -1,7 +1,6 @@
1
1
  // src/components/PntSecureBox/index.tsx
2
- import {
3
- useHighSecurity
4
- } from "../../hooks/useHighSecurity";
2
+ import { businessGameInfoHighSecurityDecrypt } from "../../api";
3
+ import { useHighSecurity } from "../../hooks/useHighSecurity";
5
4
  import { isSecurityData } from "../../utils";
6
5
  import "./index.scss";
7
6
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
@@ -13,10 +12,9 @@ var PntSecureBox = (prop) => {
13
12
  gameId,
14
13
  renderDom,
15
14
  viewText,
16
- pageId,
17
- fetcher
15
+ pageId
18
16
  } = prop;
19
- const { securityData, requestSecurityData } = useHighSecurity(fetcher);
17
+ const { securityData, requestSecurityData } = useHighSecurity(businessGameInfoHighSecurityDecrypt);
20
18
  return /* @__PURE__ */ jsx("div", { className: "pnt-secure-box", children: /* @__PURE__ */ jsxs(Fragment, { children: [
21
19
  renderDom(
22
20
  isSecurityData(dataValue) ? securityData[dataKey] || "******" : dataValue