@pnt-team/pnt-component-frontend 0.0.34 → 0.0.35

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 (2) hide show
  1. package/README.md +304 -21
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -1,34 +1,317 @@
1
- # pnt-component-frontend
1
+ # @pnt-team/pnt-component-frontend
2
2
 
3
- ## 项目说明
3
+ PNT 前端业务组件库,基于 [dumi2](https://d.umijs.org/) + [father4](https://github.com/umijs/father) 构建,收敛 PNT 业务项目中高价值的重复组件与 Hook,实现单一来源维护。
4
4
 
5
- ### 1. 项目介绍
5
+ ## 安装
6
6
 
7
- 本项目是基于 dumi2 构建的一款为 PNT 业务场景打造的业务组件库,旨在解决 PNT 项目开发中组件重复开发、风格不统一、兼容性差等问题,显著提升开发效率,降低维护成本。
7
+ ```bash
8
+ npm install @pnt-team/pnt-component-frontend
9
+ # 或
10
+ yarn add @pnt-team/pnt-component-frontend
11
+ ```
8
12
 
9
- ### 2. 快速体验
13
+ ### 依赖要求(peerDependencies)
10
14
 
11
- | 环境 | 地址 |
12
- | ---- | ---------------------------------------- |
13
- | 测试 | <http://component.pnt-dev.intlgame.com/> |
15
+ | 依赖 | 版本要求 | 说明 |
16
+ |------|---------|------|
17
+ | `react` | `>=16.9.0` | React 核心框架 |
18
+ | `react-dom` | `>=16.9.0` | React DOM 渲染 |
19
+ | `tdesign-react` | `>=1.5.0` | UI 组件库(本组件库基于 TDesign 封装) |
14
20
 
15
- ### 3. 技术选型
21
+ > ⚠️ 请确保项目中已安装以上依赖,否则组件可能无法正常运行。
16
22
 
17
- - [dumi2](https://d.umijs.org/docs/intro) 组件文档生成与开发调试工具
18
- - [React](https://react.dev/) 组件开发核心框架
19
- - [TypeScript](https://www.typescriptlang.org/) 类型安全保障
20
- - [Scss/CSS modules](https://lesscss.org/) 样式开发方案
21
- - [ESLint + Prettier](https://prettier.io/) 代码规范与格式化
23
+ ## 快速开始
22
24
 
23
- ### 4. 相关地址
25
+ ```tsx
26
+ import {
27
+ // 组件
28
+ PntCopyData,
29
+ PntImagePreview,
30
+ PntSecureBox,
31
+ // Hooks
32
+ usePagination,
33
+ useBtnPermission,
34
+ useHighSecurity,
35
+ useOsPlatformList,
36
+ } from '@pnt-team/pnt-component-frontend';
37
+ ```
24
38
 
25
- - [Git: 组件库仓库](https://git.tencent.com/pnt-web/playernetwork/frontend/pnt-component-frontend/tree/test)
26
- - [dumi2 官方文档](https://d.umijs.org/guide)
39
+ ## 组件一览
40
+
41
+ ### L1 基础展示组件
42
+
43
+ #### PntCopyData — 数据复制组件
44
+
45
+ 点击触发元素将数据复制到剪贴板,通过 Popup 气泡提示复制结果。优先使用 `navigator.clipboard`,非安全上下文自动降级为 `document.execCommand('copy')`。
46
+
47
+ **Props:**
48
+
49
+ | 属性 | 类型 | 必填 | 说明 |
50
+ |------|------|------|------|
51
+ | `data` | `string \| (() => Promise<string>)` | ✅ | 需要复制的数据,支持字符串或异步函数 |
52
+ | `tips` | `(isCopy: boolean, isFail: boolean) => ReactNode` | ✅ | 提示内容渲染函数 |
53
+ | `contentFn` | `(props: { onClick, onMouseLeave }) => ReactNode` | ✅ | 触发元素渲染函数 |
54
+ | `placement` | `PopupPlacement` | ❌ | Popup 弹出位置,默认由 TDesign 决定 |
55
+ | `className` | `string` | ❌ | 自定义类名 |
56
+
57
+ **示例:**
58
+
59
+ ```tsx
60
+ // 基础用法
61
+ <PntCopyData
62
+ data="这是一段需要复制的文本"
63
+ tips={(isCopy, isFail) => (isFail ? '复制失败' : '复制成功')}
64
+ contentFn={({ onClick, onMouseLeave }) => (
65
+ <Button onClick={onClick} onMouseLeave={onMouseLeave}>复制</Button>
66
+ )}
67
+ />
68
+
69
+ // 异步获取数据(如从接口获取密码)
70
+ <PntCopyData
71
+ data={async () => await fetchSecret()}
72
+ tips={(isCopy, isFail) => (isFail ? '获取失败' : '已复制到剪贴板')}
73
+ contentFn={({ onClick, onMouseLeave }) => (
74
+ <Link onClick={onClick} onMouseLeave={onMouseLeave}>查看密码</Link>
75
+ )}
76
+ />
77
+ ```
78
+
79
+ ---
80
+
81
+ #### PntImagePreview — 图片预览组件
82
+
83
+ 用于展示上传的图片,支持预览、删除功能和上传状态显示。
84
+
85
+ **Props:**
86
+
87
+ | 属性 | 类型 | 必填 | 说明 |
88
+ |------|------|------|------|
89
+ | `iconUrl` | `string \| undefined` | ✅ | 图片 URL 地址 |
90
+ | `loading` | `boolean` | ✅ | 上传加载状态 |
91
+ | `defaultImg` | `string` | ❌ | 默认图片(不传则使用内置默认图) |
92
+ | `params` | `{ style?: CSSProperties; [key: string]: any }` | ❌ | 自定义扩展参数 |
93
+ | `onRemove` | `(e: any) => void` | ❌ | 删除回调函数 |
94
+
95
+ **示例:**
96
+
97
+ ```tsx
98
+ <PntImagePreview
99
+ iconUrl={imageUrl}
100
+ loading={uploading}
101
+ defaultImg="/path/to/default.png"
102
+ params={{ style: { width: '200px', height: '200px' } }}
103
+ onRemove={handleRemove}
104
+ />
105
+ ```
106
+
107
+ ---
108
+
109
+ ### L2 业务复合组件
110
+
111
+ #### PntSecureBox — 高敏信息展示组件
112
+
113
+ 统一处理和展示高敏信息,支持脱敏显示和按需获取真实数据。内部集成 `useHighSecurity` Hook,通过接口解锁敏感数据。
114
+
115
+ **Props:**
116
+
117
+ | 属性 | 类型 | 必填 | 说明 |
118
+ |------|------|------|------|
119
+ | `dataKey` | `string` | ✅ | 高敏信息的唯一标识 key |
120
+ | `dataValue` | `string` | ✅ | 初始显示值(通常为脱敏后的数据) |
121
+ | `env` | `string \| number` | ✅ | 环境标识(如 dev / test / production) |
122
+ | `gameId` | `string \| number` | ✅ | 游戏 ID |
123
+ | `renderDom` | `(content: string) => React.ReactNode` | ✅ | 自定义渲染函数 |
124
+ | `viewText` | `string` | ❌ | 查看按钮文案,默认 `'View'` |
125
+ | `pageId` | `string` | ❌ | 页面 ID(用于操作日志和权限验证) |
126
+
127
+ **示例:**
128
+
129
+ ```tsx
130
+ <PntSecureBox
131
+ dataKey="userPhone"
132
+ dataValue="138****8888"
133
+ env="production"
134
+ gameId={12345}
135
+ renderDom={(content) => <span>{content}</span>}
136
+ viewText="查看"
137
+ />
138
+ ```
139
+
140
+ ---
141
+
142
+ ### L3 业务 Hooks
143
+
144
+ #### usePagination — 分页 Hook
145
+
146
+ 维护分页状态,页码/每页条数变化时通过回调通知外部发起请求。`totalCount` 为 0 时返回 `undefined`,可直接条件渲染 `<Pagination>`。
147
+
148
+ **参数:**
149
+
150
+ | 参数 | 类型 | 说明 |
151
+ |------|------|------|
152
+ | `onPaginationRequest` | `(params: { pageNumber, pageSize }) => void` | 分页变化时的回调,外部在此发起列表请求 |
153
+
154
+ **返回值:**
155
+
156
+ | 返回值 | 类型 | 说明 |
157
+ |--------|------|------|
158
+ | `paginationData` | `{ currentPage, totalCount, totalPage, pageSize }` | 当前分页数据 |
159
+ | `setPaginationData` | `(data: PaginationData) => void` | 回写分页数据(通常由外部请求完成后调用) |
160
+ | `paginationProps` | `PaginationProps \| undefined` | 可直接展开到 `<Pagination {...paginationProps} />` |
161
+
162
+ **示例:**
163
+
164
+ ```tsx
165
+ const Demo = () => {
166
+ const [list, setList] = useState([]);
167
+ const { paginationData, setPaginationData, paginationProps } = usePagination(
168
+ async ({ pageNumber, pageSize }) => {
169
+ const res = await fetchList({ page: pageNumber, size: pageSize });
170
+ setList(res.data.list);
171
+ setPaginationData((prev) => ({
172
+ ...prev,
173
+ currentPage: pageNumber,
174
+ pageSize,
175
+ totalCount: res.data.total,
176
+ totalPage: Math.ceil(res.data.total / pageSize),
177
+ }));
178
+ },
179
+ );
180
+
181
+ return (
182
+ <>
183
+ <Table data={list} />
184
+ {paginationProps && <Pagination {...paginationProps} />}
185
+ </>
186
+ );
187
+ };
188
+ ```
27
189
 
28
- ## 上手开发&发布流程
190
+ ---
29
191
 
30
- 详见:[CONTRIBUTING](./CONTRIBUTING.md)
192
+ #### useBtnPermission — 按钮权限 Hook
31
193
 
32
- ## 开发约定
194
+ 获取按钮权限处理方式,支持演示游戏判定和无权限兜底配置。零业务侵入:权限列表与演示游戏信息均通过入参注入。
33
195
 
34
- 详见:[CONVENTIONS](./CONVENTIONS.md)
196
+ **参数:**
197
+
198
+ | 参数 | 类型 | 说明 |
199
+ |------|------|------|
200
+ | `permissions` | `BtnPermissionMap` | 按钮权限映射 `{ [type]: { [key]: 1 \| -1 \| -2 } }` |
201
+ | `demoGame` | `{ id: number \| string; name: string }` | 演示游戏信息 |
202
+ | `serviceInfo` | `{ serviceType?, serviceName? }` | 当前服务信息 |
203
+
204
+ **返回值:**
205
+
206
+ | 返回值 | 类型 | 说明 |
207
+ |--------|------|------|
208
+ | `btnPermission` | `BtnPermissionMap` | 权限映射原文 |
209
+ | `isDemoGame` | `boolean` | 是否为演示游戏 |
210
+ | `getBtnPermission` | `(type, key, defaultValue?) => 1 \| -1 \| -2` | 获取按钮权限(1 有权限 / -1 隐藏 / -2 禁用) |
211
+
212
+ **示例:**
213
+
214
+ ```tsx
215
+ const Demo = ({ btnPermission, userInfo }) => {
216
+ const { isDemoGame, getBtnPermission } = useBtnPermission({
217
+ permissions: btnPermission,
218
+ demoGame: userInfo?.demoGame,
219
+ serviceInfo: { serviceType: userInfo?.serviceType, serviceName: userInfo?.serviceName },
220
+ });
221
+
222
+ const createPerm = getBtnPermission('global', 'create');
223
+ if (createPerm === -1) return null; // 隐藏
224
+ return <Button disabled={createPerm === -2}>新建{isDemoGame ? '(演示)' : ''}</Button>;
225
+ };
226
+ ```
227
+
228
+ ---
229
+
230
+ #### useHighSecurity — 高敏数据解锁 Hook
231
+
232
+ 管理高敏数据的解锁状态,通过接口请求获取真实数据。配合 `PntSecureBox` 组件使用。
233
+
234
+ **返回值:**
235
+
236
+ | 返回值 | 类型 | 说明 |
237
+ |--------|------|------|
238
+ | `securityData` | `object` | 已解锁的高敏数据映射 `{ [key]: value }` |
239
+ | `setSecurityData` | `(data: object) => void` | 手动设置已解锁数据 |
240
+ | `requestSecurityData` | `({ gameId, param, env }) => void` | 请求解锁指定高敏数据 |
241
+
242
+ ---
243
+
244
+ #### useOsPlatformList — OS/平台列表 Hook
245
+
246
+ 拉取 OS 与平台枚举数据并做模块级缓存,整个会话只请求一次,并发调用共享同一请求。
247
+
248
+ **参数:**
249
+
250
+ | 参数 | 类型 | 说明 |
251
+ |------|------|------|
252
+ | `fetcher` | `() => Promise<{ code, msg, data }>` | 自定义请求函数(不传则使用内置默认 fetcher) |
253
+
254
+ **返回值:**
255
+
256
+ | 返回值 | 类型 | 说明 |
257
+ |--------|------|------|
258
+ | `osPlatformList` | `{ os_list: OsItem[]; platform_list: PlatformItem[] } \| undefined` | OS/平台数据 |
259
+
260
+ **示例:**
261
+
262
+ ```tsx
263
+ // 使用默认 fetcher
264
+ const { osPlatformList } = useOsPlatformList();
265
+
266
+ // 注入自定义 fetcher
267
+ const { osPlatformList } = useOsPlatformList(() => http.get('/my/os/platform'));
268
+
269
+ // 渲染下拉选项
270
+ <Select
271
+ options={osPlatformList?.platform_list.map((p) => ({
272
+ label: p.platform_name_zh,
273
+ value: p.id,
274
+ }))}
275
+ />
276
+ ```
277
+
278
+ > 💡 如需强制刷新缓存,可调用 `clearOsPlatformListCache()` 清除全部缓存,或传入指定 fetcher 清除对应缓存。
279
+
280
+ ---
281
+
282
+ ## 本地开发
283
+
284
+ ```bash
285
+ # 克隆仓库 & 安装依赖
286
+ git clone <repo-url>
287
+ cd pnt-component-frontend
288
+ yarn install
289
+
290
+ # 启动文档开发服务器
291
+ yarn start
292
+
293
+ # 构建组件库(lib/ 目录)
294
+ yarn build
295
+
296
+ # 运行测试
297
+ yarn test
298
+ ```
299
+
300
+ > 📝 本地开发涉及接口调试时,需手动更新 `src/configs/token.ts` 中的 token 值。
301
+
302
+ ## 技术栈
303
+
304
+ | 工具 | 用途 |
305
+ |------|------|
306
+ | [father4](https://github.com/umijs/father) | 组件库构建(ESM / CJS / UMD) |
307
+ | [dumi2](https://d.umijs.org/) | 文档生成与开发调试 |
308
+ | [TDesign React](https://tdesign.tencent.com/react) | UI 组件库(peerDependency) |
309
+ | TypeScript | 类型安全 |
310
+ | Sass | 样式方案 |
311
+ | Jest | 单元测试 |
312
+
313
+ ## 相关资源
314
+
315
+ - [Git 仓库](https://git.tencent.com/pnt-web/playernetwork/frontend/pnt-component-frontend/tree/test)
316
+ - [dumi2 官方文档](https://d.umijs.org/guide)
317
+ - [father 官方文档](https://github.com/umijs/father/blob/master/docs/config.md)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pnt-team/pnt-component-frontend",
3
- "version": "0.0.34",
3
+ "version": "0.0.35",
4
4
  "description": "A react library developed with dumi",
5
5
  "license": "MIT",
6
6
  "main": "lib/cjs/index.js",