package service import ( "errors" "github.com/flipped-aurora/gin-vue-admin/server/global" "github.com/flipped-aurora/gin-vue-admin/server/plugin/wechat-integration/model" ) type WechatUserService struct{} // GetUnifiedUserInfo 获取统一的微信用户信息 (通过 unionid 关联) func (w *WechatUserService) GetUnifiedUserInfo(unionid string) (*UnifiedWechatUser, error) { if unionid == "" { return nil, errors.New("unionid 不能为空") } var unifiedUser UnifiedWechatUser // 查找小程序用户 var miniUser model.WechatMiniUser err := global.GVA_DB.Where("unionid = ?", unionid).First(&miniUser).Error if err == nil { unifiedUser.MiniUser = &miniUser unifiedUser.UserID = miniUser.UserID } // 查找公众号用户 var mpUser model.MpUser err = global.GVA_DB.Where("unionid = ?", unionid).First(&mpUser).Error if err == nil { unifiedUser.MpUser = &mpUser if unifiedUser.UserID == nil { unifiedUser.UserID = mpUser.UserID } } // 如果都没找到 if unifiedUser.MiniUser == nil && unifiedUser.MpUser == nil { return nil, errors.New("未找到相关用户信息") } unifiedUser.UnionID = unionid return &unifiedUser, nil } // GetUserBySystemUserID 根据系统用户ID获取微信用户信息 func (w *WechatUserService) GetUserBySystemUserID(userID uint) (*UnifiedWechatUser, error) { var unifiedUser UnifiedWechatUser unifiedUser.UserID = &userID // 查找小程序用户 var miniUser model.WechatMiniUser err := global.GVA_DB.Where("user_id = ?", userID).First(&miniUser).Error if err == nil { unifiedUser.MiniUser = &miniUser if miniUser.UnionID != nil { unifiedUser.UnionID = *miniUser.UnionID } } // 查找公众号用户 var mpUser model.MpUser err = global.GVA_DB.Where("user_id = ?", userID).First(&mpUser).Error if err == nil { unifiedUser.MpUser = &mpUser if unifiedUser.UnionID == "" && mpUser.UnionID != nil { unifiedUser.UnionID = *mpUser.UnionID } } // 如果都没找到 if unifiedUser.MiniUser == nil && unifiedUser.MpUser == nil { return nil, errors.New("未找到相关用户信息") } return &unifiedUser, nil } // LinkAllAccountsToSystemUser 将所有微信账号关联到系统用户 func (w *WechatUserService) LinkAllAccountsToSystemUser(unionid string, userID uint) error { if unionid == "" { return errors.New("unionid 不能为空") } // 开启事务 tx := global.GVA_DB.Begin() defer func() { if r := recover(); r != nil { tx.Rollback() } }() // 关联小程序用户 err := tx.Model(&model.WechatMiniUser{}).Where("unionid = ?", unionid).Update("user_id", userID).Error if err != nil { tx.Rollback() global.GVA_LOG.Error("关联小程序用户失败: " + err.Error()) return err } // 关联公众号用户 err = tx.Model(&model.MpUser{}).Where("unionid = ?", unionid).Update("user_id", userID).Error if err != nil { tx.Rollback() global.GVA_LOG.Error("关联公众号用户失败: " + err.Error()) return err } // 提交事务 err = tx.Commit().Error if err != nil { global.GVA_LOG.Error("提交事务失败: " + err.Error()) return err } global.GVA_LOG.Info("成功关联所有微信账号到系统用户") return nil } // GetAllWechatUsers 获取所有微信用户列表 (分页) func (w *WechatUserService) GetAllWechatUsers(page, pageSize int) ([]UnifiedWechatUser, int64, error) { var users []UnifiedWechatUser var total int64 // 这里需要复杂的查询逻辑,暂时简化实现 // 实际项目中可能需要使用 SQL 联合查询或者分别查询后合并 // 先获取所有有 unionid 的用户 var unionIDs []string // 从小程序用户中获取 unionid err := global.GVA_DB.Model(&model.WechatMiniUser{}). Where("unionid IS NOT NULL AND unionid != ''"). Distinct("unionid"). Pluck("unionid", &unionIDs).Error if err != nil { return nil, 0, err } // 从公众号用户中获取 unionid var mpUnionIDs []string err = global.GVA_DB.Model(&model.MpUser{}). Where("unionid IS NOT NULL AND unionid != ''"). Distinct("unionid"). Pluck("unionid", &mpUnionIDs).Error if err != nil { return nil, 0, err } // 合并去重 unionIDMap := make(map[string]bool) for _, id := range unionIDs { unionIDMap[id] = true } for _, id := range mpUnionIDs { unionIDMap[id] = true } // 转换为切片 allUnionIDs := make([]string, 0, len(unionIDMap)) for id := range unionIDMap { allUnionIDs = append(allUnionIDs, id) } total = int64(len(allUnionIDs)) // 分页处理 start := (page - 1) * pageSize end := start + pageSize if end > len(allUnionIDs) { end = len(allUnionIDs) } if start >= len(allUnionIDs) { return users, total, nil } pageUnionIDs := allUnionIDs[start:end] // 获取每个 unionid 对应的用户信息 for _, unionID := range pageUnionIDs { unifiedUser, err := w.GetUnifiedUserInfo(unionID) if err == nil { users = append(users, *unifiedUser) } } return users, total, nil } // UnifiedWechatUser 统一的微信用户信息结构 type UnifiedWechatUser struct { UnionID string `json:"unionid"` UserID *uint `json:"userId"` MiniUser *model.WechatMiniUser `json:"miniUser,omitempty"` MpUser *model.MpUser `json:"mpUser,omitempty"` } // HasMiniProgram 是否有小程序账号 func (u *UnifiedWechatUser) HasMiniProgram() bool { return u.MiniUser != nil } // HasOfficialAccount 是否有公众号账号 func (u *UnifiedWechatUser) HasOfficialAccount() bool { return u.MpUser != nil } // IsLinkedToSystemUser 是否已关联系统用户 func (u *UnifiedWechatUser) IsLinkedToSystemUser() bool { return u.UserID != nil && *u.UserID > 0 } // GetDisplayName 获取显示名称 func (u *UnifiedWechatUser) GetDisplayName() string { if u.MiniUser != nil && u.MiniUser.Nickname != nil { return *u.MiniUser.Nickname } if u.MpUser != nil && u.MpUser.Nickname != nil { return *u.MpUser.Nickname } return "未知用户" } // GetAvatarURL 获取头像URL func (u *UnifiedWechatUser) GetAvatarURL() string { if u.MiniUser != nil && u.MiniUser.AvatarURL != nil { return *u.MiniUser.AvatarURL } if u.MpUser != nil && u.MpUser.HeadImageURL != nil { return *u.MpUser.HeadImageURL } return "" }