This commit is contained in:
2025-08-05 22:32:18 +08:00
parent c07d43c779
commit 09dfc8dc4f
5 changed files with 469 additions and 73 deletions
@@ -2,36 +2,49 @@ package api
import (
"strconv"
"strings"
"time"
"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/plugin/wechat-integration/model/request"
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"
"go.uber.org/zap"
)
type MpTagApi struct{}
var mpTagService = service.ServiceGroupApp.MpTagService
// CreateTag 创建公众号标签
// @Tags MpTag
// @Summary 创建公众号标签
// @Description 创建公众号标签
// @Accept json
// @Produce json
// @Param data body map[string]interface{} true "标签信息"
// @Param data body request.CreateTagRequest true "标签信息"
// @Success 200 {object} response.Response "创建成功"
// @Router /wechat/mp/tag/create [post]
func (m *MpTagApi) CreateTag(c *gin.Context) {
var req map[string]interface{}
var req request.CreateTagRequest
err := c.ShouldBindJSON(&req)
if err != nil {
response.FailWithMessage(err.Error(), c)
return
}
// TODO: 实现标签创建逻辑
global.GVA_LOG.Info("创建标签请求", zap.Any("data", req))
response.OkWithMessage("标签创建功能待实现", c)
// 调用服务层创建标签
tag, err := mpTagService.CreateTag(req.Name)
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 更新公众号标签
@@ -40,20 +53,32 @@ func (m *MpTagApi) CreateTag(c *gin.Context) {
// @Description 更新公众号标签
// @Accept json
// @Produce json
// @Param data body map[string]interface{} true "标签信息"
// @Param data body request.UpdateTagRequest true "标签信息"
// @Success 200 {object} response.Response "更新成功"
// @Router /wechat/mp/tag/update [put]
func (m *MpTagApi) UpdateTag(c *gin.Context) {
var req map[string]interface{}
var req request.UpdateTagRequest
err := c.ShouldBindJSON(&req)
if err != nil {
response.FailWithMessage(err.Error(), c)
return
}
// TODO: 实现标签更新逻辑
global.GVA_LOG.Info("更新标签请求", zap.Any("data", req))
response.OkWithMessage("标签更新功能待实现", c)
// 调用服务层更新标签
err = mpTagService.UpdateTag(req.ID, req.Name)
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 删除公众号标签
@@ -67,52 +92,146 @@ func (m *MpTagApi) UpdateTag(c *gin.Context) {
// @Router /wechat/mp/tag/delete [delete]
func (m *MpTagApi) DeleteTag(c *gin.Context) {
idStr := c.Query("id")
id, err := strconv.ParseUint(idStr, 10, 32)
id, err := strconv.Atoi(idStr)
if err != nil {
response.FailWithMessage("无效的标签ID", c)
return
}
// TODO: 实现标签删除逻辑
global.GVA_LOG.Info("删除标签请求", zap.Uint64("id", id))
response.OkWithMessage("标签删除功能待实现", c)
// 调用服务层删除标签
err = mpTagService.DeleteTag(id)
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
// @Summary 获取公众号标签详情
// @Description 获取公众号标签详情
// @Summary 删除公众号标签(通过路径参数)
// @Description 删除公众号标签(通过路径参数)
// @Accept json
// @Produce json
// @Param id query int true "标签ID"
// @Success 200 {object} response.Response "获取成功"
// @Router /wechat/mp/tag/get [get]
func (m *MpTagApi) GetTag(c *gin.Context) {
idStr := c.Query("id")
id, err := strconv.ParseUint(idStr, 10, 32)
// @Param id path int true "标签ID"
// @Success 200 {object} response.Response "删除成功"
// @Router /wechat/mp/tag/{id} [delete]
func (m *MpTagApi) DeleteTagByPath(c *gin.Context) {
idStr := c.Param("id")
id, err := strconv.Atoi(idStr)
if err != nil {
response.FailWithMessage("无效的标签ID", c)
return
}
// TODO: 实现获取标签详情逻辑
global.GVA_LOG.Info("获取标签详情请求", zap.Uint64("id", id))
response.OkWithMessage("获取标签详情功能待实现", c)
// 调用服务层删除标签
err = mpTagService.DeleteTag(id)
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 获取公众号标签分页
// @Tags MpTag
// @Summary 获取公众号标签分页
// @Description 获取公众号标签分页
// @Description 获取公众号标签分页(注意:微信API返回所有标签,这里进行分页处理和筛选)
// @Accept json
// @Produce json
// @Param page 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} "获取成功"
// @Router /wechat/mp/tag/page [get]
// @Router /wechat/mp/tag [get]
func (m *MpTagApi) GetTagPage(c *gin.Context) {
page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
pageSize, _ := strconv.Atoi(c.DefaultQuery("pageSize", "10"))
name := c.Query("name")
minCountStr := c.Query("minCount")
maxCountStr := c.Query("maxCount")
if page <= 0 {
page = 1
@@ -121,23 +240,68 @@ func (m *MpTagApi) GetTagPage(c *gin.Context) {
pageSize = 10
}
// 模拟数据
tags := []map[string]interface{}{
{
"id": 1,
"name": "VIP用户",
"count": 150,
},
{
"id": 2,
"name": "普通用户",
"count": 1200,
},
// 调用服务层获取所有标签
allTags, err := mpTagService.GetTags()
if err != nil {
global.GVA_LOG.Error("获取标签列表失败", zap.Error(err))
response.FailWithMessage("获取标签列表失败: "+err.Error(), c)
return
}
// 筛选标签
var filteredTags []map[string]interface{}
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{
List: tags,
Total: int64(len(tags)),
Total: int64(total),
Page: page,
PageSize: pageSize,
}, "获取成功", c)
@@ -146,42 +310,264 @@ func (m *MpTagApi) GetTagPage(c *gin.Context) {
// GetSimpleTags 获取公众号标签精简信息列表
// @Tags MpTag
// @Summary 获取公众号标签精简信息列表
// @Description 获取公众号标签精简信息列表
// @Description 获取公众号标签精简信息列表(仅包含ID和名称)
// @Accept json
// @Produce json
// @Success 200 {object} response.Response "获取成功"
// @Router /wechat/mp/tag/list-all-simple [get]
func (m *MpTagApi) GetSimpleTags(c *gin.Context) {
// TODO: 实现获取简单标签列表逻辑
global.GVA_LOG.Info("获取简单标签列表请求")
// 模拟数据
tags := []map[string]interface{}{
{"id": 1, "name": "VIP用户"},
{"id": 2, "name": "普通用户"},
// 调用服务层获取标签列表
allTags, err := mpTagService.GetTags()
if err != nil {
global.GVA_LOG.Error("获取标签列表失败", zap.Error(err))
response.FailWithMessage("获取标签列表失败: "+err.Error(), c)
return
}
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 同步公众号标签
// @Tags MpTag
// @Summary 同步公众号标签
// @Description 同步公众号标签
// @Description 从微信服务器同步最新的标签数据
// @Accept json
// @Produce json
// @Param accountId query int true "公众号账号ID"
// @Success 200 {object} response.Response "同步成功"
// @Router /wechat/mp/tag/sync [post]
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 {
response.FailWithMessage("无效的账号ID", c)
global.GVA_LOG.Error("同步标签失败", zap.Error(err))
response.FailWithMessage("同步标签失败: "+err.Error(), c)
return
}
// TODO: 实现标签同步逻辑
global.GVA_LOG.Info("同步标签请求", zap.Uint64("accountId", accountId))
response.OkWithMessage("标签同步功能待实现", c)
global.GVA_LOG.Info("同步标签成功", zap.Int("count", len(tags)))
response.OkWithDetailed(map[string]interface{}{
"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)
}