Private
Public Access
1
0

新增: 云OSS存储集成(七牛云+阿里云)+多桶导航+GBK编码自动转换

This commit is contained in:
2026-05-05 03:18:47 +08:00
parent eb5b85e007
commit b4f4b4627d
34 changed files with 5225 additions and 48 deletions

View File

@@ -0,0 +1,235 @@
package qiniu
import (
"context"
"fmt"
"io"
"u-desk/internal/oss"
)
// StorageType 存储类型枚举
type StorageType int
const (
// StorageTypeStandard 标准存储 (0)
StorageTypeStandard StorageType = 0
// StorageTypeIA 低频存储 (1) - Infrequent Access
StorageTypeIA StorageType = 1
// StorageTypeArchive 归档存储 (2) - Archive
StorageTypeArchive StorageType = 2
// StorageTypeDeepArchive 深度归档存储 (3) - Deep Archive
StorageTypeDeepArchive StorageType = 3
// StorageTypeIntelligentTiering 智能分层存储 (4)
StorageTypeIntelligentTiering StorageType = 4
// StorageTypeArchiveIR 归档直读存储 (5) - Archive Immediate Retrieval
StorageTypeArchiveIR StorageType = 5
)
// String 返回存储类型的字符串表示
func (t StorageType) String() string {
switch t {
case StorageTypeStandard:
return "标准存储"
case StorageTypeIA:
return "低频存储"
case StorageTypeArchive:
return "归档存储"
case StorageTypeDeepArchive:
return "深度归档存储"
case StorageTypeIntelligentTiering:
return "智能分层存储"
case StorageTypeArchiveIR:
return "归档直读存储"
default:
return "未知"
}
}
// LifecycleConfig 文件生命周期配置
type LifecycleConfig struct {
// ToIAAfterDays 转换到低频存储的天数,-1 表示取消
ToIAAfterDays int
// ToIntelligentTieringAfterDays 转换到智能分层存储的天数,-1 表示取消
ToIntelligentTieringAfterDays int
// ToArchiveIRAfterDays 转换到归档直读存储的天数,-1 表示取消
ToArchiveIRAfterDays int
// ToArchiveAfterDays 转换到归档存储的天数,-1 表示取消
ToArchiveAfterDays int
// ToDeepArchiveAfterDays 转换到深度归档存储的天数,-1 表示取消
ToDeepArchiveAfterDays int
// DeleteAfterDays 过期删除的天数,-1 表示取消0 表示不设置
DeleteAfterDays int
}
// ChangeStorageType 修改文件存储类型
// 根据: https://developer.qiniu.com/kodo/api/3710/chtype
func (c *Client) ChangeStorageType(ctx context.Context, key string, storageType StorageType) error {
encodedEntry := c.encodeEntry(key)
path := fmt.Sprintf("/chtype/%s/type/%d", encodedEntry, storageType)
resp, err := c.doRequest("POST", path, nil)
if err != nil {
return oss.NewError("STYPE_ERROR", "failed to change storage type", err)
}
defer resp.Body.Close()
if resp.StatusCode == 200 {
return nil
}
body, _ := io.ReadAll(resp.Body)
return oss.NewError("STYPE_ERROR",
fmt.Sprintf("change storage type failed with status %d: %s", resp.StatusCode, string(body)), nil)
}
// SetDeleteAfterDays 设置文件过期删除时间
// 根据: https://developer.qiniu.com/kodo/api/update-file-lifecycle
//
// 参数:
// - key: 文件 key
// - days: 过期天数0 表示取消过期删除设置
//
// 注意:
// - 文件在设置的天数之后被删除,删除后不可恢复
// - 设置为 0 表示取消过期删除设置
func (c *Client) SetDeleteAfterDays(ctx context.Context, key string, days int) error {
encodedEntry := c.encodeEntry(key)
path := fmt.Sprintf("/deleteAfterDays/%s/%d", encodedEntry, days)
resp, err := c.doRequest("POST", path, nil)
if err != nil {
return oss.NewError("LIFECYCLE_ERROR", "failed to set delete after days", err)
}
defer resp.Body.Close()
if resp.StatusCode == 200 {
return nil
}
body, _ := io.ReadAll(resp.Body)
return oss.NewError("LIFECYCLE_ERROR",
fmt.Sprintf("set delete after days failed with status %d: %s", resp.StatusCode, string(body)), nil)
}
// SetLifecycle 设置文件生命周期
// 根据: https://developer.qiniu.com/kodo/api/8062/modify-object-life-cycle
//
// 参数说明:
// - ToIAAfterDays: 转换到低频存储的天数,设置为 -1 表示取消
// - ToIntelligentTieringAfterDays: 转换到智能分层存储的天数,设置为 -1 表示取消
// - ToArchiveIRAfterDays: 转换到归档直读存储的天数,设置为 -1 表示取消
// - ToArchiveAfterDays: 转换到归档存储的天数,设置为 -1 表示取消
// - ToDeepArchiveAfterDays: 转换到深度归档存储的天数,设置为 -1 表示取消
// - DeleteAfterDays: 过期删除的天数,设置为 -1 表示取消0 表示不设置
//
// 注意:
// - 所有参数都是可选的,只设置需要的参数即可
// - 文件删除后不可恢复
func (c *Client) SetLifecycle(ctx context.Context, key string, config *LifecycleConfig) error {
encodedEntry := c.encodeEntry(key)
path := fmt.Sprintf("/lifecycle/%s", encodedEntry)
// 添加各个生命周期参数
if config.ToIAAfterDays != 0 {
path += fmt.Sprintf("/toIAAfterDays/%d", config.ToIAAfterDays)
}
if config.ToIntelligentTieringAfterDays != 0 {
path += fmt.Sprintf("/toIntelligentTieringAfterDays/%d", config.ToIntelligentTieringAfterDays)
}
if config.ToArchiveIRAfterDays != 0 {
path += fmt.Sprintf("/toArchiveIRAfterDays/%d", config.ToArchiveIRAfterDays)
}
if config.ToArchiveAfterDays != 0 {
path += fmt.Sprintf("/toArchiveAfterDays/%d", config.ToArchiveAfterDays)
}
if config.ToDeepArchiveAfterDays != 0 {
path += fmt.Sprintf("/toDeepArchiveAfterDays/%d", config.ToDeepArchiveAfterDays)
}
if config.DeleteAfterDays != 0 {
path += fmt.Sprintf("/deleteAfterDays/%d", config.DeleteAfterDays)
}
// 如果没有设置任何参数,返回错误
if path == fmt.Sprintf("/lifecycle/%s", encodedEntry) {
return oss.NewError("LIFECYCLE_ERROR", "no lifecycle parameters specified", nil)
}
resp, err := c.doRequest("POST", path, nil)
if err != nil {
return oss.NewError("LIFECYCLE_ERROR", "failed to set lifecycle", err)
}
defer resp.Body.Close()
if resp.StatusCode == 200 {
return nil
}
body, _ := io.ReadAll(resp.Body)
return oss.NewError("LIFECYCLE_ERROR",
fmt.Sprintf("set lifecycle failed with status %d: %s", resp.StatusCode, string(body)), nil)
}
// CancelIAConversion 取消转低频存储的生命周期规则
func (c *Client) CancelIAConversion(ctx context.Context, key string) error {
config := &LifecycleConfig{
ToIAAfterDays: -1,
}
return c.SetLifecycle(ctx, key, config)
}
// CancelArchiveConversion 取消转归档存储的生命周期规则
func (c *Client) CancelArchiveConversion(ctx context.Context, key string) error {
config := &LifecycleConfig{
ToArchiveAfterDays: -1,
}
return c.SetLifecycle(ctx, key, config)
}
// CancelDeleteAfterDays 取消过期删除的生命周期规则
func (c *Client) CancelDeleteAfterDays(ctx context.Context, key string) error {
config := &LifecycleConfig{
DeleteAfterDays: -1,
}
return c.SetLifecycle(ctx, key, config)
}
// SetToIAAfterDays 设置文件转低频存储的天数
func (c *Client) SetToIAAfterDays(ctx context.Context, key string, days int) error {
config := &LifecycleConfig{
ToIAAfterDays: days,
}
return c.SetLifecycle(ctx, key, config)
}
// SetToArchiveAfterDays 设置文件转归档存储的天数
func (c *Client) SetToArchiveAfterDays(ctx context.Context, key string, days int) error {
config := &LifecycleConfig{
ToArchiveAfterDays: days,
}
return c.SetLifecycle(ctx, key, config)
}
// SetToDeepArchiveAfterDays 设置文件转深度归档存储的天数
func (c *Client) SetToDeepArchiveAfterDays(ctx context.Context, key string, days int) error {
config := &LifecycleConfig{
ToDeepArchiveAfterDays: days,
}
return c.SetLifecycle(ctx, key, config)
}
// SetToIntelligentTieringAfterDays 设置文件转智能分层存储的天数
func (c *Client) SetToIntelligentTieringAfterDays(ctx context.Context, key string, days int) error {
config := &LifecycleConfig{
ToIntelligentTieringAfterDays: days,
}
return c.SetLifecycle(ctx, key, config)
}
// SetToArchiveIRAfterDays 设置文件转归档直读存储的天数
func (c *Client) SetToArchiveIRAfterDays(ctx context.Context, key string, days int) error {
config := &LifecycleConfig{
ToArchiveIRAfterDays: days,
}
return c.SetLifecycle(ctx, key, config)
}