@pnt-team/pnt-component-frontend 0.0.36 → 0.0.39

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 (64) hide show
  1. package/lib/cjs/assets/css/tdesign-theme.css +584 -0
  2. package/lib/cjs/assets/images/uploadImg.png +0 -0
  3. package/lib/cjs/assets/svg/inputSearch.svg +4 -0
  4. package/lib/cjs/assets/svg/inputTip.svg +5 -0
  5. package/lib/cjs/assets/svg/inputWarnTip.svg +5 -0
  6. package/lib/cjs/components/PntCopyData/index.d.ts +91 -0
  7. package/lib/cjs/components/PntCopyData/index.js +81 -0
  8. package/lib/cjs/components/PntCopyData/index.scss +5 -0
  9. package/lib/cjs/components/PntImagePreview/index.d.ts +75 -0
  10. package/lib/cjs/components/PntImagePreview/index.js +91 -0
  11. package/lib/cjs/components/PntImagePreview/index.scss +54 -0
  12. package/lib/cjs/components/PntSecureBox/index.d.ts +80 -0
  13. package/lib/cjs/components/PntSecureBox/index.js +74 -0
  14. package/lib/cjs/components/PntSecureBox/index.scss +19 -0
  15. package/lib/cjs/global.d.ts +30 -0
  16. package/lib/cjs/hooks/useBtnPermission.d.ts +67 -0
  17. package/lib/cjs/hooks/useBtnPermission.js +57 -0
  18. package/lib/cjs/hooks/useHighSecurity.d.ts +48 -0
  19. package/lib/cjs/hooks/useHighSecurity.js +64 -0
  20. package/lib/cjs/hooks/useOsPlatformList.d.ts +66 -0
  21. package/lib/cjs/hooks/useOsPlatformList.js +88 -0
  22. package/lib/cjs/hooks/usePagination.d.ts +72 -0
  23. package/lib/cjs/hooks/usePagination.js +71 -0
  24. package/lib/cjs/index.d.ts +10 -0
  25. package/lib/cjs/utils/const.d.ts +13 -0
  26. package/lib/cjs/utils/const.js +51 -0
  27. package/lib/cjs/utils/index.d.ts +6 -0
  28. package/lib/cjs/utils/index.js +43 -0
  29. package/lib/cjs/utils/request.d.ts +8 -0
  30. package/lib/cjs/utils/request.js +82 -0
  31. package/lib/esm/assets/css/tdesign-theme.css +584 -0
  32. package/lib/esm/assets/images/uploadImg.png +0 -0
  33. package/lib/esm/assets/svg/inputSearch.svg +4 -0
  34. package/lib/esm/assets/svg/inputTip.svg +5 -0
  35. package/lib/esm/assets/svg/inputWarnTip.svg +5 -0
  36. package/lib/esm/components/PntCopyData/index.d.ts +91 -0
  37. package/lib/esm/components/PntCopyData/index.js +51 -0
  38. package/lib/esm/components/PntCopyData/index.scss +5 -0
  39. package/lib/esm/components/PntImagePreview/index.d.ts +75 -0
  40. package/lib/esm/components/PntImagePreview/index.js +61 -0
  41. package/lib/esm/components/PntImagePreview/index.scss +54 -0
  42. package/lib/esm/components/PntSecureBox/index.d.ts +80 -0
  43. package/lib/esm/components/PntSecureBox/index.js +46 -0
  44. package/lib/esm/components/PntSecureBox/index.scss +19 -0
  45. package/lib/esm/global.d.ts +30 -0
  46. package/lib/esm/hooks/useBtnPermission.d.ts +67 -0
  47. package/lib/esm/hooks/useBtnPermission.js +31 -0
  48. package/lib/esm/hooks/useHighSecurity.d.ts +48 -0
  49. package/lib/esm/hooks/useHighSecurity.js +40 -0
  50. package/lib/esm/hooks/useOsPlatformList.d.ts +66 -0
  51. package/lib/esm/hooks/useOsPlatformList.js +63 -0
  52. package/lib/esm/hooks/usePagination.d.ts +72 -0
  53. package/lib/esm/hooks/usePagination.js +47 -0
  54. package/lib/esm/index.d.ts +10 -0
  55. package/lib/esm/index.js +17 -0
  56. package/lib/esm/utils/const.d.ts +13 -0
  57. package/lib/esm/utils/const.js +26 -0
  58. package/lib/esm/utils/index.d.ts +6 -0
  59. package/lib/esm/utils/index.js +19 -0
  60. package/lib/esm/utils/request.d.ts +8 -0
  61. package/lib/esm/utils/request.js +52 -0
  62. package/lib/umd/pnt-component-frontend.min.css +1 -0
  63. package/lib/umd/pnt-component-frontend.min.js +1 -0
  64. package/package.json +13 -8
