235 lines
6.1 KiB
Go
235 lines
6.1 KiB
Go
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 ""
|
|
}
|