From c04f3a37d0c092539bb4d990cdfd462b8cb013cf Mon Sep 17 00:00:00 2001 From: lixxxww <941403820@qq.com> Date: Tue, 23 Jan 2024 11:41:29 +0000 Subject: [PATCH] =?UTF-8?q?=E6=8F=90=E4=BA=A4kit/model?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: lixxxww <941403820@qq.com> --- kit/model/base_model.go | 33 +++++++ kit/model/jsonb.go | 36 ++++++++ kit/model/model.go | 199 ++++++++++++++++++++++++++++++++++++++++ kit/model/page.go | 15 +++ kit/model/result.go | 62 +++++++++++++ 5 files changed, 345 insertions(+) create mode 100644 kit/model/base_model.go create mode 100644 kit/model/jsonb.go create mode 100644 kit/model/model.go create mode 100644 kit/model/page.go create mode 100644 kit/model/result.go diff --git a/kit/model/base_model.go b/kit/model/base_model.go new file mode 100644 index 0000000..faaa5c0 --- /dev/null +++ b/kit/model/base_model.go @@ -0,0 +1,33 @@ +package model + +import ( + "gorm.io/gorm" + "time" +) + +// BaseAutoModel 使用代码生成需要此,不能自由命名id +type BaseAutoModel struct { + Id int `gorm:"primary_key;AUTO_INCREMENT;column:id" json:"id" form:"id"` + CreatedAt time.Time `gorm:"column:create_time" json:"createTime" form:"createTime"` + UpdatedAt time.Time `gorm:"column:update_time" json:"updateTime" form:"updateTime"` + DeletedAt gorm.DeletedAt `gorm:"column:delete_time" sql:"index" json:"-"` +} + +// BaseAutoModelD 表想要硬删除使用他 +type BaseAutoModelD struct { + Id int `gorm:"primary_key;AUTO_INCREMENT;column:id" json:"id" form:"id"` + CreatedAt time.Time `gorm:"column:create_time" json:"createTime" form:"createTime"` + UpdatedAt time.Time `gorm:"column:update_time" json:"updateTime" form:"updateTime"` +} + +type BaseModel struct { + CreatedAt time.Time `gorm:"column:create_time" json:"createTime" form:"createTime"` + UpdatedAt time.Time `gorm:"column:update_time" json:"updateTime" form:"updateTime"` + DeletedAt gorm.DeletedAt `gorm:"column:delete_time" sql:"index" json:"-"` +} + +// BaseModelD 硬删除 +type BaseModelD struct { + CreatedAt time.Time `gorm:"column:create_time" json:"createTime" form:"create_time"` + UpdatedAt time.Time `gorm:"column:update_time" json:"updateTime" form:"update_time"` +} diff --git a/kit/model/jsonb.go b/kit/model/jsonb.go new file mode 100644 index 0000000..aa0f5e1 --- /dev/null +++ b/kit/model/jsonb.go @@ -0,0 +1,36 @@ +package model + +import ( + "database/sql/driver" + "encoding/json" + "errors" +) + +type JSONB map[string]interface{} + +func (a JSONB) Value() (driver.Value, error) { + return json.Marshal(a) +} + +func (a *JSONB) Scan(value interface{}) error { + b, ok := value.([]byte) + if !ok { + return errors.New("type assertion to []byte failed") + } + return json.Unmarshal(b, &a) +} + +// JSONBS Interface for JSONB Field of yourTableName Table +type JSONBS []interface{} + +func (a JSONBS) Value() (driver.Value, error) { + return json.Marshal(a) +} + +func (a *JSONBS) Scan(value interface{}) error { + b, ok := value.([]byte) + if !ok { + return errors.New("type assertion to []byte failed") + } + return json.Unmarshal(b, &a) +} diff --git a/kit/model/model.go b/kit/model/model.go new file mode 100644 index 0000000..c37f664 --- /dev/null +++ b/kit/model/model.go @@ -0,0 +1,199 @@ +package model + +import ( + "fmt" + "pandax/kit/biz" + "pandax/kit/starter" + "strconv" + + "strings" + "time" + + "gorm.io/gorm" +) + +type Model struct { + BaseAutoModel + CreatorId int64 `json:"creatorId"` + Creator string `json:"creator"` //创建者 + ModifierId int64 `json:"modifierId"` + Modifier string `json:"modifier"` //修改者 +} + +// 设置基础信息. 如创建时间,修改时间,创建者,修改者信息 +func (m *Model) SetBaseInfo(account *LoginAccount) { + nowTime := time.Now() + isCreate := m.Id == 0 + if isCreate { + m.CreatedAt = nowTime + } + m.UpdatedAt = nowTime + + if account == nil { + return + } + id := account.UserId + name := account.Username + if isCreate { + m.CreatorId = id + m.Creator = name + } + m.Modifier = name + m.ModifierId = id +} + +// 事务 +func Tx(funcs ...func(db *gorm.DB) error) (err error) { + tx := starter.Db.Begin() + defer func() { + var err any + err = recover() + if err != nil { + tx.Rollback() + err = fmt.Errorf("%v", err) + } + }() + for _, f := range funcs { + err = f(tx) + if err != nil { + tx.Rollback() + return + } + } + err = tx.Commit().Error + return +} + +// 根据id获取实体对象。model需为指针类型(需要将查询出来的值赋值给model) +// +// 若error不为nil则为不存在该记录 +func GetById(model any, id uint64, cols ...string) error { + return starter.Db.Select(cols).Where("id = ?", id).First(model).Error +} + +// 根据id列表查询 +func GetByIdIn(model any, list any, ids []uint64, orderBy ...string) { + var orderByStr string + if orderBy == nil { + orderByStr = "id desc" + } else { + orderByStr = strings.Join(orderBy, ",") + } + starter.Db.Model(model).Where("id in (?)", ids).Order(orderByStr).Find(list) +} + +// 根据id列表查询 model可以是对象,也可以是map[string]interface{} +func CountBy(model any) int64 { + var count int64 + starter.Db.Model(model).Where(model).Count(&count) + return count +} + +// 根据id更新model,更新字段为model中不为空的值,即int类型不为0,ptr类型不为nil这类字段值 +func UpdateById(model any) error { + return starter.Db.Model(model).Updates(model).Error +} +func UpdateByWhere(model any, where any) error { + return starter.Db.Model(model).Where(where).Updates(model).Error +} + +// 根据id删除model +func DeleteById(model any, id uint64) error { + return starter.Db.Delete(model, "id = ?", id).Error +} + +// 根据条件删除 +func DeleteByCondition(model any) error { + return starter.Db.Where(model).Delete(model).Error +} + +// 插入model +func Insert(model any) error { + return starter.Db.Create(model).Error +} + +// 获取满足model中不为空的字段值条件的所有数据. +// +// list为数组类型 如 var users *[]User,可指定为非model结构体,即只包含需要返回的字段结构体 +func ListBy(model any, list any, cols ...string) { + starter.Db.Model(model).Select(cols).Where(model).Find(list) +} + +// 获取满足model中不为空的字段值条件的所有数据. +// +// list为数组类型 如 var users *[]User,可指定为非model结构体 +func ListByOrder(model any, list any, order ...string) { + var orderByStr string + if order == nil { + orderByStr = "id desc" + } else { + orderByStr = strings.Join(order, ",") + } + starter.Db.Model(model).Where(model).Order(orderByStr).Find(list) +} + +// 获取满足model中不为空的字段值条件的单个对象。model需为指针类型(需要将查询出来的值赋值给model) +// +// 若 error不为nil,则为不存在该记录 +func GetBy(model any, cols ...string) error { + return starter.Db.Select(cols).Where(model).First(model).Error +} + +// 获取满足conditionModel中不为空的字段值条件的单个对象。model需为指针类型(需要将查询出来的值赋值给model) +// toModel 需要查询的字段 +// 若 error不为nil,则为不存在该记录 +func GetByConditionTo(conditionModel any, toModel any) error { + return starter.Db.Model(conditionModel).Where(conditionModel).First(toModel).Error +} + +// 获取分页结果 +func GetPage(pageParam *PageParam, conditionModel any, toModels any, orderBy ...string) *ResultPage { + var count int64 + err := starter.Db.Model(conditionModel).Where(conditionModel).Count(&count).Error + biz.ErrIsNilAppendErr(err, " 查询错误:%s") + if count == 0 { + return &ResultPage{Total: 0, Data: []string{}} + } + + page := pageParam.PageNum + pageSize := pageParam.PageSize + var orderByStr string + if orderBy == nil { + orderByStr = "id desc" + } else { + orderByStr = strings.Join(orderBy, ",") + } + err = starter.Db.Model(conditionModel).Where(conditionModel).Order(orderByStr).Limit(pageSize).Offset((page - 1) * pageSize).Find(toModels).Error + biz.ErrIsNil(err, "查询失败") + return &ResultPage{Total: count, Data: toModels} +} + +// 根据sql获取分页对象 +func GetPageBySql(sql string, param *PageParam, toModel any, args ...any) *ResultPage { + db := starter.Db + selectIndex := strings.Index(sql, "SELECT ") + 7 + fromIndex := strings.Index(sql, " FROM") + selectCol := sql[selectIndex:fromIndex] + countSql := strings.Replace(sql, selectCol, "COUNT(*) AS total ", 1) + // 查询count + var count int + db.Raw(countSql, args...).Scan(&count) + if count == 0 { + return &ResultPage{Total: 0, Data: []string{}} + } + // 分页查询 + limitSql := sql + " LIMIT " + strconv.Itoa(param.PageNum-1) + ", " + strconv.Itoa(param.PageSize) + err := db.Raw(limitSql).Scan(toModel).Error + biz.ErrIsNil(err, "查询失败") + return &ResultPage{Total: int64(count), Data: toModel} +} + +func GetListBySql(sql string, params ...any) []map[string]any { + var maps []map[string]any + starter.Db.Raw(sql, params).Scan(&maps) + return maps +} + +func GetListBySql2Model(sql string, toEntity any, params ...any) error { + return starter.Db.Raw(sql, params).Find(toEntity).Error +} diff --git a/kit/model/page.go b/kit/model/page.go new file mode 100644 index 0000000..5242ebd --- /dev/null +++ b/kit/model/page.go @@ -0,0 +1,15 @@ +package model + +// 分页参数 +type PageParam struct { + PageNum int `json:"pageNum"` + PageSize int `json:"pageSize"` + Params string `json:"params"` +} + +type ResultPage struct { + Total int64 `json:"total"` + PageNum int64 `json:"pageNum"` + PageSize int64 `json:"pageSize"` + Data any `json:"data"` +} diff --git a/kit/model/result.go b/kit/model/result.go new file mode 100644 index 0000000..1efb5b1 --- /dev/null +++ b/kit/model/result.go @@ -0,0 +1,62 @@ +package model + +import ( + "encoding/json" + "fmt" + "pandax/kit/biz" +) + +const ( + SuccessCode = 200 + SuccessMsg = "success" +) + +// 统一返回结果结构体 +type Result struct { + Code int16 `json:"code"` + Msg string `json:"msg"` + Data any `json:"data"` +} + +// 将Result转为json字符串 +func (r *Result) ToJson() string { + jsonData, err := json.Marshal(r) + if err != nil { + fmt.Println("data转json错误") + } + return string(jsonData) +} + +// 判断该Result是否为成功状态 +func (r *Result) IsSuccess() bool { + return r.Code == SuccessCode +} + +// 返回成功状态的Result +// data 成功附带的数据消息 +func Success(data any) *Result { + return &Result{Code: SuccessCode, Msg: SuccessMsg, Data: data} +} + +// 返回成功状态的Result +// data 成功不附带数据 +func SuccessNoData() *Result { + return &Result{Code: SuccessCode, Msg: SuccessMsg} +} + +func Error(bizerr *biz.BizError) *Result { + return &Result{Code: bizerr.Code(), Msg: bizerr.Error()} +} + +// 返回服务器错误Result +func ServerError() *Result { + return Error(biz.ServerError) +} + +func TokenError() *Result { + return Error(biz.PermissionErr) +} + +func ErrorBy(code int16, msg string) *Result { + return &Result{Code: code, Msg: msg} +}