@@ -0,0 +1,51 @@
1
+ // src/components/PntCopyData/index.tsx
2
+ import React, { useState } from "react";
3
+ import { Popup } from "tdesign-react";
4
+ import "./index.scss";
5
+ var PntCopyData = (props) => {
6
+ const { data, className, contentFn, placement, tips } = props;
7
+ const [isCopy, setIsCopy] = useState(false);
8
+ const [isFail, setIsFail] = useState(false);
9
+ const copyDataToClipboard = async () => {
10
+ const text = typeof data === "string" ? data : await data();
11
+ if (!text) {
12
+ return setIsFail(true);
13
+ }
14
+ if (navigator.clipboard && window.isSecureContext) {
15
+ navigator.clipboard.writeText(text);
16
+ setIsCopy(true);
17
+ } else {
18
+ const textArea = document.createElement("textarea");
19
+ textArea.value = text;
20
+ document.body.appendChild(textArea);
21
+ textArea.focus();
22
+ textArea.select();
23
+ document.execCommand("copy") && setIsCopy(true);
24
+ textArea.remove();
25
+ }
26
+ };
27
+ return /* @__PURE__ */ React.createElement(
28
+ Popup,
29
+ {
30
+ overlayClassName: `pnt-copy-data-popup${className ? " " + className : ""}`,
31
+ placement,
32
+ content: tips(isCopy, isFail),
33
+ visible: isCopy || isFail
34
+ },
35
+ contentFn({
36
+ onClick: () => {
37
+ copyDataToClipboard();
38
+ },
39
+ onMouseLeave: () => {
40
+ setTimeout(() => {
41
+ setIsCopy(false);
42
+ setIsFail(false);
43
+ }, 200);
44
+ }
45
+ })
46
+ );
47
+ };
48
+ var PntCopyData_default = PntCopyData;
49
+ export {
50
+ PntCopyData_default as default
51
+ };
@@ -0,0 +1,5 @@
1
+ .pnt-copy-data-popup {
2
+ .t-popup__content {
3
+ white-space: pre-wrap;
4
+ }
5
+ }
@@ -0,0 +1,75 @@
1
+ import React, { FC } from 'react';
2
+ import './index.scss';
3
+ interface PntImagePreviewProps {
4
+ /**
5
+ * 当前图片组件 URL
6
+ * @description 图片的完整 URL 地址,用于显示已上传的图片
7
+ */
8
+ iconUrl: string | undefined;
9
+ /**
10
+ * 上传加载状态
11
+ * @description 当为 true 时显示上传加载状态,阻止其他操作
12
+ */
13
+ loading: boolean;
14
+ /**
15
+ * 默认图片
16
+ * @description 支持传入默认封面图片,不传入则使用默认的 uploadImg 作为默认图片
17
+ */
18
+ defaultImg?: string;
19
+ /**
20
+ * 自定义扩展参数
21
+ * @description 用于传递额外的配置选项,如样式等
22
+ */
23
+ params?: {
24
+ /** 自定义样式 */
25
+ style?: React.CSSProperties;
26
+ /** 其他可扩展配置 */
27
+ [key: string]: any;
28
+ };
29
+ /**
30
+ * 删除回调函数
31
+ * @description 当点击删除图标时触发的回调函数
32
+ * @param e - 事件对象
33
+ */
34
+ onRemove?: (e: any) => void;
35
+ }
36
+ /**
37
+ * 上传图片查看器组件
38
+ * @description 用于展示上传的图片,支持预览、删除功能和上传状态显示
39
+ * @param {PntImagePreviewProps} props - 组件属性
40
+ * @param {string | undefined} props.iconUrl - 当前图片组件 URL
41
+ * @param {boolean} props.loading - 上传加载状态
42
+ * @param {string} [props.defaultImg] - 默认图片
43
+ * @param {object} [props.params] - 自定义扩展参数
44
+ * @param {function} [props.onRemove] - 删除回调函数
45
+ *
46
+ * @example
47
+ * ```tsx
48
+ * // 基础用法
49
+ * <UploadImageViewer
50
+ * iconUrl={imageUrl}
51
+ * loading={uploading}
52
+ * onRemove={handleRemove}
53
+ * />
54
+ *
55
+ * // 带默认图片
56
+ * <UploadImageViewer
57
+ * iconUrl={imageUrl}
58
+ * loading={false}
59
+ * defaultImg="/path/to/default.png"
60
+ * onRemove={handleRemove}
61
+ * />
62
+ *
63
+ * // 自定义样式
64
+ * <UploadImageViewer
65
+ * iconUrl={imageUrl}
66
+ * loading={uploading}
67
+ * params={{ style: { width: '200px', height: '200px' } }}
68
+ * onRemove={handleRemove}
69
+ * />
70
+ * ```
71
+ *
72
+ * @returns {ReactElement} 上传图片查看器组件
73
+ */
74
+ declare const PntImagePreview: FC<PntImagePreviewProps>;
75
+ export default PntImagePreview;
@@ -0,0 +1,61 @@
1
+ // src/components/PntImagePreview/index.tsx
2
+ import uploadImg from "../../assets/images/uploadImg.png";
3
+ import React from "react";
4
+ import { BrowseIcon, DeleteIcon, LoadingIcon } from "tdesign-icons-react";
5
+ import { Image, ImageViewer } from "tdesign-react";
6
+ import "./index.scss";
7
+ var PntImagePreview = ({
8
+ iconUrl,
9
+ loading,
10
+ defaultImg,
11
+ params,
12
+ onRemove
13
+ }) => {
14
+ const src = (iconUrl == null ? void 0 : iconUrl.length) ? iconUrl : defaultImg || uploadImg;
15
+ const LoadingContent = (isImageLoading) => /* @__PURE__ */ React.createElement(
16
+ "div",
17
+ {
18
+ className: isImageLoading ? "pnt-image-preview-progress" : "pnt-image-preview-upload-progress",
19
+ style: params == null ? void 0 : params.style
20
+ },
21
+ /* @__PURE__ */ React.createElement("div", { className: "pnt-image-preview-loading" }, /* @__PURE__ */ React.createElement(LoadingIcon, { size: "18px", name: "loading" }), /* @__PURE__ */ React.createElement("p", null, "上传中"))
22
+ );
23
+ return /* @__PURE__ */ React.createElement(
24
+ "div",
25
+ {
26
+ className: "pnt-image-preview-wrapper",
27
+ onClick: (e) => {
28
+ if ((iconUrl == null ? void 0 : iconUrl.length) || loading) {
29
+ e.stopPropagation();
30
+ }
31
+ }
32
+ },
33
+ loading ? LoadingContent(false) : /* @__PURE__ */ React.createElement(
34
+ ImageViewer,
35
+ {
36
+ images: [src],
37
+ closeOnOverlay: true,
38
+ trigger: ({ open }) => {
39
+ const mask = /* @__PURE__ */ React.createElement("div", { className: "pnt-image-preview-mask" }, /* @__PURE__ */ React.createElement("span", null, /* @__PURE__ */ React.createElement(BrowseIcon, { onClick: open, size: "16px", name: "browse" })), /* @__PURE__ */ React.createElement("span", { className: "pnt-image-preview-divider" }), /* @__PURE__ */ React.createElement("span", null, /* @__PURE__ */ React.createElement(DeleteIcon, { onClick: onRemove, size: "16px", name: "delete" })));
40
+ return /* @__PURE__ */ React.createElement(
41
+ Image,
42
+ {
43
+ alt: "",
44
+ src,
45
+ loading: LoadingContent(true),
46
+ overlayContent: iconUrl ? mask : /* @__PURE__ */ React.createElement(React.Fragment, null),
47
+ overlayTrigger: "hover",
48
+ fit: "contain",
49
+ className: "pnt-image-preview",
50
+ style: params == null ? void 0 : params.style
51
+ }
52
+ );
53
+ }
54
+ }
55
+ )
56
+ );
57
+ };
58
+ var PntImagePreview_default = PntImagePreview;
59
+ export {
60
+ PntImagePreview_default as default
61
+ };
@@ -0,0 +1,54 @@
1
+ .pnt-image-preview-wrapper {
2
+ position: relative;
3
+
4
+ .pnt-image-preview-progress,
5
+ .pnt-image-preview-upload-progress {
6
+ width: 136px;
7
+ height: 136px;
8
+ display: flex;
9
+ align-items: center;
10
+ justify-content: center;
11
+
12
+ .pnt-image-preview-loading {
13
+ width: 100%;
14
+ height: 100%;
15
+ text-align: center;
16
+ display: flex;
17
+ align-items: center;
18
+ justify-content: center;
19
+ flex-direction: column;
20
+ border-radius: 4px;
21
+ background-color: #f7f8fa;
22
+
23
+ svg {
24
+ color: var(--td-brand-color);
25
+ font-size: 24px;
26
+ }
27
+
28
+ p {
29
+ margin-top: 4px;
30
+ color: #808191;
31
+ font-size: 12px;
32
+ }
33
+ }
34
+ }
35
+
36
+ .pnt-image-preview {
37
+ width: 136px;
38
+ height: 136px;
39
+
40
+ .pnt-image-preview-mask {
41
+ background: rgba(0, 0, 0, 60%);
42
+ color: #fff;
43
+ height: 100%;
44
+ display: flex;
45
+ align-items: center;
46
+ justify-content: center;
47
+ .pnt-image-preview-divider {
48
+ margin: 0 var(--td-comp-margin-l);
49
+ border-left: 1px var(--td-text-color-anti) solid;
50
+ height: var(--td-comp-size-xxxs);
51
+ }
52
+ }
53
+ }
54
+ }
@@ -0,0 +1,80 @@
1
+ import { type HighSecurityFetcher } from "../../hooks/useHighSecurity";
2
+ import React, { FC } from 'react';
3
+ import './index.scss';
4
+ interface PntSecureBoxProps {
5
+ /**
6
+ * 高敏信息的唯一标识 key
7
+ * @description 用于标识和存储特定的高敏数据项
8
+ */
9
+ dataKey: string;
10
+ /**
11
+ * 高敏信息的实际值
12
+ * @description 初始显示的值,通常为脱敏后的数据
13
+ */
14
+ dataValue: string;
15
+ /**
16
+ * 环境标识
17
+ * @description 用于区分不同环境(如:dev, test, production)
18
+ */
19
+ env: string | number;
20
+ /**
21
+ * 游戏 ID
22
+ * @description 标识具体的游戏项目
23
+ */
24
+ gameId: string | number;
25
+ /**
26
+ * 自定义渲染函数
27
+ * @description 接收处理后的数据作为参数,返回需要渲染的 React 元素
28
+ * @param content - 处理后的数据内容(真实数据或脱敏数据)
29
+ * @returns React 元素
30
+ */
31
+ renderDom: (content: string) => React.ReactNode;
32
+ /**
33
+ * 自定义查看按钮文案
34
+ * @description 用于适配多语言场景,默认为 'View'
35
+ */
36
+ viewText?: string;
37
+ /**
38
+ * 页面 ID
39
+ * @description 用于记录操作日志和权限验证
40
+ */
41
+ pageId?: string;
42
+ /**
43
+ * 高敏数据请求函数
44
+ * @description 通过外部注入请求函数,避免组件库内部依赖敏感配置
45
+ */
46
+ fetcher: HighSecurityFetcher;
47
+ }
48
+ /**
49
+ * 高敏信息展示统一组件
50
+ * @description 用于统一处理和展示高敏信息,支持脱敏显示和按需获取真实数据
51
+ * @param {PntSecureBoxProps} props - 组件属性
52
+ * @param {string} props.dataKey - 高敏信息的唯一标识 key
53
+ * @param {string} props.dataValue - 高敏信息的实际值
54
+ * @param {string | number} props.env - 环境标识
55
+ * @param {string | number} props.gameId - 游戏 ID
56
+ * @param {(content: string) => React.ReactNode} props.renderDom - 自定义渲染函数
57
+ * @param {string} [props.viewText] - 自定义查看按钮文案
58
+ * @param {string} [props.pageId] - 页面 ID
59
+ * @param {HighSecurityFetcher} props.fetcher - 高敏数据请求函数
60
+ *
61
+ * @example
62
+ * ```tsx
63
+ * import http from '@/utils/request';
64
+ * import { PntSecureBox } from '@pnt-team/pnt-component-frontend';
65
+ *
66
+ * <PntSecureBox
67
+ * dataKey="userPhone"
68
+ * dataValue="138****8888"
69
+ * env="production"
70
+ * gameId={12345}
71
+ * fetcher={(params) => http.post('/api/v3/business/game_info/high-security-decrypt', params).then(r => r.data)}
72
+ * renderDom={(content) => <span>{content}</span>}
73
+ * viewText="查看"
74
+ * />
75
+ * ```
76
+ *
77
+ * @returns {ReactElement} 高敏信息展示组件
78
+ */
79
+ declare const PntSecureBox: FC<PntSecureBoxProps>;
80
+ export default PntSecureBox;
@@ -0,0 +1,46 @@
1
+ // src/components/PntSecureBox/index.tsx
2
+ import {
3
+ useHighSecurity
4
+ } from "../../hooks/useHighSecurity";
5
+ import { isSecurityData } from "../../utils";
6
+ import React from "react";
7
+ import "./index.scss";
8
+ var PntSecureBox = (prop) => {
9
+ const {
10
+ dataKey,
11
+ dataValue,
12
+ env,
13
+ gameId,
14
+ renderDom,
15
+ viewText,
16
+ pageId,
17
+ fetcher
18
+ } = prop;
19
+ const { securityData, requestSecurityData } = useHighSecurity(fetcher);
20
+ return /* @__PURE__ */ React.createElement("div", { className: "pnt-secure-box" }, /* @__PURE__ */ React.createElement(React.Fragment, null, renderDom(
21
+ isSecurityData(dataValue) ? securityData[dataKey] || "******" : dataValue
22
+ ), isSecurityData(dataValue) && !securityData.hasOwnProperty(dataKey) && /* @__PURE__ */ React.createElement(
23
+ "span",
24
+ {
25
+ className: "view-icon",
26
+ onClick: () => {
27
+ requestSecurityData({
28
+ env,
29
+ gameId,
30
+ pageId,
31
+ param: [
32
+ {
33
+ key: dataKey,
34
+ value: dataValue
35
+ }
36
+ ]
37
+ });
38
+ }
39
+ },
40
+ viewText || "View"
41
+ )));
42
+ };
43
+ var PntSecureBox_default = PntSecureBox;
44
+ export {
45
+ PntSecureBox_default as default
46
+ };
@@ -0,0 +1,19 @@
1
+ .pnt-secure-box {
2
+ position: relative;
3
+ color: #333;
4
+ max-width: fit-content;
5
+
6
+ .view-icon {
7
+ position: absolute;
8
+ top: 1px;
9
+ right: -30px;
10
+ color: #3f8cff !important;
11
+ cursor: pointer;
12
+ font-size: small;
13
+ }
14
+
15
+ .security-value {
16
+ position: relative;
17
+ top: 3px;
18
+ }
19
+ }
@@ -0,0 +1,30 @@
1
+ // src/global.d.ts
2
+ declare module '*.png' {
3
+ const src: string;
4
+ export default src;
5
+ }
6
+
7
+ declare module '*.jpg' {
8
+ const src: string;
9
+ export default src;
10
+ }
11
+
12
+ declare module '*.svg' {
13
+ const src: string;
14
+ export default src;
15
+ }
16
+
17
+ // 字体文件
18
+ declare module '*.woff' {
19
+ const src: string;
20
+ export default src;
21
+ }
22
+ declare module '*.woff2' {
23
+ const src: string;
24
+ export default src;
25
+ }
26
+
27
+ declare module '*.json' {
28
+ const value: any;
29
+ export default value;
30
+ }
@@ -0,0 +1,67 @@
1
+ /** 按钮权限值:1 有权限,-1 隐藏,-2 禁用 */
2
+ export type BtnPermissionValue = number;
3
+ /** 按钮权限映射:外层 key 为业务类型(全局为 'global' / 演示游戏为 '0' / 业务为具体 gameId / 兜底为 'no_permission_manner'),内层 key 为按钮标识符 */
4
+ export type BtnPermissionMap = Record<string, Record<string, BtnPermissionValue>>;
5
+ /** 演示游戏信息(来自用户信息,用于演示游戏判定) */
6
+ export interface DemoGameInfo {
7
+ id: number | string;
8
+ name: string;
9
+ }
10
+ /** 当前服务信息(与 demoGame 比对判断是否演示游戏) */
11
+ export interface ServiceInfo {
12
+ serviceType?: number | string;
13
+ serviceName?: string;
14
+ }
15
+ export interface UseBtnPermissionOptions {
16
+ /**
17
+ * 按钮权限映射(原从全局 store 注入,现改为入参注入)。
18
+ * 未传或取不到值时按有权限(1)处理。
19
+ */
20
+ permissions?: BtnPermissionMap;
21
+ /** 演示游戏信息;与 serviceInfo 同时传入才启用演示游戏判定 */
22
+ demoGame?: DemoGameInfo;
23
+ /** 当前服务信息 */
24
+ serviceInfo?: ServiceInfo;
25
+ }
26
+ /** 演示游戏在权限映射中的业务类型 key */
27
+ export declare const DEMO_GAME_TYPE_KEY = "0";
28
+ /** 无权限兜底配置的业务类型 key */
29
+ export declare const NO_PERMISSION_MANNER_KEY = "no_permission_manner";
30
+ /**
31
+ * 按钮权限 Hook(L3 业务 Hook)
32
+ *
33
+ * 融合 account-business-frontend 与 pnt-internal-tools-frontend 两版实现:
34
+ * - getBtnPermission(type, key):获取按钮处理方式,1 有权限 / -1 隐藏 / -2 禁用,
35
+ * 取不到值时依次回退到 no_permission_manner 兜底配置、defaultValue(默认 1);
36
+ * - 演示游戏(当前服务命中 demoGame)时固定使用 key '0' 的权限配置(account 版行为);
37
+ * - 零业务侵入:权限列表与演示游戏信息均通过入参注入,不再依赖 redux / umi / dva。
38
+ *
39
+ * @param options.permissions 按钮权限映射
40
+ * @param options.demoGame 演示游戏信息
41
+ * @param options.serviceInfo 当前服务信息
42
+ * @returns btnPermission 权限映射原文;isDemoGame 是否为演示游戏;getBtnPermission 获取按钮权限
43
+ *
44
+ * @example
45
+ * ```tsx
46
+ * import { useBtnPermission } from '@pnt/business-components';
47
+ *
48
+ * const Demo = ({ btnPermission, userInfo }) => {
49
+ * const { isDemoGame, getBtnPermission } = useBtnPermission({
50
+ * permissions: btnPermission, // 例如 { global: { create: 1 }, no_permission_manner: { create: -2 } }
51
+ * demoGame: userInfo?.demoGame, // 例如 { id: 11, name: 'DemoGame' }
52
+ * serviceInfo: { serviceType: userInfo?.serviceType, serviceName: userInfo?.serviceName },
53
+ * });
54
+ *
55
+ * const createPerm = getBtnPermission('global', 'create'); // 1 | -1 | -2
56
+ *
57
+ * if (createPerm === -1) return null; // 隐藏
58
+ * return <Button disabled={createPerm === -2}>新建{isDemoGame ? '(演示)' : ''}</Button>;
59
+ * };
60
+ * ```
61
+ */
62
+ export declare const useBtnPermission: (options?: UseBtnPermissionOptions) => {
63
+ btnPermission: BtnPermissionMap | undefined;
64
+ isDemoGame: boolean;
65
+ getBtnPermission: (type: string, key: string, defaultValue?: BtnPermissionValue) => BtnPermissionValue;
66
+ };
67
+ export default useBtnPermission;
@@ -0,0 +1,31 @@
1
+ // src/hooks/useBtnPermission.ts
2
+ import { useCallback, useMemo } from "react";
3
+ var DEMO_GAME_TYPE_KEY = "0";
4
+ var NO_PERMISSION_MANNER_KEY = "no_permission_manner";
5
+ var useBtnPermission = (options = {}) => {
6
+ const { permissions, demoGame, serviceInfo } = options;
7
+ const isDemoGame = useMemo(() => {
8
+ if (!demoGame || !serviceInfo)
9
+ return false;
10
+ return serviceInfo.serviceType === demoGame.id && serviceInfo.serviceName === demoGame.name;
11
+ }, [demoGame, serviceInfo]);
12
+ const getBtnPermission = useCallback(
13
+ (type, key, defaultValue = 1) => {
14
+ var _a, _b;
15
+ return ((_a = permissions == null ? void 0 : permissions[isDemoGame ? DEMO_GAME_TYPE_KEY : type]) == null ? void 0 : _a[key]) ?? ((_b = permissions == null ? void 0 : permissions[NO_PERMISSION_MANNER_KEY]) == null ? void 0 : _b[key]) ?? defaultValue ?? 1;
16
+ },
17
+ [permissions, isDemoGame]
18
+ );
19
+ return {
20
+ btnPermission: permissions,
21
+ isDemoGame,
22
+ getBtnPermission
23
+ };
24
+ };
25
+ var useBtnPermission_default = useBtnPermission;
26
+ export {
27
+ DEMO_GAME_TYPE_KEY,
28
+ NO_PERMISSION_MANNER_KEY,
29
+ useBtnPermission_default as default,
30
+ useBtnPermission
31
+ };
@@ -0,0 +1,48 @@
1
+ /** 高敏数据请求参数 */
2
+ export interface HighSecurityRequestParams {
3
+ /** 游戏 ID */
4
+ gameId: string | number;
5
+ /** 环境标识 */
6
+ env: string | number;
7
+ /** 页面 ID(不传则默认取 location.pathname) */
8
+ pageId?: string;
9
+ /** 需要解锁的参数列表 */
10
+ param: Array<{
11
+ key: string;
12
+ value: string;
13
+ }>;
14
+ }
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
+ }>;
23
+ /**
24
+ * 高敏数据解锁 Hook(L3 业务 Hook)
25
+ *
26
+ * 管理高敏数据的解锁状态。零业务侵入:请求函数通过 fetcher 注入,
27
+ * 不再依赖内部 api/configs,避免将敏感配置打包进发布产物。
28
+ *
29
+ * @param fetcher 自定义高敏数据请求函数,需返回 { ret, data } 结构且 ret === 0 视为成功
30
+ * @returns securityData 已解锁的高敏数据映射;requestSecurityData 请求解锁指定数据
31
+ *
32
+ * @example
33
+ * ```tsx
34
+ * import http from '@/utils/request';
35
+ * import { useHighSecurity } from '@pnt-team/pnt-component-frontend';
36
+ *
37
+ * const Demo = () => {
38
+ * const { securityData, requestSecurityData } = useHighSecurity((params) =>
39
+ * http.post('/api/v3/business/game_info/high-security-decrypt', params).then(r => r.data)
40
+ * );
41
+ * // ...
42
+ * };
43
+ * ```
44
+ */
45
+ export declare const useHighSecurity: (fetcher: HighSecurityFetcher) => {
46
+ securityData: Record<string, string>;
47
+ requestSecurityData: ({ gameId, param, env, pageId, }: HighSecurityRequestParams) => Promise<void>;
48
+ };
@@ -0,0 +1,40 @@
1
+ // src/hooks/useHighSecurity.ts
2
+ import { useState } from "react";
3
+ var securityCache = /* @__PURE__ */ new Map();
4
+ var useHighSecurity = (fetcher) => {
5
+ const [securityData, setSecurityData] = useState(
6
+ () => {
7
+ const cached = {};
8
+ securityCache.forEach((value, key) => {
9
+ cached[key] = value;
10
+ });
11
+ return cached;
12
+ }
13
+ );
14
+ const requestSecurityData = async ({
15
+ gameId,
16
+ param,
17
+ env,
18
+ pageId
19
+ }) => {
20
+ const result = await fetcher({
21
+ gameId,
22
+ env: Number(env),
23
+ pageId: pageId || location.pathname,
24
+ param
25
+ });
26
+ if (result.ret === 0 && result.data) {
27
+ result.data.forEach((item) => {
28
+ securityCache.set(item.key, item.value);
29
+ });
30
+ setSecurityData(Object.fromEntries(securityCache));
31
+ }
32
+ };
33
+ return {
34
+ securityData,
35
+ requestSecurityData
36
+ };
37
+ };
38
+ export {
39
+ useHighSecurity
40
+ };
@@ -0,0 +1,66 @@
1
+ /** OS 平台数据类型定义 */
2
+ export interface OsItem {
3
+ id: number;
4
+ os_name: string;
5
+ sdk_name: string;
6
+ status: number;
7
+ platform_id: number;
8
+ }
9
+ export interface PlatformItem {
10
+ id: number;
11
+ platform_name_zh: string;
12
+ platform_name_en: string;
13
+ status: number;
14
+ }
15
+ export interface OsPlatformData {
16
+ os_list: OsItem[];
17
+ platform_list: PlatformItem[];
18
+ }
19
+ /** OS/平台列表请求函数:返回 { code, msg, data } 结构且 code === 0 视为成功 */
20
+ export type OsPlatformFetcher = () => Promise<{
21
+ code: number;
22
+ msg: string;
23
+ data: OsPlatformData;
24
+ }>;
25
+ /**
26
+ * 清除缓存(用于极少数需要强制刷新的场景,如后台更新了平台列表后)。
27
+ * @param fetcher 指定要清除的 fetcher;不传则清除全部缓存
28
+ */
29
+ export declare const clearOsPlatformListCache: (fetcher?: OsPlatformFetcher) => void;
30
+ /**
31
+ * OS/平台列表 Hook(L3 业务 Hook)
32
+ *
33
+ * 拉取 OS 与平台枚举数据并做模块级缓存,整个会话只请求一次;
34
+ * 并发调用共享同一个进行中的请求。
35
+ *
36
+ * 零业务侵入:数据接口通过 fetcher 注入,不再依赖内部 request/configs,
37
+ * 避免将敏感配置打包进发布产物。
38
+ *
39
+ * @param fetcher 自定义请求函数,需返回 { code, msg, data } 结构且 code === 0 视为成功
40
+ * @returns osPlatformList OS/平台数据,请求完成或命中缓存前为 undefined
41
+ *
42
+ * @example
43
+ * ```tsx
44
+ * import http from '@/utils/request';
45
+ * import { useOsPlatformList } from '@pnt-team/pnt-component-frontend';
46
+ *
47
+ * const Demo = () => {
48
+ * const { osPlatformList } = useOsPlatformList(() =>
49
+ * http.get('/api/internal/business/manage/osPlatformList').then(r => r.data)
50
+ * );
51
+ *
52
+ * return (
53
+ * <Select
54
+ * options={osPlatformList?.platform_list.map((p) => ({
55
+ * label: p.platform_name_zh,
56
+ * value: p.id,
57
+ * }))}
58
+ * />
59
+ * );
60
+ * };
61
+ * ```
62
+ */
63
+ export declare const useOsPlatformList: (fetcher: OsPlatformFetcher) => {
64
+ osPlatformList: OsPlatformData | undefined;
65
+ };
66
+ export default useOsPlatformList;