# @mingto/huawei-obs-server

文件上传至华为云 OBS（对象存储服务）工具库，支持单文件上传和分片上传两种方式，能满足不同大小文件的上传需求。

## 特性

- 🚀 **双模式支持**：单文件上传 + 分片上传，自动根据文件大小选择
- 📊 **进度监控**：实时上传进度回调
- ❌ **取消上传**：支持随时取消上传操作
- 🔧 **灵活配置**：支持自定义分片大小、分片阈值等参数
- 📱 **浏览器端支持**：专为浏览器环境优化

## 安装

```bash
pnpm add @mingto/huawei-obs-server
```

## 快速开始

```typescript
import huaweiObsServer from '@mingto/huawei-obs-server'

// 配置全局参数
huaweiObsServer.config({
  getToken: () => '用户的token',
  baseURL: 'https://your-domain.com',
  apiPrefix: '/backend-api',
  fileSplitThreshold: 1024 * 1024 * 5 // 5MB，超过此阈值使用分片上传
})

// 创建要上传的文件对象
const sourceFile = new File(['hello world'], 'hello.txt', { type: 'text/plain' })

// 创建上传实例
const uploadContext = huaweiObsServer.create({
  sourceFile,
  sceneId: '1',
  onProgress: (event) => {
    console.log(`上传进度: ${event.percent}%`)
  },
  onSuccess: (event) => {
    console.log('上传成功:', event.fileInfo)
  },
  onError: (error) => {
    console.error('上传失败:', error.code, error.message)
  }
})

// 取消上传
// uploadContext.abort()
```

## API

### 全局配置

#### huaweiObsServer.config(options)

配置全局参数，支持以下参数：

| 参数                 | 类型           | 必填 | 默认值 | 说明                                            |
| -------------------- | -------------- | ---- | ------ | ----------------------------------------------- |
| `getToken`           | `() => string` | 是   | 无     | 用于获取上传所需的 token，该 token 用于身份验证 |
| `baseURL`            | `string`       | 否   | 当前域名 | 业务接口基础地址                                |
| `apiPrefix`          | `string`       | 否   | `/backend-api` | 业务接口前缀（反向代理前缀）              |
| `fileSplitThreshold` | `number`       | 否   | `6MB`  | 文件大小分隔线，超过阈值使用分片上传            |

### 创建上传实例

#### huaweiObsServer.create(options)

创建上传实例，支持以下参数：

| 参数         | 类型              | 必填 | 默认值     | 说明                                                  |
| ------------ | ----------------- | ---- | ---------- | ----------------------------------------------------- |
| `sourceFile` | `File`            | 是   | 无         | 要上传的文件对象                                      |
| `partSize`   | `number`          | 否   | `1MB`      | 文件分片大小                                          |
| `sceneId`    | `'0' \| '1'`      | 是   | `'1'`      | 上传桶的类型，`'0'` 为私有桶，`'1'` 为公共桶；运行时默认 `'1'` |
| `userId`     | `string`          | 否   | `''`       | 用户 ID；仅当传入非空值时才随上传请求透传给后端，不传则请求中不携带该字段 |
| `onStart`    | `() => void`      | 否   | `() => {}` | 上传开始时的回调                                      |
| `onProgress` | `(event) => void` | 否   | `() => {}` | 上传进度回调，`event.percent` 表示百分比              |
| `onSuccess`  | `(event) => void` | 否   | `() => {}` | 上传成功回调，`event` 包含 `sourceFile` 和 `fileInfo` |
| `onError`    | `(error) => void` | 否   | `() => {}` | 上传失败回调                                          |
| `onAbort`    | `() => void`      | 否   | `() => {}` | 取消上传时的回调                                      |
| `onFinally`  | `() => void`      | 否   | `() => {}` | 上传结束回调（无论成功或失败）                        |

### 取消上传

#### uploadContext.abort()

取消当前上传。

```typescript
uploadContext.abort()
```

## 错误处理

上传过程中出现错误时，会抛出对应的 `ObsError` 对象，可通过 `error.code` 获取错误码。

| 错误码  | 描述                                      |
| ------- | ----------------------------------------- |
| `10001` | 请求失败，请检查网络                      |
| `10022` | 切片上传文件初始化信息的临时 URL 获取失败 |
| `10002` | 切片上传文件初始化信息获取失败            |
| `10033` | 切片上传文件段的临时 URL 获取失败         |
| `10003` | 切片上传文件段失败                        |
| `10055` | 合并文件段的临时 URL 获取失败             |
| `10005` | 合并文件段失败                            |
| `10006` | 获取文件信息失败                          |
| `10009` | 单文件上传获取临时 URL 失败               |
| `10099` | 单文件上传失败                            |
| `10007` | 文件上传取消失败                          |

## 注意事项

- 本工具库依赖 `axios`，请确保项目中已安装 `axios`，版本要求为 `^1.7.9`
- 请确保返回的 token 是有效的，否则可能导致上传失败
- 上传大文件时，建议根据网络状况调整 `partSize` 和 `fileSplitThreshold` 参数

## 许可证

MIT
