调整项目结构,factory只负责暴露方法,不实现业务细节
This commit is contained in:
@@ -9,11 +9,13 @@ import (
|
||||
|
||||
"git.toowon.com/jimmy/go-common/config"
|
||||
"git.toowon.com/jimmy/go-common/email"
|
||||
commonhttp "git.toowon.com/jimmy/go-common/http"
|
||||
"git.toowon.com/jimmy/go-common/logger"
|
||||
"git.toowon.com/jimmy/go-common/middleware"
|
||||
"git.toowon.com/jimmy/go-common/migration"
|
||||
"git.toowon.com/jimmy/go-common/sms"
|
||||
"git.toowon.com/jimmy/go-common/storage"
|
||||
"git.toowon.com/jimmy/go-common/tools"
|
||||
"github.com/redis/go-redis/v9"
|
||||
"gorm.io/driver/mysql"
|
||||
"gorm.io/driver/postgres"
|
||||
@@ -21,6 +23,51 @@ import (
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
// ========== HTTP响应结构体(暴露给外部项目使用) ==========
|
||||
|
||||
// Response 标准响应结构(暴露给外部项目使用)
|
||||
// 外部项目可以直接使用 factory.Response 创建响应对象
|
||||
//
|
||||
// 示例:
|
||||
//
|
||||
// response := factory.Response{
|
||||
// Code: 0,
|
||||
// Message: "success",
|
||||
// Data: data,
|
||||
// }
|
||||
type Response = commonhttp.Response
|
||||
|
||||
// PageResponse 分页响应结构(暴露给外部项目使用)
|
||||
// 外部项目可以直接使用 factory.PageResponse 创建分页响应对象
|
||||
type PageResponse = commonhttp.PageResponse
|
||||
|
||||
// PageData 分页数据(暴露给外部项目使用)
|
||||
// 外部项目可以直接使用 factory.PageData 创建分页数据对象
|
||||
//
|
||||
// 示例:
|
||||
//
|
||||
// pageData := &factory.PageData{
|
||||
// List: users,
|
||||
// Total: 100,
|
||||
// Page: 1,
|
||||
// PageSize: 20,
|
||||
// }
|
||||
// fac.Success(w, pageData)
|
||||
type PageData = commonhttp.PageData
|
||||
|
||||
// ========== HTTP请求结构体(暴露给外部项目使用) ==========
|
||||
|
||||
// PaginationRequest 分页请求结构(暴露给外部项目使用)
|
||||
// 外部项目可以直接使用 factory.PaginationRequest 创建分页请求对象
|
||||
//
|
||||
// 示例:
|
||||
//
|
||||
// type ListUserRequest struct {
|
||||
// Keyword string `json:"keyword"`
|
||||
// factory.PaginationRequest // 嵌入分页请求结构
|
||||
// }
|
||||
type PaginationRequest = commonhttp.PaginationRequest
|
||||
|
||||
// Factory 工厂类 - 黑盒模式设计
|
||||
//
|
||||
// 核心理念:
|
||||
@@ -90,17 +137,8 @@ func (f *Factory) getEmailClient() (*email.Email, error) {
|
||||
return f.email, nil
|
||||
}
|
||||
|
||||
if f.cfg.Email == nil {
|
||||
return nil, fmt.Errorf("email config is nil")
|
||||
}
|
||||
|
||||
e, err := email.NewEmail(f.cfg.Email)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create email client: %w", err)
|
||||
}
|
||||
|
||||
f.email = e
|
||||
return e, nil
|
||||
f.email = email.NewEmail(f.cfg)
|
||||
return f.email, nil
|
||||
}
|
||||
|
||||
// SendEmail 发送邮件(黑盒模式,推荐使用)
|
||||
@@ -114,18 +152,7 @@ func (f *Factory) SendEmail(to []string, subject, body string, htmlBody ...strin
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
msg := &email.Message{
|
||||
To: to,
|
||||
Subject: subject,
|
||||
Body: body,
|
||||
}
|
||||
|
||||
if len(htmlBody) > 0 && htmlBody[0] != "" {
|
||||
msg.HTMLBody = htmlBody[0]
|
||||
}
|
||||
|
||||
return e.Send(msg)
|
||||
return e.SendEmail(to, subject, body, htmlBody...)
|
||||
}
|
||||
|
||||
// getSMSClient 获取短信客户端(内部方法,延迟初始化)
|
||||
@@ -134,17 +161,8 @@ func (f *Factory) getSMSClient() (*sms.SMS, error) {
|
||||
return f.sms, nil
|
||||
}
|
||||
|
||||
if f.cfg.SMS == nil {
|
||||
return nil, fmt.Errorf("SMS config is nil")
|
||||
}
|
||||
|
||||
s, err := sms.NewSMS(f.cfg.SMS)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create SMS client: %w", err)
|
||||
}
|
||||
|
||||
f.sms = s
|
||||
return s, nil
|
||||
f.sms = sms.NewSMS(f.cfg)
|
||||
return f.sms, nil
|
||||
}
|
||||
|
||||
// SendSMS 发送短信(黑盒模式,推荐使用)
|
||||
@@ -157,17 +175,7 @@ func (f *Factory) SendSMS(phoneNumbers []string, templateParam interface{}, temp
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
req := &sms.SendRequest{
|
||||
PhoneNumbers: phoneNumbers,
|
||||
TemplateParam: templateParam,
|
||||
}
|
||||
|
||||
if len(templateCode) > 0 && templateCode[0] != "" {
|
||||
req.TemplateCode = templateCode[0]
|
||||
}
|
||||
|
||||
return s.Send(req)
|
||||
return s.SendSMS(phoneNumbers, templateParam, templateCode...)
|
||||
}
|
||||
|
||||
// getLogger 获取日志记录器(内部方法,延迟初始化)
|
||||
@@ -862,3 +870,328 @@ func (f *Factory) GetMigrationStatus(migrationsDir string) ([]migration.Migratio
|
||||
|
||||
return status, nil
|
||||
}
|
||||
|
||||
// ========== HTTP响应方法(黑盒模式,推荐使用) ==========
|
||||
//
|
||||
// 这些方法直接调用 http 包的公共方法,保持低耦合。
|
||||
// 推荐直接使用 factory.Success() 等方法,而不是通过 handler。
|
||||
|
||||
// Success 成功响应(黑盒模式,推荐使用)
|
||||
// w: ResponseWriter
|
||||
// data: 响应数据,可以为nil
|
||||
// message: 响应消息(可选),如果为空则使用默认消息 "success"
|
||||
//
|
||||
// 示例:
|
||||
//
|
||||
// fac, _ := factory.NewFactoryFromFile("config.json")
|
||||
// http.HandleFunc("/user", func(w http.ResponseWriter, r *http.Request) {
|
||||
// fac.Success(w, user) // 只有数据
|
||||
// fac.Success(w, user, "查询成功") // 数据+消息
|
||||
// })
|
||||
func (f *Factory) Success(w http.ResponseWriter, data interface{}, message ...string) {
|
||||
commonhttp.Success(w, data, message...)
|
||||
}
|
||||
|
||||
// SuccessPage 分页成功响应(黑盒模式,推荐使用)
|
||||
// w: ResponseWriter
|
||||
// list: 数据列表
|
||||
// total: 总记录数
|
||||
// page: 当前页码
|
||||
// pageSize: 每页大小
|
||||
// message: 响应消息(可选),如果为空则使用默认消息 "success"
|
||||
func (f *Factory) SuccessPage(w http.ResponseWriter, list interface{}, total int64, page, pageSize int, message ...string) {
|
||||
commonhttp.SuccessPage(w, list, total, page, pageSize, message...)
|
||||
}
|
||||
|
||||
// Error 错误响应(黑盒模式,推荐使用)
|
||||
// w: ResponseWriter
|
||||
// code: 业务错误码,非0表示业务错误
|
||||
// message: 错误消息
|
||||
func (f *Factory) Error(w http.ResponseWriter, code int, message string) {
|
||||
commonhttp.Error(w, code, message)
|
||||
}
|
||||
|
||||
// SystemError 系统错误响应(返回HTTP 500)(黑盒模式,推荐使用)
|
||||
// w: ResponseWriter
|
||||
// message: 错误消息
|
||||
func (f *Factory) SystemError(w http.ResponseWriter, message string) {
|
||||
commonhttp.SystemError(w, message)
|
||||
}
|
||||
|
||||
// ========== HTTP请求解析方法(黑盒模式,推荐使用) ==========
|
||||
//
|
||||
// 这些方法直接调用 http 包的公共方法,保持低耦合。
|
||||
// 推荐直接使用 factory.ParseJSON()、factory.GetQuery() 等方法。
|
||||
|
||||
// ParseJSON 解析JSON请求体(黑盒模式,推荐使用)
|
||||
// r: HTTP请求
|
||||
// v: 目标结构体指针
|
||||
//
|
||||
// 示例:
|
||||
//
|
||||
// var req struct {
|
||||
// Name string `json:"name"`
|
||||
// }
|
||||
// if err := fac.ParseJSON(r, &req); err != nil {
|
||||
// fac.Error(w, 400, "请求参数解析失败")
|
||||
// return
|
||||
// }
|
||||
func (f *Factory) ParseJSON(r *http.Request, v interface{}) error {
|
||||
return commonhttp.ParseJSON(r, v)
|
||||
}
|
||||
|
||||
// ParsePaginationRequest 从请求中解析分页参数(黑盒模式,推荐使用)
|
||||
// r: HTTP请求
|
||||
// 支持从查询参数和form表单中解析
|
||||
// 优先级:查询参数 > form表单
|
||||
//
|
||||
// 示例:
|
||||
//
|
||||
// pagination := fac.ParsePaginationRequest(r)
|
||||
// page := pagination.GetPage()
|
||||
// pageSize := pagination.GetSize()
|
||||
func (f *Factory) ParsePaginationRequest(r *http.Request) *PaginationRequest {
|
||||
return commonhttp.ParsePaginationRequest(r)
|
||||
}
|
||||
|
||||
// GetQuery 获取查询参数(字符串)(黑盒模式,推荐使用)
|
||||
// r: HTTP请求
|
||||
// key: 参数名
|
||||
// defaultValue: 默认值
|
||||
func (f *Factory) GetQuery(r *http.Request, key, defaultValue string) string {
|
||||
return commonhttp.GetQuery(r, key, defaultValue)
|
||||
}
|
||||
|
||||
// GetQueryInt 获取整数查询参数(黑盒模式,推荐使用)
|
||||
// r: HTTP请求
|
||||
// key: 参数名
|
||||
// defaultValue: 默认值
|
||||
func (f *Factory) GetQueryInt(r *http.Request, key string, defaultValue int) int {
|
||||
return commonhttp.GetQueryInt(r, key, defaultValue)
|
||||
}
|
||||
|
||||
// GetQueryInt64 获取int64查询参数(黑盒模式,推荐使用)
|
||||
// r: HTTP请求
|
||||
// key: 参数名
|
||||
// defaultValue: 默认值
|
||||
func (f *Factory) GetQueryInt64(r *http.Request, key string, defaultValue int64) int64 {
|
||||
return commonhttp.GetQueryInt64(r, key, defaultValue)
|
||||
}
|
||||
|
||||
// GetQueryBool 获取布尔查询参数(黑盒模式,推荐使用)
|
||||
// r: HTTP请求
|
||||
// key: 参数名
|
||||
// defaultValue: 默认值
|
||||
func (f *Factory) GetQueryBool(r *http.Request, key string, defaultValue bool) bool {
|
||||
return commonhttp.GetQueryBool(r, key, defaultValue)
|
||||
}
|
||||
|
||||
// GetQueryFloat64 获取float64查询参数(黑盒模式,推荐使用)
|
||||
// r: HTTP请求
|
||||
// key: 参数名
|
||||
// defaultValue: 默认值
|
||||
func (f *Factory) GetQueryFloat64(r *http.Request, key string, defaultValue float64) float64 {
|
||||
return commonhttp.GetQueryFloat64(r, key, defaultValue)
|
||||
}
|
||||
|
||||
// GetFormValue 获取表单值(字符串)(黑盒模式,推荐使用)
|
||||
// r: HTTP请求
|
||||
// key: 参数名
|
||||
// defaultValue: 默认值
|
||||
func (f *Factory) GetFormValue(r *http.Request, key, defaultValue string) string {
|
||||
return commonhttp.GetFormValue(r, key, defaultValue)
|
||||
}
|
||||
|
||||
// GetFormInt 获取表单整数(黑盒模式,推荐使用)
|
||||
// r: HTTP请求
|
||||
// key: 参数名
|
||||
// defaultValue: 默认值
|
||||
func (f *Factory) GetFormInt(r *http.Request, key string, defaultValue int) int {
|
||||
return commonhttp.GetFormInt(r, key, defaultValue)
|
||||
}
|
||||
|
||||
// GetFormInt64 获取表单int64(黑盒模式,推荐使用)
|
||||
// r: HTTP请求
|
||||
// key: 参数名
|
||||
// defaultValue: 默认值
|
||||
func (f *Factory) GetFormInt64(r *http.Request, key string, defaultValue int64) int64 {
|
||||
return commonhttp.GetFormInt64(r, key, defaultValue)
|
||||
}
|
||||
|
||||
// GetFormBool 获取表单布尔值(黑盒模式,推荐使用)
|
||||
// r: HTTP请求
|
||||
// key: 参数名
|
||||
// defaultValue: 默认值
|
||||
func (f *Factory) GetFormBool(r *http.Request, key string, defaultValue bool) bool {
|
||||
return commonhttp.GetFormBool(r, key, defaultValue)
|
||||
}
|
||||
|
||||
// GetHeader 获取请求头(黑盒模式,推荐使用)
|
||||
// r: HTTP请求
|
||||
// key: 请求头名称
|
||||
// defaultValue: 默认值
|
||||
func (f *Factory) GetHeader(r *http.Request, key, defaultValue string) string {
|
||||
return commonhttp.GetHeader(r, key, defaultValue)
|
||||
}
|
||||
|
||||
// GetTimezone 从请求的context中获取时区(黑盒模式,推荐使用)
|
||||
// r: HTTP请求
|
||||
// 如果使用了middleware.Timezone中间件,可以从context中获取时区信息
|
||||
// 如果未设置,返回默认时区 AsiaShanghai
|
||||
func (f *Factory) GetTimezone(r *http.Request) string {
|
||||
return commonhttp.GetTimezone(r)
|
||||
}
|
||||
|
||||
// ========== Tools工具方法(黑盒模式,推荐使用) ==========
|
||||
//
|
||||
// 这些方法直接调用 tools 包的公共方法,保持低耦合。
|
||||
// factory 只负责方法暴露,具体业务在 tools 包中实现。
|
||||
|
||||
// ========== Version 版本工具 ==========
|
||||
|
||||
// GetVersion 获取版本号(黑盒模式,推荐使用)
|
||||
// 优先从环境变量 DOCKER_TAG 或 VERSION 中读取
|
||||
// 如果没有设置环境变量,则使用默认版本号
|
||||
func (f *Factory) GetVersion() string {
|
||||
return tools.GetVersion()
|
||||
}
|
||||
|
||||
// ========== Money 金额工具 ==========
|
||||
|
||||
// GetMoneyCalculator 获取金额计算器(黑盒模式,推荐使用)
|
||||
// 返回金额计算器实例,可用于金额计算操作
|
||||
func (f *Factory) GetMoneyCalculator() *tools.MoneyCalculator {
|
||||
return tools.NewMoneyCalculator()
|
||||
}
|
||||
|
||||
// YuanToCents 元转分(黑盒模式,推荐使用)
|
||||
func (f *Factory) YuanToCents(yuan float64) int64 {
|
||||
return tools.YuanToCents(yuan)
|
||||
}
|
||||
|
||||
// CentsToYuan 分转元(黑盒模式,推荐使用)
|
||||
func (f *Factory) CentsToYuan(cents int64) float64 {
|
||||
return tools.CentsToYuan(cents)
|
||||
}
|
||||
|
||||
// FormatYuan 格式化显示金额(分转元,保留2位小数)(黑盒模式,推荐使用)
|
||||
func (f *Factory) FormatYuan(cents int64) string {
|
||||
return tools.FormatYuan(cents)
|
||||
}
|
||||
|
||||
// ========== DateTime 日期时间工具 ==========
|
||||
|
||||
// Now 获取当前时间(使用指定时区)(黑盒模式,推荐使用)
|
||||
func (f *Factory) Now(timezone ...string) time.Time {
|
||||
return tools.Now(timezone...)
|
||||
}
|
||||
|
||||
// ParseDateTime 解析日期时间字符串(2006-01-02 15:04:05)(黑盒模式,推荐使用)
|
||||
func (f *Factory) ParseDateTime(value string, timezone ...string) (time.Time, error) {
|
||||
return tools.ParseDateTime(value, timezone...)
|
||||
}
|
||||
|
||||
// ParseDate 解析日期字符串(2006-01-02)(黑盒模式,推荐使用)
|
||||
func (f *Factory) ParseDate(value string, timezone ...string) (time.Time, error) {
|
||||
return tools.ParseDate(value, timezone...)
|
||||
}
|
||||
|
||||
// FormatDateTime 格式化日期时间(2006-01-02 15:04:05)(黑盒模式,推荐使用)
|
||||
func (f *Factory) FormatDateTime(t time.Time, timezone ...string) string {
|
||||
return tools.FormatDateTime(t, timezone...)
|
||||
}
|
||||
|
||||
// FormatDate 格式化日期(2006-01-02)(黑盒模式,推荐使用)
|
||||
func (f *Factory) FormatDate(t time.Time, timezone ...string) string {
|
||||
return tools.FormatDate(t, timezone...)
|
||||
}
|
||||
|
||||
// FormatTime 格式化时间(15:04:05)(黑盒模式,推荐使用)
|
||||
func (f *Factory) FormatTime(t time.Time, timezone ...string) string {
|
||||
return tools.FormatTime(t, timezone...)
|
||||
}
|
||||
|
||||
// ToUnix 转换为Unix时间戳(黑盒模式,推荐使用)
|
||||
func (f *Factory) ToUnix(t time.Time) int64 {
|
||||
return tools.ToUnix(t)
|
||||
}
|
||||
|
||||
// FromUnix 从Unix时间戳创建时间(黑盒模式,推荐使用)
|
||||
func (f *Factory) FromUnix(sec int64, timezone ...string) time.Time {
|
||||
return tools.FromUnix(sec, timezone...)
|
||||
}
|
||||
|
||||
// ToUnixMilli 转换为Unix毫秒时间戳(黑盒模式,推荐使用)
|
||||
func (f *Factory) ToUnixMilli(t time.Time) int64 {
|
||||
return tools.ToUnixMilli(t)
|
||||
}
|
||||
|
||||
// FromUnixMilli 从Unix毫秒时间戳创建时间(黑盒模式,推荐使用)
|
||||
func (f *Factory) FromUnixMilli(msec int64, timezone ...string) time.Time {
|
||||
return tools.FromUnixMilli(msec, timezone...)
|
||||
}
|
||||
|
||||
// AddDays 添加天数(黑盒模式,推荐使用)
|
||||
func (f *Factory) AddDays(t time.Time, days int) time.Time {
|
||||
return tools.AddDays(t, days)
|
||||
}
|
||||
|
||||
// AddMonths 添加月数(黑盒模式,推荐使用)
|
||||
func (f *Factory) AddMonths(t time.Time, months int) time.Time {
|
||||
return tools.AddMonths(t, months)
|
||||
}
|
||||
|
||||
// AddYears 添加年数(黑盒模式,推荐使用)
|
||||
func (f *Factory) AddYears(t time.Time, years int) time.Time {
|
||||
return tools.AddYears(t, years)
|
||||
}
|
||||
|
||||
// StartOfDay 获取一天的开始时间(00:00:00)(黑盒模式,推荐使用)
|
||||
func (f *Factory) StartOfDay(t time.Time, timezone ...string) time.Time {
|
||||
return tools.StartOfDay(t, timezone...)
|
||||
}
|
||||
|
||||
// EndOfDay 获取一天的结束时间(23:59:59.999999999)(黑盒模式,推荐使用)
|
||||
func (f *Factory) EndOfDay(t time.Time, timezone ...string) time.Time {
|
||||
return tools.EndOfDay(t, timezone...)
|
||||
}
|
||||
|
||||
// StartOfMonth 获取月份的开始时间(黑盒模式,推荐使用)
|
||||
func (f *Factory) StartOfMonth(t time.Time, timezone ...string) time.Time {
|
||||
return tools.StartOfMonth(t, timezone...)
|
||||
}
|
||||
|
||||
// EndOfMonth 获取月份的结束时间(黑盒模式,推荐使用)
|
||||
func (f *Factory) EndOfMonth(t time.Time, timezone ...string) time.Time {
|
||||
return tools.EndOfMonth(t, timezone...)
|
||||
}
|
||||
|
||||
// StartOfYear 获取年份的开始时间(黑盒模式,推荐使用)
|
||||
func (f *Factory) StartOfYear(t time.Time, timezone ...string) time.Time {
|
||||
return tools.StartOfYear(t, timezone...)
|
||||
}
|
||||
|
||||
// EndOfYear 获取年份的结束时间(黑盒模式,推荐使用)
|
||||
func (f *Factory) EndOfYear(t time.Time, timezone ...string) time.Time {
|
||||
return tools.EndOfYear(t, timezone...)
|
||||
}
|
||||
|
||||
// DiffDays 计算两个时间之间的天数差(黑盒模式,推荐使用)
|
||||
func (f *Factory) DiffDays(t1, t2 time.Time) int {
|
||||
return tools.DiffDays(t1, t2)
|
||||
}
|
||||
|
||||
// DiffHours 计算两个时间之间的小时差(黑盒模式,推荐使用)
|
||||
func (f *Factory) DiffHours(t1, t2 time.Time) int64 {
|
||||
return tools.DiffHours(t1, t2)
|
||||
}
|
||||
|
||||
// DiffMinutes 计算两个时间之间的分钟差(黑盒模式,推荐使用)
|
||||
func (f *Factory) DiffMinutes(t1, t2 time.Time) int64 {
|
||||
return tools.DiffMinutes(t1, t2)
|
||||
}
|
||||
|
||||
// DiffSeconds 计算两个时间之间的秒数差(黑盒模式,推荐使用)
|
||||
func (f *Factory) DiffSeconds(t1, t2 time.Time) int64 {
|
||||
return tools.DiffSeconds(t1, t2)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user