This commit is contained in:
@@ -0,0 +1,250 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"time"
|
||||
|
||||
"github.com/flipped-aurora/gin-vue-admin/server/global"
|
||||
"github.com/flipped-aurora/gin-vue-admin/server/plugin/wechat-integration/model"
|
||||
"github.com/silenceper/wechat/v2"
|
||||
"github.com/silenceper/wechat/v2/cache"
|
||||
"github.com/silenceper/wechat/v2/officialaccount"
|
||||
"github.com/silenceper/wechat/v2/officialaccount/config"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type MpUserService struct{}
|
||||
|
||||
// GetOfficialAccount 获取微信公众号实例
|
||||
func (m *MpUserService) GetOfficialAccount() (*officialaccount.OfficialAccount, error) {
|
||||
if global.GVA_CONFIG.Wechat.OfficialAppID == "" || global.GVA_CONFIG.Wechat.OfficialAppSecret == "" {
|
||||
return nil, errors.New("微信公众号配置不完整")
|
||||
}
|
||||
|
||||
wc := wechat.NewWechat()
|
||||
memory := cache.NewMemory()
|
||||
cfg := &config.Config{
|
||||
AppID: global.GVA_CONFIG.Wechat.OfficialAppID,
|
||||
AppSecret: global.GVA_CONFIG.Wechat.OfficialAppSecret,
|
||||
Token: global.GVA_CONFIG.Wechat.OfficialToken,
|
||||
Cache: memory,
|
||||
}
|
||||
|
||||
return wc.GetOfficialAccount(cfg), nil
|
||||
}
|
||||
|
||||
// SyncUser 同步微信用户信息
|
||||
func (m *MpUserService) SyncUser(openid string) (*model.MpUser, error) {
|
||||
oa, err := m.GetOfficialAccount()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 从微信获取用户信息
|
||||
userInfo, err := oa.GetUser().GetUserInfo(openid)
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("获取微信用户信息失败: " + err.Error())
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 查找或创建用户
|
||||
var user model.MpUser
|
||||
err = global.GVA_DB.Where("openid = ?", openid).First(&user).Error
|
||||
if err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
// 创建新用户
|
||||
user = model.MpUser{
|
||||
OpenID: userInfo.OpenID,
|
||||
SubscribeStatus: int(userInfo.Subscribe),
|
||||
}
|
||||
if userInfo.Nickname != "" {
|
||||
user.Nickname = &userInfo.Nickname
|
||||
}
|
||||
if userInfo.Headimgurl != "" {
|
||||
user.HeadImageURL = &userInfo.Headimgurl
|
||||
}
|
||||
if userInfo.Language != "" {
|
||||
user.Language = &userInfo.Language
|
||||
}
|
||||
if userInfo.Country != "" {
|
||||
user.Country = &userInfo.Country
|
||||
}
|
||||
if userInfo.Province != "" {
|
||||
user.Province = &userInfo.Province
|
||||
}
|
||||
if userInfo.City != "" {
|
||||
user.City = &userInfo.City
|
||||
}
|
||||
|
||||
// 设置关注时间
|
||||
if userInfo.Subscribe == 1 && userInfo.SubscribeTime > 0 {
|
||||
subscribeTime := time.Unix(int64(userInfo.SubscribeTime), 0)
|
||||
user.SubscribeTime = &subscribeTime
|
||||
}
|
||||
|
||||
// 设置 UnionID (仅用于记录,公众号不关联系统用户)
|
||||
if userInfo.UnionID != "" {
|
||||
user.UnionID = &userInfo.UnionID
|
||||
global.GVA_LOG.Info("公众号用户 UnionID: " + userInfo.UnionID)
|
||||
}
|
||||
|
||||
err = global.GVA_DB.Create(&user).Error
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("创建微信公众号用户失败: " + err.Error())
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
global.GVA_LOG.Error("查询微信公众号用户失败: " + err.Error())
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
// 更新用户信息
|
||||
user.SubscribeStatus = int(userInfo.Subscribe)
|
||||
if userInfo.Nickname != "" {
|
||||
user.Nickname = &userInfo.Nickname
|
||||
}
|
||||
if userInfo.Headimgurl != "" {
|
||||
user.HeadImageURL = &userInfo.Headimgurl
|
||||
}
|
||||
if userInfo.Language != "" {
|
||||
user.Language = &userInfo.Language
|
||||
}
|
||||
if userInfo.Country != "" {
|
||||
user.Country = &userInfo.Country
|
||||
}
|
||||
if userInfo.Province != "" {
|
||||
user.Province = &userInfo.Province
|
||||
}
|
||||
if userInfo.City != "" {
|
||||
user.City = &userInfo.City
|
||||
}
|
||||
|
||||
// 更新关注状态和时间
|
||||
if userInfo.Subscribe == 1 && userInfo.SubscribeTime > 0 {
|
||||
subscribeTime := time.Unix(int64(userInfo.SubscribeTime), 0)
|
||||
user.SubscribeTime = &subscribeTime
|
||||
user.UnsubscribeTime = nil
|
||||
} else if userInfo.Subscribe == 0 {
|
||||
now := time.Now()
|
||||
user.UnsubscribeTime = &now
|
||||
}
|
||||
|
||||
// 如果还没有关联系统用户且有 unionid,尝试关联
|
||||
// 注意:这里需要根据实际业务需求决定是否需要重新关联
|
||||
|
||||
err = global.GVA_DB.Save(&user).Error
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("更新微信公众号用户失败: " + err.Error())
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return &user, nil
|
||||
}
|
||||
|
||||
// GetUserByOpenID 根据 OpenID 获取用户
|
||||
func (m *MpUserService) GetUserByOpenID(openid string) (*model.MpUser, error) {
|
||||
var user model.MpUser
|
||||
err := global.GVA_DB.Where("openid = ?", openid).First(&user).Error
|
||||
if err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return nil, errors.New("用户不存在")
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
return &user, nil
|
||||
}
|
||||
|
||||
// GetUserList 获取用户列表
|
||||
func (m *MpUserService) GetUserList(page, pageSize int, subscribeStatus *int) ([]model.MpUser, int64, error) {
|
||||
var users []model.MpUser
|
||||
var total int64
|
||||
|
||||
db := global.GVA_DB.Model(&model.MpUser{})
|
||||
|
||||
// 根据关注状态筛选
|
||||
if subscribeStatus != nil {
|
||||
db = db.Where("subscribe_status = ?", *subscribeStatus)
|
||||
}
|
||||
|
||||
// 获取总数
|
||||
err := db.Count(&total).Error
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
// 分页查询
|
||||
offset := (page - 1) * pageSize
|
||||
err = db.Offset(offset).Limit(pageSize).Order("created_at desc").Find(&users).Error
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
return users, total, nil
|
||||
}
|
||||
|
||||
// UpdateUserRemark 更新用户备注
|
||||
func (m *MpUserService) UpdateUserRemark(openid, remark string) error {
|
||||
// 先更新微信服务器
|
||||
oa, err := m.GetOfficialAccount()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = oa.GetUser().UpdateRemark(openid, remark)
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("更新微信用户备注失败: " + err.Error())
|
||||
return err
|
||||
}
|
||||
|
||||
// 更新本地数据库
|
||||
err = global.GVA_DB.Model(&model.MpUser{}).Where("openid = ?", openid).Update("remark", remark).Error
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("更新本地用户备注失败: " + err.Error())
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// SubscribeUser 用户关注事件处理
|
||||
func (m *MpUserService) SubscribeUser(openid string) error {
|
||||
// 同步用户信息
|
||||
_, err := m.SyncUser(openid)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
global.GVA_LOG.Info("用户关注: " + openid)
|
||||
return nil
|
||||
}
|
||||
|
||||
// UnsubscribeUser 用户取消关注事件处理
|
||||
func (m *MpUserService) UnsubscribeUser(openid string) error {
|
||||
now := time.Now()
|
||||
err := global.GVA_DB.Model(&model.MpUser{}).Where("openid = ?", openid).Updates(map[string]interface{}{
|
||||
"subscribe_status": 0,
|
||||
"unsubscribe_time": now,
|
||||
}).Error
|
||||
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("处理用户取消关注失败: " + err.Error())
|
||||
return err
|
||||
}
|
||||
|
||||
global.GVA_LOG.Info("用户取消关注: " + openid)
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetUserByUnionID 根据 UnionID 获取公众号用户信息 (仅用于查询,不关联系统用户)
|
||||
func (m *MpUserService) GetUserByUnionID(unionid string) (*model.MpUser, error) {
|
||||
var user model.MpUser
|
||||
err := global.GVA_DB.Where("unionid = ?", unionid).First(&user).Error
|
||||
if err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return nil, errors.New("用户不存在")
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
return &user, nil
|
||||
}
|
||||
Reference in New Issue
Block a user