|
- package flashduty
-
- import (
- "errors"
-
- "github.com/ccfos/nightingale/v6/models"
- "github.com/ccfos/nightingale/v6/pkg/ctx"
-
- "github.com/toolkits/pkg/logger"
- )
-
- func SyncUsersChange(ctx *ctx.Context, dbUsers []*models.User) error {
- if !ctx.IsCenter {
- return nil
- }
-
- appKey, err := models.ConfigsGetFlashDutyAppKey(ctx)
- if err != nil {
- return err
- }
-
- req := make(map[string]interface{})
- req["limit"] = 100
- userList, err := PostFlashDutyWithResp("/member/list", appKey, req)
- if err != nil {
- return err
- }
-
- total := userList.Total
- items := []Item{}
- for i := 0; i < total/100+1; i++ {
- req["p"] = i
- req["limit"] = 100
- resp, err := PostFlashDutyWithResp("/member/list", appKey, req)
- if err != nil {
- return err
- }
- items = append(items, resp.Items...)
- }
-
- dutyUsers := make(map[string]*models.User, len(items))
- for i := range items {
- user := &models.User{
- Username: items[i].MemberName,
- Email: items[i].Email,
- Phone: items[i].Phone,
- }
- dutyUsers[user.Username+user.Email] = user
- }
-
- dbUsersHas := sliceToMap(dbUsers)
-
- delUsers := diffMap(dutyUsers, dbUsersHas)
- fdDelUsers(appKey, delUsers)
-
- addUsers := diffMap(dbUsersHas, dutyUsers)
- if err := fdAddUsers(appKey, addUsers); err != nil {
- return err
- }
-
- return nil
- }
-
- func sliceToMap(dbUsers []*models.User) map[string]*models.User {
- m := make(map[string]*models.User, len(dbUsers))
- for _, user := range dbUsers {
- m[user.Username+user.Email] = user
- }
- return m
- }
-
- // in m1 and not in m2
- func diffMap(m1, m2 map[string]*models.User) []models.User {
- var diff []models.User
- for i := range m1 {
- if _, ok := m2[i]; !ok {
- diff = append(diff, *m1[i])
- }
- }
- return diff
- }
-
- type User struct {
- Email string `json:"email,omitempty"`
- Phone string `json:"phone,omitempty"`
- MemberName string `json:"member_name,omitempty"`
- Updates Updates `json:"updates,omitempty"`
- }
-
- type Updates struct {
- Email string `json:"email,omitempty"`
- Phone string `json:"phone,omitempty"`
- MemberName string `json:"member_name,omitempty"`
- CountryCode string `json:"country_code,omitempty"`
- }
-
- func (user *User) delMember(appKey string) error {
- if user.Email == "" && user.Phone == "" {
- return errors.New("phones and email must be selected one of two")
- }
- return PostFlashDuty("/member/delete", appKey, user)
- }
-
- func (user *User) UpdateMember(ctx *ctx.Context) error {
- appKey, err := models.ConfigsGetFlashDutyAppKey(ctx)
- if err != nil {
- return err
- }
-
- return PostFlashDuty("/member/info/reset", appKey, user)
- }
-
- type Members struct {
- Users []User `json:"members"`
- }
-
- func (m *Members) addMembers(appKey string) error {
- if len(m.Users) == 0 {
- return nil
- }
- validUsers := make([]User, 0, len(m.Users))
- for _, user := range m.Users {
- if user.Email == "" && (user.Phone != "" && user.MemberName == "" || user.Phone == "") {
- logger.Errorf("user(%+v) phone and email must be selected one of two, and the member_name must be added when selecting the phone", user)
- } else {
- validUsers = append(validUsers, user)
- }
- }
- m.Users = validUsers
- return PostFlashDuty("/member/invite", appKey, m)
- }
-
- func fdAddUsers(appKey string, users []models.User) error {
- fdUsers := usersToFdUsers(users)
- members := &Members{
- Users: fdUsers,
- }
- return members.addMembers(appKey)
- }
-
- func fdDelUsers(appKey string, users []models.User) {
- fdUsers := usersToFdUsers(users)
- for _, fdUser := range fdUsers {
- if err := fdUser.delMember(appKey); err != nil {
- logger.Errorf("failed to delete user: %v", err)
- }
- }
- }
-
- func usersToFdUsers(users []models.User) []User {
- fdUsers := make([]User, 0, len(users))
- for i := range users {
- fdUsers = append(fdUsers, User{
- Email: users[i].Email,
- Phone: users[i].Phone,
- MemberName: users[i].Username,
- })
- }
- return fdUsers
- }
-
- func UpdateUser(ctx *ctx.Context, target models.User, email, phone string) {
- contact := target.FindSameContact(email, phone)
- var flashdutyUser User
- var needSync bool
- switch contact {
- case "email":
- flashdutyUser = User{
- Email: target.Email,
- }
- if target.Phone != phone {
- needSync = true
- flashdutyUser.Updates = Updates{
- Phone: phone,
- MemberName: target.Username,
- CountryCode: "CN",
- }
- }
- case "phone":
- flashdutyUser = User{
- Phone: target.Phone,
- }
-
- if target.Email != email {
- needSync = true
- flashdutyUser.Updates = Updates{
- Email: email,
- MemberName: target.Username,
- }
- }
- default:
- flashdutyUser = User{
- MemberName: target.Username,
- }
- if target.Email != email {
- needSync = true
- flashdutyUser.Updates.Email = email
- }
- if target.Phone != phone {
- needSync = true
- flashdutyUser.Updates.Phone = phone
- flashdutyUser.Updates.CountryCode = "CN"
- }
- }
-
- if needSync {
- err := flashdutyUser.UpdateMember(ctx)
- if err != nil {
- logger.Errorf("failed to update user: %v", err)
- }
- }
- }
|