package model import ( "ArmedPolice/serve/orm" "ArmedPolice/utils" "fmt" "strings" "time" "gorm.io/gorm" ) // IModel type IModel interface { SetID(id uint64) GetID() uint64 GetEncodeID() string TableName() string SetDatabase(database string, key ...string) } // Model type Model struct { ID uint64 `gorm:"column:id;primaryKey;autoIncrement;comment:主键" json:"-" form:"id"` Database string `json:"-" gorm:"-"` } // ModelTenant type ModelTenant struct { TenantID uint64 `gorm:"column:tenant_id;index:idx_sys_tenant_id;type:int(11);default:0;comment:租户ID" json:"-"` } // ModelDeleted type ModelDeleted struct { IsDeleted DeleteStatus `gorm:"column:is_deleted;type:tinyint(1);default:0;comment:删除状态(0:未删除,1:已删除)" json:"-" form:"is_deleted"` } // ModelAt type ModelAt struct { CreatedAt time.Time `gorm:"column:created_at;type:datetime;not null;comment:创建时间" json:"created_at" form:"created_at"` UpdatedAt time.Time `gorm:"column:updated_at;type:datetime;not null;comment:更新时间" json:"updated_at" form:"updated_at"` } // DeleteStatus 删除状态 type DeleteStatus int const ( // DeleteStatusForNot 未删除 DeleteStatusForNot DeleteStatus = iota // DeleteStatusForAlready 已删除 DeleteStatusForAlready ) const ( // FieldsForID 主键ID FieldsForID string = "id" // FieldsForUpdatedAt 更新时间 FieldsForUpdatedAt string = "updated_at" // FieldsForDeleted 删除字段名 FieldsForDeleted string = "is_deleted" ) func (m *Model) SetID(id uint64) { m.ID = id } func (m *Model) GetID() uint64 { return m.ID } func (m *Model) GetEncodeID() string { if m.ID <= 0 { return "" } return utils.HASHIDEncode(int(m.ID)) } func (m *ModelTenant) GetEncodeTenantID() string { if m.TenantID <= 0 { return "" } return utils.HASHIDEncode(int(m.TenantID)) } func (m *Model) SetDatabase(database string, key ...string) { m.Database = database + "_" + strings.Join(key, "_") } func (m *Model) NewTableName(tableName string) string { if m.Database == "" { return tableName } return m.Database + "." + tableName } func (m *ModelAt) BeforeCreate(db *gorm.DB) error { m.CreatedAt = time.Now() return nil } func (m *ModelAt) BeforeUpdate(db *gorm.DB) error { m.UpdatedAt = time.Now() return nil } func (m *ModelDeleted) IsDelete() bool { return m.IsDeleted == DeleteStatusForAlready } func Create(model IModel, session ...*gorm.DB) error { if len(session) > 0 { return session[0].Table(model.TableName()).Create(model).Error } return orm.GetDB().Table(model.TableName()).Create(model).Error } func Creates(model IModel, objs interface{}, session ...*gorm.DB) error { if len(session) > 0 { return session[0].Table(model.TableName()).Create(objs).Error } return orm.GetDB().Table(model.TableName()).Create(objs).Error } func Save(model IModel, session ...*gorm.DB) error { if len(session) > 0 { return session[0].Table(model.TableName()).Save(model).Error } return orm.GetDB().Table(model.TableName()).Save(model).Error } func Updates(model IModel, value interface{}, session ...*gorm.DB) error { if len(session) > 0 { return session[0].Table(model.TableName()).Where(fmt.Sprintf("%s = %d", FieldsForID, model.GetID())).Updates(value).Error } return orm.GetDB().Table(model.TableName()).Where(fmt.Sprintf("%s = %d", FieldsForID, model.GetID())).Updates(value).Error } func UpdatesWhere(model IModel, value interface{}, where []*ModelWhere, session ...*gorm.DB) error { db := orm.GetDB() if len(session) > 0 { db = session[0] } db = db.Table(model.TableName()) if len(where) > 0 { for _, wo := range where { db = db.Where(wo.Condition, wo.Value) } } return db.Updates(value).Error } func Delete(model IModel, session ...*gorm.DB) error { db := orm.GetDB() if len(session) > 0 { db = session[0] } db = db.Table(model.TableName()).Where(fmt.Sprintf("%s = %d", FieldsForID, model.GetID())) if db.Migrator().HasColumn(model, FieldsForDeleted) { return db.Updates(map[string]interface{}{FieldsForDeleted: DeleteStatusForAlready, FieldsForUpdatedAt: time.Now()}).Error } return db.Delete(model).Error } func DeleteWhere(model IModel, where []*ModelWhere, session ...*gorm.DB) error { db := orm.GetDB() if len(session) > 0 { db = session[0] } db = db.Table(model.TableName()) if len(where) > 0 { for _, wo := range where { db = db.Where(wo.Condition, wo.Value) } } if db.Migrator().HasColumn(model, FieldsForDeleted) { return db.Updates(map[string]interface{}{FieldsForDeleted: DeleteStatusForAlready, FieldsForUpdatedAt: time.Now()}).Error } return db.Delete(model).Error } func Count(model IModel, count *int64, where ...*ModelWhere) error { db := orm.GetDB().Table(model.TableName()) if len(where) > 0 { for _, wo := range where { db = db.Where(wo.Condition, wo.Value) } } if db.Migrator().HasColumn(model, FieldsForDeleted) { db = db.Where(FieldsForDeleted, DeleteStatusForNot) } return db.Count(count).Error } func First(model IModel) (bool, error) { db := orm.GetDB().Table(model.TableName()) if db.Migrator().HasColumn(model, FieldsForDeleted) { db = db.Where(FieldsForDeleted, DeleteStatusForNot) } if err := db.First(model).Error; err != nil { if err == gorm.ErrRecordNotFound { return false, nil } return false, err } return true, nil } func FirstWhere(model IModel, where ...*ModelWhere) (bool, error) { db := orm.GetDB().Table(model.TableName()) if len(where) > 0 { for _, wo := range where { db = db.Where(wo.Condition, wo.Value) } } else { db = db.Where(fmt.Sprintf("%s = %d", FieldsForID, model.GetID())) } if db.Migrator().HasColumn(model, FieldsForDeleted) { db = db.Where(FieldsForDeleted, DeleteStatusForNot) } if err := db.First(model).Error; err != nil { if err == gorm.ErrRecordNotFound { return false, nil } return false, err } return true, nil } func FirstField(model IModel, field []string, where ...*ModelWhere) (bool, error) { db := orm.GetDB().Table(model.TableName()) if len(where) > 0 { for _, wo := range where { db = db.Where(wo.Condition, wo.Value) } } else { db = db.Where(fmt.Sprintf("%s = %d", FieldsForID, model.GetID())) } if db.Migrator().HasColumn(model, FieldsForDeleted) { db = db.Where(FieldsForDeleted, DeleteStatusForNot) } if err := db.Select(field).First(model).Error; err != nil { if err == gorm.ErrRecordNotFound { return false, nil } return false, err } return true, nil } func Last(model IModel) (bool, error) { db := orm.GetDB().Table(model.TableName()) if db.Migrator().HasColumn(model, FieldsForDeleted) { db = db.Where(FieldsForDeleted, DeleteStatusForNot) } if err := db.Order("id " + OrderModeToDesc).First(model).Error; err != nil { if err == gorm.ErrRecordNotFound { return false, nil } return false, err } return true, nil } func LastWhere(model IModel, where ...*ModelWhere) (bool, error) { db := orm.GetDB().Table(model.TableName()) if len(where) > 0 { for _, wo := range where { db = db.Where(wo.Condition, wo.Value) } } else { db = db.Where(fmt.Sprintf("%s = %d", FieldsForID, model.GetID())) } if db.Migrator().HasColumn(model, FieldsForDeleted) { db = db.Where(FieldsForDeleted, DeleteStatusForNot) } if err := db.Order("id " + OrderModeToDesc).First(model).Error; err != nil { if err == gorm.ErrRecordNotFound { return false, nil } return false, err } return true, nil } func LastWhereOrder(model IModel, where ...*ModelWhereOrder) (bool, error) { db := orm.GetDB().Table(model.TableName()) if len(where) > 0 { for _, wo := range where { if wo.Where != nil { db = db.Where(wo.Where.Condition, wo.Where.Value) } if wo.Order != nil { db = db.Order(fmt.Sprintf("%s %s", wo.Order.Field, wo.Order.Mode)) } } } else { db = db.Where(fmt.Sprintf("%s = %d", FieldsForID, model.GetID())) } if db.Migrator().HasColumn(model, FieldsForDeleted) { db = db.Where(FieldsForDeleted, DeleteStatusForNot) } if err := db.Limit(1).First(model).Error; err != nil { if err == gorm.ErrRecordNotFound { return false, nil } return false, err } return true, nil } func Find(model IModel, out interface{}, where ...*ModelWhereOrder) error { db := orm.GetDB().Table(model.TableName()) if len(where) > 0 { for _, wo := range where { if wo.Where != nil { db = db.Where(wo.Where.Condition, wo.Where.Value) } if wo.Order != nil { db = db.Order(fmt.Sprintf("%s %s", wo.Order.Field, wo.Order.Mode)) } } } if db.Migrator().HasColumn(model, FieldsForDeleted) { db = db.Where(FieldsForDeleted, DeleteStatusForNot) } return db.Find(out).Error } func FindLimit(model IModel, out interface{}, limit int, where ...*ModelWhereOrder) error { db := orm.GetDB().Table(model.TableName()) if len(where) > 0 { for _, wo := range where { if wo.Where != nil { db = db.Where(wo.Where.Condition, wo.Where.Value) } if wo.Order != nil { db = db.Order(fmt.Sprintf("%s %s", wo.Order.Field, wo.Order.Mode)) } } } if db.Migrator().HasColumn(model, FieldsForDeleted) { db = db.Where(FieldsForDeleted, DeleteStatusForNot) } return db.Offset(0).Limit(limit).Find(out).Error } func Scan(model IModel, out interface{}, where ...*ModelWhereOrder) error { db := orm.GetDB().Table(model.TableName()) if len(where) > 0 { for _, wo := range where { if wo.Where != nil { db = db.Where(wo.Where.Condition, wo.Where.Value) } if wo.Order != nil { db = db.Order(fmt.Sprintf("%s %s", wo.Order.Field, wo.Order.Mode)) } } } if db.Migrator().HasColumn(model, FieldsForDeleted) { db = db.Where(FieldsForDeleted, DeleteStatusForNot) } return db.Scan(out).Error } func ScanFields(model IModel, out interface{}, fields []string, where ...*ModelWhereOrder) error { db := orm.GetDB().Table(model.TableName()).Select(fields) if len(where) > 0 { for _, wo := range where { if wo.Where != nil { db = db.Where(wo.Where.Condition, wo.Where.Value) } if wo.Order != nil { db = db.Order(fmt.Sprintf("%s %s", wo.Order.Field, wo.Order.Mode)) } } } if db.Migrator().HasColumn(model, FieldsForDeleted) { db = db.Where(FieldsForDeleted, DeleteStatusForNot) } return db.Scan(out).Error } func ScanLimitFields(model IModel, out interface{}, fields []string, limit int, where ...*ModelWhereOrder) error { db := orm.GetDB().Table(model.TableName()).Select(fields) if len(where) > 0 { for _, wo := range where { if wo.Where != nil { db = db.Where(wo.Where.Condition, wo.Where.Value) } if wo.Order != nil { db = db.Order(fmt.Sprintf("%s %s", wo.Order.Field, wo.Order.Mode)) } } } if db.Migrator().HasColumn(model, FieldsForDeleted) { db = db.Where(FieldsForDeleted, DeleteStatusForNot) } return db.Offset(0).Limit(limit).Scan(out).Error } func Pluck(model IModel, field string, out interface{}, where ...*ModelWhere) error { db := orm.GetDB().Table(model.TableName()) if len(where) > 0 { for _, wo := range where { db = db.Where(wo.Condition, wo.Value) } } if db.Migrator().HasColumn(model, FieldsForDeleted) { db = db.Where(FieldsForDeleted, DeleteStatusForNot) } return db.Pluck(field, out).Error } func Pages(model IModel, out interface{}, page, pageSize int, count *int64, where ...*ModelWhereOrder) error { db := orm.GetDB().Table(model.TableName()) if len(where) > 0 { for _, wo := range where { if wo.Where != nil { db = db.Where(wo.Where.Condition, wo.Where.Value) } if wo.Order != nil { db = db.Order(fmt.Sprintf("%s %s", wo.Order.Field, wo.Order.Mode)) } } } if db.Migrator().HasColumn(model, FieldsForDeleted) { db = db.Where(FieldsForDeleted, DeleteStatusForNot) } if err := db.Count(count).Error; err != nil { return err } return db.Offset((page - 1) * pageSize).Limit(pageSize).Scan(out).Error } func PagesFields(model IModel, out interface{}, fields []string, page, pageSize int, count *int64, where ...*ModelWhereOrder) error { db := orm.GetDB().Table(model.TableName()).Select(fields) if len(where) > 0 { for _, wo := range where { if wo.Where != nil { db = db.Where(wo.Where.Condition, wo.Where.Value) } if wo.Order != nil { db = db.Order(fmt.Sprintf("%s %s", wo.Order.Field, wo.Order.Mode)) } } } if db.Migrator().HasColumn(model, FieldsForDeleted) { db = db.Where(FieldsForDeleted, DeleteStatusForNot) } if err := db.Count(count).Error; err != nil { return err } return db.Offset((page - 1) * pageSize).Limit(pageSize).Scan(out).Error }