package pub import ( "context" "time" "perms-system-server/internal/consts" permModel "perms-system-server/internal/model/perm" "perms-system-server/internal/svc" "github.com/zeromicro/go-zero/core/stores/sqlx" "golang.org/x/crypto/bcrypt" ) type SyncPermsResult struct { Added int64 Updated int64 Disabled int64 } type SyncPermItem struct { Code string Name string Remark string } type SyncPermsError struct { Code int Message string } func (e *SyncPermsError) Error() string { return e.Message } func ExecuteSyncPerms(ctx context.Context, svcCtx *svc.ServiceContext, appKey, appSecret string, perms []SyncPermItem) (*SyncPermsResult, error) { product, err := svcCtx.SysProductModel.FindOneByAppKey(ctx, appKey) if err != nil { return nil, &SyncPermsError{Code: 401, Message: "无效的appKey"} } if err := bcrypt.CompareHashAndPassword([]byte(product.AppSecret), []byte(appSecret)); err != nil { return nil, &SyncPermsError{Code: 401, Message: "appSecret验证失败"} } if product.Status != consts.StatusEnabled { return nil, &SyncPermsError{Code: 403, Message: "产品已被禁用"} } if len(perms) == 0 { return nil, &SyncPermsError{Code: 400, Message: "权限列表不能为空,如需禁用所有权限请使用专用接口"} } existingMap, err := svcCtx.SysPermModel.FindMapByProductCode(ctx, product.Code) if err != nil { return nil, &SyncPermsError{Code: 500, Message: "查询权限数据失败"} } now := time.Now().Unix() var added, updated int64 codes := make([]string, 0, len(perms)) var toInsert []*permModel.SysPerm var toUpdate []*permModel.SysPerm seen := make(map[string]bool, len(perms)) for _, item := range perms { if seen[item.Code] { continue } seen[item.Code] = true codes = append(codes, item.Code) existing, ok := existingMap[item.Code] if !ok { toInsert = append(toInsert, &permModel.SysPerm{ ProductCode: product.Code, Name: item.Name, Code: item.Code, Remark: item.Remark, Status: consts.StatusEnabled, CreateTime: now, UpdateTime: now, }) added++ continue } if existing.Name != item.Name || existing.Remark != item.Remark || existing.Status != consts.StatusEnabled { existing.Name = item.Name existing.Remark = item.Remark existing.Status = consts.StatusEnabled existing.UpdateTime = now toUpdate = append(toUpdate, existing) updated++ } } var disabled int64 if err := svcCtx.SysPermModel.TransactCtx(ctx, func(txCtx context.Context, session sqlx.Session) error { if len(toInsert) > 0 { if err := svcCtx.SysPermModel.BatchInsertWithTx(txCtx, session, toInsert); err != nil { return err } } if len(toUpdate) > 0 { if err := svcCtx.SysPermModel.BatchUpdateWithTx(txCtx, session, toUpdate); err != nil { return err } } var err error disabled, err = svcCtx.SysPermModel.DisableNotInCodesWithTx(txCtx, session, product.Code, codes, now) return err }); err != nil { return nil, &SyncPermsError{Code: 500, Message: "同步权限事务失败"} } if added > 0 || updated > 0 || disabled > 0 { svcCtx.UserDetailsLoader.CleanByProduct(ctx, product.Code) } return &SyncPermsResult{ Added: added, Updated: updated, Disabled: disabled, }, nil }