自媒体内容分类功能和tag功能实现

This commit is contained in:
2025-08-13 19:57:10 +08:00
parent 30d9036247
commit bdb14c4c7b
8 changed files with 8259 additions and 13 deletions

View File

@@ -34,7 +34,7 @@ func Init() {
}
// 自动迁移
err = DB.AutoMigrate(model.WeMediaUser{}, model.UserFans{}, model.UserBlacklist{})
err = DB.AutoMigrate(model.Moment{}, model.MomentFile{}, model.MomentLike{}, model.MomentComment{}, model.CommentFile{}, model.MomentCollect{})
err = DB.AutoMigrate(model.Moment{}, model.MomentFile{}, model.MomentLike{}, model.MomentComment{}, model.CommentFile{}, model.MomentCollect{}, model.Category{}, model.MomentCategory{}, model.Tag{}, model.MomentTag{})
if err != nil {
hlog.Error("AutoMigrate failed: " + err.Error())
return

View File

@@ -761,3 +761,366 @@ func findAllChildCommentIDs(tx *gorm.DB, parentID int64) ([]uint, error) {
return childIDs, nil
}
// CreateTag 创建tag
func CreateTag(req moment.CreateTagRequest) error {
if req.UserID == "" || req.TagName == "" {
return errors.New("缺少必须参数")
}
db := DB
db.Model(&model.Tag{}).Create(&model.Tag{
TagName: req.TagName,
UserID: req.UserID,
})
return db.Error
}
// DeleteTag 删除tag
func DeleteTag(req moment.DeleteTagRequest) error {
if req.UserID == "" || req.TagName == "" {
return errors.New("缺少必须参数")
}
db := DB
db.Model(&model.Tag{}).
Where("tag_name = ? AND user_id = ?", req.TagName, req.UserID).
Delete(&model.Tag{})
return db.Error
}
// ListTag 获取tag列表
func ListTag(req moment.ListTagRequest) ([]*moment.TagInfo, int32, error) {
// 参数验证
if req.Page < 1 {
req.Page = 1
}
if req.PageSize < 1 {
req.PageSize = 10
}
if req.PageSize > 100 { // 限制最大分页大小,防止恶意请求
req.PageSize = 100
}
db := DB
var total int64
var result []*moment.TagInfo
// 先查询总数
if err := db.Model(&model.Tag{}).Count(&total).Error; err != nil {
return nil, 0, fmt.Errorf("查询tag总数失败: %v", err)
}
// 计算偏移量
offset := int(req.PageSize * (req.Page - 1))
// 再查询当前页数据
if err := db.Model(&model.Tag{}).
Select("id,tag_name").
Offset(int(offset)).
Limit(int(req.PageSize)).
Order("created_at DESC"). // 按时间倒序,最新创建的在前
Find(&result).Error; err != nil {
return nil, 0, err
}
return result, int32(total), nil
}
// FindTag 模糊搜索tag列表
func FindTag(keyword *string, page, pageSize int32) ([]*moment.TagInfo, int32, error) {
// 校验分页参数合理性
if page < 1 {
page = 1
}
if pageSize < 1 || pageSize > 100 { // 限制最大页大小,防止查询过大
pageSize = 20
}
offset := (page - 1) * pageSize
db := DB.Model(&model.Tag{})
var total int64
var result []*moment.TagInfo
// 处理关键词查询
if keyword != nil && len(*keyword) > 0 {
likePattern := "%" + *keyword + "%"
// 多字段模糊匹配使用括号确保OR条件正确分组
db = db.Where("tag_name LIKE ?", likePattern)
}
// 获取总条数,用于分页计算
if err := db.Count(&total).Error; err != nil {
return nil, 0, fmt.Errorf("获取tags总数失败: %w", err)
}
// 执行分页查询
if err := db.
Model(model.Tag{}).
Select("id,tag_name").
Offset(int(offset)).
Limit(int(pageSize)).
Order("created_at DESC"). // 按创建时间倒序,最新的在前
Find(&result).Error; err != nil {
return nil, 0, fmt.Errorf("查询tag列表失败: %w", err)
}
return result, int32(total), nil
}
// BindTag 文章绑定标签
func BindTag(req moment.BindTagRequest) error {
// 参数校验
if len(req.MomentID) == 0 || req.TagID == 0 {
return errors.New("缺少必须参数")
}
// 使用事务确保数据一致性
return DB.Transaction(func(tx *gorm.DB) error {
// 转换TagID类型
tagID := uint(req.TagID)
// 遍历所有需要绑定的文章ID
for _, momentID := range req.MomentID {
mID := uint(momentID)
// 检查是否已绑定,避免重复绑定
var count int64
if err := tx.Model(&model.MomentTag{}).
Where("moment_id = ? AND tag_id = ?", mID, tagID).
Count(&count).Error; err != nil {
return fmt.Errorf("检查绑定关系失败: %w", err)
}
// 如果未绑定,则创建关联
if count == 0 {
if err := tx.Create(&model.MomentTag{
MomentID: mID,
TagID: tagID,
}).Error; err != nil {
return fmt.Errorf("创建绑定关系失败: %w", err)
}
}
}
return nil
})
}
// ListMomentsByTag 获取指定标签的文章列表
func ListMomentsByTag(req moment.ListMomentsByTagRequest) ([]*moment.Moment, int32, error) {
// 1. 参数校验
if req.Tag == "" {
return nil, 0, errors.New("标签ID不能为空")
}
// 处理分页参数
page := req.Page
if page < 1 {
page = 1
}
pageSize := req.PageSize
if pageSize < 1 || pageSize > 50 {
pageSize = 10 // 限制最大页大小,避免查询压力过大
}
offset := (page - 1) * pageSize
// 2. 构建查询:通过标签关联表查询对应的文章
// 先查询关联关系表,再关联文章主表
db := DB.Model(&model.MomentTag{}).
Joins("JOIN moment ON moment_tag.moment_id = moment.id").
Where("moment_tag.tag_id = ?", req.Tag)
//Where("moment.status = 0") // 只查询正常状态的文章
// 3. 统计符合条件的总条数
var total int64
if err := db.Count(&total).Error; err != nil {
return nil, 0, fmt.Errorf("统计标签下文章总数失败: %w", err)
}
// 4. 分页查询文章基本信息
var moments []*moment.Moment
if err := db.
Select(`moment.id, moment.user_id, moment.content, moment.visibility,
moment.location, moment.like_count, moment.collect_count,
moment.comment_count, moment.created_at`).
Offset(int(offset)).
Limit(int(pageSize)).
Order("moment.created_at DESC"). // 按文章发布时间倒序
Scan(&moments).Error; err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return []*moment.Moment{}, 0, nil // 无数据时返回空列表
}
return nil, 0, fmt.Errorf("查询标签下文章列表失败: %w", err)
}
// 5. 批量查询文章图片优化N+1查询问题
if len(moments) > 0 {
// 收集所有文章ID
var momentIDs []uint64
for _, m := range moments {
momentIDs = append(momentIDs, uint64(m.ID))
}
// 一次查询所有文章的图片
var files []*model.MomentFile
if err := DB.Where("moment_id IN (?)", momentIDs).Find(&files).Error; err != nil {
return nil, 0, fmt.Errorf("查询文章图片失败: %w", err)
}
// 建立文章ID到图片的映射
fileMap := make(map[uint64][]*moment.MomentFile)
for _, f := range files {
dtoFile := &moment.MomentFile{
ID: int64(f.ID),
MomentID: int64(f.MomentID),
FileURL: f.FileURL,
FileType: f.FileType,
SortOrder: int8(f.SortOrder),
}
fileMap[uint64(f.MomentID)] = append(fileMap[uint64(f.MomentID)], dtoFile)
}
// 为每个文章分配图片
for _, m := range moments {
m.Files = fileMap[uint64(m.ID)]
}
}
// 6. 转换总条数为int32返回
return moments, int32(total), nil
}
// ListCategory 获取分类列表
func ListCategory() ([]*moment.CategoryInfo, error) {
db := DB
var result []*moment.CategoryInfo
// 查询数据
if err := db.Model(&model.Category{}).
Select("id,category_name").
Find(&result).Error; err != nil {
return nil, err
}
return result, nil
}
// BindCategory 文章绑定分类
func BindCategory(req moment.BindCategoryRequest) error {
// 参数校验
if len(req.MomentID) == 0 || req.CategoryID == 0 {
return errors.New("缺少必须参数")
}
// 使用事务确保数据一致性
return DB.Transaction(func(tx *gorm.DB) error {
// 转换类型
categoryID := uint(req.CategoryID)
// 遍历所有需要绑定的文章ID
for _, momentID := range req.MomentID {
mID := uint(momentID)
// 检查是否已绑定,避免重复绑定
var count int64
if err := tx.Model(&model.MomentCategory{}).
Where("moment_id = ? AND category_id = ?", mID, categoryID).
Count(&count).Error; err != nil {
return fmt.Errorf("检查绑定关系失败: %w", err)
}
// 如果未绑定,则创建关联
if count == 0 {
if err := tx.Create(&model.MomentCategory{
MomentID: mID,
CategoryID: categoryID,
}).Error; err != nil {
return fmt.Errorf("创建绑定关系失败: %w", err)
}
}
}
return nil
})
}
// ListMomentsByCategory 获取指定标签的文章列表
func ListMomentsByCategory(req moment.ListMomentsByCategoryRequest) ([]*moment.Moment, int32, error) {
// 1. 参数校验
if req.CategoryID == 0 {
return nil, 0, errors.New("分类不能为空")
}
// 处理分页参数
page := req.Page
if page < 1 {
page = 1
}
pageSize := req.PageSize
if pageSize < 1 || pageSize > 50 {
pageSize = 10 // 限制最大页大小,避免查询压力过大
}
offset := (page - 1) * pageSize
// 2. 构建查询:通过标签关联表查询对应的文章
// 先查询关联关系表,再关联文章主表
db := DB.Model(&model.MomentCategory{}).
Joins("JOIN moment ON moment_category.moment_id = moment.id").
Where("moment_category.category_id = ?", req.CategoryID)
//Where("moment.status = 0") // 只查询正常状态的文章
// 3. 统计符合条件的总条数
var total int64
if err := db.Count(&total).Error; err != nil {
return nil, 0, fmt.Errorf("统计标签下文章总数失败: %w", err)
}
// 4. 分页查询文章基本信息
var moments []*moment.Moment
if err := db.
Select(`moment.id, moment.user_id, moment.content, moment.visibility,
moment.location, moment.like_count, moment.collect_count,
moment.comment_count, moment.created_at`).
Offset(int(offset)).
Limit(int(pageSize)).
Order("moment.created_at DESC"). // 按文章发布时间倒序
Scan(&moments).Error; err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return []*moment.Moment{}, 0, nil // 无数据时返回空列表
}
return nil, 0, fmt.Errorf("查询标签下文章列表失败: %w", err)
}
// 5. 批量查询文章图片优化N+1查询问题
if len(moments) > 0 {
// 收集所有文章ID
var momentIDs []uint64
for _, m := range moments {
momentIDs = append(momentIDs, uint64(m.ID))
}
// 一次查询所有文章的图片
var files []*model.MomentFile
if err := DB.Where("moment_id IN (?)", momentIDs).Find(&files).Error; err != nil {
return nil, 0, fmt.Errorf("查询文章图片失败: %w", err)
}
// 建立文章ID到图片的映射
fileMap := make(map[uint64][]*moment.MomentFile)
for _, f := range files {
dtoFile := &moment.MomentFile{
ID: int64(f.ID),
MomentID: int64(f.MomentID),
FileURL: f.FileURL,
FileType: f.FileType,
SortOrder: int8(f.SortOrder),
}
fileMap[uint64(f.MomentID)] = append(fileMap[uint64(f.MomentID)], dtoFile)
}
// 为每个文章分配图片
for _, m := range moments {
m.Files = fileMap[uint64(m.ID)]
}
}
// 6. 转换总条数为int32返回
return moments, int32(total), nil
}

