mirror of https://gitee.com/answerdev/answer.git
feat: add timeline api interface
This commit is contained in:
parent
d36f758fba
commit
cd961eafc2
|
@ -46,6 +46,7 @@ import (
|
|||
auth2 "github.com/answerdev/answer/internal/service/auth"
|
||||
"github.com/answerdev/answer/internal/service/collection_common"
|
||||
comment2 "github.com/answerdev/answer/internal/service/comment"
|
||||
"github.com/answerdev/answer/internal/service/comment_common"
|
||||
"github.com/answerdev/answer/internal/service/dashboard"
|
||||
export2 "github.com/answerdev/answer/internal/service/export"
|
||||
"github.com/answerdev/answer/internal/service/follow"
|
||||
|
@ -186,7 +187,9 @@ func initApplication(debug bool, serverConf *conf.Server, dbConf *data.Database,
|
|||
dashboardController := controller.NewDashboardController(dashboardService)
|
||||
uploadController := controller.NewUploadController(uploaderService)
|
||||
activityCommon := activity_common2.NewActivityCommon(activityRepo)
|
||||
activityService := activity2.NewActivityService()
|
||||
activityActivityRepo := activity.NewActivityRepo(dataData)
|
||||
commentCommonService := comment_common.NewCommentCommonService(commentCommonRepo)
|
||||
activityService := activity2.NewActivityService(activityActivityRepo, userCommon, activityCommon, tagCommonService, objService, commentCommonService)
|
||||
activityController := controller.NewActivityController(activityCommon, activityService)
|
||||
answerAPIRouter := router.NewAnswerAPIRouter(langController, userController, commentController, reportController, voteController, tagController, followController, collectionController, questionController, answerController, searchController, revisionController, rankController, controller_backyardReportController, userBackyardController, reasonController, themeController, siteInfoController, siteinfoController, notificationController, dashboardController, uploadController, activityController)
|
||||
swaggerRouter := router.NewSwaggerRouter(swaggerConf)
|
||||
|
|
|
@ -1,20 +1,5 @@
|
|||
package constant
|
||||
|
||||
// | 问题 回答 标签 | undeleted | 操作者 | | 恢复删除的内容 |
|
||||
// | 问题 回答 标签 | deleted | 操作者 | | 删除内容 |
|
||||
// | 问题 回答 标签 | rollback | 编辑者 | 显示编辑理由 | 回滚版本编辑记录; 点击 Type 显示最近的版本比较 |
|
||||
// | 问题 回答 标签 | edit | 编辑者 | 显示编辑理由 | 编辑记录; 点击 Type 显示最近的版本比较 |
|
||||
// | 问题 回答 | downvote | 投票者 or N/A | | 内容点踩,名字仅管理员可见; 取消时显示已取消和取消时间 |
|
||||
// | 问题 回答 | upvote | 投票者 | | 内容点赞; 取消时显示已取消和取消时间 |
|
||||
// | 问题 回答 | accept | 提问者 | | 采纳答案,Type 链接到对应的回答; 取消时显示已取消和取消时间 |
|
||||
// | 问题 回答 | commented | 评论者 | 显示评论内容 | 添加评论,Type 链接到对应的评论 |
|
||||
// | 问题 | answered | 回答者 | | 添加回答,Type 链接到对应的回答 |
|
||||
// | 问题 | reopened | 操作者 | | 重新开启问题 |
|
||||
// | 问题 | closed | 操作者 | 显示关闭理由 | 关闭问题 |
|
||||
// | 问题 | asked | 提问者 | | 初始提问版本,点击展开无需比较 |
|
||||
// | 回答 | answered | 回答者 | | 初始回答版本,点击展开无需比较 |
|
||||
// | 标签 | created | 创建者 | | 初始标签版本,点击展开无需比较 |
|
||||
|
||||
// question activity
|
||||
|
||||
type ActivityTypeKey string
|
||||
|
|
|
@ -1,8 +1,12 @@
|
|||
package controller
|
||||
|
||||
import (
|
||||
"github.com/answerdev/answer/internal/base/handler"
|
||||
"github.com/answerdev/answer/internal/base/middleware"
|
||||
"github.com/answerdev/answer/internal/schema"
|
||||
"github.com/answerdev/answer/internal/service/activity"
|
||||
"github.com/answerdev/answer/internal/service/activity_common"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
type ActivityController struct {
|
||||
|
@ -16,3 +20,26 @@ func NewActivityController(
|
|||
activityService *activity.ActivityService) *ActivityController {
|
||||
return &ActivityController{activityCommonService: activityCommonService, activityService: activityService}
|
||||
}
|
||||
|
||||
// GetObjectTimeline get object timeline
|
||||
// @Summary get object timeline
|
||||
// @Description get object timeline
|
||||
// @Tags Comment
|
||||
// @Produce json
|
||||
// @Param object_id query string false "object id"
|
||||
// @Param tag_slug_name query string false "tag slug name"
|
||||
// @Param object_type query string false "object type" Enums(question, answer, tag)
|
||||
// @Param show_vote bool false "is show vote"
|
||||
// @Success 200 {object} handler.RespBody{data=schema.GetObjectTimelineResp}
|
||||
// @Router /answer/api/v1/activity/timeline [get]
|
||||
func (ac *ActivityController) GetObjectTimeline(ctx *gin.Context) {
|
||||
req := &schema.GetObjectTimelineReq{}
|
||||
if handler.BindAndCheck(ctx, req) {
|
||||
return
|
||||
}
|
||||
|
||||
req.UserID = middleware.GetLoginUserIDFromContext(ctx)
|
||||
|
||||
resp, err := ac.activityService.GetObjectTimeline(ctx, req)
|
||||
handler.HandleResponse(ctx, err, resp)
|
||||
}
|
||||
|
|
|
@ -16,10 +16,12 @@ type Activity struct {
|
|||
UserID string `xorm:"not null index BIGINT(20) user_id"`
|
||||
TriggerUserID int64 `xorm:"not null default 0 index BIGINT(20) trigger_user_id"`
|
||||
ObjectID string `xorm:"not null default 0 index BIGINT(20) object_id"`
|
||||
OriginalObjectID string `xorm:"not null default 0 BIGINT(20) original_object_id"`
|
||||
ActivityType int `xorm:"not null INT(11) activity_type"`
|
||||
Cancelled int `xorm:"not null default 0 TINYINT(4) cancelled"`
|
||||
Rank int `xorm:"not null default 0 INT(11) rank"`
|
||||
HasRank int `xorm:"not null default 0 TINYINT(4) has_rank"`
|
||||
RevisionID int64 `xorm:"not null default 0 BIGINT(20) revision_id"`
|
||||
}
|
||||
|
||||
type ActivityRankSum struct {
|
||||
|
|
|
@ -6,19 +6,19 @@ import (
|
|||
|
||||
const (
|
||||
QuestionStatusAvailable = 1
|
||||
QuestionStatusclosed = 2
|
||||
QuestionStatusClosed = 2
|
||||
QuestionStatusDeleted = 10
|
||||
)
|
||||
|
||||
var CmsQuestionSearchStatus = map[string]int{
|
||||
"available": QuestionStatusAvailable,
|
||||
"closed": QuestionStatusclosed,
|
||||
"closed": QuestionStatusClosed,
|
||||
"deleted": QuestionStatusDeleted,
|
||||
}
|
||||
|
||||
var CmsQuestionSearchStatusIntToString = map[int]string{
|
||||
QuestionStatusAvailable: "available",
|
||||
QuestionStatusclosed: "closed",
|
||||
QuestionStatusClosed: "closed",
|
||||
QuestionStatusDeleted: "deleted",
|
||||
}
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ type Revision struct {
|
|||
Content string `xorm:"not null TEXT content"`
|
||||
Log string `xorm:"VARCHAR(255) log"`
|
||||
Status int `xorm:"not null default 1 INT(11) status"`
|
||||
ReviewUserID string `xorm:"not null default 0 BIGINT(20) review_user_id"`
|
||||
ReviewUserID int64 `xorm:"not null default 0 BIGINT(20) review_user_id"`
|
||||
}
|
||||
|
||||
// TableName revision table name
|
||||
|
|
|
@ -163,7 +163,7 @@ func InitBaseInfo(ctx *gin.Context) {
|
|||
}
|
||||
|
||||
if cli.CheckDBTableExist(c.Data.Database) {
|
||||
log.Warnf("database is already initialized")
|
||||
log.Warn("database is already initialized")
|
||||
handler.HandleResponse(ctx, nil, nil)
|
||||
return
|
||||
}
|
||||
|
|
|
@ -242,6 +242,26 @@ func initConfigTable(engine *xorm.Engine) error {
|
|||
{ID: 84, Key: "question.review.reasons", Value: `["reason.looks_ok","reason.needs_edit","reason.needs_close","reason.needs_delete"]`},
|
||||
{ID: 85, Key: "answer.review.reasons", Value: `["reason.looks_ok","reason.needs_edit","reason.needs_delete"]`},
|
||||
{ID: 86, Key: "comment.review.reasons", Value: `["reason.looks_ok","reason.needs_edit","reason.needs_delete"]`},
|
||||
{ID: 87, Key: "question.asked", Value: `0`},
|
||||
{ID: 88, Key: "question.closed", Value: `0`},
|
||||
{ID: 89, Key: "question.reopened", Value: `0`},
|
||||
{ID: 90, Key: "question.answered", Value: `0`},
|
||||
{ID: 91, Key: "question.commented", Value: `0`},
|
||||
{ID: 92, Key: "question.accept", Value: `0`},
|
||||
{ID: 93, Key: "question.edit", Value: `0`},
|
||||
{ID: 94, Key: "question.rollback", Value: `0`},
|
||||
{ID: 95, Key: "question.deleted", Value: `0`},
|
||||
{ID: 96, Key: "question.undeleted", Value: `0`},
|
||||
{ID: 97, Key: "answer.answered", Value: `0`},
|
||||
{ID: 98, Key: "answer.commented", Value: `0`},
|
||||
{ID: 99, Key: "answer.edit", Value: `0`},
|
||||
{ID: 100, Key: "answer.rollback", Value: `0`},
|
||||
{ID: 101, Key: "answer.undeleted", Value: `0`},
|
||||
{ID: 102, Key: "tag.created", Value: `0`},
|
||||
{ID: 103, Key: "tag.edit", Value: `0`},
|
||||
{ID: 104, Key: "tag.rollback", Value: `0`},
|
||||
{ID: 105, Key: "tag.deleted", Value: `0`},
|
||||
{ID: 106, Key: "tag.undeleted", Value: `0`},
|
||||
}
|
||||
_, err := engine.Insert(defaultConfigTable)
|
||||
return err
|
||||
|
|
|
@ -44,6 +44,7 @@ var migrations = []Migration{
|
|||
NewMigration("this is first version, no operation", noopMigration),
|
||||
NewMigration("add user language", addUserLanguage),
|
||||
NewMigration("add recommend and reserved tag fields", addTagRecommendedAndReserved),
|
||||
NewMigration("add activity timeline", addActivityTimeline),
|
||||
}
|
||||
|
||||
// GetCurrentDBVersion returns the current db version
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
package migrations
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"xorm.io/xorm"
|
||||
)
|
||||
|
||||
func addActivityTimeline(x *xorm.Engine) error {
|
||||
type Reversion struct {
|
||||
ReviewUserID int64 `xorm:"not null default 0 BIGINT(20) review_user_id"`
|
||||
}
|
||||
type Activity struct {
|
||||
CancelledAt time.Time `xorm:"TIMESTAMP cancelled_at"`
|
||||
RevisionID int64 `xorm:"not null default 0 BIGINT(20) revision_id"`
|
||||
OriginalObjectID string `xorm:"not null default 0 BIGINT(20) original_object_id"`
|
||||
}
|
||||
return x.Sync(new(Activity), new(Reversion))
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
package activity
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/answerdev/answer/internal/base/data"
|
||||
"github.com/answerdev/answer/internal/base/reason"
|
||||
"github.com/answerdev/answer/internal/entity"
|
||||
"github.com/answerdev/answer/internal/service/activity"
|
||||
"github.com/segmentfault/pacman/errors"
|
||||
)
|
||||
|
||||
// activityRepo activity repository
|
||||
type activityRepo struct {
|
||||
data *data.Data
|
||||
}
|
||||
|
||||
// NewActivityRepo new repository
|
||||
func NewActivityRepo(
|
||||
data *data.Data,
|
||||
) activity.ActivityRepo {
|
||||
return &activityRepo{
|
||||
data: data,
|
||||
}
|
||||
}
|
||||
|
||||
func (ar *activityRepo) GetObjectAllActivity(ctx context.Context, objectID string, showVote bool) (
|
||||
activityList []*entity.Activity, err error) {
|
||||
activityList = make([]*entity.Activity, 0)
|
||||
err = ar.data.DB.Find(&activityList, &entity.Activity{OriginalObjectID: objectID})
|
||||
if err != nil {
|
||||
return nil, errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
|
||||
}
|
||||
return activityList, nil
|
||||
}
|
|
@ -2,6 +2,7 @@ package activity
|
|||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/answerdev/answer/internal/base/constant"
|
||||
"github.com/answerdev/answer/internal/base/data"
|
||||
|
@ -96,8 +97,8 @@ func (ar *AnswerActivityRepo) DeleteQuestion(ctx context.Context, questionID str
|
|||
return nil, errors.InternalServer(reason.DatabaseError).WithError(e).WithStack()
|
||||
}
|
||||
|
||||
if _, e := session.Where("id = ?", act.ID).Cols("`cancelled`").
|
||||
Update(&entity.Activity{Cancelled: entity.ActivityCancelled}); e != nil {
|
||||
if _, e := session.Where("id = ?", act.ID).Cols("cancelled", "cancelled_at").
|
||||
Update(&entity.Activity{Cancelled: entity.ActivityCancelled, CancelledAt: time.Now()}); e != nil {
|
||||
return nil, errors.InternalServer(reason.DatabaseError).WithError(e).WithStack()
|
||||
}
|
||||
}
|
||||
|
@ -124,7 +125,7 @@ func (ar *AnswerActivityRepo) DeleteQuestion(ctx context.Context, questionID str
|
|||
|
||||
// AcceptAnswer accept other answer
|
||||
func (ar *AnswerActivityRepo) AcceptAnswer(ctx context.Context,
|
||||
answerObjID, questionUserID, answerUserID string, isSelf bool,
|
||||
answerObjID, questionObjID, questionUserID, answerUserID string, isSelf bool,
|
||||
) (err error) {
|
||||
addActivityList := make([]*entity.Activity, 0)
|
||||
for _, action := range acceptActionList {
|
||||
|
@ -135,6 +136,7 @@ func (ar *AnswerActivityRepo) AcceptAnswer(ctx context.Context,
|
|||
}
|
||||
addActivity := &entity.Activity{
|
||||
ObjectID: answerObjID,
|
||||
OriginalObjectID: questionObjID,
|
||||
ActivityType: activityType,
|
||||
Rank: deltaRank,
|
||||
HasRank: hasRank,
|
||||
|
@ -222,7 +224,7 @@ func (ar *AnswerActivityRepo) AcceptAnswer(ctx context.Context,
|
|||
|
||||
// CancelAcceptAnswer accept other answer
|
||||
func (ar *AnswerActivityRepo) CancelAcceptAnswer(ctx context.Context,
|
||||
answerObjID, questionUserID, answerUserID string,
|
||||
answerObjID, questionObjID, questionUserID, answerUserID string,
|
||||
) (err error) {
|
||||
addActivityList := make([]*entity.Activity, 0)
|
||||
for _, action := range acceptActionList {
|
||||
|
@ -233,6 +235,7 @@ func (ar *AnswerActivityRepo) CancelAcceptAnswer(ctx context.Context,
|
|||
}
|
||||
addActivity := &entity.Activity{
|
||||
ObjectID: answerObjID,
|
||||
OriginalObjectID: questionObjID,
|
||||
ActivityType: activityType,
|
||||
Rank: -deltaRank,
|
||||
HasRank: hasRank,
|
||||
|
@ -265,8 +268,8 @@ func (ar *AnswerActivityRepo) CancelAcceptAnswer(ctx context.Context,
|
|||
return nil, errors.InternalServer(reason.DatabaseError).WithError(e).WithStack()
|
||||
}
|
||||
|
||||
if _, e := session.Where("id = ?", existsActivity.ID).Cols("`cancelled`").
|
||||
Update(&entity.Activity{Cancelled: entity.ActivityCancelled}); e != nil {
|
||||
if _, e := session.Where("id = ?", existsActivity.ID).Cols("cancelled", "cancelled_at").
|
||||
Update(&entity.Activity{Cancelled: entity.ActivityCancelled, CancelledAt: time.Now()}); e != nil {
|
||||
return nil, errors.InternalServer(reason.DatabaseError).WithError(e).WithStack()
|
||||
}
|
||||
}
|
||||
|
@ -326,8 +329,8 @@ func (ar *AnswerActivityRepo) DeleteAnswer(ctx context.Context, answerID string)
|
|||
return nil, errors.InternalServer(reason.DatabaseError).WithError(e).WithStack()
|
||||
}
|
||||
|
||||
if _, e := session.Where("id = ?", act.ID).Cols("`cancelled`").
|
||||
Update(&entity.Activity{Cancelled: entity.ActivityCancelled}); e != nil {
|
||||
if _, e := session.Where("id = ?", act.ID).Cols("cancelled", "cancelled_at").
|
||||
Update(&entity.Activity{Cancelled: entity.ActivityCancelled, CancelledAt: time.Now()}); e != nil {
|
||||
return nil, errors.InternalServer(reason.DatabaseError).WithError(e).WithStack()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -75,6 +75,7 @@ func (ar *FollowRepo) Follow(ctx context.Context, objectID, userID string) error
|
|||
_, err = session.Insert(&entity.Activity{
|
||||
UserID: userID,
|
||||
ObjectID: objectID,
|
||||
OriginalObjectID: objectID,
|
||||
ActivityType: activityType,
|
||||
Cancelled: entity.ActivityAvailable,
|
||||
Rank: 0,
|
||||
|
|
|
@ -57,6 +57,7 @@ func (ar *UserActiveActivityRepo) UserActive(ctx context.Context, userID string)
|
|||
addActivity := &entity.Activity{
|
||||
UserID: userID,
|
||||
ObjectID: "0",
|
||||
OriginalObjectID: "0",
|
||||
ActivityType: activityType,
|
||||
Rank: deltaRank,
|
||||
HasRank: 1,
|
||||
|
|
|
@ -107,6 +107,7 @@ func (vr *VoteRepo) vote(ctx context.Context, objectID string, userID, objectUse
|
|||
|
||||
insertActivity = entity.Activity{
|
||||
ObjectID: objectID,
|
||||
OriginalObjectID: objectID,
|
||||
UserID: activityUserID,
|
||||
TriggerUserID: converter.StringToInt64(triggerUserID),
|
||||
ActivityType: activityType,
|
||||
|
@ -206,7 +207,7 @@ func (vr *VoteRepo) voteCancel(ctx context.Context, objectID string, userID, obj
|
|||
return
|
||||
}
|
||||
|
||||
if _, err = session.Where("id = ?", existsActivity.ID).Cols("`cancelled`").
|
||||
if _, err = session.Where("id = ?", existsActivity.ID).Cols("cancelled", "cancelled_at").
|
||||
Update(&entity.Activity{
|
||||
Cancelled: entity.ActivityCancelled,
|
||||
CancelledAt: time.Now(),
|
||||
|
|
|
@ -53,6 +53,7 @@ var ProviderSetRepo = wire.NewSet(
|
|||
activity.NewAnswerActivityRepo,
|
||||
activity.NewQuestionActivityRepo,
|
||||
activity.NewUserActiveActivityRepo,
|
||||
activity.NewActivityRepo,
|
||||
tag.NewTagRepo,
|
||||
tag_common.NewTagCommonRepo,
|
||||
tag.NewTagRelRepo,
|
||||
|
|
|
@ -166,7 +166,7 @@ func (qr *questionRepo) GetQuestionList(ctx context.Context, question *entity.Qu
|
|||
func (qr *questionRepo) GetQuestionCount(ctx context.Context) (count int64, err error) {
|
||||
questionList := make([]*entity.Question, 0)
|
||||
|
||||
count, err = qr.data.DB.In("question.status", []int{entity.QuestionStatusAvailable, entity.QuestionStatusclosed}).FindAndCount(&questionList)
|
||||
count, err = qr.data.DB.In("question.status", []int{entity.QuestionStatusAvailable, entity.QuestionStatusClosed}).FindAndCount(&questionList)
|
||||
if err != nil {
|
||||
return count, errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
|
||||
}
|
||||
|
@ -210,7 +210,7 @@ func (qr *questionRepo) SearchList(ctx context.Context, search *schema.QuestionS
|
|||
session = session.And("question.user_id = ?", search.UserID)
|
||||
}
|
||||
|
||||
session = session.In("question.status", []int{entity.QuestionStatusAvailable, entity.QuestionStatusclosed})
|
||||
session = session.In("question.status", []int{entity.QuestionStatusAvailable, entity.QuestionStatusClosed})
|
||||
// if search.Status > 0 {
|
||||
// session = session.And("question.status = ?", search.Status)
|
||||
// }
|
||||
|
|
|
@ -203,6 +203,9 @@ func (a *AnswerAPIRouter) RegisterAnswerAPIRouter(r *gin.RouterGroup) {
|
|||
|
||||
// upload file
|
||||
r.POST("/file", a.uploadController.UploadFile)
|
||||
|
||||
// activity
|
||||
r.GET("/activity/timeline", a.activityController.GetObjectTimeline)
|
||||
}
|
||||
|
||||
func (a *AnswerAPIRouter) RegisterAnswerCmsAPIRouter(r *gin.RouterGroup) {
|
||||
|
|
|
@ -7,5 +7,45 @@ type ActivityMsg struct {
|
|||
UserID string `json:"user_id"`
|
||||
TriggerUserID int64 `json:"trigger_user_id"`
|
||||
ObjectID string `json:"object_id"`
|
||||
OriginalObjectID string `json:"original_object_id"`
|
||||
ActivityTypeKey constant.ActivityTypeKey `json:"activity_type_key"`
|
||||
RevisionID string `json:"revision_id"`
|
||||
}
|
||||
|
||||
// GetObjectTimelineReq get object timeline request
|
||||
type GetObjectTimelineReq struct {
|
||||
ObjectId string `validate:"omitempty,gt=0,lte=100" form:"object_id"`
|
||||
TagSlugName string `validate:"omitempty,gt=0,lte=35" form:"slug_name"`
|
||||
ObjectType string `validate:"required,oneof=question answer tag" form:"object_type"`
|
||||
ShowVote bool `validate:"omitempty" form:"show_vote"`
|
||||
UserID string `json:"-"`
|
||||
}
|
||||
|
||||
// GetObjectTimelineResp get object timeline response
|
||||
type GetObjectTimelineResp struct {
|
||||
ObjectInfo *ActObjectInfo `json:"object_info"`
|
||||
Timeline []*ActObjectTimeline `json:"timeline"`
|
||||
}
|
||||
|
||||
// ActObjectTimeline act object timeline
|
||||
type ActObjectTimeline struct {
|
||||
ActivityID string `json:"activity_id"`
|
||||
RevisionID string `json:"revision_id"`
|
||||
CreatedAt int64 `json:"created_at"`
|
||||
ActivityType string `json:"activity_type"`
|
||||
Username string `json:"username"`
|
||||
UserDisplayName string `json:"user_display_name"`
|
||||
Comment string `json:"comment"`
|
||||
ObjectID string `json:"object_id"`
|
||||
ObjectType string `json:"object_type"`
|
||||
Cancelled bool `json:"cancelled"`
|
||||
CancelledAt int64 `json:"cancelled_at"`
|
||||
}
|
||||
|
||||
// ActObjectInfo act object info
|
||||
type ActObjectInfo struct {
|
||||
Title string `json:"title"`
|
||||
ObjectType string `json:"object_type"`
|
||||
QuestionID string `json:"question_id"`
|
||||
AnswerID string `json:"answer_id"`
|
||||
}
|
||||
|
|
|
@ -1,9 +1,132 @@
|
|||
package activity
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strings"
|
||||
|
||||
"github.com/answerdev/answer/internal/base/constant"
|
||||
"github.com/answerdev/answer/internal/entity"
|
||||
"github.com/answerdev/answer/internal/repo/config"
|
||||
"github.com/answerdev/answer/internal/schema"
|
||||
"github.com/answerdev/answer/internal/service/activity_common"
|
||||
"github.com/answerdev/answer/internal/service/comment_common"
|
||||
"github.com/answerdev/answer/internal/service/object_info"
|
||||
"github.com/answerdev/answer/internal/service/tag_common"
|
||||
usercommon "github.com/answerdev/answer/internal/service/user_common"
|
||||
"github.com/answerdev/answer/pkg/converter"
|
||||
"github.com/segmentfault/pacman/log"
|
||||
)
|
||||
|
||||
// ActivityRepo activity repository
|
||||
type ActivityRepo interface {
|
||||
GetObjectAllActivity(ctx context.Context, objectID string, showVote bool) (activityList []*entity.Activity, err error)
|
||||
}
|
||||
|
||||
// ActivityService activity service
|
||||
type ActivityService struct {
|
||||
activityRepo ActivityRepo
|
||||
userCommon *usercommon.UserCommon
|
||||
activityCommonService *activity_common.ActivityCommon
|
||||
tagCommonService *tag_common.TagCommonService
|
||||
objectInfoService *object_info.ObjService
|
||||
commentCommonService *comment_common.CommentCommonService
|
||||
}
|
||||
|
||||
func NewActivityService() *ActivityService {
|
||||
return &ActivityService{}
|
||||
// NewActivityService new activity service
|
||||
func NewActivityService(
|
||||
activityRepo ActivityRepo,
|
||||
userCommon *usercommon.UserCommon,
|
||||
activityCommonService *activity_common.ActivityCommon,
|
||||
tagCommonService *tag_common.TagCommonService,
|
||||
objectInfoService *object_info.ObjService,
|
||||
commentCommonService *comment_common.CommentCommonService,
|
||||
) *ActivityService {
|
||||
return &ActivityService{
|
||||
objectInfoService: objectInfoService,
|
||||
activityRepo: activityRepo,
|
||||
userCommon: userCommon,
|
||||
activityCommonService: activityCommonService,
|
||||
tagCommonService: tagCommonService,
|
||||
commentCommonService: commentCommonService,
|
||||
}
|
||||
}
|
||||
|
||||
// GetObjectTimeline get object timeline
|
||||
func (as *ActivityService) GetObjectTimeline(ctx context.Context, req *schema.GetObjectTimelineReq) (
|
||||
resp *schema.GetObjectTimelineResp, err error) {
|
||||
resp = &schema.GetObjectTimelineResp{
|
||||
ObjectInfo: &schema.ActObjectInfo{},
|
||||
Timeline: make([]*schema.ActObjectTimeline, 0),
|
||||
}
|
||||
|
||||
objInfo, err := as.objectInfoService.GetInfo(ctx, req.ObjectId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
resp.ObjectInfo.Title = objInfo.Title
|
||||
resp.ObjectInfo.ObjectType = objInfo.ObjectType
|
||||
resp.ObjectInfo.QuestionID = objInfo.QuestionID
|
||||
resp.ObjectInfo.AnswerID = objInfo.AnswerID
|
||||
|
||||
activityList, err := as.activityRepo.GetObjectAllActivity(ctx, req.ObjectId, req.ShowVote)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, act := range activityList {
|
||||
item := &schema.ActObjectTimeline{
|
||||
ActivityID: act.ID,
|
||||
RevisionID: converter.IntToString(act.RevisionID),
|
||||
CreatedAt: act.CreatedAt.Unix(),
|
||||
Cancelled: act.Cancelled == entity.ActivityCancelled,
|
||||
ObjectID: act.ObjectID,
|
||||
}
|
||||
if item.Cancelled {
|
||||
item.CancelledAt = act.CancelledAt.Unix()
|
||||
}
|
||||
|
||||
// database save activity type is number, change to activity type string is like "question.asked".
|
||||
// so we need to cut the front part of '.'
|
||||
item.ObjectType, item.ActivityType, _ = strings.Cut(config.ID2KeyMapping[act.ActivityType], ".")
|
||||
|
||||
isHidden, formattedActivityType := formatActivity(item.ActivityType)
|
||||
if isHidden {
|
||||
continue
|
||||
}
|
||||
item.ActivityType = formattedActivityType
|
||||
|
||||
// get user info
|
||||
userBasicInfo, exist, err := as.userCommon.GetUserBasicInfoByID(ctx, act.UserID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if exist {
|
||||
item.Username = userBasicInfo.Username
|
||||
item.UserDisplayName = userBasicInfo.DisplayName
|
||||
}
|
||||
|
||||
if item.ObjectType == constant.CommentObjectType {
|
||||
comment, err := as.commentCommonService.GetComment(ctx, item.ObjectID)
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
} else {
|
||||
item.Comment = comment.ParsedText
|
||||
}
|
||||
}
|
||||
|
||||
resp.Timeline = append(resp.Timeline, item)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func formatActivity(activityType string) (isHidden bool, formattedActivityType string) {
|
||||
if activityType == "voted_up" || activityType == "voted_down" || activityType == "accepted" {
|
||||
return true, ""
|
||||
}
|
||||
if activityType == "vote_up" {
|
||||
return false, "upvote"
|
||||
}
|
||||
if activityType == "vote_down" {
|
||||
return false, "downvote"
|
||||
}
|
||||
return false, activityType
|
||||
}
|
||||
|
|
|
@ -10,9 +10,9 @@ import (
|
|||
// AnswerActivityRepo answer activity
|
||||
type AnswerActivityRepo interface {
|
||||
AcceptAnswer(ctx context.Context,
|
||||
answerObjID, questionUserID, answerUserID string, isSelf bool) (err error)
|
||||
answerObjID, questionObjID, questionUserID, answerUserID string, isSelf bool) (err error)
|
||||
CancelAcceptAnswer(ctx context.Context,
|
||||
answerObjID, questionUserID, answerUserID string) (err error)
|
||||
answerObjID, questionObjID, questionUserID, answerUserID string) (err error)
|
||||
DeleteAnswer(ctx context.Context, answerID string) (err error)
|
||||
}
|
||||
|
||||
|
@ -38,14 +38,14 @@ func NewAnswerActivityService(
|
|||
|
||||
// AcceptAnswer accept answer change activity
|
||||
func (as *AnswerActivityService) AcceptAnswer(ctx context.Context,
|
||||
answerObjID, questionUserID, answerUserID string, isSelf bool) (err error) {
|
||||
return as.answerActivityRepo.AcceptAnswer(ctx, answerObjID, questionUserID, answerUserID, isSelf)
|
||||
answerObjID, questionObjID, questionUserID, answerUserID string, isSelf bool) (err error) {
|
||||
return as.answerActivityRepo.AcceptAnswer(ctx, answerObjID, questionObjID, questionUserID, answerUserID, isSelf)
|
||||
}
|
||||
|
||||
// CancelAcceptAnswer cancel accept answer change activity
|
||||
func (as *AnswerActivityService) CancelAcceptAnswer(ctx context.Context,
|
||||
answerObjID, questionUserID, answerUserID string) (err error) {
|
||||
return as.answerActivityRepo.CancelAcceptAnswer(ctx, answerObjID, questionUserID, answerUserID)
|
||||
answerObjID, questionObjID, questionUserID, answerUserID string) (err error) {
|
||||
return as.answerActivityRepo.CancelAcceptAnswer(ctx, answerObjID, questionObjID, questionUserID, answerUserID)
|
||||
}
|
||||
|
||||
// DeleteAnswer delete answer change activity
|
||||
|
|
|
@ -5,6 +5,7 @@ import (
|
|||
|
||||
"github.com/answerdev/answer/internal/entity"
|
||||
"github.com/answerdev/answer/internal/service/activity_queue"
|
||||
"github.com/answerdev/answer/pkg/converter"
|
||||
"github.com/segmentfault/pacman/log"
|
||||
"xorm.io/xorm"
|
||||
)
|
||||
|
@ -48,16 +49,20 @@ func (ac *ActivityCommon) HandleActivity() {
|
|||
|
||||
activityType, err := ac.activityRepo.GetActivityTypeByConfigKey(context.Background(), string(msg.ActivityTypeKey))
|
||||
if err != nil {
|
||||
log.Errorf("error getting activity type %s, activity type is %s", err, activityType)
|
||||
log.Errorf("error getting activity type %s, activity type is %d", err, activityType)
|
||||
}
|
||||
|
||||
act := &entity.Activity{
|
||||
UserID: msg.UserID,
|
||||
TriggerUserID: msg.TriggerUserID,
|
||||
ObjectID: msg.ObjectID,
|
||||
OriginalObjectID: msg.OriginalObjectID,
|
||||
ActivityType: activityType,
|
||||
Cancelled: entity.ActivityAvailable,
|
||||
}
|
||||
if len(msg.RevisionID) > 0 {
|
||||
act.RevisionID = converter.StringToInt64(msg.RevisionID)
|
||||
}
|
||||
if err := ac.activityRepo.AddActivity(context.TODO(), act); err != nil {
|
||||
log.Error(err)
|
||||
}
|
||||
|
|
|
@ -165,7 +165,7 @@ func (as *AnswerService) Insert(ctx context.Context, req *schema.AnswerAddReq) (
|
|||
}
|
||||
infoJSON, _ := json.Marshal(insertData)
|
||||
revisionDTO.Content = string(infoJSON)
|
||||
err = as.revisionService.AddRevision(ctx, revisionDTO, true)
|
||||
revisionID, err := as.revisionService.AddRevision(ctx, revisionDTO, true)
|
||||
if err != nil {
|
||||
return insertData.ID, err
|
||||
}
|
||||
|
@ -174,12 +174,16 @@ func (as *AnswerService) Insert(ctx context.Context, req *schema.AnswerAddReq) (
|
|||
activity_queue.AddActivity(&schema.ActivityMsg{
|
||||
UserID: insertData.UserID,
|
||||
ObjectID: insertData.ID,
|
||||
OriginalObjectID: insertData.ID,
|
||||
ActivityTypeKey: constant.ActAnswerAnswered,
|
||||
RevisionID: revisionID,
|
||||
})
|
||||
activity_queue.AddActivity(&schema.ActivityMsg{
|
||||
UserID: insertData.UserID,
|
||||
ObjectID: insertData.ID,
|
||||
OriginalObjectID: questionInfo.ID,
|
||||
ActivityTypeKey: constant.ActQuestionAnswered,
|
||||
RevisionID: revisionID,
|
||||
})
|
||||
return insertData.ID, nil
|
||||
}
|
||||
|
@ -215,11 +219,19 @@ func (as *AnswerService) Update(ctx context.Context, req *schema.AnswerUpdateReq
|
|||
}
|
||||
infoJSON, _ := json.Marshal(insertData)
|
||||
revisionDTO.Content = string(infoJSON)
|
||||
err = as.revisionService.AddRevision(ctx, revisionDTO, true)
|
||||
revisionID, err := as.revisionService.AddRevision(ctx, revisionDTO, true)
|
||||
if err != nil {
|
||||
return insertData.ID, err
|
||||
}
|
||||
as.notificationUpdateAnswer(ctx, questionInfo.UserID, insertData.ID, req.UserID)
|
||||
|
||||
activity_queue.AddActivity(&schema.ActivityMsg{
|
||||
UserID: insertData.UserID,
|
||||
ObjectID: insertData.ID,
|
||||
OriginalObjectID: insertData.ID,
|
||||
ActivityTypeKey: constant.ActAnswerEdit,
|
||||
RevisionID: revisionID,
|
||||
})
|
||||
return insertData.ID, nil
|
||||
}
|
||||
|
||||
|
@ -288,14 +300,14 @@ func (as *AnswerService) updateAnswerRank(ctx context.Context, userID string,
|
|||
// if this question is already been answered, should cancel old answer rank
|
||||
if oldAnswerInfo != nil {
|
||||
err := as.answerActivityService.CancelAcceptAnswer(
|
||||
ctx, questionInfo.AcceptedAnswerID, questionInfo.UserID, oldAnswerInfo.UserID)
|
||||
ctx, questionInfo.AcceptedAnswerID, questionInfo.ID, questionInfo.UserID, oldAnswerInfo.UserID)
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
}
|
||||
}
|
||||
if newAnswerInfo.ID != "" {
|
||||
err := as.answerActivityService.AcceptAnswer(
|
||||
ctx, newAnswerInfo.ID, questionInfo.UserID, newAnswerInfo.UserID, newAnswerInfo.UserID == userID)
|
||||
ctx, newAnswerInfo.ID, questionInfo.ID, questionInfo.UserID, newAnswerInfo.UserID, newAnswerInfo.UserID == userID)
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
}
|
||||
|
@ -360,7 +372,7 @@ func (as *AnswerService) AdminSetAnswerStatus(ctx context.Context, answerID stri
|
|||
}
|
||||
|
||||
if setStatus == entity.AnswerStatusDeleted {
|
||||
err = as.answerActivityService.DeleteQuestion(ctx, answerInfo.ID, answerInfo.CreatedAt, answerInfo.VoteCount)
|
||||
err = as.answerActivityService.DeleteAnswer(ctx, answerInfo.ID, answerInfo.CreatedAt, answerInfo.VoteCount)
|
||||
if err != nil {
|
||||
log.Errorf("admin delete question then rank rollback error %s", err.Error())
|
||||
}
|
||||
|
|
|
@ -40,7 +40,7 @@ func (as *AuthService) GetUserCacheInfo(ctx context.Context, accessToken string)
|
|||
}
|
||||
cacheInfo, _ := as.authRepo.GetUserStatus(ctx, userCacheInfo.UserID)
|
||||
if cacheInfo != nil {
|
||||
log.Infof("user status updated: %+v", cacheInfo)
|
||||
log.Debugf("user status updated: %+v", cacheInfo)
|
||||
userCacheInfo.UserStatus = cacheInfo.UserStatus
|
||||
userCacheInfo.EmailStatus = cacheInfo.EmailStatus
|
||||
userCacheInfo.IsAdmin = cacheInfo.IsAdmin
|
||||
|
|
|
@ -153,6 +153,7 @@ func (cs *CommentService) AddComment(ctx context.Context, req *schema.AddComment
|
|||
activity_queue.AddActivity(&schema.ActivityMsg{
|
||||
UserID: comment.UserID,
|
||||
ObjectID: comment.ID,
|
||||
OriginalObjectID: req.ObjectID,
|
||||
ActivityTypeKey: constant.ActQuestionCommented,
|
||||
})
|
||||
return resp, nil
|
||||
|
|
|
@ -5,8 +5,10 @@ import (
|
|||
"encoding/json"
|
||||
"time"
|
||||
|
||||
"github.com/answerdev/answer/internal/base/constant"
|
||||
"github.com/answerdev/answer/internal/base/reason"
|
||||
"github.com/answerdev/answer/internal/service/activity_common"
|
||||
"github.com/answerdev/answer/internal/service/activity_queue"
|
||||
"github.com/answerdev/answer/internal/service/config"
|
||||
"github.com/answerdev/answer/internal/service/meta"
|
||||
"github.com/segmentfault/pacman/errors"
|
||||
|
@ -308,7 +310,7 @@ func (qs *QuestionCommon) CloseQuestion(ctx context.Context, req *schema.CloseQu
|
|||
if !has {
|
||||
return nil
|
||||
}
|
||||
questionInfo.Status = entity.QuestionStatusclosed
|
||||
questionInfo.Status = entity.QuestionStatusClosed
|
||||
err = qs.questionRepo.UpdateQuestionStatus(ctx, questionInfo)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -322,6 +324,14 @@ func (qs *QuestionCommon) CloseQuestion(ctx context.Context, req *schema.CloseQu
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
activity_queue.AddActivity(&schema.ActivityMsg{
|
||||
UserID: questionInfo.UserID,
|
||||
ObjectID: questionInfo.ID,
|
||||
OriginalObjectID: questionInfo.ID,
|
||||
ActivityTypeKey: constant.ActQuestionClosed,
|
||||
RevisionID: questionInfo.RevisionID,
|
||||
})
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
@ -72,7 +72,7 @@ func (qs *QuestionService) CloseQuestion(ctx context.Context, req *schema.CloseQ
|
|||
if !has {
|
||||
return nil
|
||||
}
|
||||
questionInfo.Status = entity.QuestionStatusclosed
|
||||
questionInfo.Status = entity.QuestionStatusClosed
|
||||
err = qs.questionRepo.UpdateQuestionStatus(ctx, questionInfo)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -90,7 +90,9 @@ func (qs *QuestionService) CloseQuestion(ctx context.Context, req *schema.CloseQ
|
|||
activity_queue.AddActivity(&schema.ActivityMsg{
|
||||
UserID: req.UserID,
|
||||
ObjectID: questionInfo.ID,
|
||||
OriginalObjectID: questionInfo.ID,
|
||||
ActivityTypeKey: constant.ActQuestionClosed,
|
||||
RevisionID: questionInfo.RevisionID,
|
||||
})
|
||||
return nil
|
||||
}
|
||||
|
@ -160,7 +162,7 @@ func (qs *QuestionService) AddQuestion(ctx context.Context, req *schema.Question
|
|||
}
|
||||
infoJSON, _ := json.Marshal(questionWithTagsRevision)
|
||||
revisionDTO.Content = string(infoJSON)
|
||||
err = qs.revisionService.AddRevision(ctx, revisionDTO, true)
|
||||
revisionID, err := qs.revisionService.AddRevision(ctx, revisionDTO, true)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
@ -174,7 +176,9 @@ func (qs *QuestionService) AddQuestion(ctx context.Context, req *schema.Question
|
|||
activity_queue.AddActivity(&schema.ActivityMsg{
|
||||
UserID: question.UserID,
|
||||
ObjectID: question.ID,
|
||||
OriginalObjectID: question.ID,
|
||||
ActivityTypeKey: constant.ActQuestionAsked,
|
||||
RevisionID: revisionID,
|
||||
})
|
||||
|
||||
questionInfo, err = qs.GetQuestion(ctx, question.ID, question.UserID, false)
|
||||
|
@ -217,7 +221,13 @@ func (qs *QuestionService) RemoveQuestion(ctx context.Context, req *schema.Remov
|
|||
if err != nil {
|
||||
log.Errorf("user DeleteQuestion rank rollback error %s", err.Error())
|
||||
}
|
||||
|
||||
activity_queue.AddActivity(&schema.ActivityMsg{
|
||||
UserID: questionInfo.UserID,
|
||||
ObjectID: questionInfo.ID,
|
||||
OriginalObjectID: questionInfo.ID,
|
||||
ActivityTypeKey: constant.ActQuestionDeleted,
|
||||
RevisionID: questionInfo.RevisionID,
|
||||
})
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -285,7 +295,7 @@ func (qs *QuestionService) UpdateQuestion(ctx context.Context, req *schema.Quest
|
|||
}
|
||||
infoJSON, _ := json.Marshal(question)
|
||||
revisionDTO.Content = string(infoJSON)
|
||||
err = qs.revisionService.AddRevision(ctx, revisionDTO, true)
|
||||
revisionID, err := qs.revisionService.AddRevision(ctx, revisionDTO, true)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
@ -293,6 +303,8 @@ func (qs *QuestionService) UpdateQuestion(ctx context.Context, req *schema.Quest
|
|||
UserID: req.UserID,
|
||||
ObjectID: question.ID,
|
||||
ActivityTypeKey: constant.ActQuestionEdit,
|
||||
RevisionID: revisionID,
|
||||
OriginalObjectID: question.ID,
|
||||
})
|
||||
|
||||
questionInfo, err = qs.GetQuestion(ctx, question.ID, question.UserID, false)
|
||||
|
@ -602,8 +614,7 @@ func (qs *QuestionService) AdminSetQuestionStatus(ctx context.Context, questionI
|
|||
if !exist {
|
||||
return errors.BadRequest(reason.QuestionNotFound)
|
||||
}
|
||||
questionInfo.Status = setStatus
|
||||
err = qs.questionRepo.UpdateQuestionStatus(ctx, questionInfo)
|
||||
err = qs.questionRepo.UpdateQuestionStatus(ctx, &entity.Question{ID: questionInfo.ID, Status: setStatus})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -614,6 +625,24 @@ func (qs *QuestionService) AdminSetQuestionStatus(ctx context.Context, questionI
|
|||
log.Errorf("admin delete question then rank rollback error %s", err.Error())
|
||||
}
|
||||
}
|
||||
if setStatus == entity.QuestionStatusAvailable && questionInfo.Status == entity.QuestionStatusClosed {
|
||||
activity_queue.AddActivity(&schema.ActivityMsg{
|
||||
UserID: questionInfo.UserID,
|
||||
ObjectID: questionInfo.ID,
|
||||
OriginalObjectID: questionInfo.ID,
|
||||
ActivityTypeKey: constant.ActQuestionDeleted,
|
||||
RevisionID: questionInfo.RevisionID,
|
||||
})
|
||||
}
|
||||
if setStatus == entity.QuestionStatusClosed && questionInfo.Status != entity.QuestionStatusClosed {
|
||||
activity_queue.AddActivity(&schema.ActivityMsg{
|
||||
UserID: questionInfo.UserID,
|
||||
ObjectID: questionInfo.ID,
|
||||
OriginalObjectID: questionInfo.ID,
|
||||
ActivityTypeKey: constant.ActQuestionClosed,
|
||||
RevisionID: questionInfo.RevisionID,
|
||||
})
|
||||
}
|
||||
msg := &schema.NotificationMsg{}
|
||||
msg.ObjectID = questionInfo.ID
|
||||
msg.Type = schema.NotificationTypeInbox
|
||||
|
|
|
@ -29,12 +29,13 @@ func NewRevisionService(revisionRepo revision.RevisionRepo, userRepo usercommon.
|
|||
// autoUpdateRevisionID bool : if autoUpdateRevisionID is true , the object.revision_id will be updated,
|
||||
// if not need auto update object.revision_id, it must be false.
|
||||
// example: user can edit the object, but need audit, the revision_id will be updated when admin approved
|
||||
func (rs *RevisionService) AddRevision(ctx context.Context, req *schema.AddRevisionDTO, autoUpdateRevisionID bool) (err error) {
|
||||
func (rs *RevisionService) AddRevision(ctx context.Context, req *schema.AddRevisionDTO, autoUpdateRevisionID bool) (
|
||||
revisionID string, err error) {
|
||||
rev := &entity.Revision{}
|
||||
_ = copier.Copy(rev, req)
|
||||
err = rs.revisionRepo.AddRevision(ctx, rev, autoUpdateRevisionID)
|
||||
if err != nil {
|
||||
return err
|
||||
return "", err
|
||||
}
|
||||
return nil
|
||||
return rev.ID, nil
|
||||
}
|
||||
|
|
|
@ -4,6 +4,8 @@ import (
|
|||
"context"
|
||||
"encoding/json"
|
||||
|
||||
"github.com/answerdev/answer/internal/base/constant"
|
||||
"github.com/answerdev/answer/internal/service/activity_queue"
|
||||
"github.com/answerdev/answer/internal/service/revision_common"
|
||||
"github.com/answerdev/answer/internal/service/siteinfo_common"
|
||||
"github.com/answerdev/answer/internal/service/tag_common"
|
||||
|
@ -105,10 +107,17 @@ func (ts *TagService) UpdateTag(ctx context.Context, req *schema.UpdateTagReq) (
|
|||
}
|
||||
tagInfoJson, _ := json.Marshal(tagInfo)
|
||||
revisionDTO.Content = string(tagInfoJson)
|
||||
err = ts.revisionService.AddRevision(ctx, revisionDTO, true)
|
||||
revisionID, err := ts.revisionService.AddRevision(ctx, revisionDTO, true)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
activity_queue.AddActivity(&schema.ActivityMsg{
|
||||
UserID: req.UserID,
|
||||
ObjectID: tag.ID,
|
||||
OriginalObjectID: tag.ID,
|
||||
ActivityTypeKey: constant.ActTagEdit,
|
||||
RevisionID: revisionID,
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -299,10 +308,17 @@ func (ts *TagService) UpdateTagSynonym(ctx context.Context, req *schema.UpdateTa
|
|||
}
|
||||
tagInfoJson, _ := json.Marshal(tag)
|
||||
revisionDTO.Content = string(tagInfoJson)
|
||||
err = ts.revisionService.AddRevision(ctx, revisionDTO, true)
|
||||
revisionID, err := ts.revisionService.AddRevision(ctx, revisionDTO, true)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
activity_queue.AddActivity(&schema.ActivityMsg{
|
||||
UserID: req.UserID,
|
||||
ObjectID: tag.ID,
|
||||
OriginalObjectID: tag.ID,
|
||||
ActivityTypeKey: constant.ActTagCreated,
|
||||
RevisionID: revisionID,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -7,10 +7,12 @@ import (
|
|||
"sort"
|
||||
"strings"
|
||||
|
||||
"github.com/answerdev/answer/internal/base/constant"
|
||||
"github.com/answerdev/answer/internal/base/reason"
|
||||
"github.com/answerdev/answer/internal/base/validator"
|
||||
"github.com/answerdev/answer/internal/entity"
|
||||
"github.com/answerdev/answer/internal/schema"
|
||||
"github.com/answerdev/answer/internal/service/activity_queue"
|
||||
"github.com/answerdev/answer/internal/service/revision_common"
|
||||
"github.com/answerdev/answer/internal/service/siteinfo_common"
|
||||
"github.com/segmentfault/pacman/errors"
|
||||
|
@ -480,10 +482,17 @@ func (ts *TagCommonService) ObjectChangeTag(ctx context.Context, objectTagData *
|
|||
}
|
||||
tagInfoJson, _ := json.Marshal(tag)
|
||||
revisionDTO.Content = string(tagInfoJson)
|
||||
err = ts.revisionService.AddRevision(ctx, revisionDTO, true)
|
||||
revisionID, err := ts.revisionService.AddRevision(ctx, revisionDTO, true)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
activity_queue.AddActivity(&schema.ActivityMsg{
|
||||
UserID: objectTagData.UserID,
|
||||
ObjectID: tag.ID,
|
||||
OriginalObjectID: tag.ID,
|
||||
ActivityTypeKey: constant.ActTagCreated,
|
||||
RevisionID: revisionID,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue