package cool import ( "context" "github.com/gogf/gf/v2/container/garray" "github.com/gogf/gf/v2/database/gdb" "github.com/gogf/gf/v2/errors/gerror" "github.com/gogf/gf/v2/frame/g" "github.com/gogf/gf/v2/util/gconv" ) type IService interface { ServiceAdd(ctx context.Context, req *AddReq) (data interface{}, err error) // 新增 ServiceDelete(ctx context.Context, req *DeleteReq) (data interface{}, err error) // 删除 ServiceUpdate(ctx context.Context, req *UpdateReq) (data interface{}, err error) // 修改 ServiceInfo(ctx context.Context, req *InfoReq) (data interface{}, err error) // 详情 ServiceList(ctx context.Context, req *ListReq) (data interface{}, err error) // 列表 ServicePage(ctx context.Context, req *PageReq) (data interface{}, err error) // 分页 ModifyBefore(ctx context.Context, method string, param g.MapStrAny) (err error) // 新增|删除|修改前的操作 ModifyAfter(ctx context.Context, method string, param g.MapStrAny) (err error) // 新增|删除|修改后的操作 GetModel() IModel // 获取model } type Service struct { Model IModel ListQueryOp *QueryOp PageQueryOp *QueryOp InsertParam func(ctx context.Context) g.MapStrAny // Add时插入参数 Before func(ctx context.Context) (err error) // CRUD前的操作 InfoIgnoreProperty string // Info时忽略的字段,多个字段用逗号隔开 UniqueKey g.MapStrStr // 唯一键 key:字段名 value:错误信息 NotNullKey g.MapStrStr // 非空键 key:字段名 value:错误信息 } // List/Add接口条件配置 type QueryOp struct { FieldEQ []string // 字段等于 KeyWordField []string // 模糊搜索匹配的数据库字段 AddOrderby g.MapStrStr // 添加排序 Where func(ctx context.Context) []g.Array // 自定义条件 Select string // 查询字段,多个字段用逗号隔开 如: id,name 或 a.id,a.name,b.name AS bname Join []*JoinOp // 关联查询 Extend func(ctx g.Ctx, m *gdb.Model) *gdb.Model // 追加其他条件 ModifyResult func(ctx g.Ctx, data interface{}) interface{} // 修改结果 } // JoinOp 关联查询 type JoinOp struct { Model IModel // 关联的model Alias string // 别名 Condition string // 关联条件 Type JoinType // 关联类型 LeftJoin RightJoin InnerJoin } // JoinType 关联类型 type JoinType string // ServiceAdd 新增 func (s *Service) ServiceAdd(ctx context.Context, req *AddReq) (data interface{}, err error) { r := g.RequestFromCtx(ctx) rmap := r.GetMap() // 非空键 if s.NotNullKey != nil { for k, v := range s.NotNullKey { if rmap[k] == nil { return nil, gerror.New(v) } } } // 唯一键 if s.UniqueKey != nil { for k, v := range s.UniqueKey { if rmap[k] != nil { m := DBM(s.Model) count, err := m.Where(k, rmap[k]).Count() if err != nil { return nil, err } if count > 0 { err = gerror.New(v) return nil, err } } } } if s.InsertParam != nil { insertParams := s.InsertParam(ctx) if len(insertParams) > 0 { for k, v := range insertParams { rmap[k] = v } } } m := DBM(s.Model) lastInsertId, err := m.Data(rmap).InsertAndGetId() if err != nil { return } data = g.Map{"id": lastInsertId} return } // ServiceDelete 删除 func (s *Service) ServiceDelete(ctx context.Context, req *DeleteReq) (data interface{}, err error) { ids := g.RequestFromCtx(ctx).Get("ids").Slice() m := g.DB(s.Model.GroupName()).Model(s.Model.TableName()) data, err = m.WhereIn("id", ids).Delete() return } // ServiceUpdate 修改 func (s *Service) ServiceUpdate(ctx context.Context, req *UpdateReq) (data interface{}, err error) { r := g.RequestFromCtx(ctx) rmap := r.GetMap() if rmap["id"] == nil { err = gerror.New("id不能为空") return } if s.UniqueKey != nil { for k, v := range s.UniqueKey { if rmap[k] != nil { count, err := DBM(s.Model).Where(k, rmap[k]).WhereNot("id", rmap["id"]).Count() if err != nil { return nil, err } if count > 0 { err = gerror.New(v) return nil, err } } } } m := DBM(s.Model) _, err = m.Data(rmap).Where("id", rmap["id"]).Update() return } func (s *Service) ServiceInfo(ctx context.Context, req *InfoReq) (data interface{}, err error) { if s.Before != nil { err = s.Before(ctx) if err != nil { return } } m := g.DB(s.Model.GroupName()).Model(s.Model.TableName()) // 如果InfoIgnoreProperty不为空 则忽略相关字段 if len(s.InfoIgnoreProperty) > 0 { m = m.FieldsEx(s.InfoIgnoreProperty) } data, err = m.Clone().Where("id", req.Id).One() return } func (s *Service) ServiceList(ctx context.Context, req *ListReq) (data interface{}, err error) { if s.Before != nil { err = s.Before(ctx) if err != nil { return } } r := g.RequestFromCtx(ctx) m := g.DB(s.Model.GroupName()).Model(s.Model.TableName()) // 如果 req.Order 和 req.Sort 均不为空 则添加排序 if !r.Get("order").IsEmpty() && !r.Get("sort").IsEmpty() { m.Order(r.Get("order").String() + " " + r.Get("sort").String()) // m.OrderDesc("orderNum") } // 如果 ListQueryOp 不为空 则使用 ListQueryOp 进行查询 if s.ListQueryOp != nil { if Select := s.ListQueryOp.Select; Select != "" { m.Fields(Select) } // 如果Join不为空 则添加Join if len(s.ListQueryOp.Join) > 0 { for _, join := range s.ListQueryOp.Join { switch join.Type { case LeftJoin: m.LeftJoin(join.Model.TableName(), join.Condition).As(join.Alias) case RightJoin: m.RightJoin(join.Model.TableName(), join.Condition).As(join.Alias) case InnerJoin: m.InnerJoin(join.Model.TableName(), join.Condition).As(join.Alias) } } } // 如果fileldEQ不为空 则添加查询条件 if len(s.ListQueryOp.FieldEQ) > 0 { for _, field := range s.ListQueryOp.FieldEQ { if !r.Get(field).IsEmpty() { m.Where(field, r.Get(field)) } } } // 如果KeyWordField不为空 则添加查询条件 if !r.Get("keyWord").IsEmpty() { if len(s.ListQueryOp.KeyWordField) > 0 { builder := m.Builder() for _, field := range s.ListQueryOp.KeyWordField { // g.DumpWithType(field) // builder.WhereLike(field, "%"+r.Get("keyWord").String()+"%") builder = builder.WhereOrLike(field, "%"+r.Get("keyWord").String()+"%") } m.Where(builder) } } if s.ListQueryOp.Where != nil { where := s.ListQueryOp.Where(ctx) if len(where) > 0 { for _, v := range where { if len(v) == 3 { if gconv.Bool(v[2]) { m.Where(v[0], v[1]) } } if len(v) == 2 { m.Where(v[0], v[1]) } } } } // 如果ListQueryOp的Extend不为空 则执行Extend if s.ListQueryOp.Extend != nil { m = s.ListQueryOp.Extend(ctx, m) } // 如果 addOrderby 不为空 则添加排序 if len(s.ListQueryOp.AddOrderby) > 0 && r.Get("order").IsEmpty() && r.Get("sort").IsEmpty() { for field, order := range s.ListQueryOp.AddOrderby { m.Order(field, order) } } } // 增加默认数据限制,防止查询所有数据 m.Limit(10000) result, err := m.All() if err != nil { g.Log().Error(ctx, "ServiceList error:", err) } if result == nil { data = garray.New() } else { data = result } if s.ListQueryOp != nil { if s.ListQueryOp.ModifyResult != nil { data = s.ListQueryOp.ModifyResult(ctx, data) } } return } func (s *Service) ServicePage(ctx context.Context, req *PageReq) (data interface{}, err error) { var ( r = g.RequestFromCtx(ctx) total = 0 ) type pagination struct { Page int `json:"page"` Size int `json:"size"` Total int `json:"total"` } if req.Size <= 0 { req.Size = 10 } if req.Page <= 0 { req.Page = 1 } m := g.DB(s.Model.GroupName()).Model(s.Model.TableName()) // 如果pageQueryOp不为空 则使用pageQueryOp进行查询 if s.PageQueryOp != nil { // 如果Join不为空 则添加Join if len(s.PageQueryOp.Join) > 0 { for _, join := range s.PageQueryOp.Join { switch join.Type { case LeftJoin: m.LeftJoin(join.Model.TableName(), join.Condition).As(join.Alias) case RightJoin: m.RightJoin(join.Model.TableName(), join.Condition).As(join.Alias) case InnerJoin: m.InnerJoin(join.Model.TableName(), join.Condition).As(join.Alias) } } } // 如果fileldEQ不为空 则添加查询条件 if len(s.PageQueryOp.FieldEQ) > 0 { for _, field := range s.PageQueryOp.FieldEQ { if !r.Get(field).IsEmpty() { m.Where(field, r.Get(field)) } } } // 如果KeyWordField不为空 则添加查询条件 if !r.Get("keyWord").IsEmpty() { if len(s.PageQueryOp.KeyWordField) > 0 { builder := m.Builder() for _, field := range s.PageQueryOp.KeyWordField { // g.DumpWithType(field) // builder.WhereLike(field, "%"+r.Get("keyWord").String()+"%") builder = builder.WhereOrLike(field, "%"+r.Get("keyWord").String()+"%") } m.Where(builder) } } // 加入where条件 if s.PageQueryOp.Where != nil { where := s.PageQueryOp.Where(ctx) if len(where) > 0 { for _, v := range where { if len(v) == 3 { if gconv.Bool(v[2]) { m.Where(v[0], v[1]) } } if len(v) == 2 { m.Where(v[0], v[1]) } } } } // 如果PageQueryOp的Extend不为空 则执行Extend if s.PageQueryOp.Extend != nil { m = s.PageQueryOp.Extend(ctx, m) } // 如果 addOrderby 不为空 则添加排序 if len(s.PageQueryOp.AddOrderby) > 0 && r.Get("order").IsEmpty() && r.Get("sort").IsEmpty() { for field, order := range s.PageQueryOp.AddOrderby { m.Order(field, order) } } } // 统计总数 total, err = m.Clone().Count() if err != nil { return nil, err } if s.PageQueryOp != nil { if Select := s.PageQueryOp.Select; Select != "" { m.Fields(Select) } } // 如果 req.Order 和 req.Sort 均不为空 则添加排序 if !r.Get("order").IsEmpty() && !r.Get("sort").IsEmpty() { m.Order(r.Get("order").String() + " " + r.Get("sort").String()) } // 如果req.IsExport为true 则导出数据 if req.IsExport { // 如果req.MaxExportSize大于0 则限制导出数据的最大条数 if req.MaxExportLimit > 0 { m.Limit(req.MaxExportLimit) } result, err := m.All() if err != nil { return nil, err } data = g.Map{ "list": result, "total": total, } return data, nil } result, err := m.Offset((req.Page - 1) * req.Size).Limit(req.Size).All() if err != nil { return nil, err } if result != nil { data = g.Map{ "list": result, "pagination": pagination{ Page: req.Page, Size: req.Size, Total: total, }, } } else { data = g.Map{ "list": garray.New(), "pagination": pagination{ Page: req.Page, Size: req.Size, Total: total, }, } } if s.PageQueryOp != nil { if s.PageQueryOp.ModifyResult != nil { data = s.PageQueryOp.ModifyResult(ctx, data) } } return } // ModifyBefore 新增|删除|修改前的操作 func (s *Service) ModifyBefore(ctx context.Context, method string, param g.MapStrAny) (err error) { // g.Log().Debugf(ctx, "ModifyBefore: %s", method) return } // ModifyAfter 新增|删除|修改后的操作 func (s *Service) ModifyAfter(ctx context.Context, method string, param g.MapStrAny) (err error) { return } // GetModel 获取model func (s *Service) GetModel() IModel { return s.Model } // NewService 新建一个service func NewService(model IModel) *Service { return &Service{ Model: model, } }