465 lines
12 KiB
Go
465 lines
12 KiB
Go
package model
|
||
|
||
import (
|
||
"SciencesServer/serve/orm"
|
||
"SciencesServer/utils"
|
||
"fmt"
|
||
"strings"
|
||
"time"
|
||
|
||
"gorm.io/gorm"
|
||
)
|
||
|
||
// IModel
|
||
type IModel interface {
|
||
SetID(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"
|
||
)
|
||
|
||
const (
|
||
SubDatabase string = "tenant"
|
||
)
|
||
|
||
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, fields []string, where ...*ModelWhere) (bool, error) {
|
||
db := orm.GetDB().Table(model.TableName()).Select(fields)
|
||
|
||
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 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, fields []string, where ...*ModelWhere) (bool, error) {
|
||
db := orm.GetDB().Table(model.TableName())
|
||
|
||
if len(fields) > 0 {
|
||
db = db.Select(fields)
|
||
}
|
||
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(FieldsForID + " " + 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 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
|
||
}
|