package agent import ( "context" "git.5iot.com/iotlcm-public/iotlcm-admin-svr/internal/dao" "git.5iot.com/iotlcm-public/iotlcm-admin-svr/internal/library/contexts" "git.5iot.com/iotlcm-public/iotlcm-admin-svr/internal/library/exportcenter" "git.5iot.com/iotlcm-public/iotlcm-admin-svr/internal/library/xgorm" "git.5iot.com/iotlcm-public/iotlcm-admin-svr/internal/library/xgorm/handler" "git.5iot.com/iotlcm-public/iotlcm-admin-svr/internal/library/xgorm/hook" "git.5iot.com/iotlcm-public/iotlcm-admin-svr/internal/model" "git.5iot.com/iotlcm-public/iotlcm-admin-svr/internal/service" "git.5iot.com/iotlcm-public/iotlcm-admin-svr/utility/convert" "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/os/gtime" "github.com/gogf/gf/v2/util/gconv" ) type sAgentTApiGroup struct{} // NewAgentTApiGroup 创建开放接口权限组后台服务实例。 func NewAgentTApiGroup() *sAgentTApiGroup { return &sAgentTApiGroup{} } func init() { service.RegisterAgentTApiGroup(NewAgentTApiGroup()) } // Model 返回开放接口权限组 ORM 模型,默认启用租户和数据权限过滤。 func (s *sAgentTApiGroup) Model(ctx context.Context, option ...*handler.Option) *gdb.Model { if len(option) == 0 { option = append(option, &handler.Option{ FilterTenant: true, FilterAuth: true, }) } return handler.Model(dao.TApiGroup.Ctx(ctx), option...) } // List 分页查询开放接口权限组列表。 func (s *sAgentTApiGroup) List(ctx context.Context, in *model.TApiGroupListParam) (list []*model.TApiGroupListModel, totalCount int, err error) { mod := s.Model(ctx).Fields(model.TApiGroupListModel{}) if in.Id > 0 { mod = mod.Where(dao.TApiGroup.Columns().Id, in.Id) } if in.Status > 0 { mod = mod.Where(dao.TApiGroup.Columns().Status, in.Status) } if in.GroupName != "" { mod = mod.Where(dao.TApiGroup.Columns().GroupName+" LIKE ?", "%"+in.GroupName+"%") } if len(in.CreatedAt) == 2 { in.CreatedAt[1] = in.CreatedAt[1].EndOfDay() mod = mod.WhereBetween(dao.TApiGroup.Columns().CreatedAt, in.CreatedAt[0], in.CreatedAt[1]) } mod = mod.Page(in.Page, in.PageSize). OrderDesc(dao.TApiGroup.Columns().Id). Hook(hook.MemberSummary) if err = mod.ScanAndCount(&list, &totalCount, false); err != nil { return nil, 0, gerror.Wrap(err, "获取开放接口权限组列表失败,请稍后重试!") } return } // Export 导出开放接口权限组(异步:提交任务后到下载中心取文件) func (s *sAgentTApiGroup) Export(ctx context.Context, in *model.TApiGroupListParam) (err error) { _, err = exportcenter.Submit(ctx, &exportcenter.Request{ BizKey: "tApiGroup", BizName: "开放接口权限组", PermCode: "cpm:agent:tApiGroup:export", QueryParam: in, Tags: func() ([]string, error) { return convert.GetEntityDescTags(model.TApiGroupListModel{}) }, Fetch: func(ctx context.Context, page, pageSize int) (rows []interface{}, total int, err error) { query := *in query.Page = page query.PageSize = pageSize list, count, err := s.List(ctx, &query) if err != nil { return nil, 0, err } rows = make([]interface{}, 0, len(list)) for _, item := range list { rows = append(rows, item) } return rows, count, nil }, }) return err } // Edit 新增或修改开放接口权限组,并同步维护权限组与接口资源的关联。 func (s *sAgentTApiGroup) Edit(ctx context.Context, in *model.TApiGroupEditParam) (err error) { if in.GroupCode != nil { if err = xgorm.IsUnique(ctx, &dao.TApiGroup, g.Map{dao.TApiGroup.Columns().GroupCode: *in.GroupCode}, "权限组编码已存在", in.Id); err != nil { return } } return g.DB().Transaction(ctx, func(ctx context.Context, tx gdb.TX) (err error) { groupId := in.Id if in.Id > 0 { updatedBy := contexts.GetUserId(ctx) in.UpdatedBy = &updatedBy in.UpdatedAt = gtime.Now() tenantId := contexts.GetTenantId(ctx) in.TenantId = &tenantId if _, err = s.Model(ctx). Fields(model.TApiGroupUpdateFields{}). WherePri(in.Id). Data(in). Update(); err != nil { return gerror.Wrap(err, "修改开放接口权限组失败,请稍后重试!") } return s.replaceGroupResources(ctx, tx, groupId, in.ApiIds) } tenantId := contexts.GetTenantId(ctx) in.TenantId = &tenantId createdDept := contexts.GetDeptId(ctx) in.CreatedDept = &createdDept createdBy := contexts.GetUserId(ctx) in.CreatedBy = &createdBy in.CreatedAt = gtime.Now() groupId, err = s.Model(ctx, &handler.Option{FilterAuth: false}). Fields(model.TApiGroupInsertFields{}). Data(in). InsertAndGetId() if err != nil { return gerror.Wrap(err, "新增开放接口权限组失败,请稍后重试!") } return s.replaceGroupResources(ctx, tx, groupId, in.ApiIds) }) } // Delete 删除开放接口权限组,并删除该权限组下的资源关联。 func (s *sAgentTApiGroup) Delete(ctx context.Context, in *model.TApiGroupDeleteParam) (err error) { return g.DB().Transaction(ctx, func(ctx context.Context, tx gdb.TX) (err error) { groupIds := gconv.Int64s(in.Id) if len(groupIds) > 0 { if _, err = tx.Ctx(ctx).Model(dao.TApiGroupResource.Table()). WhereIn(dao.TApiGroupResource.Columns().GroupId, groupIds). Delete(); err != nil { return gerror.Wrap(err, "删除开放接口权限组资源关联失败,请稍后重试!") } } if _, err = s.Model(ctx).WherePri(in.Id).Unscoped().Delete(); err != nil { return gerror.Wrap(err, "删除开放接口权限组失败,请稍后重试!") } return nil }) } // View returns the API group detail with bound resource IDs and resource list. func (s *sAgentTApiGroup) View(ctx context.Context, in *model.TApiGroupViewParam) (res *model.TApiGroupViewModel, err error) { if err = s.Model(ctx).WherePri(in.Id).Hook(hook.MemberSummary).Scan(&res); err != nil { return nil, gerror.Wrap(err, "get open api group failed") } if res == nil { return } apiIds, err := dao.TApiGroupResource.Ctx(ctx). Fields(dao.TApiGroupResource.Columns().ApiId). Where(dao.TApiGroupResource.Columns().GroupId, in.Id). Array() if err != nil { return nil, gerror.Wrap(err, "get open api group resource relations failed") } res.ApiIds = gconv.Int64s(apiIds) res.Apis = []*model.TApiResourceListModel{} if len(res.ApiIds) > 0 { if err = handler.Model(dao.TApiResource.Ctx(ctx), &handler.Option{FilterTenant: true, FilterAuth: false}). Fields(model.TApiResourceListModel{}). WhereIn(dao.TApiResource.Columns().Id, res.ApiIds). OrderAsc(dao.TApiResource.Columns().Id). Hook(hook.MemberSummary). Scan(&res.Apis); err != nil { return nil, gerror.Wrap(err, "get open api group resources failed") } } return } // Status 更新开放接口权限组启停状态。 func (s *sAgentTApiGroup) Status(ctx context.Context, in *model.TApiGroupStatusParam) (err error) { if _, err = s.Model(ctx).WherePri(in.Id).Data(g.Map{ dao.TApiGroup.Columns().Status: in.Status, dao.TApiGroup.Columns().UpdatedBy: contexts.GetUserId(ctx), dao.TApiGroup.Columns().UpdatedAt: gtime.Now(), }).Update(); err != nil { return gerror.Wrap(err, "更新开放接口权限组状态失败,请稍后重试!") } return } // replaceGroupResources 替换权限组绑定的接口资源,先清空旧关联再批量写入新关联。 func (s *sAgentTApiGroup) replaceGroupResources(ctx context.Context, tx gdb.TX, groupId int64, apiIds []int64) (err error) { if groupId <= 0 { return gerror.New("权限组ID不能为空") } if _, err = tx.Ctx(ctx).Model(dao.TApiGroupResource.Table()). Where(dao.TApiGroupResource.Columns().GroupId, groupId). Delete(); err != nil { return gerror.Wrap(err, "删除开放接口权限组资源关联失败,请稍后重试!") } seen := make(map[int64]struct{}, len(apiIds)) data := g.List{} for _, apiId := range apiIds { if apiId <= 0 { continue } if _, ok := seen[apiId]; ok { continue } seen[apiId] = struct{}{} data = append(data, g.Map{ dao.TApiGroupResource.Columns().GroupId: groupId, dao.TApiGroupResource.Columns().ApiId: apiId, }) } if len(data) == 0 { return nil } if _, err = tx.Ctx(ctx).Model(dao.TApiGroupResource.Table()).Data(data).Insert(); err != nil { return gerror.Wrap(err, "保存开放接口权限组资源关联失败,请稍后重试!") } return nil }