feat: 更新应用版本和集成腾讯云 COS 上传功能
- 将应用版本更新至 1.0.2,修改相关配置文件 - 集成腾讯云 COS 上传功能,新增相关服务和钩子 - 更新 AI 体态评估页面,支持照片上传和评估结果展示 - 添加雷达图组件以展示评估结果 - 更新样式以适应新功能的展示和交互 - 修改登录页面背景效果,提升用户体验
This commit is contained in:
174
docs/cos.md
Normal file
174
docs/cos.md
Normal file
@@ -0,0 +1,174 @@
|
||||
# 腾讯云 COS 上传集成说明
|
||||
|
||||
本文档记录本项目在前端(Expo/React Native)侧对腾讯云 COS 的接入方式与使用规范,包含配置、接口约定、上传用法、进度/取消/重试、URL 构建、权限与安全、常见问题等。
|
||||
|
||||
## 概览
|
||||
- 依赖:`cos-js-sdk-v5`
|
||||
- 临时密钥接口:`GET /api/users/cos-token`
|
||||
- 统一封装:
|
||||
- 配置:`constants/Cos.ts`
|
||||
- 上传服务:`services/cos.ts`
|
||||
- Hook:`hooks/useCosUpload.ts`
|
||||
|
||||
## 安装与依赖
|
||||
已在 `package.json` 中添加:
|
||||
|
||||
```json
|
||||
{
|
||||
"dependencies": {
|
||||
"cos-js-sdk-v5": "^1.6.0"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 配置
|
||||
编辑 `constants/Cos.ts`,填入实际 COS 参数:
|
||||
|
||||
```ts
|
||||
export const COS_BUCKET = 'your-bucket-125xxxxxxx';
|
||||
export const COS_REGION = 'ap-shanghai';
|
||||
export const COS_PUBLIC_BASE = 'https://your-bucket-125xxxxxxx.cos.ap-shanghai.myqcloud.com';
|
||||
export const COS_KEY_PREFIX = 'uploads/';
|
||||
```
|
||||
|
||||
说明:
|
||||
- COS_PUBLIC_BASE:若桶或 CDN 具有公网访问,使用对应域名(建议 HTTPS)。若为私有桶,可忽略该项(前端不能直接拼公开 URL)。
|
||||
- `buildCosKey` 会依据日期和随机串生成不重复 Key,可通过 `prefix`/`userId` 定制目录。
|
||||
|
||||
## 后端接口约定:/api/users/cos-token
|
||||
- 方法:`GET`
|
||||
- 鉴权:建议要求登录态,后端根据用户权限签发最小权限临时凭证。
|
||||
- 响应体示例(关键字段):
|
||||
|
||||
```json
|
||||
{
|
||||
"credentials": {
|
||||
"tmpSecretId": "TMPID...",
|
||||
"tmpSecretKey": "TMPKEY...",
|
||||
"sessionToken": "SESSION_TOKEN..."
|
||||
},
|
||||
"startTime": 1730000000,
|
||||
"expiredTime": 1730001800
|
||||
}
|
||||
```
|
||||
|
||||
- 最小权限策略建议(示例,后端侧):
|
||||
|
||||
```json
|
||||
{
|
||||
"version": "2.0",
|
||||
"statement": [
|
||||
{
|
||||
"action": [
|
||||
"name/cos:PutObject",
|
||||
"name/cos:InitiateMultipartUpload",
|
||||
"name/cos:UploadPart",
|
||||
"name/cos:CompleteMultipartUpload"
|
||||
],
|
||||
"effect": "allow",
|
||||
"resource": [
|
||||
"qcs::cos:ap-shanghai:uid/125xxxxxxx:your-bucket-125xxxxxxx/*"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
注意:对上传路径进行前缀限制(如 `uploads/*`)能进一步收敛权限范围。
|
||||
|
||||
## 前端用法一:Hook(推荐)
|
||||
在页面/组件内使用 `useCosUpload`,支持进度、取消与重试。
|
||||
|
||||
```tsx
|
||||
import { useCosUpload } from '@/hooks/useCosUpload';
|
||||
import * as ImagePicker from 'expo-image-picker';
|
||||
|
||||
export default function Uploader() {
|
||||
const { upload, progress, uploading, cancel } = useCosUpload({ prefix: 'images/', userId: 'uid-123' });
|
||||
|
||||
const pickAndUpload = async () => {
|
||||
const res = await ImagePicker.launchImageLibraryAsync({ mediaTypes: ImagePicker.MediaTypeOptions.Images });
|
||||
if (res.canceled || !res.assets?.[0]) return;
|
||||
const asset = res.assets[0];
|
||||
const result = await upload({ uri: asset.uri, name: asset.fileName, type: asset.mimeType });
|
||||
console.log('uploaded:', result); // { key, url }
|
||||
};
|
||||
|
||||
return null;
|
||||
}
|
||||
```
|
||||
|
||||
说明:
|
||||
- `progress` 范围 0-1;`uploading` 指示进行中;可随时 `cancel()`。
|
||||
- 未开启公网访问时,`url` 可能为空(需服务端签名下载)。
|
||||
|
||||
## 前端用法二:直接调用服务
|
||||
`services/cos.ts` 提供基础方法:
|
||||
|
||||
```ts
|
||||
import { uploadWithRetry } from '@/services/cos';
|
||||
|
||||
const { key, etag } = await uploadWithRetry({
|
||||
key: 'uploads/demo.png',
|
||||
body: blob,
|
||||
contentType: 'image/png'
|
||||
});
|
||||
```
|
||||
|
||||
- 进度回调:`onProgress: ({ percent }) => { ... }`
|
||||
- 取消:传入 `signal: AbortSignal`
|
||||
- 重试:`maxRetries`/`backoffMs` 配置指数退避
|
||||
|
||||
## URL 构建
|
||||
若为公网可访问场景,使用:
|
||||
|
||||
```ts
|
||||
import { buildPublicUrl } from '@/constants/Cos';
|
||||
const url = buildPublicUrl(key);
|
||||
```
|
||||
|
||||
若为私有桶,请改走服务端生成临时下载链接或代理下载。
|
||||
|
||||
## 大文件与分片上传
|
||||
当前默认使用 `putObject`。若需大文件/断点续传,建议切换 SDK 的分片接口 `sliceUploadFile`:
|
||||
|
||||
```ts
|
||||
const taskId = cos.sliceUploadFile({
|
||||
Bucket: COS_BUCKET,
|
||||
Region: COS_REGION,
|
||||
Key: key,
|
||||
Body: fileOrBlob,
|
||||
onProgress(progress) { /* ... */ }
|
||||
}, (err, data) => { /* ... */ });
|
||||
```
|
||||
|
||||
如需切换,可在 `services/cos.ts` 中将 `putObject` 替换为 `sliceUploadFile`,并保留同样的进度、取消与重试包装。
|
||||
|
||||
## CORS 与浏览器(如使用 Web)
|
||||
- COS 控制台需配置 CORS,允许来源域名、方法(PUT/POST/OPTIONS)、请求头(含 `Authorization`、`x-cos-*` 等)、暴露头。
|
||||
- 若通过自有域名/网关代理,也需在代理层正确透传 CORS 与签名头。
|
||||
|
||||
## 安全与最佳实践
|
||||
- 永久密钥仅存在服务端,通过 `/api/users/cos-token` 颁发短期凭证。
|
||||
- 严控临时凭证权限与有效期,并限制上传前缀。
|
||||
- 前端仅持有短期凭证;错误重试次数受限,避免暴力重放。
|
||||
|
||||
## 常见问题排查
|
||||
- 403/签名失败:确认服务端时间同步、`region/bucket`/`resource` 配置正确;临时密钥未过期。
|
||||
- CORS 失败:检查 COS 跨域规则;确认需要的请求头(含 `Authorization`)均已放行。
|
||||
- URL 访问 403:私有桶下请改用服务端签名下载;或为指定前缀开启公共读(谨慎)。
|
||||
- MIME/ContentType:从 ImagePicker 取 `mimeType`,或按扩展名兜底设置。
|
||||
|
||||
## 测试清单
|
||||
- 小图上传成功且进度递增、可取消。
|
||||
- 取消后不再继续发片段;重试如期生效。
|
||||
- 返回的 `key` 能通过 `buildPublicUrl` 拼出可访问地址(公网桶)。
|
||||
- 临时密钥过期后,能够重新获取并继续上传。
|
||||
|
||||
## 变更点速记
|
||||
- 依赖:`cos-js-sdk-v5`
|
||||
- 新增:`constants/Cos.ts`、`services/cos.ts`、`hooks/useCosUpload.ts`
|
||||
- 接口:`GET /api/users/cos-token`(返回临时凭证)
|
||||
|
||||
---
|
||||
如需我将某页面接入示例按钮或改造为分片上传,请在需求中指明目标文件与交互期望。
|
||||
Reference in New Issue
Block a user