// Mapper 接口(保持原样,用于 PageResult.Convert 方法)
type Mapper interface {
    NewRow() any
    NewRows() []any
}

// Converter 泛型结构体:T = From/Source, D = To/Destination
type Converter[T any, D any] struct{}

// ========== 单条转换 ==========

// To: T -> D
func (c Converter[T, D]) To(src T) D {
    var dst D
    gconv.Struct(src, &dst)
    return dst
}

// From: D -> T
func (c Converter[T, D]) From(src D) T {
    var dst T
    gconv.Struct(src, &dst)
    return dst
}

// ========== 列表转换 ==========

// ToList: []T -> []D
func (c Converter[T, D]) ToList(src []T) []D {
    if len(src) == 0 {
        return nil
    }
    dst := make([]D, len(src))
    for i, v := range src {
        dst[i] = c.To(v)
    }
    return dst
}

// FromList: []D -> []T
func (c Converter[T, D]) FromList(src []D) []T {
    if len(src) == 0 {
        return nil
    }
    dst := make([]T, len(src))
    for i, v := range src {
        dst[i] = c.From(v)
    }
    return dst
}

// ========== 实现 Mapper 接口 ==========

func (c Converter[T, D]) NewRow() any {
    var d D
    return &d
}

func (c Converter[T, D]) NewRows() []any {
    return []any{}
}

// ========== PageResult 转换(包级函数,类型安全) ==========

// PageTo: *PageResult[T] -> *PageResult[D]
func PageTo[T any, D any](p *PageResult[T], c Converter[T, D]) *PageResult[D] {
    var ret = NewPageResult[D]()
    ret.FromPageResult(p.PageResult)
    if !p.ExistRecord() {
        return ret
    }
    ret.Data = c.ToList(p.Data)
    return ret
}

// PageFrom: *PageResult[D] -> *PageResult[T]
func PageFrom[T any, D any](p *PageResult[D], c Converter[T, D]) *PageResult[T] {
    var ret = NewPageResult[T]()
    ret.FromPageResult(p.PageResult)
    if !p.ExistRecord() {
        return ret
    }
    ret.Data = c.FromList(p.Data)
    return ret
}

// ========== PageResult 方法(兼容旧接口,返回 any) ==========

func (p *PageResult[T]) Convert(m Mapper) *PageResult[any] {
    var ret = NewPageResult[any]()
    ret.FromPageResult(p.PageResult)
    if !p.ExistRecord() {
        return ret
    }
    var data = m.NewRows()
    for i := range p.Data {
        var row = m.NewRow()
        err := gconv.Struct(p.Data[i], row)
        if err != nil {
            golog.Error("PageResult Convert err:", err)
            ret.FailMsg(err.Error())
            return ret
        }
        data = append(data, row)
    }
    ret.Data = data
    return ret
}
 

更多推荐