@pnt-team/pnt-component-frontend 0.0.91 → 0.0.95
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.
- package/README.md +149 -54
- package/lib/cjs/api/cos.d.ts +103 -0
- package/lib/cjs/api/cos.js +137 -0
- package/lib/cjs/components/PntCosUploader/index.d.ts +135 -0
- package/lib/cjs/components/PntCosUploader/index.js +209 -0
- package/lib/cjs/components/PntImage/index.d.ts +9 -3
- package/lib/cjs/components/PntImage/index.js +9 -1
- package/lib/cjs/components/PntSecureBox/index.js +8 -5
- package/lib/cjs/components/PntUpload/index.d.ts +149 -0
- package/lib/cjs/components/PntUpload/index.js +228 -0
- package/lib/cjs/components/PntUpload/index.scss +101 -0
- package/lib/cjs/hooks/useHighSecurity.d.ts +55 -15
- package/lib/cjs/hooks/useHighSecurity.js +168 -35
- package/lib/cjs/index.d.ts +6 -0
- package/lib/cjs/index.js +18 -2
- package/lib/esm/api/cos.d.ts +103 -0
- package/lib/esm/api/cos.js +189 -0
- package/lib/esm/components/PntCosUploader/index.d.ts +135 -0
- package/lib/esm/components/PntCosUploader/index.js +289 -0
- package/lib/esm/components/PntImage/index.d.ts +9 -3
- package/lib/esm/components/PntImage/index.js +22 -3
- package/lib/esm/components/PntSecureBox/index.js +9 -3
- package/lib/esm/components/PntUpload/index.d.ts +149 -0
- package/lib/esm/components/PntUpload/index.js +276 -0
- package/lib/esm/components/PntUpload/index.scss +101 -0
- package/lib/esm/hooks/useHighSecurity.d.ts +55 -15
- package/lib/esm/hooks/useHighSecurity.js +174 -32
- package/lib/esm/index.d.ts +6 -0
- package/lib/esm/index.js +9 -1
- package/lib/umd/pnt-component-frontend.min.css +1 -1
- package/lib/umd/pnt-component-frontend.min.js +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import { type CosScene, type GetCosCredentialParams, type NormalizeCredential, type NormalizedCosCredential } from "../../api/cos";
|
|
2
|
+
import { usePntConfig } from "../../config";
|
|
3
|
+
import type { AxiosInstance } from 'axios';
|
|
4
|
+
/**
|
|
5
|
+
* 文件名生成策略
|
|
6
|
+
* @description 内置三种策略;如需自定义可传函数
|
|
7
|
+
* - uuid: UUID v4 + 原扩展名(默认,最简单)
|
|
8
|
+
* - md5: 文件内容 MD5 + 原扩展名(与 pnt-tools CosApi 原策略一致)
|
|
9
|
+
* - timestamp: 时间戳(36进制)+自增计数器 + 原扩展名(与 SDK 定制场景原策略一致)
|
|
10
|
+
*/
|
|
11
|
+
export type FileNameStrategy = 'uuid' | 'md5' | 'timestamp' | ((file: File) => string | Promise<string>);
|
|
12
|
+
/**
|
|
13
|
+
* COS 上传配置
|
|
14
|
+
*/
|
|
15
|
+
export interface PntCosUploadOptions {
|
|
16
|
+
/**
|
|
17
|
+
* 业务场景,决定走哪个凭证接口
|
|
18
|
+
* @description 内置 4 个 scene,消费方可传 string 自定义并配合 getCredential 使用
|
|
19
|
+
*/
|
|
20
|
+
scene: CosScene;
|
|
21
|
+
/**
|
|
22
|
+
* 业务类型路径 key
|
|
23
|
+
* @description 通用场景透传给后端 path map 选取对应业务路径;
|
|
24
|
+
* sdk_customize 场景作为受控目录(filePath)下的子目录继续拼接
|
|
25
|
+
*/
|
|
26
|
+
pathKey?: string;
|
|
27
|
+
/**
|
|
28
|
+
* 业务上下文参数(gameId/env/updType 等)
|
|
29
|
+
* @description 按 scene 不同传递给后端;default/default_download 下 gameId 自动映射到 x-service-type 请求头
|
|
30
|
+
*/
|
|
31
|
+
context?: Record<string, string | number>;
|
|
32
|
+
/**
|
|
33
|
+
* 网关 audience
|
|
34
|
+
* @default '/player-network'
|
|
35
|
+
* @description 账号管理等子系统需覆盖为对应 audience(如 '/laas-pnt')
|
|
36
|
+
*/
|
|
37
|
+
audience?: string;
|
|
38
|
+
/**
|
|
39
|
+
* 文件名生成策略
|
|
40
|
+
* @default 'uuid'
|
|
41
|
+
*/
|
|
42
|
+
fileNameStrategy?: FileNameStrategy;
|
|
43
|
+
/**
|
|
44
|
+
* 是否走 CDN 域名拼接
|
|
45
|
+
* @description true 且凭证返回 cosHost 时用 cosHost + cosKey;否则用 COS putObject 返回的 Location
|
|
46
|
+
* @default true
|
|
47
|
+
*/
|
|
48
|
+
useCdn?: boolean;
|
|
49
|
+
/**
|
|
50
|
+
* 自定义凭证获取函数(覆盖内置 scene 路由)
|
|
51
|
+
* @description 后端接口非内置 scene 时使用;返回归一化后的凭证
|
|
52
|
+
*/
|
|
53
|
+
getCredential?: (http: ReturnType<typeof usePntConfig>['http'], params: GetCosCredentialParams) => Promise<NormalizedCosCredential>;
|
|
54
|
+
/**
|
|
55
|
+
* 自定义凭证响应归一化
|
|
56
|
+
* @description 后端字段不标准时使用;入参为内置 scene 接口返回的原始 data,需返回归一化凭证
|
|
57
|
+
*/
|
|
58
|
+
normalizeCredential?: NormalizeCredential;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* COS 上传结果
|
|
62
|
+
*/
|
|
63
|
+
export interface PntCosUploadResult {
|
|
64
|
+
/** 上传后的可访问 URL */
|
|
65
|
+
fileUrl: string;
|
|
66
|
+
/** COS 对象 Key */
|
|
67
|
+
cosKey: string;
|
|
68
|
+
/** 原始文件名 */
|
|
69
|
+
fileName: string;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* 单次请求覆盖参数
|
|
73
|
+
* @description 上传/下载入口的 gameId/task_id/pathKey 常来自表单或表格行数据,
|
|
74
|
+
* 可通过该参数在单次调用覆盖 hook 初始化时的配置
|
|
75
|
+
*/
|
|
76
|
+
export interface PntCosRequestOverrides {
|
|
77
|
+
/** 覆盖业务上下文(与初始化 context 浅合并,如行级 gameId/task_id) */
|
|
78
|
+
context?: Record<string, string | number>;
|
|
79
|
+
/** 覆盖网关 audience */
|
|
80
|
+
audience?: string;
|
|
81
|
+
/** 覆盖凭证场景 */
|
|
82
|
+
scene?: CosScene;
|
|
83
|
+
/** 覆盖业务路径 key */
|
|
84
|
+
pathKey?: string;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* COS 上传器实例
|
|
88
|
+
*/
|
|
89
|
+
export interface PntCosUploader {
|
|
90
|
+
/**
|
|
91
|
+
* 上传文件到 COS
|
|
92
|
+
* @param file 原始文件
|
|
93
|
+
* @param onProgress 上传进度回调(0~100)
|
|
94
|
+
* @param overrides 单次调用覆盖配置(表单/行级 gameId 等)
|
|
95
|
+
*/
|
|
96
|
+
upload: (file: File, onProgress?: (percent: number) => void, overrides?: PntCosRequestOverrides) => Promise<PntCosUploadResult>;
|
|
97
|
+
/**
|
|
98
|
+
* 获取文件预签名下载 URL(临时)
|
|
99
|
+
* @param cosKey COS 对象 Key,或完整 URL(自动剥离域名)
|
|
100
|
+
* @param overrides 单次调用覆盖配置(行级 gameId/task_id 等)
|
|
101
|
+
*/
|
|
102
|
+
getDownloadUrl: (cosKey: string, overrides?: PntCosRequestOverrides) => Promise<string>;
|
|
103
|
+
}
|
|
104
|
+
export type { CosScene, GetCosCredentialParams, NormalizeCredential, NormalizedCosCredential, };
|
|
105
|
+
export { normalizeSnakeCredential } from "../../api/cos";
|
|
106
|
+
/**
|
|
107
|
+
* 创建 COS 直传器实例(不依赖 React)
|
|
108
|
+
* @description 与 usePntCosUploader 共用同一套核心逻辑,适用于 class 兼容层、
|
|
109
|
+
* 工具函数、非 React 入口等场景;React 组件请优先使用 usePntCosUploader
|
|
110
|
+
*
|
|
111
|
+
* @param http 消费方 axios 实例(约定响应拦截器已解包 response.data)
|
|
112
|
+
* @param options 上传配置(固定值),或返回配置的 getter(需要动态配置时使用)
|
|
113
|
+
*
|
|
114
|
+
* @example
|
|
115
|
+
* ```ts
|
|
116
|
+
* const uploader = createPntCosUploader(http, { scene: 'default', pathKey: 'marketing_icon' });
|
|
117
|
+
* const { fileUrl } = await uploader.upload(file);
|
|
118
|
+
* ```
|
|
119
|
+
*/
|
|
120
|
+
export declare const createPntCosUploader: (http: AxiosInstance, options: PntCosUploadOptions | (() => PntCosUploadOptions)) => PntCosUploader;
|
|
121
|
+
/**
|
|
122
|
+
* COS 直传 Service Hook
|
|
123
|
+
* @description 内置凭证获取 + COS SDK 初始化 + 文件名策略 + URL 拼接,
|
|
124
|
+
* 收敛各项目重复的 4 份自实现;http 实例由 PntProvider 注入
|
|
125
|
+
*
|
|
126
|
+
* @param options 上传配置
|
|
127
|
+
*
|
|
128
|
+
* @example
|
|
129
|
+
* ```ts
|
|
130
|
+
* const uploader = usePntCosUploader({ scene: 'default', pathKey: 'marketing_icon' });
|
|
131
|
+
* const { fileUrl, cosKey } = await uploader.upload(file, (p) => setProgress(p));
|
|
132
|
+
* ```
|
|
133
|
+
*/
|
|
134
|
+
export declare const usePntCosUploader: (options: PntCosUploadOptions) => PntCosUploader;
|
|
135
|
+
export default usePntCosUploader;
|
|
@@ -0,0 +1,209 @@
|
|
|
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/components/PntCosUploader/index.ts
|
|
30
|
+
var PntCosUploader_exports = {};
|
|
31
|
+
__export(PntCosUploader_exports, {
|
|
32
|
+
createPntCosUploader: () => createPntCosUploader,
|
|
33
|
+
default: () => PntCosUploader_default,
|
|
34
|
+
normalizeSnakeCredential: () => import_cos2.normalizeSnakeCredential,
|
|
35
|
+
usePntCosUploader: () => usePntCosUploader
|
|
36
|
+
});
|
|
37
|
+
module.exports = __toCommonJS(PntCosUploader_exports);
|
|
38
|
+
var import_cos = require("../../api/cos");
|
|
39
|
+
var import_config = require("../../config");
|
|
40
|
+
var import_cos_js_sdk_v5 = __toESM(require("cos-js-sdk-v5"));
|
|
41
|
+
var import_crypto_js = __toESM(require("crypto-js"));
|
|
42
|
+
var import_react = require("react");
|
|
43
|
+
var import_uuid = require("uuid");
|
|
44
|
+
var import_cos2 = require("../../api/cos");
|
|
45
|
+
var trimSlash = (seg, leading = true) => seg.replace(/\/$/, "").replace(leading ? /^\// : "", "");
|
|
46
|
+
var getFileExt = (filename) => {
|
|
47
|
+
const idx = filename.lastIndexOf(".");
|
|
48
|
+
return idx > -1 ? filename.slice(idx) : "";
|
|
49
|
+
};
|
|
50
|
+
var _timestampCounter = 0;
|
|
51
|
+
var generateTimestampName = () => `${Date.now().toString(36)}${(_timestampCounter++).toString(36)}`;
|
|
52
|
+
var computeFileMd5 = async (file) => {
|
|
53
|
+
const buffer = await file.arrayBuffer();
|
|
54
|
+
return import_crypto_js.default.MD5(import_crypto_js.default.lib.WordArray.create(buffer)).toString();
|
|
55
|
+
};
|
|
56
|
+
var generateFileName = async (file, strategy) => {
|
|
57
|
+
if (typeof strategy === "function") {
|
|
58
|
+
return strategy(file);
|
|
59
|
+
}
|
|
60
|
+
const ext = getFileExt(file.name);
|
|
61
|
+
switch (strategy) {
|
|
62
|
+
case "md5": {
|
|
63
|
+
const md5 = await computeFileMd5(file);
|
|
64
|
+
return `${md5}${ext}`;
|
|
65
|
+
}
|
|
66
|
+
case "timestamp":
|
|
67
|
+
return `${generateTimestampName()}${ext}`;
|
|
68
|
+
case "uuid":
|
|
69
|
+
default:
|
|
70
|
+
return `${(0, import_uuid.v4)()}${ext}`;
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
var resolveBasePath = (cred, pathKey) => {
|
|
74
|
+
if (cred.filePath) {
|
|
75
|
+
const prefix = cred.filePath.replace(/\/$/, "");
|
|
76
|
+
return pathKey ? `${prefix}/${trimSlash(pathKey)}` : prefix;
|
|
77
|
+
}
|
|
78
|
+
if (pathKey && cred.path) {
|
|
79
|
+
return cred.path[pathKey] || "";
|
|
80
|
+
}
|
|
81
|
+
return "";
|
|
82
|
+
};
|
|
83
|
+
var stripHost = (key) => key.replace(/^https?:\/\/[^/]+/, "");
|
|
84
|
+
var createCosClient = (cred) => new import_cos_js_sdk_v5.default({
|
|
85
|
+
getAuthorization: (_, callback) => {
|
|
86
|
+
callback({
|
|
87
|
+
TmpSecretId: cred.secretId,
|
|
88
|
+
TmpSecretKey: cred.secretKey,
|
|
89
|
+
SecurityToken: cred.sessionToken,
|
|
90
|
+
StartTime: cred.startTime,
|
|
91
|
+
ExpiredTime: cred.expiredTime
|
|
92
|
+
});
|
|
93
|
+
},
|
|
94
|
+
Protocol: "https:",
|
|
95
|
+
FileParallelLimit: 3,
|
|
96
|
+
ChunkParallelLimit: 3,
|
|
97
|
+
ChunkSize: 1024 * 1024,
|
|
98
|
+
ProgressInterval: 1
|
|
99
|
+
});
|
|
100
|
+
var createPntCosUploader = (http, options) => {
|
|
101
|
+
const getOptions = () => typeof options === "function" ? options() : options;
|
|
102
|
+
const upload = async (file, onProgress, overrides) => {
|
|
103
|
+
var _a, _b, _c;
|
|
104
|
+
const opts = getOptions();
|
|
105
|
+
const {
|
|
106
|
+
scene,
|
|
107
|
+
pathKey,
|
|
108
|
+
context,
|
|
109
|
+
audience,
|
|
110
|
+
fileNameStrategy = "uuid",
|
|
111
|
+
useCdn = true,
|
|
112
|
+
getCredential,
|
|
113
|
+
normalizeCredential
|
|
114
|
+
} = opts;
|
|
115
|
+
const mergedContext = { ...context, ...overrides == null ? void 0 : overrides.context };
|
|
116
|
+
const mergedScene = (_a = overrides == null ? void 0 : overrides.scene) != null ? _a : scene;
|
|
117
|
+
const mergedAudience = (_b = overrides == null ? void 0 : overrides.audience) != null ? _b : audience;
|
|
118
|
+
const mergedPathKey = (_c = overrides == null ? void 0 : overrides.pathKey) != null ? _c : pathKey;
|
|
119
|
+
const credParams = {
|
|
120
|
+
scene: mergedScene,
|
|
121
|
+
pathKey: mergedPathKey,
|
|
122
|
+
context: mergedContext,
|
|
123
|
+
audience: mergedAudience,
|
|
124
|
+
contentLength: file.size
|
|
125
|
+
};
|
|
126
|
+
const cred = getCredential ? await getCredential(http, credParams) : await (0, import_cos.fetchCosCredential)(http, credParams, normalizeCredential);
|
|
127
|
+
const basePath = resolveBasePath(cred, mergedPathKey);
|
|
128
|
+
const fileName = await generateFileName(file, fileNameStrategy);
|
|
129
|
+
const cosKey = basePath ? `${basePath.replace(/\/$/, "")}/${fileName}` : fileName;
|
|
130
|
+
const cos = createCosClient(cred);
|
|
131
|
+
return new Promise((resolve, reject) => {
|
|
132
|
+
cos.putObject(
|
|
133
|
+
{
|
|
134
|
+
Bucket: cred.bucket,
|
|
135
|
+
Region: cred.region,
|
|
136
|
+
Key: cosKey,
|
|
137
|
+
Body: file,
|
|
138
|
+
onProgress: onProgress ? (progressData) => {
|
|
139
|
+
onProgress(Math.round(progressData.percent * 100));
|
|
140
|
+
} : void 0
|
|
141
|
+
},
|
|
142
|
+
(err, data) => {
|
|
143
|
+
if (err) {
|
|
144
|
+
reject(err);
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
const fileUrl = useCdn && cred.cosHost ? `${cred.cosHost.replace(/\/$/, "")}/${cosKey}` : `https://${data.Location}`;
|
|
148
|
+
resolve({
|
|
149
|
+
fileUrl,
|
|
150
|
+
cosKey,
|
|
151
|
+
fileName: file.name
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
);
|
|
155
|
+
});
|
|
156
|
+
};
|
|
157
|
+
const getDownloadUrl = async (cosKey, overrides) => {
|
|
158
|
+
var _a, _b, _c;
|
|
159
|
+
const opts = getOptions();
|
|
160
|
+
const { scene, pathKey, context, audience, getCredential } = opts;
|
|
161
|
+
const mergedContext = { ...context, ...overrides == null ? void 0 : overrides.context };
|
|
162
|
+
const mergedScene = (_a = overrides == null ? void 0 : overrides.scene) != null ? _a : scene;
|
|
163
|
+
const mergedAudience = (_b = overrides == null ? void 0 : overrides.audience) != null ? _b : audience;
|
|
164
|
+
const mergedPathKey = (_c = overrides == null ? void 0 : overrides.pathKey) != null ? _c : pathKey;
|
|
165
|
+
const credParams = {
|
|
166
|
+
scene: getCredential ? mergedScene : mergedScene === "sdk_customize" ? mergedScene : "default_download",
|
|
167
|
+
pathKey: mergedPathKey,
|
|
168
|
+
context: mergedContext,
|
|
169
|
+
audience: mergedAudience,
|
|
170
|
+
fileUrl: cosKey
|
|
171
|
+
};
|
|
172
|
+
const cred = getCredential ? await getCredential(http, credParams) : await (0, import_cos.fetchCosCredential)(http, credParams);
|
|
173
|
+
const cos = createCosClient(cred);
|
|
174
|
+
return new Promise((resolve, reject) => {
|
|
175
|
+
cos.getObjectUrl(
|
|
176
|
+
{
|
|
177
|
+
Bucket: cred.bucket,
|
|
178
|
+
Region: cred.region,
|
|
179
|
+
Key: stripHost(cosKey),
|
|
180
|
+
Sign: true
|
|
181
|
+
},
|
|
182
|
+
(err, data) => {
|
|
183
|
+
if (err) {
|
|
184
|
+
reject(err);
|
|
185
|
+
return;
|
|
186
|
+
}
|
|
187
|
+
resolve(data.Url);
|
|
188
|
+
}
|
|
189
|
+
);
|
|
190
|
+
});
|
|
191
|
+
};
|
|
192
|
+
return { upload, getDownloadUrl };
|
|
193
|
+
};
|
|
194
|
+
var usePntCosUploader = (options) => {
|
|
195
|
+
const { http } = (0, import_config.usePntConfig)();
|
|
196
|
+
const optionsRef = (0, import_react.useRef)(options);
|
|
197
|
+
optionsRef.current = options;
|
|
198
|
+
return (0, import_react.useMemo)(
|
|
199
|
+
() => createPntCosUploader(http, () => optionsRef.current),
|
|
200
|
+
[http]
|
|
201
|
+
);
|
|
202
|
+
};
|
|
203
|
+
var PntCosUploader_default = usePntCosUploader;
|
|
204
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
205
|
+
0 && (module.exports = {
|
|
206
|
+
createPntCosUploader,
|
|
207
|
+
normalizeSnakeCredential,
|
|
208
|
+
usePntCosUploader
|
|
209
|
+
});
|
|
@@ -28,9 +28,15 @@ export interface PntImageProps {
|
|
|
28
28
|
* @description src 为空时展示的占位图;不传则使用内置的 uploadImg
|
|
29
29
|
*/
|
|
30
30
|
defaultImg?: string;
|
|
31
|
+
/**
|
|
32
|
+
* 快捷尺寸(正方形)
|
|
33
|
+
* @description 预设尺寸:`small`=36px、`medium`=60px、`large`=136px;默认 `large`
|
|
34
|
+
* 若 `style` 中显式指定了 width/height,则以 style 为准;非正方形场景请使用 `style`
|
|
35
|
+
*/
|
|
36
|
+
size?: 'small' | 'medium' | 'large';
|
|
31
37
|
/**
|
|
32
38
|
* 自定义样式
|
|
33
|
-
* @description
|
|
39
|
+
* @description 一般用于控制图片宽高;其中 width/height 优先级高于 size
|
|
34
40
|
*/
|
|
35
41
|
style?: React.CSSProperties;
|
|
36
42
|
/**
|
|
@@ -69,14 +75,14 @@ export interface PntImageProps {
|
|
|
69
75
|
* loading={loading}
|
|
70
76
|
* defaultImg={defaultImg}
|
|
71
77
|
* onRemove={handleRemove}
|
|
72
|
-
*
|
|
78
|
+
* size="large"
|
|
73
79
|
* />
|
|
74
80
|
*
|
|
75
81
|
* // 纯预览模式
|
|
76
82
|
* <PntImage
|
|
77
83
|
* src={url}
|
|
78
84
|
* alt="avatar"
|
|
79
|
-
*
|
|
85
|
+
* size="medium"
|
|
80
86
|
* container={container}
|
|
81
87
|
* />
|
|
82
88
|
* ```
|
|
@@ -46,6 +46,7 @@ var PntImage = ({
|
|
|
46
46
|
src,
|
|
47
47
|
alt = "",
|
|
48
48
|
defaultImg,
|
|
49
|
+
size,
|
|
49
50
|
style,
|
|
50
51
|
loading = false,
|
|
51
52
|
onRemove,
|
|
@@ -54,6 +55,13 @@ var PntImage = ({
|
|
|
54
55
|
}) => {
|
|
55
56
|
const isUploadMode = typeof onRemove === "function";
|
|
56
57
|
const finalSrc = (src == null ? void 0 : src.length) ? src : defaultImg || import_uploadImg.default;
|
|
58
|
+
const SIZE_MAP = { small: 36, medium: 60, large: 136 };
|
|
59
|
+
const sizeValue = SIZE_MAP[size != null ? size : "large"];
|
|
60
|
+
const sizeStyle = {
|
|
61
|
+
width: `${sizeValue}px`,
|
|
62
|
+
height: `${sizeValue}px`
|
|
63
|
+
};
|
|
64
|
+
const mergedStyle = { ...sizeStyle, ...style };
|
|
57
65
|
const attach = container ? typeof container === "function" ? container : () => container : void 0;
|
|
58
66
|
const finalTexts = { ...DEFAULT_TEXTS, ...texts };
|
|
59
67
|
const UploadLoadingContent = (isImageLoading) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
@@ -125,7 +133,7 @@ var PntImage = ({
|
|
|
125
133
|
overlayTrigger: "hover",
|
|
126
134
|
fit: "contain",
|
|
127
135
|
className: "pnt-image",
|
|
128
|
-
style
|
|
136
|
+
style: mergedStyle
|
|
129
137
|
}
|
|
130
138
|
);
|
|
131
139
|
}
|
|
@@ -28,12 +28,15 @@ var import_index = require("./index.scss");
|
|
|
28
28
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
29
29
|
var PntSecureBox = (prop) => {
|
|
30
30
|
const { dataKey, dataValue, env, gameId, renderDom, viewText, pageId } = prop;
|
|
31
|
-
const { securityData, requestSecurityData } = (0, import_useHighSecurity.useHighSecurity)(
|
|
31
|
+
const { securityData, isUnlocked, requestSecurityData } = (0, import_useHighSecurity.useHighSecurity)({
|
|
32
|
+
gameId,
|
|
33
|
+
env
|
|
34
|
+
});
|
|
35
|
+
const isSecurity = (0, import_utils.isSecurityData)(dataValue);
|
|
36
|
+
const unlocked = isSecurity && isUnlocked(dataKey);
|
|
32
37
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "pnt-secure-box", children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
|
|
33
|
-
renderDom(
|
|
34
|
-
|
|
35
|
-
),
|
|
36
|
-
(0, import_utils.isSecurityData)(dataValue) && !securityData.hasOwnProperty(dataKey) && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
38
|
+
renderDom(unlocked ? securityData[dataKey] || "******" : isSecurity ? "******" : dataValue),
|
|
39
|
+
isSecurity && !isUnlocked(dataKey) && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
37
40
|
"span",
|
|
38
41
|
{
|
|
39
42
|
className: "view-icon",
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import type { CosScene } from "../../api/cos";
|
|
2
|
+
import type { FileNameStrategy, PntCosUploadOptions } from "../PntCosUploader";
|
|
3
|
+
import React, { FC } from 'react';
|
|
4
|
+
import './index.scss';
|
|
5
|
+
/**
|
|
6
|
+
* PntUpload 文案集合
|
|
7
|
+
* @description 所有内部展示文案均可通过 texts prop 自定义,用于多语言场景
|
|
8
|
+
*/
|
|
9
|
+
export interface PntUploadTexts {
|
|
10
|
+
/** 上传中文案 */
|
|
11
|
+
uploading?: string;
|
|
12
|
+
/** 上传失败文案 */
|
|
13
|
+
uploadFailed?: string;
|
|
14
|
+
/** 文件大小超出限制文案 */
|
|
15
|
+
sizeInvalid?: string;
|
|
16
|
+
/** 文件类型不支持文案 */
|
|
17
|
+
typeInvalid?: string;
|
|
18
|
+
/** 选择文件文案(无文件时) */
|
|
19
|
+
selectFile?: string;
|
|
20
|
+
/** 重新选择文案(已有文件时,非图片模式) */
|
|
21
|
+
reselect?: string;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* 校验/上传失败阶段
|
|
25
|
+
*/
|
|
26
|
+
export type PntUploadErrorPhase = 'validate' | 'upload';
|
|
27
|
+
export interface PntUploadProps {
|
|
28
|
+
/**
|
|
29
|
+
* 当前已上传文件 URL(受控)
|
|
30
|
+
*/
|
|
31
|
+
value?: string;
|
|
32
|
+
/**
|
|
33
|
+
* 上传成功回调
|
|
34
|
+
* @param fileUrl 上传后的可访问 URL
|
|
35
|
+
* @param cosKey COS 对象 Key
|
|
36
|
+
* @param file 原始文件
|
|
37
|
+
*/
|
|
38
|
+
onChange?: (fileUrl: string, cosKey: string, file: File) => void;
|
|
39
|
+
/**
|
|
40
|
+
* 删除回调
|
|
41
|
+
* @description 由消费方清空 value
|
|
42
|
+
*/
|
|
43
|
+
onRemove?: () => void;
|
|
44
|
+
/**
|
|
45
|
+
* 异常回调(校验失败 / 上传失败)
|
|
46
|
+
* @param err 错误对象(校验失败时 message 为对应文案)
|
|
47
|
+
* @param phase 失败阶段:validate=本地校验,upload=凭证获取或 COS 上传
|
|
48
|
+
* @param file 原始文件
|
|
49
|
+
*/
|
|
50
|
+
onError?: (err: Error, phase: PntUploadErrorPhase, file: File) => void;
|
|
51
|
+
/**
|
|
52
|
+
* 业务场景(透传给 PntCosUploader)
|
|
53
|
+
*/
|
|
54
|
+
scene: CosScene;
|
|
55
|
+
/**
|
|
56
|
+
* 业务类型路径 key(透传给 PntCosUploader)
|
|
57
|
+
*/
|
|
58
|
+
pathKey?: string;
|
|
59
|
+
/**
|
|
60
|
+
* 业务上下文(透传给 PntCosUploader)
|
|
61
|
+
*/
|
|
62
|
+
context?: Record<string, string | number>;
|
|
63
|
+
/**
|
|
64
|
+
* 网关 audience(透传给 PntCosUploader)
|
|
65
|
+
* @default '/player-network'
|
|
66
|
+
*/
|
|
67
|
+
audience?: string;
|
|
68
|
+
/**
|
|
69
|
+
* 文件类型限制
|
|
70
|
+
* @description 支持 MIME('image/png')、通配('image/*')、扩展名('.zip'),可传数组
|
|
71
|
+
*/
|
|
72
|
+
accept?: string | string[];
|
|
73
|
+
/**
|
|
74
|
+
* 文件大小限制(字节)
|
|
75
|
+
*/
|
|
76
|
+
sizeLimit?: number;
|
|
77
|
+
/**
|
|
78
|
+
* 是否为图片预览模式
|
|
79
|
+
* @description true 使用 PntImage 预览;false 使用文件名 + 选择区域
|
|
80
|
+
* @default true
|
|
81
|
+
*/
|
|
82
|
+
imagePreview?: boolean;
|
|
83
|
+
/**
|
|
84
|
+
* 图片预览区样式(imagePreview=true 生效,一般控制宽高)
|
|
85
|
+
*/
|
|
86
|
+
previewStyle?: React.CSSProperties;
|
|
87
|
+
/**
|
|
88
|
+
* 默认占位图(imagePreview=true 生效)
|
|
89
|
+
*/
|
|
90
|
+
defaultImg?: string;
|
|
91
|
+
/**
|
|
92
|
+
* 文件名生成策略(透传给 PntCosUploader)
|
|
93
|
+
* @default 'uuid'
|
|
94
|
+
*/
|
|
95
|
+
fileNameStrategy?: FileNameStrategy;
|
|
96
|
+
/**
|
|
97
|
+
* 是否走 CDN 域名拼接(透传给 PntCosUploader)
|
|
98
|
+
* @default true
|
|
99
|
+
*/
|
|
100
|
+
useCdn?: boolean;
|
|
101
|
+
/**
|
|
102
|
+
* 自定义凭证获取函数(透传给 PntCosUploader)
|
|
103
|
+
*/
|
|
104
|
+
getCredential?: PntCosUploadOptions['getCredential'];
|
|
105
|
+
/**
|
|
106
|
+
* 自定义凭证响应归一化(透传给 PntCosUploader)
|
|
107
|
+
*/
|
|
108
|
+
normalizeCredential?: PntCosUploadOptions['normalizeCredential'];
|
|
109
|
+
/**
|
|
110
|
+
* 多语言文案
|
|
111
|
+
* @description 传入即覆盖默认中文文案;仅对应字段会覆盖,未传字段仍用默认值
|
|
112
|
+
*/
|
|
113
|
+
texts?: PntUploadTexts;
|
|
114
|
+
/**
|
|
115
|
+
* 禁用上传与删除
|
|
116
|
+
* @default false
|
|
117
|
+
*/
|
|
118
|
+
disabled?: boolean;
|
|
119
|
+
/**
|
|
120
|
+
* 自定义样式
|
|
121
|
+
*/
|
|
122
|
+
style?: React.CSSProperties;
|
|
123
|
+
/**
|
|
124
|
+
* 自定义类名
|
|
125
|
+
*/
|
|
126
|
+
className?: string;
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* PntUpload 业务上传组件
|
|
130
|
+
* @description 基于 TDesign Upload + PntImage + usePntCosUploader,
|
|
131
|
+
* 内置 COS 凭证获取、直传、进度、校验、错误处理;支持图片预览 / 文件两种模式
|
|
132
|
+
*
|
|
133
|
+
* @example
|
|
134
|
+
* ```tsx
|
|
135
|
+
* <PntUpload
|
|
136
|
+
* scene="default"
|
|
137
|
+
* pathKey="marketing_icon"
|
|
138
|
+
* context={{ gameId }}
|
|
139
|
+
* accept="image/png"
|
|
140
|
+
* sizeLimit={500 * 1024}
|
|
141
|
+
* imagePreview
|
|
142
|
+
* value={iconUrl}
|
|
143
|
+
* onChange={(url) => setIconUrl(url)}
|
|
144
|
+
* onRemove={() => setIconUrl('')}
|
|
145
|
+
* />
|
|
146
|
+
* ```
|
|
147
|
+
*/
|
|
148
|
+
declare const PntUpload: FC<PntUploadProps>;
|
|
149
|
+
export default PntUpload;
|