View File

@@ -311,3 +311,190 @@ func ListUserCollects(ctx context.Context, c *app.RequestContext) {
c.JSON(consts.StatusOK, resp)
}
// CreateTag .
// @router /v1/weMedia/moments/tag/ [POST]
func CreateTag(ctx context.Context, c *app.RequestContext) {
var err error
var req moment.CreateTagRequest
err = c.BindAndValidate(&req)
if err != nil {
c.String(consts.StatusBadRequest, err.Error())
return
}
err = mysql.CreateTag(req)
if err != nil {
c.String(consts.StatusBadRequest, err.Error())
return
}
resp := new(moment.CreateTagResponse)
c.JSON(consts.StatusOK, resp)
}
// DeleteTag .
// @router /v1/weMedia/moments/tag/ [DELETE]
func DeleteTag(ctx context.Context, c *app.RequestContext) {
var err error
var req moment.DeleteTagRequest
err = c.BindAndValidate(&req)
if err != nil {
c.String(consts.StatusBadRequest, err.Error())
return
}
err = mysql.DeleteTag(req)
if err != nil {
c.String(consts.StatusBadRequest, err.Error())
return
}
resp := new(moment.DeleteTagResponse)
c.JSON(consts.StatusOK, resp)
}
// ListTag .
// @router /v1/weMedia/moments/tag/ [GET]
func ListTag(ctx context.Context, c *app.RequestContext) {
var err error
var req moment.ListTagRequest
err = c.BindAndValidate(&req)
if err != nil {
c.String(consts.StatusBadRequest, err.Error())
return
}
tag, total, err := mysql.ListTag(req)
if err != nil {
c.String(consts.StatusBadRequest, err.Error())
return
}
resp := new(moment.ListTagResponse)
resp.Tags = tag
resp.Total = int32(total)
c.JSON(consts.StatusOK, resp)
}
// FandTag .
// @router /v1/weMedia/moments/tag/find/ [GET]
func FandTag(ctx context.Context, c *app.RequestContext) {
var err error
var req moment.FindTagRequest
err = c.BindAndValidate(&req)
if err != nil {
c.String(consts.StatusBadRequest, err.Error())
return
}
data, total, err := mysql.FindTag(&req.Keyword, req.Page, req.PageSize)
if err != nil {
c.String(consts.StatusBadRequest, err.Error())
return
}
resp := new(moment.FindTagResponse)
resp.Tags = data
resp.Total = total
c.JSON(consts.StatusOK, resp)
}
// BindTag .
// @router /v1/weMedia/moments/tag/bind/ [POST]
func BindTag(ctx context.Context, c *app.RequestContext) {
var err error
var req moment.BindTagRequest
err = c.BindAndValidate(&req)
if err != nil {
c.String(consts.StatusBadRequest, err.Error())
return
}
err = mysql.BindTag(req)
if err != nil {
c.String(consts.StatusBadRequest, err.Error())
return
}
resp := new(moment.BindTagResponse)
c.JSON(consts.StatusOK, resp)
}
// ListMomentsByTag .
// @router /v1/weMedia/moments/tag/list/ [GET]
func ListMomentsByTag(ctx context.Context, c *app.RequestContext) {
var err error
var req moment.ListMomentsByTagRequest
err = c.BindAndValidate(&req)
if err != nil {
c.String(consts.StatusBadRequest, err.Error())
return
}
data, total, err := mysql.ListMomentsByTag(req)
if err != nil {
return
}
resp := new(moment.ListMomentsByTagResponse)
resp.Moments = data
resp.Total = total
c.JSON(consts.StatusOK, resp)
}
// ListCategory .
// @router /v1/weMedia/moments/category/ [GET]
func ListCategory(ctx context.Context, c *app.RequestContext) {
var err error
var req moment.ListCategoryRequest
err = c.BindAndValidate(&req)
if err != nil {
c.String(consts.StatusBadRequest, err.Error())
return
}
category, err := mysql.ListCategory()
if err != nil {
c.String(consts.StatusBadRequest, err.Error())
return
}
resp := new(moment.ListCategoryResponse)
resp.Categorys = category
c.JSON(consts.StatusOK, resp)
}
// BindCategory .
// @router /v1/weMedia/moments/category/ [POST]
func BindCategory(ctx context.Context, c *app.RequestContext) {
var err error
var req moment.BindCategoryRequest
err = c.BindAndValidate(&req)
if err != nil {
c.String(consts.StatusBadRequest, err.Error())
return
}
err = mysql.BindCategory(req)
if err != nil {
c.String(consts.StatusBadRequest, err.Error())
return
}
resp := new(moment.BindCategoryResponse)
c.JSON(consts.StatusOK, resp)
}
// ListMomentsByCategory .
// @router /v1/weMedia/moments/category/list/ [GET]
func ListMomentsByCategory(ctx context.Context, c *app.RequestContext) {
var err error
var req moment.ListMomentsByCategoryRequest
err = c.BindAndValidate(&req)
if err != nil {
c.String(consts.StatusBadRequest, err.Error())
return
}
category, tatol, err := mysql.ListMomentsByCategory(req)
if err != nil {
return
}
resp := new(moment.ListMomentsByCategoryResponse)
resp.Moments = category
resp.Total = tatol
c.JSON(consts.StatusOK, resp)
}

