This commit is contained in:
yvan 2025-08-05 22:32:18 +08:00
parent c07d43c779
commit 09dfc8dc4f
5 changed files with 469 additions and 73 deletions

View File

@ -2,36 +2,49 @@ package api
import ( import (
"strconv" "strconv"
"strings"
"time"
"github.com/flipped-aurora/gin-vue-admin/server/global" "github.com/flipped-aurora/gin-vue-admin/server/global"
"github.com/flipped-aurora/gin-vue-admin/server/model/common/response" "github.com/flipped-aurora/gin-vue-admin/server/model/common/response"
"github.com/flipped-aurora/gin-vue-admin/server/plugin/wechat-integration/model/request"
wechatResponse "github.com/flipped-aurora/gin-vue-admin/server/plugin/wechat-integration/model/response" wechatResponse "github.com/flipped-aurora/gin-vue-admin/server/plugin/wechat-integration/model/response"
"github.com/flipped-aurora/gin-vue-admin/server/plugin/wechat-integration/service"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"go.uber.org/zap" "go.uber.org/zap"
) )
type MpTagApi struct{} type MpTagApi struct{}
var mpTagService = service.ServiceGroupApp.MpTagService
// CreateTag 创建公众号标签 // CreateTag 创建公众号标签
// @Tags MpTag // @Tags MpTag
// @Summary 创建公众号标签 // @Summary 创建公众号标签
// @Description 创建公众号标签 // @Description 创建公众号标签
// @Accept json // @Accept json
// @Produce json // @Produce json
// @Param data body map[string]interface{} true "标签信息" // @Param data body request.CreateTagRequest true "标签信息"
// @Success 200 {object} response.Response "创建成功" // @Success 200 {object} response.Response "创建成功"
// @Router /wechat/mp/tag/create [post] // @Router /wechat/mp/tag/create [post]
func (m *MpTagApi) CreateTag(c *gin.Context) { func (m *MpTagApi) CreateTag(c *gin.Context) {
var req map[string]interface{} var req request.CreateTagRequest
err := c.ShouldBindJSON(&req) err := c.ShouldBindJSON(&req)
if err != nil { if err != nil {
response.FailWithMessage(err.Error(), c) response.FailWithMessage(err.Error(), c)
return return
} }
// TODO: 实现标签创建逻辑 // 调用服务层创建标签
global.GVA_LOG.Info("创建标签请求", zap.Any("data", req)) tag, err := mpTagService.CreateTag(req.Name)
response.OkWithMessage("标签创建功能待实现", c) if err != nil {
global.GVA_LOG.Error("创建标签失败", zap.String("name", req.Name), zap.Error(err))
response.FailWithMessage("创建标签失败: "+err.Error(), c)
return
}
global.GVA_LOG.Info("创建标签成功", zap.String("name", req.Name), zap.Any("tag", tag))
response.OkWithData(tag, c)
} }
// UpdateTag 更新公众号标签 // UpdateTag 更新公众号标签
@ -40,20 +53,32 @@ func (m *MpTagApi) CreateTag(c *gin.Context) {
// @Description 更新公众号标签 // @Description 更新公众号标签
// @Accept json // @Accept json
// @Produce json // @Produce json
// @Param data body map[string]interface{} true "标签信息" // @Param data body request.UpdateTagRequest true "标签信息"
// @Success 200 {object} response.Response "更新成功" // @Success 200 {object} response.Response "更新成功"
// @Router /wechat/mp/tag/update [put] // @Router /wechat/mp/tag/update [put]
func (m *MpTagApi) UpdateTag(c *gin.Context) { func (m *MpTagApi) UpdateTag(c *gin.Context) {
var req map[string]interface{} var req request.UpdateTagRequest
err := c.ShouldBindJSON(&req) err := c.ShouldBindJSON(&req)
if err != nil { if err != nil {
response.FailWithMessage(err.Error(), c) response.FailWithMessage(err.Error(), c)
return return
} }
// TODO: 实现标签更新逻辑 // 调用服务层更新标签
global.GVA_LOG.Info("更新标签请求", zap.Any("data", req)) err = mpTagService.UpdateTag(req.ID, req.Name)
response.OkWithMessage("标签更新功能待实现", c) if err != nil {
global.GVA_LOG.Error("更新标签失败",
zap.Int("id", req.ID),
zap.String("name", req.Name),
zap.Error(err))
response.FailWithMessage("更新标签失败: "+err.Error(), c)
return
}
global.GVA_LOG.Info("更新标签成功",
zap.Int("id", req.ID),
zap.String("name", req.Name))
response.OkWithMessage("更新标签成功", c)
} }
// DeleteTag 删除公众号标签 // DeleteTag 删除公众号标签
@ -67,52 +92,146 @@ func (m *MpTagApi) UpdateTag(c *gin.Context) {
// @Router /wechat/mp/tag/delete [delete] // @Router /wechat/mp/tag/delete [delete]
func (m *MpTagApi) DeleteTag(c *gin.Context) { func (m *MpTagApi) DeleteTag(c *gin.Context) {
idStr := c.Query("id") idStr := c.Query("id")
id, err := strconv.ParseUint(idStr, 10, 32) id, err := strconv.Atoi(idStr)
if err != nil { if err != nil {
response.FailWithMessage("无效的标签ID", c) response.FailWithMessage("无效的标签ID", c)
return return
} }
// TODO: 实现标签删除逻辑 // 调用服务层删除标签
global.GVA_LOG.Info("删除标签请求", zap.Uint64("id", id)) err = mpTagService.DeleteTag(id)
response.OkWithMessage("标签删除功能待实现", c) if err != nil {
global.GVA_LOG.Error("删除标签失败", zap.Int("id", id), zap.Error(err))
response.FailWithMessage("删除标签失败: "+err.Error(), c)
return
}
global.GVA_LOG.Info("删除标签成功", zap.Int("id", id))
response.OkWithMessage("删除标签成功", c)
} }
// GetTag 获取公众号标签详情 // DeleteTagByPath 删除公众号标签(通过路径参数)
// @Tags MpTag // @Tags MpTag
// @Summary 获取公众号标签详情 // @Summary 删除公众号标签(通过路径参数)
// @Description 获取公众号标签详情 // @Description 删除公众号标签(通过路径参数)
// @Accept json // @Accept json
// @Produce json // @Produce json
// @Param id query int true "标签ID" // @Param id path int true "标签ID"
// @Success 200 {object} response.Response "获取成功" // @Success 200 {object} response.Response "删除成功"
// @Router /wechat/mp/tag/get [get] // @Router /wechat/mp/tag/{id} [delete]
func (m *MpTagApi) GetTag(c *gin.Context) { func (m *MpTagApi) DeleteTagByPath(c *gin.Context) {
idStr := c.Query("id") idStr := c.Param("id")
id, err := strconv.ParseUint(idStr, 10, 32) id, err := strconv.Atoi(idStr)
if err != nil { if err != nil {
response.FailWithMessage("无效的标签ID", c) response.FailWithMessage("无效的标签ID", c)
return return
} }
// TODO: 实现获取标签详情逻辑 // 调用服务层删除标签
global.GVA_LOG.Info("获取标签详情请求", zap.Uint64("id", id)) err = mpTagService.DeleteTag(id)
response.OkWithMessage("获取标签详情功能待实现", c) if err != nil {
global.GVA_LOG.Error("删除标签失败", zap.Int("id", id), zap.Error(err))
response.FailWithMessage("删除标签失败: "+err.Error(), c)
return
}
global.GVA_LOG.Info("删除标签成功", zap.Int("id", id))
response.OkWithMessage("删除标签成功", c)
}
// GetTags 获取所有公众号标签
// @Tags MpTag
// @Summary 获取所有公众号标签
// @Description 获取所有公众号标签列表
// @Accept json
// @Produce json
// @Success 200 {object} response.Response "获取成功"
// @Router /wechat/mp/tag/list [get]
func (m *MpTagApi) GetTags(c *gin.Context) {
// 调用服务层获取标签列表
tags, err := mpTagService.GetTags()
if err != nil {
global.GVA_LOG.Error("获取标签列表失败", zap.Error(err))
response.FailWithMessage("获取标签列表失败: "+err.Error(), c)
return
}
global.GVA_LOG.Info("获取标签列表成功", zap.Int("count", len(tags)))
response.OkWithData(tags, c)
}
// GetTagInfo 获取单个标签详情
// @Tags MpTag
// @Summary 获取单个标签详情
// @Description 获取指定ID的标签详情信息
// @Accept json
// @Produce json
// @Param id path int true "标签ID"
// @Success 200 {object} response.Response "获取成功"
// @Router /wechat/mp/tag/{id} [get]
func (m *MpTagApi) GetTagInfo(c *gin.Context) {
idStr := c.Param("id")
id, err := strconv.Atoi(idStr)
if err != nil {
response.FailWithMessage("无效的标签ID", c)
return
}
// 调用服务层获取所有标签然后找到指定ID的标签
allTags, err := mpTagService.GetTags()
if err != nil {
global.GVA_LOG.Error("获取标签列表失败", zap.Error(err))
response.FailWithMessage("获取标签信息失败: "+err.Error(), c)
return
}
// 查找指定ID的标签
var targetTag map[string]interface{}
for _, tag := range allTags {
if tagID, ok := tag["id"].(int); ok && tagID == id {
targetTag = tag
break
}
}
if targetTag == nil {
response.FailWithMessage("标签不存在", c)
return
}
// 添加一些额外的统计信息
result := map[string]interface{}{
"id": targetTag["id"],
"name": targetTag["name"],
"count": targetTag["count"],
"userCount": targetTag["count"], // 用户数量与count相同
"createdAt": time.Now().Format("2006-01-02 15:04:05"), // 模拟创建时间
"updatedAt": time.Now().Format("2006-01-02 15:04:05"), // 模拟更新时间
}
global.GVA_LOG.Info("获取标签详情成功", zap.Int("id", id))
response.OkWithData(result, c)
} }
// GetTagPage 获取公众号标签分页 // GetTagPage 获取公众号标签分页
// @Tags MpTag // @Tags MpTag
// @Summary 获取公众号标签分页 // @Summary 获取公众号标签分页
// @Description 获取公众号标签分页 // @Description 获取公众号标签分页注意微信API返回所有标签这里进行分页处理和筛选
// @Accept json // @Accept json
// @Produce json // @Produce json
// @Param page query int false "页码" // @Param page query int false "页码"
// @Param pageSize query int false "每页数量" // @Param pageSize query int false "每页数量"
// @Param name query string false "标签名称(模糊搜索)"
// @Param minCount query int false "最小粉丝数量"
// @Param maxCount query int false "最大粉丝数量"
// @Success 200 {object} response.Response{data=response.PageResult} "获取成功" // @Success 200 {object} response.Response{data=response.PageResult} "获取成功"
// @Router /wechat/mp/tag/page [get] // @Router /wechat/mp/tag [get]
func (m *MpTagApi) GetTagPage(c *gin.Context) { func (m *MpTagApi) GetTagPage(c *gin.Context) {
page, _ := strconv.Atoi(c.DefaultQuery("page", "1")) page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
pageSize, _ := strconv.Atoi(c.DefaultQuery("pageSize", "10")) pageSize, _ := strconv.Atoi(c.DefaultQuery("pageSize", "10"))
name := c.Query("name")
minCountStr := c.Query("minCount")
maxCountStr := c.Query("maxCount")
if page <= 0 { if page <= 0 {
page = 1 page = 1
@ -121,23 +240,68 @@ func (m *MpTagApi) GetTagPage(c *gin.Context) {
pageSize = 10 pageSize = 10
} }
// 模拟数据 // 调用服务层获取所有标签
tags := []map[string]interface{}{ allTags, err := mpTagService.GetTags()
{ if err != nil {
"id": 1, global.GVA_LOG.Error("获取标签列表失败", zap.Error(err))
"name": "VIP用户", response.FailWithMessage("获取标签列表失败: "+err.Error(), c)
"count": 150, return
}, }
{
"id": 2, // 筛选标签
"name": "普通用户", var filteredTags []map[string]interface{}
"count": 1200, for _, tag := range allTags {
}, // 名称筛选
if name != "" {
tagName, ok := tag["name"].(string)
if !ok || !strings.Contains(strings.ToLower(tagName), strings.ToLower(name)) {
continue
}
}
// 粉丝数量筛选
count, ok := tag["count"].(int)
if !ok {
count = 0
}
// 最小粉丝数筛选
if minCountStr != "" {
minCount, err := strconv.Atoi(minCountStr)
if err == nil && count < minCount {
continue
}
}
// 最大粉丝数筛选
if maxCountStr != "" {
maxCount, err := strconv.Atoi(maxCountStr)
if err == nil && count > maxCount {
continue
}
}
filteredTags = append(filteredTags, tag)
}
// 手动分页处理
total := len(filteredTags)
start := (page - 1) * pageSize
end := start + pageSize
var tags []map[string]interface{}
if start < total {
if end > total {
end = total
}
tags = filteredTags[start:end]
} else {
tags = []map[string]interface{}{}
} }
response.OkWithDetailed(wechatResponse.PageResult{ response.OkWithDetailed(wechatResponse.PageResult{
List: tags, List: tags,
Total: int64(len(tags)), Total: int64(total),
Page: page, Page: page,
PageSize: pageSize, PageSize: pageSize,
}, "获取成功", c) }, "获取成功", c)
@ -146,42 +310,264 @@ func (m *MpTagApi) GetTagPage(c *gin.Context) {
// GetSimpleTags 获取公众号标签精简信息列表 // GetSimpleTags 获取公众号标签精简信息列表
// @Tags MpTag // @Tags MpTag
// @Summary 获取公众号标签精简信息列表 // @Summary 获取公众号标签精简信息列表
// @Description 获取公众号标签精简信息列表 // @Description 获取公众号标签精简信息列表仅包含ID和名称
// @Accept json // @Accept json
// @Produce json // @Produce json
// @Success 200 {object} response.Response "获取成功" // @Success 200 {object} response.Response "获取成功"
// @Router /wechat/mp/tag/list-all-simple [get] // @Router /wechat/mp/tag/list-all-simple [get]
func (m *MpTagApi) GetSimpleTags(c *gin.Context) { func (m *MpTagApi) GetSimpleTags(c *gin.Context) {
// TODO: 实现获取简单标签列表逻辑 // 调用服务层获取标签列表
global.GVA_LOG.Info("获取简单标签列表请求") allTags, err := mpTagService.GetTags()
if err != nil {
// 模拟数据 global.GVA_LOG.Error("获取标签列表失败", zap.Error(err))
tags := []map[string]interface{}{ response.FailWithMessage("获取标签列表失败: "+err.Error(), c)
{"id": 1, "name": "VIP用户"}, return
{"id": 2, "name": "普通用户"},
} }
response.OkWithData(tags, c) // 转换为精简格式仅包含ID和名称
simpleTags := make([]map[string]interface{}, 0, len(allTags))
for _, tag := range allTags {
simpleTags = append(simpleTags, map[string]interface{}{
"id": tag["id"],
"name": tag["name"],
})
}
global.GVA_LOG.Info("获取简单标签列表成功", zap.Int("count", len(simpleTags)))
response.OkWithData(simpleTags, c)
} }
// SyncTag 同步公众号标签 // SyncTag 同步公众号标签
// @Tags MpTag // @Tags MpTag
// @Summary 同步公众号标签 // @Summary 同步公众号标签
// @Description 同步公众号标签 // @Description 从微信服务器同步最新的标签数据
// @Accept json // @Accept json
// @Produce json // @Produce json
// @Param accountId query int true "公众号账号ID"
// @Success 200 {object} response.Response "同步成功" // @Success 200 {object} response.Response "同步成功"
// @Router /wechat/mp/tag/sync [post] // @Router /wechat/mp/tag/sync [post]
func (m *MpTagApi) SyncTag(c *gin.Context) { func (m *MpTagApi) SyncTag(c *gin.Context) {
accountIdStr := c.Query("accountId") // 调用服务层获取最新标签数据(实际上就是重新从微信获取)
accountId, err := strconv.ParseUint(accountIdStr, 10, 32) tags, err := mpTagService.GetTags()
if err != nil { if err != nil {
response.FailWithMessage("无效的账号ID", c) global.GVA_LOG.Error("同步标签失败", zap.Error(err))
response.FailWithMessage("同步标签失败: "+err.Error(), c)
return return
} }
// TODO: 实现标签同步逻辑 global.GVA_LOG.Info("同步标签成功", zap.Int("count", len(tags)))
global.GVA_LOG.Info("同步标签请求", zap.Uint64("accountId", accountId)) response.OkWithDetailed(map[string]interface{}{
response.OkWithMessage("标签同步功能待实现", c) "count": len(tags),
"tags": tags,
}, "同步标签成功", c)
}
// GetTagUsers 获取标签下的用户列表
// @Tags MpTag
// @Summary 获取标签下的用户列表
// @Description 获取指定标签下的用户列表
// @Accept json
// @Produce json
// @Param tagId query int true "标签ID"
// @Param nextOpenId query string false "拉取列表的第一个用户的OPENID"
// @Success 200 {object} response.Response "获取成功"
// @Router /wechat/mp/tag/users [get]
func (m *MpTagApi) GetTagUsers(c *gin.Context) {
var req request.GetTagUsersRequest
err := c.ShouldBindQuery(&req)
if err != nil {
response.FailWithMessage(err.Error(), c)
return
}
// 调用服务层获取标签用户列表
users, err := mpTagService.GetTagUsers(req.TagID, req.NextOpenID)
if err != nil {
global.GVA_LOG.Error("获取标签用户列表失败",
zap.Int("tagID", req.TagID),
zap.Error(err))
response.FailWithMessage("获取标签用户列表失败: "+err.Error(), c)
return
}
global.GVA_LOG.Info("获取标签用户列表成功",
zap.Int("tagID", req.TagID),
zap.Any("count", users["count"]))
response.OkWithData(users, c)
}
// GetTagUsersByPath 获取标签下的用户列表(通过路径参数)
// @Tags MpTag
// @Summary 获取标签下的用户列表(通过路径参数)
// @Description 获取指定标签下的用户列表(通过路径参数)
// @Accept json
// @Produce json
// @Param id path int true "标签ID"
// @Param nextOpenId query string false "拉取列表的第一个用户的OPENID"
// @Success 200 {object} response.Response "获取成功"
// @Router /wechat/mp/tag/{id}/users [get]
func (m *MpTagApi) GetTagUsersByPath(c *gin.Context) {
tagIdStr := c.Param("id")
tagId, err := strconv.Atoi(tagIdStr)
if err != nil {
response.FailWithMessage("无效的标签ID", c)
return
}
nextOpenID := c.Query("nextOpenId")
// 调用服务层获取标签用户列表
users, err := mpTagService.GetTagUsers(tagId, nextOpenID)
if err != nil {
global.GVA_LOG.Error("获取标签用户列表失败",
zap.Int("tagID", tagId),
zap.Error(err))
response.FailWithMessage("获取标签用户列表失败: "+err.Error(), c)
return
}
global.GVA_LOG.Info("获取标签用户列表成功",
zap.Int("tagID", tagId),
zap.Any("count", users["count"]))
response.OkWithData(users, c)
}
// BatchTagUsers 批量为用户打标签
// @Tags MpTag
// @Summary 批量为用户打标签
// @Description 批量为用户打标签
// @Accept json
// @Produce json
// @Param data body request.BatchTagUsersRequest true "批量打标签请求"
// @Success 200 {object} response.Response "操作成功"
// @Router /wechat/mp/tag/batch-tag [post]
func (m *MpTagApi) BatchTagUsers(c *gin.Context) {
var req request.BatchTagUsersRequest
err := c.ShouldBindJSON(&req)
if err != nil {
response.FailWithMessage(err.Error(), c)
return
}
// 调用服务层批量打标签
err = mpTagService.BatchTagUsers(req.TagID, req.OpenIDs)
if err != nil {
global.GVA_LOG.Error("批量打标签失败",
zap.Int("tagID", req.TagID),
zap.Strings("openIDs", req.OpenIDs),
zap.Error(err))
response.FailWithMessage("批量打标签失败: "+err.Error(), c)
return
}
global.GVA_LOG.Info("批量打标签成功",
zap.Int("tagID", req.TagID),
zap.Int("userCount", len(req.OpenIDs)))
response.OkWithMessage("批量打标签成功", c)
}
// BatchUntagUsers 批量为用户取消标签
// @Tags MpTag
// @Summary 批量为用户取消标签
// @Description 批量为用户取消标签
// @Accept json
// @Produce json
// @Param data body request.BatchUntagUsersRequest true "批量取消标签请求"
// @Success 200 {object} response.Response "操作成功"
// @Router /wechat/mp/tag/batch-untag [post]
func (m *MpTagApi) BatchUntagUsers(c *gin.Context) {
var req request.BatchUntagUsersRequest
err := c.ShouldBindJSON(&req)
if err != nil {
response.FailWithMessage(err.Error(), c)
return
}
// 调用服务层批量取消标签
err = mpTagService.BatchUntagUsers(req.TagID, req.OpenIDs)
if err != nil {
global.GVA_LOG.Error("批量取消标签失败",
zap.Int("tagID", req.TagID),
zap.Strings("openIDs", req.OpenIDs),
zap.Error(err))
response.FailWithMessage("批量取消标签失败: "+err.Error(), c)
return
}
global.GVA_LOG.Info("批量取消标签成功",
zap.Int("tagID", req.TagID),
zap.Int("userCount", len(req.OpenIDs)))
response.OkWithMessage("批量取消标签成功", c)
}
// RemoveUserTag 移除用户标签(单个用户)
// @Tags MpTag
// @Summary 移除用户标签(单个用户)
// @Description 为单个用户移除指定标签
// @Accept json
// @Produce json
// @Param data body object{tagId=int,openid=string} true "移除标签请求"
// @Success 200 {object} response.Response "操作成功"
// @Router /wechat/mp/tag/remove-tag [post]
func (m *MpTagApi) RemoveUserTag(c *gin.Context) {
var req struct {
TagID int `json:"tagId" binding:"required"`
OpenID string `json:"openid" binding:"required"`
}
err := c.ShouldBindJSON(&req)
if err != nil {
response.FailWithMessage(err.Error(), c)
return
}
// 调用服务层批量取消标签(单个用户)
err = mpTagService.BatchUntagUsers(req.TagID, []string{req.OpenID})
if err != nil {
global.GVA_LOG.Error("移除用户标签失败",
zap.Int("tagID", req.TagID),
zap.String("openID", req.OpenID),
zap.Error(err))
response.FailWithMessage("移除用户标签失败: "+err.Error(), c)
return
}
global.GVA_LOG.Info("移除用户标签成功",
zap.Int("tagID", req.TagID),
zap.String("openID", req.OpenID))
response.OkWithMessage("移除用户标签成功", c)
}
// GetUserTags 获取用户的标签列表
// @Tags MpTag
// @Summary 获取用户的标签列表
// @Description 获取指定用户的标签列表
// @Accept json
// @Produce json
// @Param openId query string true "用户OpenID"
// @Success 200 {object} response.Response "获取成功"
// @Router /wechat/mp/tag/user-tags [get]
func (m *MpTagApi) GetUserTags(c *gin.Context) {
openID := c.Query("openId")
if openID == "" {
response.FailWithMessage("用户OpenID不能为空", c)
return
}
// 调用服务层获取用户标签
tagIDs, err := mpTagService.GetUserTags(openID)
if err != nil {
global.GVA_LOG.Error("获取用户标签失败",
zap.String("openID", openID),
zap.Error(err))
response.FailWithMessage("获取用户标签失败: "+err.Error(), c)
return
}
global.GVA_LOG.Info("获取用户标签成功",
zap.String("openID", openID),
zap.Ints("tagIDs", tagIDs))
response.OkWithData(map[string]interface{}{
"openId": openID,
"tagIds": tagIDs,
}, c)
} }

View File

@ -87,14 +87,22 @@ func (w *WechatRouter) InitWechatRouter(Router *gin.RouterGroup) {
mpGroup.GET("material/download", mpMaterialApi.DownloadMaterial) // 下载素材 mpGroup.GET("material/download", mpMaterialApi.DownloadMaterial) // 下载素材
mpGroup.POST("material/sync", mpMaterialApi.SyncMaterials) // 同步素材 mpGroup.POST("material/sync", mpMaterialApi.SyncMaterials) // 同步素材
// 标签管理 // 标签管理 - 注意:具体路径要放在通配符路径之前
mpGroup.GET("tag", mpTagApi.GetTagPage) // 获取标签列表 mpGroup.GET("tag", mpTagApi.GetTagPage) // 获取标签分页列表
mpGroup.GET("tag/:id", mpTagApi.GetTag) // 获取标签详情 mpGroup.GET("tag/list", mpTagApi.GetTags) // 获取所有标签
mpGroup.GET("tag/list-all-simple", mpTagApi.GetSimpleTags) // 获取简单标签列表
mpGroup.GET("tag/users", mpTagApi.GetTagUsers) // 获取标签下的用户列表query参数
mpGroup.GET("tag/user-tags", mpTagApi.GetUserTags) // 获取用户的标签列表
mpGroup.POST("tag", mpTagApi.CreateTag) // 创建标签 mpGroup.POST("tag", mpTagApi.CreateTag) // 创建标签
mpGroup.PUT("tag", mpTagApi.UpdateTag) // 更新标签 mpGroup.PUT("tag", mpTagApi.UpdateTag) // 更新标签
mpGroup.DELETE("tag/:id", mpTagApi.DeleteTag) // 删除标签 mpGroup.DELETE("tag", mpTagApi.DeleteTag) // 删除标签通过query参数id
mpGroup.POST("tag/batch-tag", mpTagApi.BatchTagUsers) // 批量为用户打标签
mpGroup.POST("tag/batch-untag", mpTagApi.BatchUntagUsers) // 批量为用户取消标签
mpGroup.POST("tag/remove-tag", mpTagApi.RemoveUserTag) // 移除用户标签(单个)
mpGroup.POST("tag/sync", mpTagApi.SyncTag) // 同步标签 mpGroup.POST("tag/sync", mpTagApi.SyncTag) // 同步标签
mpGroup.GET("tag/list-all-simple", mpTagApi.GetSimpleTags) // 获取简单标签列表 mpGroup.GET("tag/:id/users", mpTagApi.GetTagUsersByPath) // 获取标签下的用户列表(路径参数)
mpGroup.GET("tag/:id", mpTagApi.GetTagInfo) // 获取标签详情
mpGroup.DELETE("tag/:id", mpTagApi.DeleteTagByPath) // 删除标签(通过路径参数)
// 统计数据 // 统计数据
mpGroup.GET("statistics", mpStatisticsApi.GetStatistics) // 获取基础统计数据 mpGroup.GET("statistics", mpStatisticsApi.GetStatistics) // 获取基础统计数据

View File

@ -14,6 +14,7 @@ type ServiceGroup struct {
MpStatisticsService MpStatisticsService // 公众号统计服务 MpStatisticsService MpStatisticsService // 公众号统计服务
MpConfigService MpConfigService // 微信配置管理服务 MpConfigService MpConfigService // 微信配置管理服务
MpDraftService MpDraftService // 公众号草稿服务 MpDraftService MpDraftService // 公众号草稿服务
MpTagService MpTagService // 公众号标签服务
} }
// ServiceGroupApp 服务组实例 // ServiceGroupApp 服务组实例

View File

@ -52,10 +52,11 @@ export const syncTags = () => {
} }
// 获取标签用户 // 获取标签用户
export const getTagUsers = (tagId) => { export const getTagUsers = (tagId, nextOpenId = '') => {
return service({ return service({
url: `/wechat/mp/tag/${tagId}/users`, url: `/wechat/mp/tag/${tagId}/users`,
method: 'get' method: 'get',
params: { nextOpenId }
}) })
} }

View File

@ -98,7 +98,7 @@
row-key="ID" row-key="ID"
v-loading="tableLoading" v-loading="tableLoading"
> >
<el-table-column align="left" label="标签ID" prop="tagId" width="100" /> <el-table-column align="left" label="标签ID" prop="id" width="100" />
<el-table-column align="left" label="标签名称" prop="name" width="200"> <el-table-column align="left" label="标签名称" prop="name" width="200">
<template #default="scope"> <template #default="scope">
<div class="tag-name-cell"> <div class="tag-name-cell">
@ -458,7 +458,7 @@ const createTag = () => {
// //
const editTag = (row) => { const editTag = (row) => {
tagFormRef.value?.openEdit(row.tagId || row.ID) tagFormRef.value?.openEdit(row.id || row.ID)
} }
// //
@ -473,7 +473,7 @@ const deleteTag = (row) => {
cancelButtonText: '取消', cancelButtonText: '取消',
type: 'warning' type: 'warning'
}).then(async() => { }).then(async() => {
const res = await deleteTagApi(row.ID) const res = await deleteTagApi(row.id || row.ID)
if (res.code === 0) { if (res.code === 0) {
ElMessage.success('删除成功') ElMessage.success('删除成功')
getTableData() getTableData()
@ -501,9 +501,9 @@ const viewTagUsers = async(row) => {
try { try {
currentTag.value = row currentTag.value = row
tagUsersLoading.value = true tagUsersLoading.value = true
const res = await getTagUsersApi(row.tagId) const res = await getTagUsersApi(row.id || row.tagId)
if (res.code === 0) { if (res.code === 0) {
tagUsers.value = res.data.list || [] tagUsers.value = res.data.data?.openid || res.data.list || []
usersDialogVisible.value = true usersDialogVisible.value = true
} else { } else {
ElMessage.error(res.msg || '获取标签用户失败') ElMessage.error(res.msg || '获取标签用户失败')
@ -564,8 +564,8 @@ const confirmBatchTag = async() => {
try { try {
batchTagLoading.value = true batchTagLoading.value = true
const res = await batchTagUsersApi({ const res = await batchTagUsersApi({
tagId: currentTag.value.tagId, tagId: currentTag.value.id || currentTag.value.tagId,
openids: selectedUserIds.value openIds: selectedUserIds.value
}) })
if (res.code === 0) { if (res.code === 0) {
@ -592,7 +592,7 @@ const confirmBatchTag = async() => {
const removeUserTag = async(user) => { const removeUserTag = async(user) => {
try { try {
const res = await removeUserTagApi({ const res = await removeUserTagApi({
tagId: currentTag.value.tagId, tagId: currentTag.value.id || currentTag.value.tagId,
openid: user.openid openid: user.openid
}) })