Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(admin): add team info sync functionality #213

Merged
merged 3 commits into from
Mar 11, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 14 additions & 1 deletion api/admin/team/team.proto
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,14 @@ service Team {
get: "/v1/team/member/detail/{id}"
};
}

// 同步基础信息
rpc SyncTeamInfo (SyncTeamInfoRequest) returns (SyncTeamInfoReply) {
option (google.api.http) = {
put: "/v1/team/sync"
body: "*"
};
}
}

message CreateTeamRequest {
Expand Down Expand Up @@ -293,4 +301,9 @@ message GetTeamMemberDetailRequest {
}
message GetTeamMemberDetailReply {
TeamMemberItem detail = 1;
}
}

message SyncTeamInfoRequest {
repeated uint32 teamIds = 1;
}
message SyncTeamInfoReply {}
3 changes: 3 additions & 0 deletions cmd/server/palace/internal/biz/repository/team.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,4 +70,7 @@ type Team interface {

// GetMemberDetail 获取团队成员详情
GetMemberDetail(context.Context, uint32) (*bizmodel.SysTeamMember, error)

// SyncTeamInfo 同步团队信息
SyncTeamInfo(context.Context, ...uint32) error
}
8 changes: 8 additions & 0 deletions cmd/server/palace/internal/biz/team.go
Original file line number Diff line number Diff line change
Expand Up @@ -247,3 +247,11 @@ func (t *TeamBiz) GetTeamMemberDetail(ctx context.Context, memberID uint32) (*bi
}
return member, nil
}

// SyncTeamInfo 同步团队信息
func (t *TeamBiz) SyncTeamInfo(ctx context.Context, teamIds []uint32) error {
if err := t.teamRepo.SyncTeamInfo(ctx, teamIds...); !types.IsNil(err) {
return merr.ErrorI18nNotificationSystemError(ctx).WithCause(err)
}
return nil
}
12 changes: 0 additions & 12 deletions cmd/server/palace/internal/data/data.go
Original file line number Diff line number Diff line change
Expand Up @@ -160,13 +160,6 @@ func NewData(c *palaceconf.Bootstrap) (*Data, func(), error) {
return nil, nil, err
}

// 同步业务模型到各个团队, 保证数据一致性
if err := d.syncBizDatabase(); err != nil {
log.Fatalf("Error init biz database: %v\n", err)
cleanup()
return nil, nil, err
}

