初始版本,工具基础类
This commit is contained in:
124
examples/config_example.go
Normal file
124
examples/config_example.go
Normal file
@@ -0,0 +1,124 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
|
||||
"github.com/go-common/config"
|
||||
"github.com/go-common/middleware"
|
||||
// "gorm.io/driver/mysql"
|
||||
// "gorm.io/gorm"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// 加载配置文件
|
||||
cfg, err := config.LoadFromFile("./config/example.json")
|
||||
if err != nil {
|
||||
log.Fatal("Failed to load config:", err)
|
||||
}
|
||||
|
||||
// 1. 使用数据库配置
|
||||
fmt.Println("=== Database Config ===")
|
||||
dbConfig := cfg.GetDatabase()
|
||||
if dbConfig != nil {
|
||||
fmt.Printf("Type: %s\n", dbConfig.Type)
|
||||
fmt.Printf("Host: %s:%d\n", dbConfig.Host, dbConfig.Port)
|
||||
fmt.Printf("Database: %s\n", dbConfig.Database)
|
||||
fmt.Printf("User: %s\n", dbConfig.User)
|
||||
}
|
||||
|
||||
// 获取数据库连接字符串
|
||||
dsn, err := cfg.GetDatabaseDSN()
|
||||
if err != nil {
|
||||
log.Printf("Failed to get DSN: %v", err)
|
||||
} else {
|
||||
fmt.Printf("DSN: %s\n", dsn)
|
||||
// 实际使用时可以这样连接数据库
|
||||
// db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
|
||||
// if err != nil {
|
||||
// log.Fatal(err)
|
||||
// }
|
||||
}
|
||||
|
||||
// 2. 使用OSS配置
|
||||
fmt.Println("\n=== OSS Config ===")
|
||||
ossConfig := cfg.GetOSS()
|
||||
if ossConfig != nil {
|
||||
fmt.Printf("Provider: %s\n", ossConfig.Provider)
|
||||
fmt.Printf("Endpoint: %s\n", ossConfig.Endpoint)
|
||||
fmt.Printf("Bucket: %s\n", ossConfig.Bucket)
|
||||
fmt.Printf("Region: %s\n", ossConfig.Region)
|
||||
}
|
||||
|
||||
// 3. 使用Redis配置
|
||||
fmt.Println("\n=== Redis Config ===")
|
||||
redisConfig := cfg.GetRedis()
|
||||
if redisConfig != nil {
|
||||
fmt.Printf("Host: %s\n", redisConfig.Host)
|
||||
fmt.Printf("Port: %d\n", redisConfig.Port)
|
||||
fmt.Printf("Database: %d\n", redisConfig.Database)
|
||||
}
|
||||
|
||||
// 获取Redis地址
|
||||
redisAddr := cfg.GetRedisAddr()
|
||||
fmt.Printf("Redis Address: %s\n", redisAddr)
|
||||
|
||||
// 4. 使用CORS配置
|
||||
fmt.Println("\n=== CORS Config ===")
|
||||
corsConfig := cfg.GetCORS()
|
||||
if corsConfig != nil {
|
||||
fmt.Printf("Allowed Origins: %v\n", corsConfig.AllowedOrigins)
|
||||
fmt.Printf("Allowed Methods: %v\n", corsConfig.AllowedMethods)
|
||||
fmt.Printf("Max Age: %d\n", corsConfig.MaxAge)
|
||||
}
|
||||
|
||||
// 使用CORS配置创建中间件
|
||||
chain := middleware.NewChain(
|
||||
middleware.CORS(corsConfig),
|
||||
)
|
||||
fmt.Printf("CORS middleware created: %v\n", chain != nil)
|
||||
|
||||
// 5. 使用MinIO配置
|
||||
fmt.Println("\n=== MinIO Config ===")
|
||||
minioConfig := cfg.GetMinIO()
|
||||
if minioConfig != nil {
|
||||
fmt.Printf("Endpoint: %s\n", minioConfig.Endpoint)
|
||||
fmt.Printf("Bucket: %s\n", minioConfig.Bucket)
|
||||
fmt.Printf("UseSSL: %v\n", minioConfig.UseSSL)
|
||||
}
|
||||
|
||||
// 6. 使用邮件配置
|
||||
fmt.Println("\n=== Email Config ===")
|
||||
emailConfig := cfg.GetEmail()
|
||||
if emailConfig != nil {
|
||||
fmt.Printf("Host: %s:%d\n", emailConfig.Host, emailConfig.Port)
|
||||
fmt.Printf("From: %s <%s>\n", emailConfig.FromName, emailConfig.From)
|
||||
fmt.Printf("UseTLS: %v\n", emailConfig.UseTLS)
|
||||
}
|
||||
|
||||
// 7. 使用短信配置
|
||||
fmt.Println("\n=== SMS Config ===")
|
||||
smsConfig := cfg.GetSMS()
|
||||
if smsConfig != nil {
|
||||
fmt.Printf("Region: %s\n", smsConfig.Region)
|
||||
fmt.Printf("Sign Name: %s\n", smsConfig.SignName)
|
||||
fmt.Printf("Template Code: %s\n", smsConfig.TemplateCode)
|
||||
}
|
||||
|
||||
// 示例:实际使用配置连接数据库
|
||||
fmt.Println("\n=== Example: Connect to Database ===")
|
||||
if dbConfig != nil && dbConfig.Type == "mysql" {
|
||||
// 注意:这里只是示例,实际使用时需要确保数据库服务正在运行
|
||||
// db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
|
||||
// if err != nil {
|
||||
// log.Printf("Failed to connect to database: %v", err)
|
||||
// } else {
|
||||
// fmt.Println("Database connected successfully")
|
||||
// sqlDB, _ := db.DB()
|
||||
// sqlDB.SetMaxOpenConns(dbConfig.MaxOpenConns)
|
||||
// sqlDB.SetMaxIdleConns(dbConfig.MaxIdleConns)
|
||||
// sqlDB.SetConnMaxLifetime(time.Duration(dbConfig.ConnMaxLifetime) * time.Second)
|
||||
// }
|
||||
fmt.Println("Database connection example (commented out)")
|
||||
}
|
||||
}
|
||||
56
examples/datetime_example.go
Normal file
56
examples/datetime_example.go
Normal file
@@ -0,0 +1,56 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"time"
|
||||
|
||||
"github.com/go-common/datetime"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// 设置默认时区
|
||||
err := datetime.SetDefaultTimeZone(datetime.AsiaShanghai)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
// 获取当前时间
|
||||
now := datetime.Now()
|
||||
fmt.Printf("Current time: %s\n", datetime.FormatDateTime(now))
|
||||
|
||||
// 解析时间字符串
|
||||
t, err := datetime.ParseDateTime("2024-01-01 12:00:00")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
fmt.Printf("Parsed time: %s\n", datetime.FormatDateTime(t))
|
||||
|
||||
// 时区转换
|
||||
t2, err := datetime.ToTimezone(t, datetime.AmericaNewYork)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
fmt.Printf("Time in New York: %s\n", datetime.FormatDateTime(t2))
|
||||
|
||||
// Unix时间戳
|
||||
unix := datetime.ToUnix(now)
|
||||
fmt.Printf("Unix timestamp: %d\n", unix)
|
||||
t3 := datetime.FromUnix(unix)
|
||||
fmt.Printf("From Unix: %s\n", datetime.FormatDateTime(t3))
|
||||
|
||||
// 时间计算
|
||||
tomorrow := datetime.AddDays(now, 1)
|
||||
fmt.Printf("Tomorrow: %s\n", datetime.FormatDate(tomorrow))
|
||||
|
||||
// 时间范围
|
||||
startOfDay := datetime.StartOfDay(now)
|
||||
endOfDay := datetime.EndOfDay(now)
|
||||
fmt.Printf("Start of day: %s\n", datetime.FormatDateTime(startOfDay))
|
||||
fmt.Printf("End of day: %s\n", datetime.FormatDateTime(endOfDay))
|
||||
|
||||
// 时间差
|
||||
diff := datetime.DiffDays(now, tomorrow)
|
||||
fmt.Printf("Days difference: %d\n", diff)
|
||||
}
|
||||
|
||||
74
examples/datetime_utc_example.go
Normal file
74
examples/datetime_utc_example.go
Normal file
@@ -0,0 +1,74 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"time"
|
||||
|
||||
"github.com/go-common/datetime"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// 示例1:将当前时间转换为UTC
|
||||
fmt.Println("=== Example 1: Convert Current Time to UTC ===")
|
||||
now := time.Now()
|
||||
utcTime := datetime.ToUTC(now)
|
||||
fmt.Printf("Local time: %s\n", datetime.FormatDateTime(now))
|
||||
fmt.Printf("UTC time: %s\n", datetime.FormatDateTime(utcTime))
|
||||
|
||||
// 示例2:从指定时区转换为UTC
|
||||
fmt.Println("\n=== Example 2: Convert from Specific Timezone to UTC ===")
|
||||
// 解析上海时区的时间
|
||||
shanghaiTime, err := datetime.ParseDateTime("2024-01-01 12:00:00", datetime.AsiaShanghai)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
fmt.Printf("Shanghai time: %s\n", datetime.FormatDateTime(shanghaiTime, datetime.AsiaShanghai))
|
||||
|
||||
// 转换为UTC
|
||||
utcTime2, err := datetime.ToUTCFromTimezone(shanghaiTime, datetime.AsiaShanghai)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
fmt.Printf("UTC time: %s\n", datetime.FormatDateTime(utcTime2, datetime.UTC))
|
||||
|
||||
// 示例3:解析时间字符串并直接转换为UTC
|
||||
fmt.Println("\n=== Example 3: Parse and Convert to UTC ===")
|
||||
utcTime3, err := datetime.ParseDateTimeToUTC("2024-01-01 12:00:00", datetime.AsiaShanghai)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
fmt.Printf("Parsed from Shanghai timezone, UTC: %s\n", datetime.FormatDateTime(utcTime3, datetime.UTC))
|
||||
|
||||
// 示例4:解析日期并转换为UTC
|
||||
fmt.Println("\n=== Example 4: Parse Date and Convert to UTC ===")
|
||||
utcTime4, err := datetime.ParseDateToUTC("2024-01-01", datetime.AsiaShanghai)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
fmt.Printf("Date parsed from Shanghai timezone, UTC: %s\n", datetime.FormatDateTime(utcTime4, datetime.UTC))
|
||||
|
||||
// 示例5:数据库存储场景
|
||||
fmt.Println("\n=== Example 5: Database Storage Scenario ===")
|
||||
// 从请求中获取时间(假设是上海时区)
|
||||
requestTimeStr := "2024-01-01 12:00:00"
|
||||
requestTimezone := datetime.AsiaShanghai
|
||||
|
||||
// 转换为UTC时间(用于数据库存储)
|
||||
dbTime, err := datetime.ParseDateTimeToUTC(requestTimeStr, requestTimezone)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
fmt.Printf("Request time (Shanghai): %s\n", requestTimeStr)
|
||||
fmt.Printf("Database time (UTC): %s\n", datetime.FormatDateTime(dbTime, datetime.UTC))
|
||||
|
||||
// 从数据库读取UTC时间,转换为用户时区显示
|
||||
userTimezone := datetime.AsiaShanghai
|
||||
displayTime, err := datetime.ToTimezone(dbTime, userTimezone)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
fmt.Printf("Display time (Shanghai): %s\n", datetime.FormatDateTime(displayTime, userTimezone))
|
||||
}
|
||||
|
||||
121
examples/email_example.go
Normal file
121
examples/email_example.go
Normal file
@@ -0,0 +1,121 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
|
||||
"github.com/go-common/config"
|
||||
"github.com/go-common/email"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// 加载配置
|
||||
cfg, err := config.LoadFromFile("./config/example.json")
|
||||
if err != nil {
|
||||
log.Fatal("Failed to load config:", err)
|
||||
}
|
||||
|
||||
// 创建邮件发送器
|
||||
emailConfig := cfg.GetEmail()
|
||||
if emailConfig == nil {
|
||||
log.Fatal("Email config is nil")
|
||||
}
|
||||
|
||||
mailer, err := email.NewEmail(emailConfig)
|
||||
if err != nil {
|
||||
log.Fatal("Failed to create email client:", err)
|
||||
}
|
||||
|
||||
// 示例1:发送原始邮件内容(推荐,最灵活)
|
||||
fmt.Println("=== Example 1: Send Raw Email Content ===")
|
||||
// 外部构建完整的邮件内容(MIME格式)
|
||||
emailBody := []byte(`From: ` + emailConfig.From + `
|
||||
To: recipient@example.com
|
||||
Subject: 原始邮件测试
|
||||
Content-Type: text/html; charset=UTF-8
|
||||
|
||||
<html>
|
||||
<body>
|
||||
<h1>这是原始邮件内容</h1>
|
||||
<p>由外部完全控制邮件格式和内容</p>
|
||||
</body>
|
||||
</html>
|
||||
`)
|
||||
|
||||
err = mailer.SendRaw(
|
||||
[]string{"recipient@example.com"},
|
||||
emailBody,
|
||||
)
|
||||
if err != nil {
|
||||
log.Printf("Failed to send raw email: %v", err)
|
||||
} else {
|
||||
fmt.Println("Raw email sent successfully")
|
||||
}
|
||||
|
||||
// 示例2:发送简单邮件(便捷方法)
|
||||
fmt.Println("\n=== Example 2: Send Simple Email ===")
|
||||
err = mailer.SendSimple(
|
||||
[]string{"recipient@example.com"},
|
||||
"测试邮件",
|
||||
"这是一封测试邮件,使用Go标准库发送。",
|
||||
)
|
||||
if err != nil {
|
||||
log.Printf("Failed to send email: %v", err)
|
||||
} else {
|
||||
fmt.Println("Email sent successfully")
|
||||
}
|
||||
|
||||
// 示例3:发送HTML邮件
|
||||
fmt.Println("\n=== Example 3: Send HTML Email ===")
|
||||
htmlBody := `
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
</head>
|
||||
<body>
|
||||
<h1>欢迎使用邮件服务</h1>
|
||||
<p>这是一封HTML格式的邮件。</p>
|
||||
<p>支持<strong>富文本</strong>格式。</p>
|
||||
</body>
|
||||
</html>
|
||||
`
|
||||
|
||||
err = mailer.SendHTML(
|
||||
[]string{"recipient@example.com"},
|
||||
"HTML邮件测试",
|
||||
htmlBody,
|
||||
)
|
||||
if err != nil {
|
||||
log.Printf("Failed to send HTML email: %v", err)
|
||||
} else {
|
||||
fmt.Println("HTML email sent successfully")
|
||||
}
|
||||
|
||||
// 示例4:发送完整邮件(包含抄送、密送)
|
||||
fmt.Println("\n=== Example 4: Send Full Email ===")
|
||||
msg := &email.Message{
|
||||
To: []string{"to@example.com"},
|
||||
Cc: []string{"cc@example.com"},
|
||||
Bcc: []string{"bcc@example.com"},
|
||||
Subject: "完整邮件示例",
|
||||
Body: "这是纯文本正文",
|
||||
HTMLBody: `
|
||||
<html>
|
||||
<body>
|
||||
<h1>这是HTML正文</h1>
|
||||
<p>支持同时发送纯文本和HTML版本。</p>
|
||||
</body>
|
||||
</html>
|
||||
`,
|
||||
}
|
||||
|
||||
err = mailer.Send(msg)
|
||||
if err != nil {
|
||||
log.Printf("Failed to send full email: %v", err)
|
||||
} else {
|
||||
fmt.Println("Full email sent successfully")
|
||||
}
|
||||
|
||||
fmt.Println("\nNote: Make sure your email configuration is correct and SMTP service is enabled.")
|
||||
}
|
||||
|
||||
101
examples/http_example.go
Normal file
101
examples/http_example.go
Normal file
@@ -0,0 +1,101 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
"net/http"
|
||||
|
||||
"github.com/go-common/http"
|
||||
)
|
||||
|
||||
// 用户结构
|
||||
type User struct {
|
||||
ID int64 `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Email string `json:"email"`
|
||||
}
|
||||
|
||||
// 获取用户列表
|
||||
func GetUserList(w http.ResponseWriter, r *http.Request) {
|
||||
// 获取分页参数
|
||||
page, pageSize := http.GetPaginationParams(r)
|
||||
|
||||
// 获取查询参数
|
||||
keyword := http.GetQuery(r, "keyword", "")
|
||||
|
||||
// 模拟查询数据
|
||||
users := []User{
|
||||
{ID: 1, Name: "User1", Email: "user1@example.com"},
|
||||
{ID: 2, Name: "User2", Email: "user2@example.com"},
|
||||
}
|
||||
total := int64(100)
|
||||
|
||||
// 返回分页响应
|
||||
http.SuccessPage(w, users, total, page, pageSize)
|
||||
}
|
||||
|
||||
// 创建用户
|
||||
func CreateUser(w http.ResponseWriter, r *http.Request) {
|
||||
// 解析请求体
|
||||
var req struct {
|
||||
Name string `json:"name"`
|
||||
Email string `json:"email"`
|
||||
}
|
||||
|
||||
if err := http.ParseJSON(r, &req); err != nil {
|
||||
http.BadRequest(w, "请求参数解析失败")
|
||||
return
|
||||
}
|
||||
|
||||
// 参数验证
|
||||
if req.Name == "" {
|
||||
http.Error(w, 1001, "用户名不能为空")
|
||||
return
|
||||
}
|
||||
|
||||
// 模拟创建用户
|
||||
user := User{
|
||||
ID: 1,
|
||||
Name: req.Name,
|
||||
Email: req.Email,
|
||||
}
|
||||
|
||||
// 返回成功响应
|
||||
http.SuccessWithMessage(w, "创建成功", user)
|
||||
}
|
||||
|
||||
// 获取用户详情
|
||||
func GetUser(w http.ResponseWriter, r *http.Request) {
|
||||
// 获取查询参数
|
||||
id := http.GetQueryInt64(r, "id", 0)
|
||||
|
||||
if id == 0 {
|
||||
http.BadRequest(w, "用户ID不能为空")
|
||||
return
|
||||
}
|
||||
|
||||
// 模拟查询用户
|
||||
if id == 1 {
|
||||
user := User{ID: 1, Name: "User1", Email: "user1@example.com"}
|
||||
http.Success(w, user)
|
||||
} else {
|
||||
http.Error(w, 1002, "用户不存在")
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
http.HandleFunc("/users", func(w http.ResponseWriter, r *http.Request) {
|
||||
switch r.Method {
|
||||
case http.MethodGet:
|
||||
GetUserList(w, r)
|
||||
case http.MethodPost:
|
||||
CreateUser(w, r)
|
||||
default:
|
||||
http.NotFound(w, "方法不支持")
|
||||
}
|
||||
})
|
||||
|
||||
http.HandleFunc("/user", GetUser)
|
||||
|
||||
log.Println("Server started on :8080")
|
||||
log.Fatal(http.ListenAndServe(":8080", nil))
|
||||
}
|
||||
64
examples/middleware_example.go
Normal file
64
examples/middleware_example.go
Normal file
@@ -0,0 +1,64 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
"net/http"
|
||||
|
||||
"github.com/go-common/datetime"
|
||||
"github.com/go-common/http"
|
||||
"github.com/go-common/middleware"
|
||||
)
|
||||
|
||||
// 示例:使用CORS和时区中间件
|
||||
func main() {
|
||||
// 配置CORS
|
||||
corsConfig := &middleware.CORSConfig{
|
||||
AllowedOrigins: []string{"*"},
|
||||
AllowedMethods: []string{"GET", "POST", "PUT", "DELETE", "OPTIONS"},
|
||||
AllowedHeaders: []string{
|
||||
"Content-Type",
|
||||
"Authorization",
|
||||
"X-Requested-With",
|
||||
"X-Timezone",
|
||||
},
|
||||
AllowCredentials: false,
|
||||
MaxAge: 3600,
|
||||
}
|
||||
|
||||
// 创建中间件链
|
||||
chain := middleware.NewChain(
|
||||
middleware.CORS(corsConfig),
|
||||
middleware.Timezone,
|
||||
)
|
||||
|
||||
// 定义处理器
|
||||
handler := chain.ThenFunc(apiHandler)
|
||||
|
||||
// 注册路由
|
||||
http.Handle("/api", handler)
|
||||
|
||||
log.Println("Server started on :8080")
|
||||
log.Println("Try: curl -H 'X-Timezone: America/New_York' http://localhost:8080/api")
|
||||
log.Fatal(http.ListenAndServe(":8080", nil))
|
||||
}
|
||||
|
||||
// apiHandler 处理API请求
|
||||
func apiHandler(w http.ResponseWriter, r *http.Request) {
|
||||
// 从context获取时区
|
||||
timezone := http.GetTimezone(r)
|
||||
|
||||
// 使用时区进行时间处理
|
||||
now := datetime.Now(timezone)
|
||||
startOfDay := datetime.StartOfDay(now, timezone)
|
||||
endOfDay := datetime.EndOfDay(now, timezone)
|
||||
|
||||
// 返回响应
|
||||
http.Success(w, map[string]interface{}{
|
||||
"message": "Hello from API",
|
||||
"timezone": timezone,
|
||||
"currentTime": datetime.FormatDateTime(now),
|
||||
"startOfDay": datetime.FormatDateTime(startOfDay),
|
||||
"endOfDay": datetime.FormatDateTime(endOfDay),
|
||||
})
|
||||
}
|
||||
|
||||
58
examples/migration_example.go
Normal file
58
examples/migration_example.go
Normal file
@@ -0,0 +1,58 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
|
||||
"gorm.io/driver/mysql"
|
||||
"gorm.io/gorm"
|
||||
"github.com/go-common/migration"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// 初始化数据库连接
|
||||
dsn := "user:password@tcp(localhost:3306)/dbname?charset=utf8mb4&parseTime=True&loc=Local"
|
||||
db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
// 创建迁移器
|
||||
migrator := migration.NewMigrator(db)
|
||||
|
||||
// 添加迁移
|
||||
migrator.AddMigration(migration.Migration{
|
||||
Version: "20240101000001",
|
||||
Description: "create_users_table",
|
||||
Up: func(db *gorm.DB) error {
|
||||
return db.Exec(`
|
||||
CREATE TABLE IF NOT EXISTS users (
|
||||
id INT PRIMARY KEY AUTO_INCREMENT,
|
||||
name VARCHAR(255) NOT NULL,
|
||||
email VARCHAR(255) UNIQUE NOT NULL,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
)
|
||||
`).Error
|
||||
},
|
||||
Down: func(db *gorm.DB) error {
|
||||
return db.Exec("DROP TABLE IF EXISTS users").Error
|
||||
},
|
||||
})
|
||||
|
||||
// 执行迁移
|
||||
if err := migrator.Up(); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
// 查看迁移状态
|
||||
status, err := migrator.Status()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
for _, s := range status {
|
||||
fmt.Printf("Version: %s, Description: %s, Applied: %v\n",
|
||||
s.Version, s.Description, s.Applied)
|
||||
}
|
||||
}
|
||||
|
||||
102
examples/sms_example.go
Normal file
102
examples/sms_example.go
Normal file
@@ -0,0 +1,102 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
|
||||
"github.com/go-common/config"
|
||||
"github.com/go-common/sms"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// 加载配置
|
||||
cfg, err := config.LoadFromFile("./config/example.json")
|
||||
if err != nil {
|
||||
log.Fatal("Failed to load config:", err)
|
||||
}
|
||||
|
||||
// 创建短信发送器
|
||||
smsConfig := cfg.GetSMS()
|
||||
if smsConfig == nil {
|
||||
log.Fatal("SMS config is nil")
|
||||
}
|
||||
|
||||
smsClient, err := sms.NewSMS(smsConfig)
|
||||
if err != nil {
|
||||
log.Fatal("Failed to create SMS client:", err)
|
||||
}
|
||||
|
||||
// 示例1:发送原始请求(推荐,最灵活)
|
||||
fmt.Println("=== Example 1: Send Raw SMS Request ===")
|
||||
// 外部构建完整的请求参数
|
||||
params := map[string]string{
|
||||
"PhoneNumbers": "13800138000",
|
||||
"SignName": smsConfig.SignName,
|
||||
"TemplateCode": smsConfig.TemplateCode,
|
||||
"TemplateParam": `{"code":"123456","expire":"5"}`,
|
||||
}
|
||||
|
||||
resp, err := smsClient.SendRaw(params)
|
||||
if err != nil {
|
||||
log.Printf("Failed to send raw SMS: %v", err)
|
||||
} else {
|
||||
fmt.Printf("Raw SMS sent successfully, RequestID: %s\n", resp.RequestID)
|
||||
}
|
||||
|
||||
// 示例2:发送简单短信(使用配置中的模板代码)
|
||||
fmt.Println("\n=== Example 2: Send Simple SMS ===")
|
||||
templateParam := map[string]string{
|
||||
"code": "123456",
|
||||
"expire": "5",
|
||||
}
|
||||
|
||||
resp2, err := smsClient.SendSimple(
|
||||
[]string{"13800138000"},
|
||||
templateParam,
|
||||
)
|
||||
if err != nil {
|
||||
log.Printf("Failed to send SMS: %v", err)
|
||||
} else {
|
||||
fmt.Printf("SMS sent successfully, RequestID: %s\n", resp2.RequestID)
|
||||
}
|
||||
|
||||
// 示例3:使用指定模板发送短信
|
||||
fmt.Println("\n=== Example 3: Send SMS with Template ===")
|
||||
templateParam3 := map[string]string{
|
||||
"code": "654321",
|
||||
"expire": "10",
|
||||
}
|
||||
|
||||
resp3, err := smsClient.SendWithTemplate(
|
||||
[]string{"13800138000"},
|
||||
"SMS_123456789", // 使用指定的模板代码
|
||||
templateParam3,
|
||||
)
|
||||
if err != nil {
|
||||
log.Printf("Failed to send SMS: %v", err)
|
||||
} else {
|
||||
fmt.Printf("SMS sent successfully, RequestID: %s\n", resp3.RequestID)
|
||||
}
|
||||
|
||||
// 示例4:使用JSON字符串作为模板参数
|
||||
fmt.Println("\n=== Example 4: Send SMS with JSON String Template Param ===")
|
||||
req := &sms.SendRequest{
|
||||
PhoneNumbers: []string{"13800138000"},
|
||||
TemplateCode: smsConfig.TemplateCode,
|
||||
TemplateParam: `{"code":"888888","expire":"15"}`, // 直接使用JSON字符串
|
||||
}
|
||||
|
||||
resp4, err := smsClient.Send(req)
|
||||
if err != nil {
|
||||
log.Printf("Failed to send SMS: %v", err)
|
||||
} else {
|
||||
fmt.Printf("SMS sent successfully, RequestID: %s\n", resp4.RequestID)
|
||||
}
|
||||
|
||||
fmt.Println("\nNote: Make sure your Aliyun SMS service is configured correctly:")
|
||||
fmt.Println("1. AccessKey ID and Secret are valid")
|
||||
fmt.Println("2. Sign name is approved")
|
||||
fmt.Println("3. Template code is approved")
|
||||
fmt.Println("4. Template parameters match the template definition")
|
||||
}
|
||||
|
||||
71
examples/storage_example.go
Normal file
71
examples/storage_example.go
Normal file
@@ -0,0 +1,71 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
"net/http"
|
||||
|
||||
"github.com/go-common/config"
|
||||
"github.com/go-common/middleware"
|
||||
"github.com/go-common/storage"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// 加载配置
|
||||
cfg, err := config.LoadFromFile("./config/example.json")
|
||||
if err != nil {
|
||||
log.Fatal("Failed to load config:", err)
|
||||
}
|
||||
|
||||
// 创建存储实例(使用OSS)
|
||||
// 注意:需要先实现OSS SDK集成
|
||||
ossStorage, err := storage.NewStorage(storage.StorageTypeOSS, cfg)
|
||||
if err != nil {
|
||||
log.Printf("Failed to create OSS storage: %v", err)
|
||||
log.Println("Note: OSS SDK integration is required")
|
||||
// 继续演示其他功能
|
||||
} else {
|
||||
// 创建上传处理器
|
||||
uploadHandler := storage.NewUploadHandler(storage.UploadHandlerConfig{
|
||||
Storage: ossStorage,
|
||||
MaxFileSize: 10 * 1024 * 1024, // 10MB
|
||||
AllowedExts: []string{".jpg", ".jpeg", ".png", ".gif", ".pdf"},
|
||||
ObjectPrefix: "uploads/",
|
||||
})
|
||||
|
||||
// 创建代理查看处理器
|
||||
proxyHandler := storage.NewProxyHandler(ossStorage)
|
||||
|
||||
// 创建中间件链
|
||||
chain := middleware.NewChain(
|
||||
middleware.CORS(cfg.GetCORS()),
|
||||
middleware.Timezone,
|
||||
)
|
||||
|
||||
// 注册路由
|
||||
mux := http.NewServeMux()
|
||||
mux.Handle("/upload", chain.Then(uploadHandler))
|
||||
mux.Handle("/file", chain.Then(proxyHandler))
|
||||
|
||||
log.Println("Storage server started on :8080")
|
||||
log.Println("Upload: POST /upload")
|
||||
log.Println("View: GET /file?key=images/test.jpg")
|
||||
log.Fatal(http.ListenAndServe(":8080", mux))
|
||||
}
|
||||
|
||||
// 演示MinIO存储
|
||||
minioStorage, err := storage.NewStorage(storage.StorageTypeMinIO, cfg)
|
||||
if err != nil {
|
||||
log.Printf("Failed to create MinIO storage: %v", err)
|
||||
log.Println("Note: MinIO SDK integration is required")
|
||||
} else {
|
||||
log.Printf("MinIO storage created: %v", minioStorage != nil)
|
||||
}
|
||||
|
||||
// 演示对象键生成
|
||||
objectKey1 := storage.GenerateObjectKey("images/", "test.jpg")
|
||||
log.Printf("Object key 1: %s", objectKey1)
|
||||
|
||||
objectKey2 := storage.GenerateObjectKeyWithDate("images", "test.jpg")
|
||||
log.Printf("Object key 2: %s", objectKey2)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user