Files
bl/cool/service.go
2025-06-20 17:13:51 +08:00

430 lines
12 KiB
Go

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,
}
}