This commit is contained in:
yvan 2025-08-05 22:32:24 +08:00
parent 09dfc8dc4f
commit 2cddbc3e73
2 changed files with 294 additions and 0 deletions

View File

@ -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不填默认从头开始拉取
}

View File

@ -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
}