# 工厂工具文档 ## 概述 工厂工具提供了从配置直接创建已初始化客户端对象的功能,并提供了黑盒模式的便捷方法,让调用方无需关心底层实现细节,大大降低业务复杂度。 ## 功能特性 - **黑盒模式**:提供直接调用的方法,无需获取客户端对象 - **延迟初始化**:所有客户端在首次使用时才创建 - **自动选择**:存储类型(OSS/MinIO)根据配置自动选择 - **统一接口**:所有操作通过工厂方法调用 - **向后兼容**:保留 `GetXXX()` 方法,需要时可获取对象 ## 方法分类总览 ### 🌟 推荐使用:黑盒方法(一行代码搞定) 外部项目直接调用,无需获取内部对象: | 功能 | 方法 | 示例 | |------|------|------| | **中间件** | `GetMiddlewareChain()` | `chain := fac.GetMiddlewareChain()` | | **日志** | `LogInfo()`, `LogError()` 等 | `fac.LogInfo("用户登录")` | | **Redis** | `RedisSet()`, `RedisGet()` 等 | `fac.RedisSet(ctx, "key", "val", time.Hour)` | | **邮件** | `SendEmail()` | `fac.SendEmail(to, subject, body)` | | **短信** | `SendSMS()` | `fac.SendSMS(phones, params)` | | **存储** | `UploadFile()`, `GetFileURL()` | `fac.UploadFile(ctx, key, file)` | | **Excel导出** | `ExportToExcel()`, `ExportToExcelFile()` | `fac.ExportToExcelFile("users.xlsx", "用户列表", columns, users)` | | **日期时间** | `Now()`, `ParseDateTime()`, `FormatDateTime()` 等 | `fac.Now("Asia/Shanghai")` | | **时间工具** | `GetTimestamp()`, `IsToday()`, `GetBeginOfWeek()` 等 | `fac.GetTimestamp()` | | **加密工具** | `HashPassword()`, `MD5()`, `SHA256()`, `GenerateSMSCode()` 等 | `fac.HashPassword("password")` | | **金额计算** | `YuanToCents()`, `CentsToYuan()`, `FormatYuan()` | `fac.YuanToCents(100.5)` | | **版本信息** | `GetVersion()` | `fac.GetVersion()` | | **HTTP响应** | `Success()`, `Error()`, `SuccessPage()` | `fac.Success(w, data)` | | **HTTP请求** | `ParseJSON()`, `ConvertInt()`, `GetTimezone()` 等 | `fac.ParseJSON(r, &req)` | ### 🔧 高级功能:Get方法(仅在必要时使用) 返回客户端对象,用于复杂操作: | 方法 | 返回类型 | 使用场景 | |------|----------|----------| | `GetDatabase()` | `*gorm.DB` | 数据库复杂查询、事务、关联查询等 | | `GetRedisClient()` | `*redis.Client` | Hash、List、Set、ZSet、Pub/Sub等高级操作 | | `GetExcel()` | `*excel.Excel` | 多工作表、自定义样式、图表等高级操作 | | `GetLogger()` | `*logger.Logger` | Close()、设置全局logger等 | ## 使用方法 ### 1. 创建工厂(推荐) ```go import "git.toowon.com/jimmy/go-common/factory" // 方式1:直接从配置文件创建(最推荐) fac, err := factory.NewFactoryFromFile("./config.json") if err != nil { log.Fatal(err) } // 方式2:从配置对象创建 cfg, _ := config.LoadFromFile("./config.json") fac := factory.NewFactory(cfg) ``` ### 2. 日志记录(黑盒模式,推荐) ```go // 简单日志 fac.LogDebug("调试信息: %s", "test") fac.LogInfo("用户登录成功") fac.LogWarn("警告信息") fac.LogError("错误信息: %v", err) // 带字段的日志 fac.LogInfof(map[string]interface{}{ "user_id": 123, "ip": "192.168.1.1", }, "用户登录成功") fac.LogErrorf(map[string]interface{}{ "error_code": 1001, }, "登录失败: %v", err) ``` ### 3. 邮件发送(黑盒模式,推荐) ```go // 简单邮件 err := fac.SendEmail( []string{"user@example.com"}, "验证码", "您的验证码是:123456", ) // HTML邮件 err := fac.SendEmail( []string{"user@example.com"}, "验证码", "纯文本内容", "

HTML内容

", ) ``` ### 4. 短信发送(黑盒模式,推荐) ```go // 使用配置中的模板代码 resp, err := fac.SendSMS( []string{"13800138000"}, map[string]string{"code": "123456"}, ) // 指定模板代码 resp, err := fac.SendSMS( []string{"13800138000"}, map[string]string{"code": "123456"}, "SMS_123456789", // 模板代码 ) ``` ### 5. 文件上传和查看(黑盒模式,推荐) ```go import ( "context" "os" ) ctx := context.Background() // 上传文件(自动选择OSS或MinIO) file, _ := os.Open("test.jpg") defer file.Close() url, err := fac.UploadFile(ctx, "images/test.jpg", file, "image/jpeg") if err != nil { log.Fatal(err) } fmt.Println("文件URL:", url) // 获取文件URL(永久有效) url, _ := fac.GetFileURL("images/test.jpg", 0) // 获取临时访问URL(1小时后过期) url, _ := fac.GetFileURL("images/test.jpg", 3600) ``` ### 6. Excel导出(黑盒模式,推荐) ```go import ( "net/http" "time" "git.toowon.com/jimmy/go-common/excel" ) // 定义结构体 type User struct { ID int `json:"id"` Name string `json:"name"` Email string `json:"email"` CreatedAt time.Time `json:"created_at"` } // 准备数据 users := []User{ {ID: 1, Name: "Alice", Email: "alice@example.com", CreatedAt: time.Now()}, {ID: 2, Name: "Bob", Email: "bob@example.com", CreatedAt: time.Now()}, } // 定义导出列 columns := []factory.ExportColumn{ {Header: "ID", Field: "ID", Width: 10}, {Header: "姓名", Field: "Name", Width: 20}, {Header: "邮箱", Field: "Email", Width: 30}, { Header: "创建时间", Field: "CreatedAt", Width: 20, Format: excel.AdaptTimeFormatter(tools.FormatDateTime), }, } // 导出到文件 err := fac.ExportToExcelFile("users.xlsx", "用户列表", columns, users) // 导出到HTTP响应 func exportUsersHandler(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet") w.Header().Set("Content-Disposition", "attachment; filename=users.xlsx") fac.ExportToExcel(w, "用户列表", columns, users) } ``` ### 7. Redis操作(黑盒模式,推荐) ```go import "context" ctx := context.Background() // 设置值(不过期) err := fac.RedisSet(ctx, "user:123", "value") // 设置值(带过期时间) err := fac.RedisSet(ctx, "user:123", "value", time.Hour) // 获取值 value, err := fac.RedisGet(ctx, "user:123") // 删除键 err := fac.RedisDelete(ctx, "user:123", "user:456") // 检查键是否存在 exists, err := fac.RedisExists(ctx, "user:123") ``` ### 8. 数据库操作(黑盒模式) ```go // 获取数据库对象(已初始化,黑盒模式) db, err := fac.GetDatabase() if err != nil { log.Fatal(err) } // 直接使用GORM,无需自己实现创建逻辑 var users []User db.Find(&users) db.Create(&user) ``` ### 9. 日期时间操作(黑盒模式) ```go // 获取当前时间 now := fac.Now("Asia/Shanghai") // 解析时间 t, _ := fac.ParseDateTime("2024-01-01 12:00:00", "Asia/Shanghai") // 格式化时间 str := fac.FormatDateTime(now) // 时间计算 tomorrow := fac.AddDays(now, 1) startOfDay := fac.StartOfDay(now, "Asia/Shanghai") endOfDay := fac.EndOfDay(now, "Asia/Shanghai") // Unix时间戳 unix := fac.ToUnix(now) t2 := fac.FromUnix(unix, "Asia/Shanghai") ``` ### 10. 时间操作(黑盒模式) ```go // 时间戳 timestamp := fac.GetTimestamp() // 当前时间戳(秒) millisTimestamp := fac.GetMillisTimestamp() // 当前时间戳(毫秒) utcTimestamp := fac.GetUTCTimestamp() // UTC时间戳 // 自定义格式格式化 str := fac.FormatTimeWithLayout(now, "2006年01月02日 15:04:05") // 自定义格式解析 t, _ := fac.ParseTime("2024-01-01 12:00:00", "2006-01-02 15:04:05") // 时间计算(补充) nextHour := fac.AddHours(now, 1) nextMinute := fac.AddMinutes(now, 30) // 周相关 beginOfWeek := fac.GetBeginOfWeek(now) endOfWeek := fac.GetEndOfWeek(now) // 时间判断 if fac.IsToday(t) { fmt.Println("是今天") } if fac.IsYesterday(t) { fmt.Println("是昨天") } // 生成详细时间信息 timeInfo := fac.GenerateTimeInfoWithTimezone(now, "Asia/Shanghai") fmt.Printf("UTC: %s, Local: %s, Unix: %d\n", timeInfo.UTC, timeInfo.Local, timeInfo.Unix) ``` ### 11. 金额计算(黑盒模式) ```go // 元转分 cents := fac.YuanToCents(100.5) // 10050 // 分转元 yuan := fac.CentsToYuan(10050) // 100.5 // 格式化显示 str := fac.FormatYuan(10050) // "100.50" ``` ### 12. 版本信息(黑盒模式) ```go version := fac.GetVersion() fmt.Println("当前版本:", version) ``` ### 13. HTTP响应(黑盒模式,推荐) ```go import "net/http" // 成功响应 fac.Success(w, data) fac.Success(w, data, "操作成功") // 分页响应 fac.SuccessPage(w, users, total, page, pageSize) // 错误响应 fac.Error(w, 1001, "用户不存在") fac.SystemError(w, "系统错误") ``` ### 14. HTTP请求解析(黑盒模式,推荐) ```go import "net/http" // 解析JSON var req UserRequest fac.ParseJSON(r, &req) // 获取查询参数(使用类型转换方法) id := fac.ConvertInt64(r.URL.Query().Get("id"), 0) uid := fac.ConvertUint64(r.URL.Query().Get("uid"), 0) userId := fac.ConvertUint32(r.URL.Query().Get("user_id"), 0) keyword := r.URL.Query().Get("keyword") // 字符串直接获取 // 获取表单参数 age := fac.ConvertInt(r.FormValue("age"), 0) isActive := fac.ConvertBool(r.FormValue("is_active"), false) // 获取时区(需要配合middleware.Timezone使用) timezone := fac.GetTimezone(r) ``` ### 15. Redis操作(获取客户端对象,高级功能) ```go import ( "context" "github.com/redis/go-redis/v9" ) ctx := context.Background() // 获取Redis客户端对象(已初始化,黑盒模式) redisClient, err := fac.GetRedisClient() if err != nil { log.Fatal(err) } // 直接使用Redis客户端,无需自己实现创建逻辑 val, err := redisClient.Get(ctx, "key").Result() if err != nil && err != redis.Nil { log.Printf("Redis error: %v", err) } else if err == redis.Nil { fmt.Println("Key not found") } else { fmt.Printf("Value: %s\n", val) } // 使用高级功能(如Hash操作) redisClient.HSet(ctx, "user:123", "name", "John") name, _ := redisClient.HGet(ctx, "user:123", "name").Result() ``` ## 完整示例 ```go package main import ( "context" "log" "os" "time" "git.toowon.com/jimmy/go-common/factory" ) func main() { // 创建工厂 fac, err := factory.NewFactoryFromFile("./config.json") if err != nil { log.Fatal(err) } ctx := context.Background() // 日志记录(黑盒模式) fac.LogInfo("应用启动") fac.LogInfof(map[string]interface{}{ "version": "1.0.0", }, "应用启动成功") // 邮件发送(黑盒模式) err = fac.SendEmail( []string{"user@example.com"}, "欢迎", "欢迎使用我们的服务", ) if err != nil { fac.LogError("发送邮件失败: %v", err) } // 短信发送(黑盒模式) resp, err := fac.SendSMS( []string{"13800138000"}, map[string]string{"code": "123456"}, ) if err != nil { fac.LogError("发送短信失败: %v", err) } else { fac.LogInfo("短信发送成功: %s", resp.RequestID) } // 文件上传(黑盒模式,自动选择OSS或MinIO) file, _ := os.Open("test.jpg") defer file.Close() url, err := fac.UploadFile(ctx, "images/test.jpg", file, "image/jpeg") if err != nil { fac.LogError("上传文件失败: %v", err) } else { fac.LogInfo("文件上传成功: %s", url) } // Redis操作(黑盒模式) err = fac.RedisSet(ctx, "user:123", "value", time.Hour) if err != nil { fac.LogError("Redis设置失败: %v", err) } value, err := fac.RedisGet(ctx, "user:123") if err != nil { fac.LogError("Redis获取失败: %v", err) } else { fac.LogInfo("Redis值: %s", value) } // 数据库操作 db, err := fac.GetDatabase() if err != nil { fac.LogError("数据库连接失败: %v", err) } else { var count int64 db.Table("users").Count(&count) fac.LogInfo("用户数量: %d", count) } } ``` ## API 参考 ### 工厂创建 #### NewFactory(cfg *config.Config) *Factory 创建工厂实例。 **参数:** - `cfg`: 配置对象 **返回:** 工厂实例 #### NewFactoryFromFile(filePath string) (*Factory, error) 从配置文件直接创建工厂实例(便捷方法)。 **参数:** - `filePath`: 配置文件路径 **返回:** 工厂实例和错误信息 **说明:** 这是推荐的使用方式,一步完成配置加载和工厂创建。 ### 日志方法(黑盒模式) #### LogDebug(message string, args ...interface{}) 记录调试日志。 #### LogDebugf(fields map[string]interface{}, message string, args ...interface{}) 记录调试日志(带字段)。 #### LogInfo(message string, args ...interface{}) 记录信息日志。 #### LogInfof(fields map[string]interface{}, message string, args ...interface{}) 记录信息日志(带字段)。 #### LogWarn(message string, args ...interface{}) 记录警告日志。 #### LogWarnf(fields map[string]interface{}, message string, args ...interface{}) 记录警告日志(带字段)。 #### LogError(message string, args ...interface{}) 记录错误日志。 #### LogErrorf(fields map[string]interface{}, message string, args ...interface{}) 记录错误日志(带字段)。 ### 邮件方法(黑盒模式) #### SendEmail(to []string, subject, body string, htmlBody ...string) error 发送邮件。 **参数:** - `to`: 收件人列表 - `subject`: 邮件主题 - `body`: 邮件正文(纯文本) - `htmlBody`: HTML正文(可选,如果设置了会优先使用) ### 短信方法(黑盒模式) #### SendSMS(phoneNumbers []string, templateParam interface{}, templateCode ...string) (*sms.SendResponse, error) 发送短信。 **参数:** - `phoneNumbers`: 手机号列表 - `templateParam`: 模板参数(map或JSON字符串) - `templateCode`: 模板代码(可选,如果为空使用配置中的模板代码) ### 存储方法(黑盒模式) #### UploadFile(ctx context.Context, objectKey string, reader io.Reader, contentType ...string) (string, error) 上传文件。 **参数:** - `ctx`: 上下文 - `objectKey`: 对象键(文件路径) - `reader`: 文件内容 - `contentType`: 文件类型(可选) **返回:** 文件访问URL和错误信息 **说明:** 自动根据配置选择OSS或MinIO(优先级:MinIO > OSS) #### GetFileURL(objectKey string, expires int64) (string, error) 获取文件访问URL。 **参数:** - `objectKey`: 对象键 - `expires`: 过期时间(秒),0表示永久有效 **返回:** 文件访问URL和错误信息 ### Excel导出方法(黑盒模式) #### ExportToExcel(w io.Writer, sheetName string, columns []ExportColumn, data interface{}) error 导出数据到Writer。 **参数:** - `w`: Writer对象(如http.ResponseWriter) - `sheetName`: 工作表名称(可选,默认为"Sheet1") - `columns`: 列定义 - `data`: 数据列表(可以是结构体切片或实现了ExportData接口的对象) **返回:** 错误信息 **示例:** ```go fac.ExportToExcel(w, "用户列表", columns, users) ``` #### ExportToExcelFile(filePath string, sheetName string, columns []ExportColumn, data interface{}) error 导出数据到文件。 **参数:** - `filePath`: 文件路径 - `sheetName`: 工作表名称(可选,默认为"Sheet1") - `columns`: 列定义 - `data`: 数据列表 **返回:** 错误信息 **示例:** ```go fac.ExportToExcelFile("users.xlsx", "用户列表", columns, users) ``` #### GetExcel() (*excel.Excel, error) 获取Excel导出器对象(高级功能时使用)。 **返回:** Excel导出器对象和错误信息 **说明:** - 仅在需要使用高级功能时使用 - 推荐使用黑盒方法:`ExportToExcel()`、`ExportToExcelFile()` **详细说明请参考:[Excel导出工具文档](./excel.md)** ### Redis方法(黑盒模式) #### RedisGet(ctx context.Context, key string) (string, error) 获取Redis值。 **参数:** - `ctx`: 上下文 - `key`: Redis键 **返回:** 值和错误信息(key不存在时返回空字符串) #### RedisSet(ctx context.Context, key string, value interface{}, expiration ...time.Duration) error 设置Redis值。 **参数:** - `ctx`: 上下文 - `key`: Redis键 - `value`: Redis值 - `expiration`: 过期时间(可选,0表示不过期) #### RedisDelete(ctx context.Context, keys ...string) error 删除Redis键。 **参数:** - `ctx`: 上下文 - `keys`: Redis键列表 #### RedisExists(ctx context.Context, key string) (bool, error) 检查Redis键是否存在。 **参数:** - `ctx`: 上下文 - `key`: Redis键 **返回:** 是否存在和错误信息 ### 数据库方法 #### GetDatabase() (*gorm.DB, error) 获取数据库连接对象(已初始化)。 **返回:** 已初始化的GORM数据库对象和错误信息 **说明:** - 支持MySQL、PostgreSQL、SQLite - 自动配置连接池参数 - 数据库时间统一使用UTC时区 - 延迟初始化,首次调用时创建连接 - 黑盒模式:只需传递config对象,无需自己实现创建逻辑 ### Redis方法 #### GetRedisClient() (*redis.Client, error) 获取Redis客户端对象(已初始化)。 **返回:** 已初始化的Redis客户端对象和错误信息 **说明:** - 自动处理所有配置检查和连接测试 - 自动设置默认值(连接池大小、超时时间等) - 连接失败时会自动关闭客户端并返回错误 - 返回的客户端已通过Ping测试,可直接使用 - 黑盒模式:只需传递config对象,无需自己实现创建逻辑 - 推荐使用 `RedisGet`、`RedisSet`、`RedisDelete` 等方法直接操作Redis - 如果需要使用Redis的高级功能(如Hash、List、Set等),可以使用此方法获取客户端对象 ### 配置方法 #### GetConfig() *config.Config 获取配置对象。 **返回:** 配置对象 ### HTTP响应方法(黑盒模式) #### Success(w http.ResponseWriter, data interface{}, message ...string) 发送成功响应。 **参数:** - `w`: HTTP响应写入器 - `data`: 响应数据 - `message`: 可选,成功消息(如果不提供,使用默认消息) **示例:** ```go fac.Success(w, user) // 使用默认消息 fac.Success(w, user, "获取成功") // 自定义消息 ``` #### Error(w http.ResponseWriter, code int, message string) 发送错误响应。 **参数:** - `w`: HTTP响应写入器 - `code`: 业务错误码 - `message`: 错误消息 #### SystemError(w http.ResponseWriter, message string) 发送系统错误响应(HTTP 500)。 **参数:** - `w`: HTTP响应写入器 - `message`: 错误消息 #### SuccessPage(w http.ResponseWriter, data interface{}, total int64, page, pageSize int, message ...string) 发送分页成功响应。 **参数:** - `w`: HTTP响应写入器 - `data`: 响应数据列表 - `total`: 总记录数 - `page`: 当前页码 - `pageSize`: 每页大小 - `message`: 可选,成功消息 ### HTTP请求方法(黑盒模式) #### ParseJSON(r *http.Request, v interface{}) error 解析JSON请求体。 **参数:** - `r`: HTTP请求 - `v`: 目标结构体指针 #### GetTimezone(r *http.Request) string 从请求的context中获取时区(需要配合middleware.Timezone使用)。 ### 类型转换方法(黑盒模式) #### ConvertInt(value string, defaultValue int) int 将字符串转换为int类型。 **参数:** - `value`: 待转换的字符串 - `defaultValue`: 转换失败或字符串为空时返回的默认值 **示例:** ```go // 从查询参数获取整数 id := fac.ConvertInt(r.URL.Query().Get("id"), 0) // 从表单获取整数 age := fac.ConvertInt(r.FormValue("age"), 0) ``` #### ConvertInt64(value string, defaultValue int64) int64 将字符串转换为int64类型。 **示例:** ```go id := fac.ConvertInt64(r.URL.Query().Get("id"), 0) ``` #### ConvertUint64(value string, defaultValue uint64) uint64 将字符串转换为uint64类型。 **示例:** ```go uid := fac.ConvertUint64(r.URL.Query().Get("uid"), 0) ``` #### ConvertUint32(value string, defaultValue uint32) uint32 将字符串转换为uint32类型。 **示例:** ```go userId := fac.ConvertUint32(r.URL.Query().Get("user_id"), 0) ``` #### ConvertBool(value string, defaultValue bool) bool 将字符串转换为bool类型。 **示例:** ```go isActive := fac.ConvertBool(r.URL.Query().Get("is_active"), false) ``` #### ConvertFloat64(value string, defaultValue float64) float64 将字符串转换为float64类型。 **示例:** ```go price := fac.ConvertFloat64(r.URL.Query().Get("price"), 0.0) ``` ### 日期时间工具方法(黑盒模式) #### Now(timezone ...string) time.Time 获取当前时间。 **参数:** - `timezone`: 可选,时区字符串(如 "Asia/Shanghai"),不指定则使用默认时区 #### ParseDateTime(value string, timezone ...string) (time.Time, error) 解析日期时间字符串(格式:2006-01-02 15:04:05)。 #### ParseDate(value string, timezone ...string) (time.Time, error) 解析日期字符串(格式:2006-01-02)。 #### FormatDateTime(t time.Time, timezone ...string) string 格式化日期时间(格式:2006-01-02 15:04:05)。 #### FormatDate(t time.Time, timezone ...string) string 格式化日期(格式:2006-01-02)。 #### FormatTime(t time.Time, timezone ...string) string 格式化时间(格式:15:04:05)。 #### ToUnix(t time.Time) int64 转换为Unix时间戳(秒)。 #### FromUnix(sec int64, timezone ...string) time.Time 从Unix时间戳创建时间。 #### ToUnixMilli(t time.Time) int64 转换为Unix毫秒时间戳。 #### FromUnixMilli(msec int64, timezone ...string) time.Time 从Unix毫秒时间戳创建时间。 #### AddDays(t time.Time, days int) time.Time 添加天数。 #### AddMonths(t time.Time, months int) time.Time 添加月数。 #### AddYears(t time.Time, years int) time.Time 添加年数。 #### StartOfDay(t time.Time, timezone ...string) time.Time 获取一天的开始时间(00:00:00)。 #### EndOfDay(t time.Time, timezone ...string) time.Time 获取一天的结束时间(23:59:59.999999999)。 #### StartOfMonth(t time.Time, timezone ...string) time.Time 获取月份的开始时间。 #### EndOfMonth(t time.Time, timezone ...string) time.Time 获取月份的结束时间。 #### StartOfYear(t time.Time, timezone ...string) time.Time 获取年份的开始时间。 #### EndOfYear(t time.Time, timezone ...string) time.Time 获取年份的结束时间。 #### DiffDays(t1, t2 time.Time) int 计算两个时间之间的天数差。 #### DiffHours(t1, t2 time.Time) int64 计算两个时间之间的小时差。 #### DiffMinutes(t1, t2 time.Time) int64 计算两个时间之间的分钟差。 #### DiffSeconds(t1, t2 time.Time) int64 计算两个时间之间的秒数差。 ### 加密工具方法(黑盒模式) #### 密码加密 ##### HashPassword(password string) (string, error) 使用bcrypt加密密码。 **参数:** - `password`: 原始密码 **返回:** 加密后的密码哈希值和错误信息 **示例:** ```go hashedPassword, err := fac.HashPassword("myPassword") ``` ##### CheckPassword(password, hash string) bool 验证密码。 **参数:** - `password`: 原始密码 - `hash`: 加密后的密码哈希值 **返回:** 密码是否正确 **示例:** ```go isValid := fac.CheckPassword("myPassword", hashedPassword) ``` #### 哈希计算 ##### MD5(text string) string 计算MD5哈希值。 **参数:** - `text`: 要计算哈希的文本 **返回:** MD5哈希值(十六进制字符串) **示例:** ```go hash := fac.MD5("text") ``` ##### SHA256(text string) string 计算SHA256哈希值。 **参数:** - `text`: 要计算哈希的文本 **返回:** SHA256哈希值(十六进制字符串) **示例:** ```go hash := fac.SHA256("text") ``` #### 随机字符串生成 ##### GenerateRandomString(length int) string 生成指定长度的随机字符串。 **参数:** - `length`: 字符串长度 **返回:** 随机字符串(包含大小写字母和数字) **示例:** ```go randomStr := fac.GenerateRandomString(16) ``` ##### GenerateRandomNumber(length int) string 生成指定长度的随机数字字符串。 **参数:** - `length`: 字符串长度 **返回:** 随机数字字符串 **示例:** ```go randomNum := fac.GenerateRandomNumber(6) ``` #### 业务相关随机码生成 ##### GenerateSMSCode() string 生成短信验证码。 **返回:** 6位数字验证码 **示例:** ```go code := fac.GenerateSMSCode() ``` ##### GenerateOrderNo(prefix string) string 生成订单号。 **参数:** - `prefix`: 订单号前缀 **返回:** 订单号(格式:前缀+时间戳+6位随机数) **示例:** ```go orderNo := fac.GenerateOrderNo("ORD") ``` ##### GeneratePaymentNo() string 生成支付单号。 **返回:** 支付单号(格式:PAY+时间戳+6位随机数) **示例:** ```go paymentNo := fac.GeneratePaymentNo() ``` ##### GenerateRefundNo() string 生成退款单号。 **返回:** 退款单号(格式:RF+时间戳+6位随机数) **示例:** ```go refundNo := fac.GenerateRefundNo() ``` ##### GenerateTransferNo() string 生成调拨单号。 **返回:** 调拨单号(格式:TF+时间戳+6位随机数) **示例:** ```go transferNo := fac.GenerateTransferNo() ``` ### 时间工具方法(黑盒模式) **说明**:Time 工具提供基础时间操作、时间戳、时间判断等功能,与 DateTime 工具的区别: - **DateTime**:专注于时区相关、格式化、解析、UTC转换 - **Time**:专注于基础时间操作、时间戳、时间判断、时间信息生成 #### 时间戳方法 ##### GetTimestamp() int64 获取当前时间戳(秒)。 ##### GetMillisTimestamp() int64 获取当前时间戳(毫秒)。 ##### GetUTCTimestamp() int64 获取UTC时间戳(秒)。 ##### GetUTCTimestampFromTime(t time.Time) int64 从指定时间获取UTC时间戳(秒)。 #### 格式化方法(自定义格式) ##### FormatTimeWithLayout(t time.Time, layout string) string 格式化时间(自定义格式)。 **参数:** - `t`: 时间对象 - `layout`: 时间格式,如 "2006-01-02 15:04:05",如果为空则使用默认格式 ##### FormatTimeUTC(t time.Time) string 格式化时间为UTC字符串(ISO 8601格式)。 ##### GetCurrentTime() string 获取当前时间字符串(使用默认格式 "2006-01-02 15:04:05")。 #### 解析方法(自定义格式) ##### ParseTime(timeStr, layout string) (time.Time, error) 解析时间字符串(自定义格式)。 **参数:** - `timeStr`: 时间字符串 - `layout`: 时间格式,如 "2006-01-02 15:04:05",如果为空则使用默认格式 #### 时间计算(补充 DateTime 的 Add 系列) ##### AddHours(t time.Time, hours int) time.Time 增加小时数。 ##### AddMinutes(t time.Time, minutes int) time.Time 增加分钟数。 #### 时间范围(周相关) ##### GetBeginOfWeek(t time.Time) time.Time 获取某周的开始时间(周一)。 ##### GetEndOfWeek(t time.Time) time.Time 获取某周的结束时间(周日)。 #### 时间判断 ##### IsToday(t time.Time) bool 判断是否为今天。 ##### IsYesterday(t time.Time) bool 判断是否为昨天。 ##### IsTomorrow(t time.Time) bool 判断是否为明天。 #### 时间信息生成 ##### GenerateTimeInfoWithTimezone(t time.Time, timezone string) TimeInfo 生成详细时间信息(指定时区)。 **参数:** - `t`: 时间对象 - `timezone`: 时区字符串,如 "Asia/Shanghai" **返回:** TimeInfo 结构体,包含: - `UTC`: UTC时间(RFC3339格式) - `Local`: 本地时间(RFC3339格式) - `Unix`: Unix时间戳(秒) - `Timezone`: 时区名称 - `Offset`: 时区偏移量(小时) - `RFC3339`: RFC3339格式时间 - `DateTime`: 日期时间格式(2006-01-02 15:04:05) - `Date`: 日期格式(2006-01-02) - `Time`: 时间格式(15:04:05) ### 金额工具方法(黑盒模式) #### GetMoneyCalculator() *tools.MoneyCalculator 获取金额计算器实例。 #### YuanToCents(yuan float64) int64 元转分。 **示例:** ```go cents := fac.YuanToCents(100.5) // 返回 10050 ``` #### CentsToYuan(cents int64) float64 分转元。 **示例:** ```go yuan := fac.CentsToYuan(10050) // 返回 100.5 ``` #### FormatYuan(cents int64) string 格式化显示金额(分转元,保留2位小数)。 **示例:** ```go str := fac.FormatYuan(10050) // 返回 "100.50" ``` ### 版本工具方法(黑盒模式) #### GetVersion() string 获取版本号。 **说明:** - 优先从环境变量 `DOCKER_TAG` 或 `VERSION` 中读取 - 如果没有设置环境变量,则使用默认版本号 ## 设计优势 ### 优势总结 1. **降低复杂度**:调用方无需关心客户端对象的创建和管理 2. **延迟初始化**:所有客户端在首次使用时才创建,提高性能 3. **自动选择**:存储类型根据配置自动选择,无需手动指定 4. **统一接口**:所有操作通过工厂方法调用,接口统一 5. **容错处理**:日志初始化失败时自动回退到标准输出 6. **代码简洁**:只提供黑盒模式方法,保持代码简洁清晰 ## 注意事项 1. **配置检查**:工厂方法会自动检查配置是否存在,如果配置为nil会返回错误 2. **错误处理**:所有方法都可能返回错误,需要正确处理 3. **延迟初始化**:所有客户端在首次使用时才创建,首次调用可能稍慢 4. **存储选择**:存储类型根据配置自动选择(优先级:MinIO > OSS) 5. **数据库对象**:数据库保持返回GORM对象,因为GORM已经提供了很好的抽象 6. **黑盒模式**:所有功能都通过工厂方法直接调用,无需获取底层客户端对象 ## 示例 完整示例请参考 `examples/factory_example.go`