feat: 更新应用版本和集成腾讯云 COS 上传功能
- 将应用版本更新至 1.0.2,修改相关配置文件 - 集成腾讯云 COS 上传功能,新增相关服务和钩子 - 更新 AI 体态评估页面,支持照片上传和评估结果展示 - 添加雷达图组件以展示评估结果 - 更新样式以适应新功能的展示和交互 - 修改登录页面背景效果,提升用户体验
This commit is contained in:
59
hooks/useCosUpload.ts
Normal file
59
hooks/useCosUpload.ts
Normal file
@@ -0,0 +1,59 @@
|
||||
import { buildCosKey, buildPublicUrl } from '@/constants/Cos';
|
||||
import { uploadWithRetry } from '@/services/cos';
|
||||
import { useCallback, useMemo, useRef, useState } from 'react';
|
||||
|
||||
export type UseCosUploadOptions = {
|
||||
prefix?: string;
|
||||
userId?: string;
|
||||
contentType?: string;
|
||||
};
|
||||
|
||||
export function useCosUpload(defaultOptions?: UseCosUploadOptions) {
|
||||
const abortRef = useRef<AbortController | null>(null);
|
||||
const [progress, setProgress] = useState(0);
|
||||
const [uploading, setUploading] = useState(false);
|
||||
|
||||
const cancel = useCallback(() => {
|
||||
abortRef.current?.abort();
|
||||
}, []);
|
||||
|
||||
const upload = useCallback(
|
||||
async (file: { uri?: string; name?: string; type?: string; buffer?: any; blob?: Blob } | Blob | any, options?: UseCosUploadOptions) => {
|
||||
const finalOptions = { ...(defaultOptions || {}), ...(options || {}) };
|
||||
const extGuess = (() => {
|
||||
const name = (file && (file.name || (file as any).filename)) || '';
|
||||
const match = name.match(/\.([a-zA-Z0-9]+)$/);
|
||||
return match ? match[1] : undefined;
|
||||
})();
|
||||
const key = buildCosKey({ prefix: finalOptions.prefix, userId: finalOptions.userId, ext: extGuess });
|
||||
const controller = new AbortController();
|
||||
abortRef.current = controller;
|
||||
setProgress(0);
|
||||
setUploading(true);
|
||||
try {
|
||||
let body = (file as any)?.blob || (file as any)?.buffer || file;
|
||||
// Expo ImagePicker 返回 { uri } 时,转换为 Blob
|
||||
if (!body && (file as any)?.uri) {
|
||||
const resp = await fetch((file as any).uri);
|
||||
body = await resp.blob();
|
||||
}
|
||||
const res = await uploadWithRetry({
|
||||
key,
|
||||
body,
|
||||
contentType: finalOptions.contentType || (file as any)?.type,
|
||||
signal: controller.signal,
|
||||
onProgress: ({ percent }) => setProgress(percent),
|
||||
});
|
||||
const url = buildPublicUrl(res.key);
|
||||
return { key: res.key, url };
|
||||
} finally {
|
||||
setUploading(false);
|
||||
}
|
||||
},
|
||||
[defaultOptions]
|
||||
);
|
||||
|
||||
return useMemo(() => ({ upload, cancel, progress, uploading }), [upload, cancel, progress, uploading]);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user