File diff suppressed because it is too large Load Diff

View File

@@ -62,6 +62,34 @@ type CommentFile struct {
SortOrder int `gorm:"column:sort_order;type:int;default:0;comment:'文件排序'"`
}
// Category 分类表
type Category struct {
gorm.Model
CategoryName string `gorm:"column:category_name;size:50;not null;unique;comment:'分类名'"` // 分类名称
ParentID uint `gorm:"column:parent_id;type:bigint unsigned;not null;comment:'父分类ID'"` // 父分类ID
}
// MomentCategory 分类关系表
type MomentCategory struct {
gorm.Model
MomentID uint `gorm:"column:moment_id;type:bigint unsigned;not null;comment:'动态ID'"`
CategoryID uint `gorm:"column:category_id;type:bigint unsigned;not null;comment:'分类ID'"`
}
// Tag 标签表
type Tag struct {
gorm.Model
TagName string `gorm:"column:tag_name;size:50;not null;unique;comment:'标签名'"` // 标签名称
UserID string `gorm:"column:user_id;type:varchar(32);not null;comment:'创建者Id'"`
}
// MomentTag 标签关系表
type MomentTag struct {
gorm.Model
MomentID uint `gorm:"column:moment_id;type:bigint unsigned;not null;comment:'动态ID'"`
TagID uint `gorm:"column:tag_id;type:bigint unsigned;not null;comment:'标签ID'"`
}
func (Moment) TableName() string {
return "moment"
}
@@ -85,3 +113,19 @@ func (MomentCollect) TableName() string {
func (CommentFile) TableName() string {
return "moment_comment_file"
}
func (Category) TableName() string {
return "category"
}
func (MomentCategory) TableName() string {
return "moment_category"
}
func (Tag) TableName() string {
return "tag"
}
func (MomentTag) TableName() string {
return "moment_tag"
}

View File

@@ -165,3 +165,78 @@ func _listuserlikesMw() []app.HandlerFunc {
// your code...
return nil
}
func _categoryMw() []app.HandlerFunc {
// your code...
return nil
}
func _listcategoryMw() []app.HandlerFunc {
// your code...
return nil
}
func _bindcategoryMw() []app.HandlerFunc {
// your code...
return nil
}
func _listmomentsbycategoryMw() []app.HandlerFunc {
// your code...
return nil
}
func _tagMw() []app.HandlerFunc {
// your code...
return nil
}
func _deletetagMw() []app.HandlerFunc {
// your code...
return nil
}
func _listtagMw() []app.HandlerFunc {
// your code...
return nil
}
func _createtagMw() []app.HandlerFunc {
// your code...
return nil
}
func _bindMw() []app.HandlerFunc {
// your code...
return nil
}
func _bindtagMw() []app.HandlerFunc {
// your code...
return nil
}
func _findMw() []app.HandlerFunc {
// your code...
return nil
}
func _fandtagMw() []app.HandlerFunc {
// your code...
return nil
}
func _listmomentsbytagMw() []app.HandlerFunc {
// your code...
return nil
}
func _list5Mw() []app.HandlerFunc {
// your code...
return nil
}
func _list6Mw() []app.HandlerFunc {
// your code...
return nil
}

View File

@@ -25,6 +25,15 @@ func Register(r *server.Hertz) {
_moments := _wemedia.Group("/moments", _momentsMw()...)
_moments.DELETE("/", append(_deletemomentMw(), moment.DeleteMoment)...)
_moments.POST("/", append(_createmomentMw(), moment.CreateMoment)...)
{
_category := _moments.Group("/category", _categoryMw()...)
_category.GET("/", append(_listcategoryMw(), moment.ListCategory)...)
_category.POST("/", append(_bindcategoryMw(), moment.BindCategory)...)
{
_list := _category.Group("/list", _listMw()...)
_list.GET("/", append(_listmomentsbycategoryMw(), moment.ListMomentsByCategory)...)
}
}
{
_collect := _moments.Group("/collect", _collectMw()...)
_collect.POST("/", append(_collectmomentMw(), moment.CollectMoment)...)
@@ -34,8 +43,8 @@ func Register(r *server.Hertz) {
_comment.DELETE("/", append(_deletecommentMw(), moment.DeleteComment)...)
_comment.POST("/", append(_commentmomentMw(), moment.CommentMoment)...)
{
_list := _comment.Group("/list", _listMw()...)
_list.GET("/", append(_listmomentcommentsMw(), moment.ListMomentComments)...)
_list0 := _comment.Group("/list", _list0Mw()...)
_list0.GET("/", append(_listmomentcommentsMw(), moment.ListMomentComments)...)
}
}
{
@@ -46,13 +55,31 @@ func Register(r *server.Hertz) {
_like := _moments.Group("/like", _likeMw()...)
_like.POST("/", append(_likemomentMw(), moment.LikeMoment)...)
{
_list0 := _like.Group("/list", _list0Mw()...)
_list0.GET("/", append(_listmomentlikesMw(), moment.ListMomentLikes)...)
_list1 := _like.Group("/list", _list1Mw()...)
_list1.GET("/", append(_listmomentlikesMw(), moment.ListMomentLikes)...)
}
}
{
_list1 := _moments.Group("/list", _list1Mw()...)
_list1.GET("/", append(_listmomentsMw(), moment.ListMoments)...)
_list2 := _moments.Group("/list", _list2Mw()...)
_list2.GET("/", append(_listmomentsMw(), moment.ListMoments)...)
}
{
_tag := _moments.Group("/tag", _tagMw()...)
_tag.DELETE("/", append(_deletetagMw(), moment.DeleteTag)...)
_tag.GET("/", append(_listtagMw(), moment.ListTag)...)
_tag.POST("/", append(_createtagMw(), moment.CreateTag)...)
{
_bind := _tag.Group("/bind", _bindMw()...)
_bind.POST("/", append(_bindtagMw(), moment.BindTag)...)
}
{
_find := _tag.Group("/find", _findMw()...)
_find.GET("/", append(_fandtagMw(), moment.FandTag)...)
}
{
_list3 := _tag.Group("/list", _list3Mw()...)
_list3.GET("/", append(_listmomentsbytagMw(), moment.ListMomentsByTag)...)
}
}
{
_uncollect := _moments.Group("/unCollect", _uncollectMw()...)
@@ -61,22 +88,22 @@ func Register(r *server.Hertz) {
{
_user := _moments.Group("/user", _userMw()...)
{
_list2 := _user.Group("/list", _list2Mw()...)
_list2.GET("/", append(_listmomentsappointMw(), moment.ListMomentsAppoint)...)
_list4 := _user.Group("/list", _list4Mw()...)
_list4.GET("/", append(_listmomentsappointMw(), moment.ListMomentsAppoint)...)
}
}
{
_usercollects := _moments.Group("/userCollects", _usercollectsMw()...)
{
_list3 := _usercollects.Group("/list", _list3Mw()...)
_list3.GET("/", append(_listusercollectsMw(), moment.ListUserCollects)...)
_list5 := _usercollects.Group("/list", _list5Mw()...)
_list5.GET("/", append(_listusercollectsMw(), moment.ListUserCollects)...)
}
}
{
_userlike := _moments.Group("/userlike", _userlikeMw()...)
{
_list4 := _userlike.Group("/list", _list4Mw()...)
_list4.GET("/", append(_listuserlikesMw(), moment.ListUserLikes)...)
_list6 := _userlike.Group("/list", _list6Mw()...)
_list6.GET("/", append(_listuserlikesMw(), moment.ListUserLikes)...)
}
}
}

View File

@@ -261,6 +261,119 @@ struct ListMomentsAppointResponse {
3: i32 total // 总数量
}
struct TagInfo{
1: i32 id
2: string tag_name
}
struct CreateTagResponse {
1: Code code
2: string msg
}
struct CreateTagRequest {
1: string tag_name
2: string user_id
}
struct DeleteTagResponse {
1: Code code
2: string msg
}
struct DeleteTagRequest {
1: string tag_name
2: string user_id
}
struct ListTagResponse{
1: Code code
2: string msg
3: list<TagInfo> tags
4: i32 total
}
struct ListTagRequest{
1: string user_id
2: i32 page // 页码默认1
3: i32 page_size // 每页数量
}
struct FindTagRequest{
1: string keyword // 关键字
2: i32 page // 页码默认1
3: i32 page_size // 每页数量
}
struct FindTagResponse{
1: Code code
2: list<TagInfo> tags
3: i32 total
}
struct BindTagResponse{
1: Code code
2: string msg
}
struct BindTagRequest{
1: list<i32> moment_id
2: i32 tag_id
}
// 获取指定tag动态列表请求
struct ListMomentsByTagRequest {
1: string tag
2: i32 page // 页码默认1
3: i32 page_size // 每页数量默认10
}
// 获取指定tag动态列表响应
struct ListMomentsByTagResponse {
1: Code code
2: list<Moment> moments // 动态列表
3: i32 total // 总数量
}
struct CategoryInfo{
1: i32 id
2: string category_name
}
struct ListCategoryResponse{
1: Code code
2: string msg
3: list<CategoryInfo> categorys
}
struct ListCategoryRequest{
1: string user_id
}
struct BindCategoryResponse{
1: Code code
2: string msg
}
struct BindCategoryRequest{
1: list<i32> moment_id
2: i32 category_id
}
// 获取指定分类动态列表请求
struct ListMomentsByCategoryRequest {
1: i32 category_id
2: i32 page // 页码默认1
3: i32 page_size // 每页数量默认10
}
// 获取指定分类动态列表响应
struct ListMomentsByCategoryResponse {
1: Code code
2: list<Moment> moments // 动态列表
3: i32 total // 总数量
}
// 动态服务接口
service MomentsService {
// 发布动态
@@ -304,4 +417,31 @@ service MomentsService {
// 删除评论
DeleteCommentResponse DeleteComment(1: DeleteCommentRequest req)(api.delete="/v1/weMedia/moments/comment/")
//新增tag
CreateTagResponse CreateTag(1: CreateTagRequest req)(api.post="/v1/weMedia/moments/tag/")
//删除tag
DeleteTagResponse DeleteTag(1: DeleteTagRequest req)(api.delete="/v1/weMedia/moments/tag/")
//获取tag列表
ListTagResponse ListTag(1: ListTagRequest req)(api.get="/v1/weMedia/moments/tag/")
//获取tag列表
FindTagResponse FandTag(1: FindTagRequest req)(api.get="/v1/weMedia/moments/tag/find/")
//绑定tag
BindTagResponse BindTag(1: BindTagRequest req)(api.post="/v1/weMedia/moments/tag/bind/")
//通过tag获取文章列表
ListMomentsByTagResponse ListMomentsByTag(1: ListMomentsByTagRequest req)(api.get="/v1/weMedia/moments/tag/list/")
//获取分类列表
ListCategoryResponse ListCategory(1: ListCategoryRequest req)(api.get="/v1/weMedia/moments/category/")
//绑定分类
BindCategoryResponse BindCategory(1: BindCategoryRequest req)(api.post="/v1/weMedia/moments/category/")
//通过分类获取文章列表
ListMomentsByCategoryResponse ListMomentsByCategory(1: ListMomentsByCategoryRequest req)(api.get="/v1/weMedia/moments/category/list/")
}