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) }