closeFuncList = append(closeFuncList, func() {
mainDBClose, _ := d.mainDB.DB()
log.Debugw("close main db", mainDBClose.Close())
Expand All @@ -181,11 +174,6 @@ func (d *Data) initMainDatabase() error {
return initMainDatabase(d)
}

// syncBizDatabase 同步业务模型到各个团队, 保证数据一致性
func (d *Data) syncBizDatabase() error {
return syncBizDatabase(d)
}

// GetMainDB 获取主库连接
func (d *Data) GetMainDB(ctx context.Context) *gorm.DB {
db, exist := conn.GetDB(ctx)
Expand Down
208 changes: 84 additions & 124 deletions cmd/server/palace/internal/data/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,24 +6,19 @@ import (

"github.com/aide-family/moon/pkg/env"
"github.com/aide-family/moon/pkg/palace/model"
"github.com/aide-family/moon/pkg/palace/model/alarmmodel"
"github.com/aide-family/moon/pkg/palace/model/bizmodel"
"github.com/aide-family/moon/pkg/palace/model/bizmodel/bizquery"
"github.com/aide-family/moon/pkg/palace/model/query"
"github.com/aide-family/moon/pkg/util/types"
"github.com/aide-family/moon/pkg/vobj"
"golang.org/x/sync/errgroup"

"gorm.io/gorm/clause"
)

func initMainDatabase(d *Data) error {
if env.Env() != "dev" {
return nil
}
//if err := d.mainDB.AutoMigrate(model.Models()...); err != nil {
// return err
//}

if err := d.mainDB.AutoMigrate(model.Models()...); err != nil {
return err
}

if err := query.Use(d.mainDB).SysDict.Clauses(clause.OnConflict{DoNothing: true}).Create(defaultDictList...); err != nil {
return err
Expand All @@ -42,121 +37,6 @@ func initMainDatabase(d *Data) error {
return nil
}

// syncBizDatabase 同步业务模型到各个团队, 保证数据一致性
func syncBizDatabase(d *Data) error {
if env.Env() != "dev" {
return nil
}
return nil
// 获取所有团队
teams, err := query.Use(d.mainDB).SysTeam.Find()
if !types.IsNil(err) {
return err
}
mainQuery := query.Use(d.mainDB)
sysApis, err := mainQuery.SysAPI.Find()
if !types.IsNil(err) {
return err
}

sysDict, err := mainQuery.SysDict.Find()
if !types.IsNil(err) {
return err
}

sendTemplates, err := mainQuery.SysSendTemplate.Find()
if !types.IsNil(err) {
return err
}

teamApis := types.SliceToWithFilter(sysApis, func(apiItem *model.SysAPI) (*bizmodel.SysTeamAPI, bool) {
return &bizmodel.SysTeamAPI{
Name: apiItem.Name,
Path: apiItem.Path,
Status: apiItem.Status,
Remark: apiItem.Remark,
Module: apiItem.Module,
Domain: apiItem.Domain,
}, true
})

dictList := types.SliceToWithFilter(sysDict, func(dictItem *model.SysDict) (*bizmodel.SysDict, bool) {
return &bizmodel.SysDict{
Name: dictItem.Name,
Value: dictItem.Value,
DictType: dictItem.DictType,
ColorType: dictItem.ColorType,
CSSClass: dictItem.CSSClass,
Icon: dictItem.Icon,
ImageURL: dictItem.ImageURL,
Status: dictItem.Status,
LanguageCode: dictItem.LanguageCode,
Remark: dictItem.Remark,
}, true
})

sendTemplatesList := types.SliceToWithFilter(sendTemplates, func(item *model.SysSendTemplate) (*bizmodel.SysSendTemplate, bool) {
return &bizmodel.SysSendTemplate{
Name: item.Name,
Content: item.Content,
Status: item.Status,
Remark: item.Remark,
SendType: item.SendType,
}, true
})

eg := new(errgroup.Group)
eg.SetLimit(30)
for _, teamItem := range teams {
team := teamItem
eg.Go(func() error {
// 获取团队业务库连接
db, err := d.GetBizGormDB(team.ID)
if err != nil {
return err
}

if err = db.AutoMigrate(bizmodel.Models()...); err != nil {
return err
}
// 同步实时告警数据库
alarmDB, err := d.GetAlarmGormDB(team.ID)
if err != nil {
return err
}

if err = alarmDB.AutoMigrate(alarmmodel.Models()...); err != nil {
return err
}
if len(dictList) > 0 {
if err = bizquery.Use(db).SysDict.Clauses(clause.OnConflict{DoNothing: true}).Create(dictList...); !types.IsNil(err) {
return err
}
}
if err := bizquery.Use(db).SysTeamAPI.Clauses(clause.OnConflict{DoNothing: true}).Create(teamApis...); !types.IsNil(err) {
return err
}
teamMember := &bizmodel.SysTeamMember{
UserID: team.GetCreatorID(),
Status: vobj.StatusEnable,
Role: vobj.RoleSuperAdmin,
}
// 把创建人同步到团队成员表
if err := bizquery.Use(db).SysTeamMember.Clauses(clause.OnConflict{DoNothing: true}).Create(teamMember); !types.IsNil(err) {
return err
}

if len(sendTemplatesList) > 0 {
if err := bizquery.Use(db).SysSendTemplate.Clauses(clause.OnConflict{DoNothing: true}).Create(sendTemplatesList...); err != nil {
return err
}
}
return nil
})
}
return eg.Wait()
}

// 创建默认字典
var defaultDictList = []*model.SysDict{
{
Expand Down Expand Up @@ -780,6 +660,78 @@ var resourceList = []*model.SysAPI{
Status: vobj.StatusEnable,
Allow: vobj.AllowRBAC,
},
// 添加图表
{
Name: "添加图表",
Path: "/api.admin.realtime.Dashboard/AddChart",
Remark: "添加图表, 用于添加图表",
Status: vobj.StatusEnable,
Allow: vobj.AllowRBAC,
},
// 更新图表
{
Name: "更新图表",
Path: "/api.admin.realtime.Dashboard/UpdateChart",
Remark: "更新图表, 用于更新图表",
Status: vobj.StatusEnable,
Allow: vobj.AllowRBAC,
},
// DeleteChart 删除图表
{
Name: "删除图表",
Path: "/api.admin.realtime.Dashboard/DeleteChart",
Remark: "删除图表, 用于删除图表",
Status: vobj.StatusEnable,
Allow: vobj.AllowRBAC,
},
// GetChart 获取图表
{
Name: "获取图表",
Path: "/api.admin.realtime.Dashboard/GetChart",
Remark: "获取图表, 用于获取图表",
Status: vobj.StatusEnable,
Allow: vobj.AllowRBAC,
},
// 获取图表列表
{
Name: "获取图表列表",
Path: "/api.admin.realtime.Dashboard/ListChart",
Remark: "获取图表列表, 用于获取图表列表",
Status: vobj.StatusEnable,
Allow: vobj.AllowRBAC,
},
// 批量修改图表状态
{
Name: "批量修改图表状态",
Path: "/api.admin.realtime.Dashboard/BatchUpdateChartStatus",
Remark: "批量修改图表状态, 用于批量修改图表状态",
Status: vobj.StatusEnable,
Allow: vobj.AllowRBAC,
},
// 批量更新图表排序
{
Name: "批量更新图表排序",
Path: "/api.admin.realtime.Dashboard/BatchUpdateChartSort",
Remark: "批量更新图表排序, 用于批量更新图表排序",
Status: vobj.StatusEnable,
Allow: vobj.AllowRBAC,
},
// 获取个人仪表板列表
{
Name: "获取个人仪表板列表",
Path: "/api.admin.realtime.Dashboard/ListDashboardSelf",
Remark: "获取个人仪表板列表, 用于获取个人仪表板列表",
Status: vobj.StatusEnable,
Allow: vobj.AllowRBAC,
},
// UpdateSelfDashboard
{
Name: "更新个人仪表板",
Path: "/api.admin.realtime.Dashboard/UpdateSelfDashboard",
Remark: "更新个人仪表板, 用于更新个人仪表板",
Status: vobj.StatusEnable,
Allow: vobj.AllowRBAC,
},
// 系统公共API资源管理模块
// 获取资源详情
{
Expand Down Expand Up @@ -1196,6 +1148,14 @@ var resourceList = []*model.SysAPI{
Status: vobj.StatusEnable,
Allow: vobj.AllowTeam,
},
// 同步基础信息
{
Name: "同步团队基础信息",
Path: "/api.admin.team.Team/SyncTeamInfo",
Remark: "同步团队基础信息, 用于同步团队基础信息",
Status: vobj.StatusEnable,
Allow: vobj.AllowSystem,
},
// 用户个人消息模块
// 删除消息, 用于清除所有通知
{
Expand Down
6 changes: 3 additions & 3 deletions cmd/server/palace/internal/data/repoimpl/lock.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,15 @@ type lockRepositoryImpl struct {
}

func (l *lockRepositoryImpl) Lock(ctx context.Context, key string, expire time.Duration) error {
exist, err := l.data.GetCacher().Client().Exists(ctx, key).Result()
locked, err := l.data.GetCacher().Client().SetNX(ctx, key, key, expire).Result()
if err != nil {
return err
}
// 判断是否存在
if exist == 1 {
if !locked {
return merr.ErrorI18nToastDatasourceSyncing(ctx)
}
return l.data.GetCacher().Client().Set(ctx, key, key, expire).Err()
return nil
}

func (l *lockRepositoryImpl) UnLock(ctx context.Context, key string) error {
Expand Down
24 changes: 14 additions & 10 deletions cmd/server/palace/internal/data/repoimpl/realtime_alarm.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"github.com/aide-family/moon/pkg/palace/model/alarmmodel"
"github.com/aide-family/moon/pkg/palace/model/alarmmodel/alarmquery"
"github.com/aide-family/moon/pkg/palace/model/bizmodel"
"github.com/aide-family/moon/pkg/util/after"
"github.com/aide-family/moon/pkg/util/types"
"github.com/aide-family/moon/pkg/vobj"

Expand Down Expand Up @@ -145,16 +146,19 @@ func (r *realtimeAlarmRepositoryImpl) GetRealTimeAlarms(ctx context.Context, par
return nil, err
}

// 删除已经恢复的告警及关联数据
var resolvedIds []uint32
_ = alarmQuery.WithContext(ctx).RealtimeAlarm.Where(alarmQuery.RealtimeAlarm.Status.Eq(vobj.AlertStatusResolved.GetValue())).
Select(alarmQuery.RealtimeAlarm.ID).Scan(&resolvedIds)
if len(resolvedIds) > 0 {
_, _ = alarmQuery.RealtimeAlarm.Where(alarmQuery.RealtimeAlarm.Status.Eq(vobj.AlertStatusResolved.GetValue())).Delete()
_, _ = alarmQuery.RealtimeDetails.Where(alarmQuery.RealtimeDetails.RealtimeAlarmID.In(resolvedIds...)).Delete()
_, _ = alarmQuery.RealtimeAlarmPage.Where(alarmQuery.RealtimeAlarmPage.RealtimeAlarmID.In(resolvedIds...)).Delete()
_, _ = alarmQuery.RealtimeAlarmReceiver.Where(alarmQuery.RealtimeAlarmReceiver.RealtimeAlarmID.In(resolvedIds...)).Delete()
}
go func() {
defer after.RecoverX()
// 删除已经恢复的告警及关联数据
var resolvedIds []uint32
_ = alarmQuery.WithContext(types.CopyValueCtx(ctx)).RealtimeAlarm.Where(alarmQuery.RealtimeAlarm.Status.Eq(vobj.AlertStatusResolved.GetValue())).
Select(alarmQuery.RealtimeAlarm.ID).Scan(&resolvedIds)
if len(resolvedIds) > 0 {
_, _ = alarmQuery.RealtimeAlarm.Where(alarmQuery.RealtimeAlarm.Status.Eq(vobj.AlertStatusResolved.GetValue())).Delete()
_, _ = alarmQuery.RealtimeDetails.Where(alarmQuery.RealtimeDetails.RealtimeAlarmID.In(resolvedIds...)).Delete()
_, _ = alarmQuery.RealtimeAlarmPage.Where(alarmQuery.RealtimeAlarmPage.RealtimeAlarmID.In(resolvedIds...)).Delete()
_, _ = alarmQuery.RealtimeAlarmReceiver.Where(alarmQuery.RealtimeAlarmReceiver.RealtimeAlarmID.In(resolvedIds...)).Delete()
}
}()

wheres := []gen.Condition{
alarmQuery.RealtimeAlarm.Status.Eq(vobj.AlertStatusFiring.GetValue()),
Expand Down
Loading