This commit is contained in:
parent
09dfc8dc4f
commit
2cddbc3e73
|
|
@ -0,0 +1,30 @@
|
||||||
|
package request
|
||||||
|
|
||||||
|
// CreateTagRequest 创建标签请求
|
||||||
|
type CreateTagRequest struct {
|
||||||
|
Name string `json:"name" binding:"required" example:"VIP用户"` // 标签名称
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateTagRequest 更新标签请求
|
||||||
|
type UpdateTagRequest struct {
|
||||||
|
ID int `json:"id" binding:"required" example:"1"` // 标签ID
|
||||||
|
Name string `json:"name" binding:"required" example:"VIP用户"` // 标签名称
|
||||||
|
}
|
||||||
|
|
||||||
|
// BatchTagUsersRequest 批量为用户打标签请求
|
||||||
|
type BatchTagUsersRequest struct {
|
||||||
|
TagID int `json:"tagId" binding:"required" example:"1"` // 标签ID
|
||||||
|
OpenIDs []string `json:"openIds" binding:"required" example:"[\"openid1\",\"openid2\"]"` // 用户OpenID列表
|
||||||
|
}
|
||||||
|
|
||||||
|
// BatchUntagUsersRequest 批量为用户取消标签请求
|
||||||
|
type BatchUntagUsersRequest struct {
|
||||||
|
TagID int `json:"tagId" binding:"required" example:"1"` // 标签ID
|
||||||
|
OpenIDs []string `json:"openIds" binding:"required" example:"[\"openid1\",\"openid2\"]"` // 用户OpenID列表
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetTagUsersRequest 获取标签用户列表请求
|
||||||
|
type GetTagUsersRequest struct {
|
||||||
|
TagID int `form:"tagId" binding:"required" example:"1"` // 标签ID
|
||||||
|
NextOpenID string `form:"nextOpenId" example:""` // 拉取列表的第一个用户的OPENID,不填默认从头开始拉取
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,264 @@
|
||||||
|
package service
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"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"
|
||||||
|
"go.uber.org/zap"
|
||||||
|
)
|
||||||
|
|
||||||
|
type MpTagService struct{}
|
||||||
|
|
||||||
|
// GetOfficialAccount 获取微信公众号实例(从数据库获取配置)
|
||||||
|
func (m *MpTagService) GetOfficialAccount() (*officialaccount.OfficialAccount, error) {
|
||||||
|
// 从数据库获取微信公众号配置
|
||||||
|
var mpConfig model.MpConfig
|
||||||
|
err := global.GVA_DB.Where("config_type = ?", model.ConfigTypeMP).First(&mpConfig).Error
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("获取微信公众号配置失败: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if mpConfig.AppID == "" || mpConfig.AppSecret == "" {
|
||||||
|
return nil, errors.New("微信公众号配置不完整")
|
||||||
|
}
|
||||||
|
|
||||||
|
wc := wechat.NewWechat()
|
||||||
|
memory := cache.NewMemory()
|
||||||
|
|
||||||
|
cfg := &config.Config{
|
||||||
|
AppID: mpConfig.AppID,
|
||||||
|
AppSecret: mpConfig.AppSecret,
|
||||||
|
Cache: memory,
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果有Token,设置服务器配置
|
||||||
|
if mpConfig.Token != nil && *mpConfig.Token != "" {
|
||||||
|
cfg.Token = *mpConfig.Token
|
||||||
|
}
|
||||||
|
|
||||||
|
return wc.GetOfficialAccount(cfg), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateTag 创建标签
|
||||||
|
func (m *MpTagService) CreateTag(name string) (map[string]interface{}, error) {
|
||||||
|
// 获取微信公众号实例
|
||||||
|
oa, err := m.GetOfficialAccount()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// 使用 silenceper/wechat 库创建标签
|
||||||
|
user := oa.GetUser()
|
||||||
|
tag, err := user.CreateTag(name)
|
||||||
|
if err != nil {
|
||||||
|
global.GVA_LOG.Error("创建标签失败", zap.String("name", name), zap.Error(err))
|
||||||
|
return nil, fmt.Errorf("创建标签失败: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
result := map[string]interface{}{
|
||||||
|
"id": int(tag.ID),
|
||||||
|
"name": tag.Name,
|
||||||
|
}
|
||||||
|
|
||||||
|
global.GVA_LOG.Info("创建标签成功",
|
||||||
|
zap.String("name", name),
|
||||||
|
zap.Int32("id", tag.ID))
|
||||||
|
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateTag 更新标签
|
||||||
|
func (m *MpTagService) UpdateTag(id int, name string) error {
|
||||||
|
// 获取微信公众号实例
|
||||||
|
oa, err := m.GetOfficialAccount()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// 使用 silenceper/wechat 库更新标签
|
||||||
|
user := oa.GetUser()
|
||||||
|
err = user.UpdateTag(int32(id), name)
|
||||||
|
if err != nil {
|
||||||
|
global.GVA_LOG.Error("更新标签失败",
|
||||||
|
zap.Int("id", id),
|
||||||
|
zap.String("name", name),
|
||||||
|
zap.Error(err))
|
||||||
|
return fmt.Errorf("更新标签失败: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
global.GVA_LOG.Info("更新标签成功",
|
||||||
|
zap.Int("id", id),
|
||||||
|
zap.String("name", name))
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteTag 删除标签
|
||||||
|
func (m *MpTagService) DeleteTag(id int) error {
|
||||||
|
// 获取微信公众号实例
|
||||||
|
oa, err := m.GetOfficialAccount()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// 使用 silenceper/wechat 库删除标签
|
||||||
|
user := oa.GetUser()
|
||||||
|
err = user.DeleteTag(int32(id))
|
||||||
|
if err != nil {
|
||||||
|
global.GVA_LOG.Error("删除标签失败", zap.Int("id", id), zap.Error(err))
|
||||||
|
return fmt.Errorf("删除标签失败: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
global.GVA_LOG.Info("删除标签成功", zap.Int("id", id))
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetTags 获取所有标签
|
||||||
|
func (m *MpTagService) GetTags() ([]map[string]interface{}, error) {
|
||||||
|
// 获取微信公众号实例
|
||||||
|
oa, err := m.GetOfficialAccount()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// 使用 silenceper/wechat 库获取标签列表
|
||||||
|
user := oa.GetUser()
|
||||||
|
tagsResponse, err := user.GetTag()
|
||||||
|
if err != nil {
|
||||||
|
global.GVA_LOG.Error("获取标签列表失败", zap.Error(err))
|
||||||
|
return nil, fmt.Errorf("获取标签列表失败: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 转换为前端需要的格式
|
||||||
|
result := make([]map[string]interface{}, 0, len(tagsResponse))
|
||||||
|
for _, tag := range tagsResponse {
|
||||||
|
result = append(result, map[string]interface{}{
|
||||||
|
"id": int(tag.ID),
|
||||||
|
"name": tag.Name,
|
||||||
|
"count": int(tag.Count),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
global.GVA_LOG.Info("获取标签列表成功", zap.Int("count", len(result)))
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetTagUsers 获取标签下的用户列表
|
||||||
|
func (m *MpTagService) GetTagUsers(tagID int, nextOpenID string) (map[string]interface{}, error) {
|
||||||
|
// 获取微信公众号实例
|
||||||
|
oa, err := m.GetOfficialAccount()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// 使用 silenceper/wechat 库获取标签用户列表
|
||||||
|
user := oa.GetUser()
|
||||||
|
usersResponse, err := user.OpenIDListByTag(int32(tagID), nextOpenID)
|
||||||
|
if err != nil {
|
||||||
|
global.GVA_LOG.Error("获取标签用户列表失败",
|
||||||
|
zap.Int("tagID", tagID),
|
||||||
|
zap.Error(err))
|
||||||
|
return nil, fmt.Errorf("获取标签用户列表失败: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
result := map[string]interface{}{
|
||||||
|
"count": int(usersResponse.Count),
|
||||||
|
"data": usersResponse.Data,
|
||||||
|
"nextOpenID": usersResponse.NextOpenID,
|
||||||
|
}
|
||||||
|
|
||||||
|
global.GVA_LOG.Info("获取标签用户列表成功",
|
||||||
|
zap.Int("tagID", tagID),
|
||||||
|
zap.Int("count", usersResponse.Count))
|
||||||
|
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// BatchTagUsers 批量为用户打标签
|
||||||
|
func (m *MpTagService) BatchTagUsers(tagID int, openIDs []string) error {
|
||||||
|
// 获取微信公众号实例
|
||||||
|
oa, err := m.GetOfficialAccount()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// 使用 silenceper/wechat 库批量打标签
|
||||||
|
user := oa.GetUser()
|
||||||
|
err = user.BatchTag(openIDs, int32(tagID))
|
||||||
|
if err != nil {
|
||||||
|
global.GVA_LOG.Error("批量打标签失败",
|
||||||
|
zap.Int("tagID", tagID),
|
||||||
|
zap.Strings("openIDs", openIDs),
|
||||||
|
zap.Error(err))
|
||||||
|
return fmt.Errorf("批量打标签失败: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
global.GVA_LOG.Info("批量打标签成功",
|
||||||
|
zap.Int("tagID", tagID),
|
||||||
|
zap.Int("userCount", len(openIDs)))
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// BatchUntagUsers 批量为用户取消标签
|
||||||
|
func (m *MpTagService) BatchUntagUsers(tagID int, openIDs []string) error {
|
||||||
|
// 获取微信公众号实例
|
||||||
|
oa, err := m.GetOfficialAccount()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// 使用 silenceper/wechat 库批量取消标签
|
||||||
|
user := oa.GetUser()
|
||||||
|
err = user.BatchUntag(openIDs, int32(tagID))
|
||||||
|
if err != nil {
|
||||||
|
global.GVA_LOG.Error("批量取消标签失败",
|
||||||
|
zap.Int("tagID", tagID),
|
||||||
|
zap.Strings("openIDs", openIDs),
|
||||||
|
zap.Error(err))
|
||||||
|
return fmt.Errorf("批量取消标签失败: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
global.GVA_LOG.Info("批量取消标签成功",
|
||||||
|
zap.Int("tagID", tagID),
|
||||||
|
zap.Int("userCount", len(openIDs)))
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetUserTags 获取用户的标签列表
|
||||||
|
func (m *MpTagService) GetUserTags(openID string) ([]int, error) {
|
||||||
|
// 获取微信公众号实例
|
||||||
|
oa, err := m.GetOfficialAccount()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// 使用 silenceper/wechat 库获取用户标签
|
||||||
|
user := oa.GetUser()
|
||||||
|
tagsResponse, err := user.UserTidList(openID)
|
||||||
|
if err != nil {
|
||||||
|
global.GVA_LOG.Error("获取用户标签失败",
|
||||||
|
zap.String("openID", openID),
|
||||||
|
zap.Error(err))
|
||||||
|
return nil, fmt.Errorf("获取用户标签失败: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 转换 int32 切片为 int 切片
|
||||||
|
tagIDs := make([]int, len(tagsResponse))
|
||||||
|
for i, tagID := range tagsResponse {
|
||||||
|
tagIDs[i] = int(tagID)
|
||||||
|
}
|
||||||
|
|
||||||
|
global.GVA_LOG.Info("获取用户标签成功",
|
||||||
|
zap.String("openID", openID),
|
||||||
|
zap.Ints("tagIDs", tagIDs))
|
||||||
|
|
||||||
|
return tagIDs, nil
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue