Merge branch 'feat/1.0.7/short-id' into test

This commit is contained in:
aichy126 2023-03-09 11:38:58 +08:00
commit 21799bad0a
17 changed files with 318 additions and 20 deletions

View File

@ -128,7 +128,7 @@ func initApplication(debug bool, serverConf *conf.Server, dbConf *data.Database,
answerRepo := answer.NewAnswerRepo(dataData, uniqueIDRepo, userRankRepo, activityRepo)
questionRepo := question.NewQuestionRepo(dataData, uniqueIDRepo)
tagCommonRepo := tag_common.NewTagCommonRepo(dataData, uniqueIDRepo)
tagRelRepo := tag.NewTagRelRepo(dataData)
tagRelRepo := tag.NewTagRelRepo(dataData, uniqueIDRepo)
tagRepo := tag.NewTagRepo(dataData, uniqueIDRepo)
revisionRepo := revision.NewRevisionRepo(dataData, uniqueIDRepo)
revisionService := revision_common.NewRevisionService(revisionRepo, userRepo)

View File

@ -7,6 +7,7 @@ import (
"github.com/answerdev/answer/internal/schema"
"github.com/answerdev/answer/internal/service"
"github.com/answerdev/answer/pkg/converter"
"github.com/answerdev/answer/pkg/uid"
"github.com/gin-gonic/gin"
"github.com/jinzhu/copier"
"github.com/segmentfault/pacman/errors"
@ -37,6 +38,7 @@ func (cc *CollectionController) CollectionSwitch(ctx *gin.Context) {
if handler.BindAndCheck(ctx, req) {
return
}
req.ObjectID = uid.DeShortID(req.ObjectID)
dto := &schema.CollectionSwitchDTO{}
_ = copier.Copy(dto, req)

View File

@ -8,6 +8,7 @@ import (
"github.com/answerdev/answer/internal/service/comment"
"github.com/answerdev/answer/internal/service/permission"
"github.com/answerdev/answer/internal/service/rank"
"github.com/answerdev/answer/pkg/uid"
"github.com/gin-gonic/gin"
"github.com/segmentfault/pacman/errors"
)
@ -40,7 +41,7 @@ func (cc *CommentController) AddComment(ctx *gin.Context) {
if handler.BindAndCheck(ctx, req) {
return
}
req.ObjectID = uid.DeShortID(req.ObjectID)
req.UserID = middleware.GetLoginUserIDFromContext(ctx)
canList, err := cc.rankService.CheckOperationPermissions(ctx, req.UserID, []string{
permission.CommentAdd,
@ -154,7 +155,7 @@ func (cc *CommentController) GetCommentWithPage(ctx *gin.Context) {
if handler.BindAndCheck(ctx, req) {
return
}
req.ObjectID = uid.DeShortID(req.ObjectID)
req.UserID = middleware.GetLoginUserIDFromContext(ctx)
canList, err := cc.rankService.CheckOperationPermissions(ctx, req.UserID, []string{
permission.CommentEdit,

View File

@ -5,6 +5,7 @@ import (
"github.com/answerdev/answer/internal/base/middleware"
"github.com/answerdev/answer/internal/schema"
"github.com/answerdev/answer/internal/service/follow"
"github.com/answerdev/answer/pkg/uid"
"github.com/gin-gonic/gin"
"github.com/jinzhu/copier"
)
@ -34,7 +35,7 @@ func (fc *FollowController) Follow(ctx *gin.Context) {
if handler.BindAndCheck(ctx, req) {
return
}
req.ObjectID = uid.DeShortID(req.ObjectID)
dto := &schema.FollowDTO{}
_ = copier.Copy(dto, req)
dto.UserID = middleware.GetLoginUserIDFromContext(ctx)

View File

@ -8,6 +8,7 @@ import (
"github.com/answerdev/answer/internal/service/permission"
"github.com/answerdev/answer/internal/service/rank"
"github.com/answerdev/answer/internal/service/report"
"github.com/answerdev/answer/pkg/uid"
"github.com/gin-gonic/gin"
"github.com/segmentfault/pacman/errors"
)
@ -39,7 +40,7 @@ func (rc *ReportController) AddReport(ctx *gin.Context) {
if handler.BindAndCheck(ctx, req) {
return
}
req.ObjectID = uid.DeShortID(req.ObjectID)
req.UserID = middleware.GetLoginUserIDFromContext(ctx)
can, err := rc.rankService.CheckOperationPermission(ctx, req.UserID, permission.ReportAdd, "")
if err != nil {

View File

@ -10,6 +10,7 @@ import (
"github.com/answerdev/answer/internal/service/permission"
"github.com/answerdev/answer/internal/service/rank"
"github.com/answerdev/answer/pkg/obj"
"github.com/answerdev/answer/pkg/uid"
"github.com/gin-gonic/gin"
"github.com/segmentfault/pacman/errors"
)
@ -45,7 +46,7 @@ func (rc *RevisionController) GetRevisionList(ctx *gin.Context) {
handler.HandleResponse(ctx, errors.BadRequest(reason.RequestFormatError), nil)
return
}
objectID = uid.DeShortID(objectID)
req := &schema.GetRevisionListReq{
ObjectID: objectID,
}
@ -137,6 +138,7 @@ func (rc *RevisionController) CheckCanUpdateRevision(ctx *gin.Context) {
req.UserID = middleware.GetLoginUserIDFromContext(ctx)
action := ""
req.ID = uid.DeShortID(req.ID)
objectTypeStr, _ := obj.GetObjectTypeStrByObjectID(req.ID)
switch objectTypeStr {
case constant.QuestionObjectType:

View File

@ -18,6 +18,7 @@ import (
answercommon "github.com/answerdev/answer/internal/service/answer_common"
"github.com/answerdev/answer/internal/service/rank"
"github.com/answerdev/answer/internal/service/unique"
"github.com/answerdev/answer/pkg/uid"
"github.com/segmentfault/pacman/errors"
)
@ -46,6 +47,7 @@ func NewAnswerRepo(
// AddAnswer add answer
func (ar *answerRepo) AddAnswer(ctx context.Context, answer *entity.Answer) (err error) {
answer.QuestionID = uid.DeShortID(answer.QuestionID)
ID, err := ar.uniqueIDRepo.GenUniqueIDStr(ctx, answer.TableName())
if err != nil {
return errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
@ -56,11 +58,14 @@ func (ar *answerRepo) AddAnswer(ctx context.Context, answer *entity.Answer) (err
if err != nil {
return errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
}
answer.ID = uid.EnShortID(answer.ID)
answer.QuestionID = uid.EnShortID(answer.QuestionID)
return nil
}
// RemoveAnswer delete answer
func (ar *answerRepo) RemoveAnswer(ctx context.Context, id string) (err error) {
id = uid.DeShortID(id)
answer := &entity.Answer{
ID: id,
Status: entity.AnswerStatusDeleted,
@ -74,6 +79,8 @@ func (ar *answerRepo) RemoveAnswer(ctx context.Context, id string) (err error) {
// UpdateAnswer update answer
func (ar *answerRepo) UpdateAnswer(ctx context.Context, answer *entity.Answer, Colar []string) (err error) {
answer.ID = uid.DeShortID(answer.ID)
answer.QuestionID = uid.DeShortID(answer.QuestionID)
_, err = ar.data.DB.ID(answer.ID).Cols(Colar...).Update(answer)
if err != nil {
err = errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
@ -83,6 +90,7 @@ func (ar *answerRepo) UpdateAnswer(ctx context.Context, answer *entity.Answer, C
func (ar *answerRepo) UpdateAnswerStatus(ctx context.Context, answer *entity.Answer) (err error) {
now := time.Now()
answer.ID = uid.DeShortID(answer.ID)
answer.UpdatedAt = now
_, err = ar.data.DB.Where("id =?", answer.ID).Cols("status", "updated_at").Update(answer)
if err != nil {
@ -95,11 +103,15 @@ func (ar *answerRepo) UpdateAnswerStatus(ctx context.Context, answer *entity.Ans
func (ar *answerRepo) GetAnswer(ctx context.Context, id string) (
answer *entity.Answer, exist bool, err error,
) {
id = uid.DeShortID(id)
answer = &entity.Answer{}
exist, err = ar.data.DB.ID(id).Get(answer)
if err != nil {
return nil, false, errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
}
answer.ID = uid.EnShortID(answer.ID)
answer.QuestionID = uid.EnShortID(answer.QuestionID)
return
}
@ -116,20 +128,32 @@ func (ar *answerRepo) GetAnswerCount(ctx context.Context) (count int64, err erro
// GetAnswerList get answer list all
func (ar *answerRepo) GetAnswerList(ctx context.Context, answer *entity.Answer) (answerList []*entity.Answer, err error) {
answerList = make([]*entity.Answer, 0)
answer.ID = uid.DeShortID(answer.ID)
answer.QuestionID = uid.DeShortID(answer.QuestionID)
err = ar.data.DB.Find(answerList, answer)
if err != nil {
err = errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
}
for _, item := range answerList {
item.ID = uid.EnShortID(item.ID)
item.QuestionID = uid.EnShortID(item.QuestionID)
}
return
}
// GetAnswerPage get answer page
func (ar *answerRepo) GetAnswerPage(ctx context.Context, page, pageSize int, answer *entity.Answer) (answerList []*entity.Answer, total int64, err error) {
answer.ID = uid.DeShortID(answer.ID)
answer.QuestionID = uid.DeShortID(answer.QuestionID)
answerList = make([]*entity.Answer, 0)
total, err = pager.Help(page, pageSize, answerList, answer, ar.data.DB.NewSession())
if err != nil {
err = errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
}
for _, item := range answerList {
item.ID = uid.EnShortID(item.ID)
item.QuestionID = uid.EnShortID(item.QuestionID)
}
return
}
@ -139,6 +163,8 @@ func (ar *answerRepo) UpdateAccepted(ctx context.Context, id string, questionID
if questionID == "" {
return nil
}
id = uid.DeShortID(id)
questionID = uid.DeShortID(questionID)
var data entity.Answer
data.ID = id
@ -160,24 +186,32 @@ func (ar *answerRepo) UpdateAccepted(ctx context.Context, id string, questionID
// GetByID
func (ar *answerRepo) GetByID(ctx context.Context, id string) (*entity.Answer, bool, error) {
var resp entity.Answer
id = uid.DeShortID(id)
has, err := ar.data.DB.Where("id =? ", id).Get(&resp)
if err != nil {
return &resp, false, errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
}
resp.ID = uid.EnShortID(resp.ID)
resp.QuestionID = uid.EnShortID(resp.QuestionID)
return &resp, has, nil
}
func (ar *answerRepo) GetByUserIDQuestionID(ctx context.Context, userID string, questionID string) (*entity.Answer, bool, error) {
questionID = uid.DeShortID(questionID)
var resp entity.Answer
has, err := ar.data.DB.Where("question_id =? and user_id = ?", questionID, userID).Get(&resp)
if err != nil {
return &resp, false, errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
}
resp.ID = uid.EnShortID(resp.ID)
resp.QuestionID = uid.EnShortID(resp.QuestionID)
return &resp, has, nil
}
// SearchList
func (ar *answerRepo) SearchList(ctx context.Context, search *entity.AnswerSearch) ([]*entity.Answer, int64, error) {
search.QuestionID = uid.DeShortID(search.QuestionID)
search.ID = uid.DeShortID(search.ID)
var count int64
var err error
rows := make([]*entity.Answer, 0)
@ -215,6 +249,10 @@ func (ar *answerRepo) SearchList(ctx context.Context, search *entity.AnswerSearc
if err != nil {
return rows, count, errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
}
for _, item := range rows {
item.ID = uid.EnShortID(item.ID)
item.QuestionID = uid.EnShortID(item.QuestionID)
}
return rows, count, nil
}
@ -224,6 +262,9 @@ func (ar *answerRepo) AdminSearchList(ctx context.Context, search *entity.AdminA
err error
session = ar.data.DB.Table([]string{entity.Answer{}.TableName(), "a"}).Select("a.*")
)
if search.QuestionID != "" {
search.QuestionID = uid.DeShortID(search.QuestionID)
}
session.Where(builder.Eq{
"a.status": search.Status,
@ -250,6 +291,7 @@ func (ar *answerRepo) AdminSearchList(ctx context.Context, search *entity.AdminA
if strings.Contains(search.Query, "answer:") {
idSearch = true
id = strings.TrimSpace(strings.TrimPrefix(search.Query, "answer:"))
id = uid.DeShortID(id)
for _, r := range id {
if !unicode.IsDigit(r) {
idSearch = false
@ -285,5 +327,9 @@ func (ar *answerRepo) AdminSearchList(ctx context.Context, search *entity.AdminA
if err != nil {
return rows, count, errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
}
for _, item := range rows {
item.ID = uid.EnShortID(item.ID)
item.QuestionID = uid.EnShortID(item.QuestionID)
}
return rows, count, nil
}

View File

@ -30,6 +30,7 @@ func NewCollectionRepo(data *data.Data, uniqueIDRepo unique.UniqueIDRepo) collec
// AddCollection add collection
func (cr *collectionRepo) AddCollection(ctx context.Context, collection *entity.Collection) (err error) {
needAdd := false
_, err = cr.data.DB.Transaction(func(session *xorm.Session) (result any, err error) {
var has bool
dbcollection := &entity.Collection{}
@ -41,16 +42,23 @@ func (cr *collectionRepo) AddCollection(ctx context.Context, collection *entity.
if has {
return
}
needAdd = true
return
})
if err != nil {
return
}
if needAdd {
id, err := cr.uniqueIDRepo.GenUniqueIDStr(ctx, collection.TableName())
if err == nil {
collection.ID = id
_, err = session.Insert(collection)
_, err = cr.data.DB.Insert(collection)
if err != nil {
return result, errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
return errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
}
}
return
})
}
return err
}

View File

@ -10,6 +10,7 @@ import (
"github.com/answerdev/answer/internal/entity"
"github.com/answerdev/answer/internal/schema"
notficationcommon "github.com/answerdev/answer/internal/service/notification_common"
"github.com/answerdev/answer/pkg/uid"
"github.com/segmentfault/pacman/errors"
)
@ -27,6 +28,7 @@ func NewNotificationRepo(data *data.Data) notficationcommon.NotificationRepo {
// AddNotification add notification
func (nr *notificationRepo) AddNotification(ctx context.Context, notification *entity.Notification) (err error) {
notification.ObjectID = uid.DeShortID(notification.ObjectID)
_, err = nr.data.DB.Insert(notification)
if err != nil {
return errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
@ -37,6 +39,7 @@ func (nr *notificationRepo) AddNotification(ctx context.Context, notification *e
func (nr *notificationRepo) UpdateNotificationContent(ctx context.Context, notification *entity.Notification) (err error) {
now := time.Now()
notification.UpdatedAt = now
notification.ObjectID = uid.DeShortID(notification.ObjectID)
_, err = nr.data.DB.Where("id =?", notification.ID).Cols("content", "updated_at").Update(notification)
if err != nil {
return errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()

View File

@ -18,6 +18,7 @@ import (
questioncommon "github.com/answerdev/answer/internal/service/question_common"
"github.com/answerdev/answer/internal/service/unique"
"github.com/answerdev/answer/pkg/htmltext"
"github.com/answerdev/answer/pkg/uid"
"github.com/segmentfault/pacman/errors"
)
@ -49,11 +50,13 @@ func (qr *questionRepo) AddQuestion(ctx context.Context, question *entity.Questi
if err != nil {
return errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
}
question.ID = uid.EnShortID(question.ID)
return
}
// RemoveQuestion delete question
func (qr *questionRepo) RemoveQuestion(ctx context.Context, id string) (err error) {
id = uid.DeShortID(id)
_, err = qr.data.DB.Where("id =?", id).Delete(&entity.Question{})
if err != nil {
err = errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
@ -63,14 +66,17 @@ func (qr *questionRepo) RemoveQuestion(ctx context.Context, id string) (err erro
// UpdateQuestion update question
func (qr *questionRepo) UpdateQuestion(ctx context.Context, question *entity.Question, Cols []string) (err error) {
question.ID = uid.DeShortID(question.ID)
_, err = qr.data.DB.Where("id =?", question.ID).Cols(Cols...).Update(question)
if err != nil {
return errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
}
question.ID = uid.EnShortID(question.ID)
return
}
func (qr *questionRepo) UpdatePvCount(ctx context.Context, questionID string) (err error) {
questionID = uid.DeShortID(questionID)
question := &entity.Question{}
_, err = qr.data.DB.Where("id =?", questionID).Incr("view_count", 1).Update(question)
if err != nil {
@ -80,6 +86,7 @@ func (qr *questionRepo) UpdatePvCount(ctx context.Context, questionID string) (e
}
func (qr *questionRepo) UpdateAnswerCount(ctx context.Context, questionID string, num int) (err error) {
questionID = uid.DeShortID(questionID)
question := &entity.Question{}
_, err = qr.data.DB.Where("id =?", questionID).Incr("answer_count", num).Update(question)
if err != nil {
@ -89,6 +96,7 @@ func (qr *questionRepo) UpdateAnswerCount(ctx context.Context, questionID string
}
func (qr *questionRepo) UpdateCollectionCount(ctx context.Context, questionID string, num int) (err error) {
questionID = uid.DeShortID(questionID)
question := &entity.Question{}
_, err = qr.data.DB.Where("id =?", questionID).Incr("collection_count", num).Update(question)
if err != nil {
@ -98,6 +106,7 @@ func (qr *questionRepo) UpdateCollectionCount(ctx context.Context, questionID st
}
func (qr *questionRepo) UpdateQuestionStatus(ctx context.Context, question *entity.Question) (err error) {
question.ID = uid.DeShortID(question.ID)
now := time.Now()
question.UpdatedAt = now
_, err = qr.data.DB.Where("id =?", question.ID).Cols("status", "updated_at").Update(question)
@ -108,6 +117,7 @@ func (qr *questionRepo) UpdateQuestionStatus(ctx context.Context, question *enti
}
func (qr *questionRepo) UpdateQuestionStatusWithOutUpdateTime(ctx context.Context, question *entity.Question) (err error) {
question.ID = uid.DeShortID(question.ID)
_, err = qr.data.DB.Where("id =?", question.ID).Cols("status").Update(question)
if err != nil {
return errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
@ -116,6 +126,7 @@ func (qr *questionRepo) UpdateQuestionStatusWithOutUpdateTime(ctx context.Contex
}
func (qr *questionRepo) UpdateAccepted(ctx context.Context, question *entity.Question) (err error) {
question.ID = uid.DeShortID(question.ID)
_, err = qr.data.DB.Where("id =?", question.ID).Cols("accepted_answer_id").Update(question)
if err != nil {
return errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
@ -124,6 +135,7 @@ func (qr *questionRepo) UpdateAccepted(ctx context.Context, question *entity.Que
}
func (qr *questionRepo) UpdateLastAnswer(ctx context.Context, question *entity.Question) (err error) {
question.ID = uid.DeShortID(question.ID)
_, err = qr.data.DB.Where("id =?", question.ID).Cols("last_answer_id").Update(question)
if err != nil {
return errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
@ -135,12 +147,14 @@ func (qr *questionRepo) UpdateLastAnswer(ctx context.Context, question *entity.Q
func (qr *questionRepo) GetQuestion(ctx context.Context, id string) (
question *entity.Question, exist bool, err error,
) {
id = uid.DeShortID(id)
question = &entity.Question{}
question.ID = id
exist, err = qr.data.DB.Where("id = ?", id).Get(question)
if err != nil {
return nil, false, errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
}
question.ID = uid.EnShortID(question.ID)
return
}
@ -151,25 +165,38 @@ func (qr *questionRepo) SearchByTitleLike(ctx context.Context, title string) (qu
if err != nil {
return nil, errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
}
for _, item := range questionList {
item.ID = uid.EnShortID(item.ID)
}
return
}
func (qr *questionRepo) FindByID(ctx context.Context, id []string) (questionList []*entity.Question, err error) {
for key, itemID := range id {
id[key] = uid.EnShortID(itemID)
}
questionList = make([]*entity.Question, 0)
err = qr.data.DB.Table("question").In("id", id).Find(&questionList)
if err != nil {
return nil, errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
}
for _, item := range questionList {
item.ID = uid.DeShortID(item.ID)
}
return
}
// GetQuestionList get question list all
func (qr *questionRepo) GetQuestionList(ctx context.Context, question *entity.Question) (questionList []*entity.Question, err error) {
question.ID = uid.DeShortID(question.ID)
questionList = make([]*entity.Question, 0)
err = qr.data.DB.Find(questionList, question)
if err != nil {
return questionList, errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
}
for _, item := range questionList {
item.ID = uid.DeShortID(item.ID)
}
return
}
@ -199,15 +226,19 @@ func (qr *questionRepo) GetQuestionIDsPage(ctx context.Context, page, pageSize i
session = session.In("question.status", []int{entity.QuestionStatusAvailable, entity.QuestionStatusClosed})
session = session.Limit(pageSize, offset)
session = session.OrderBy("question.created_at asc")
err = session.Select("id,title,post_update_time").Find(&rows)
err = session.Select("id,title,created_at,post_update_time").Find(&rows)
if err != nil {
return questionIDList, err
}
for _, question := range rows {
item := &schema.SiteMapQuestionInfo{}
item.ID = question.ID
item.ID = uid.EnShortID(question.ID)
item.Title = htmltext.UrlTitle(question.Title)
item.UpdateTime = fmt.Sprintf("%v", question.PostUpdateTime.Format(time.RFC3339))
updateTime := fmt.Sprintf("%v", question.PostUpdateTime.Format(time.RFC3339))
if question.PostUpdateTime.Unix() < 1 {
updateTime = fmt.Sprintf("%v", question.CreatedAt.Format(time.RFC3339))
}
item.UpdateTime = updateTime
questionIDList = append(questionIDList, item)
}
return questionIDList, nil
@ -246,6 +277,9 @@ func (qr *questionRepo) GetQuestionPage(ctx context.Context, page, pageSize int,
if err != nil {
err = errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
}
for _, item := range questionList {
item.ID = uid.EnShortID(item.ID)
}
return questionList, total, err
}
@ -277,9 +311,11 @@ func (qr *questionRepo) AdminSearchList(ctx context.Context, search *schema.Admi
idSearch = false
id = ""
)
if strings.Contains(search.Query, "question:") {
idSearch = true
id = strings.TrimSpace(strings.TrimPrefix(search.Query, "question:"))
id = uid.DeShortID(id)
for _, r := range id {
if !unicode.IsDigit(r) {
idSearch = false
@ -308,5 +344,8 @@ func (qr *questionRepo) AdminSearchList(ctx context.Context, search *schema.Admi
err = errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
return rows, count, err
}
for _, item := range rows {
item.ID = uid.EnShortID(item.ID)
}
return rows, count, nil
}

View File

@ -7,32 +7,44 @@ import (
"github.com/answerdev/answer/internal/base/reason"
"github.com/answerdev/answer/internal/entity"
tagcommon "github.com/answerdev/answer/internal/service/tag_common"
"github.com/answerdev/answer/internal/service/unique"
"github.com/answerdev/answer/pkg/uid"
"github.com/segmentfault/pacman/errors"
)
// tagRelRepo tag rel repository
type tagRelRepo struct {
data *data.Data
data *data.Data
uniqueIDRepo unique.UniqueIDRepo
}
// NewTagRelRepo new repository
func NewTagRelRepo(data *data.Data) tagcommon.TagRelRepo {
func NewTagRelRepo(data *data.Data,
uniqueIDRepo unique.UniqueIDRepo) tagcommon.TagRelRepo {
return &tagRelRepo{
data: data,
data: data,
uniqueIDRepo: uniqueIDRepo,
}
}
// AddTagRelList add tag list
func (tr *tagRelRepo) AddTagRelList(ctx context.Context, tagList []*entity.TagRel) (err error) {
for _, item := range tagList {
item.ObjectID = uid.DeShortID(item.ObjectID)
}
_, err = tr.data.DB.Insert(tagList)
if err != nil {
err = errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
}
for _, item := range tagList {
item.ObjectID = uid.EnShortID(item.ObjectID)
}
return
}
// RemoveTagRelListByObjectID delete tag list
func (tr *tagRelRepo) RemoveTagRelListByObjectID(ctx context.Context, objectID string) (err error) {
objectID = uid.DeShortID(objectID)
_, err = tr.data.DB.Where("object_id = ?", objectID).Update(&entity.TagRel{Status: entity.TagRelStatusDeleted})
if err != nil {
err = errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
@ -53,12 +65,14 @@ func (tr *tagRelRepo) RemoveTagRelListByIDs(ctx context.Context, ids []int64) (e
func (tr *tagRelRepo) GetObjectTagRelWithoutStatus(ctx context.Context, objectID, tagID string) (
tagRel *entity.TagRel, exist bool, err error,
) {
objectID = uid.DeShortID(objectID)
tagRel = &entity.TagRel{}
session := tr.data.DB.Where("object_id = ?", objectID).And("tag_id = ?", tagID)
exist, err = session.Get(tagRel)
if err != nil {
err = errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
}
tagRel.ObjectID = uid.EnShortID(tagRel.ObjectID)
return
}
@ -73,6 +87,7 @@ func (tr *tagRelRepo) EnableTagRelByIDs(ctx context.Context, ids []int64) (err e
// GetObjectTagRelList get object tag relation list all
func (tr *tagRelRepo) GetObjectTagRelList(ctx context.Context, objectID string) (tagListList []*entity.TagRel, err error) {
objectID = uid.DeShortID(objectID)
tagListList = make([]*entity.TagRel, 0)
session := tr.data.DB.Where("object_id = ?", objectID)
session.Where("status = ?", entity.TagRelStatusAvailable)
@ -80,11 +95,17 @@ func (tr *tagRelRepo) GetObjectTagRelList(ctx context.Context, objectID string)
if err != nil {
err = errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
}
for _, item := range tagListList {
item.ObjectID = uid.EnShortID(item.ObjectID)
}
return
}
// BatchGetObjectTagRelList get object tag relation list all
func (tr *tagRelRepo) BatchGetObjectTagRelList(ctx context.Context, objectIds []string) (tagListList []*entity.TagRel, err error) {
for num, item := range objectIds {
objectIds[num] = uid.DeShortID(item)
}
tagListList = make([]*entity.TagRel, 0)
session := tr.data.DB.In("object_id", objectIds)
session.Where("status = ?", entity.TagRelStatusAvailable)
@ -92,6 +113,9 @@ func (tr *tagRelRepo) BatchGetObjectTagRelList(ctx context.Context, objectIds []
if err != nil {
err = errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
}
for _, item := range tagListList {
item.ObjectID = uid.EnShortID(item.ObjectID)
}
return
}

View File

@ -18,6 +18,7 @@ import (
"github.com/answerdev/answer/internal/service/permission"
usercommon "github.com/answerdev/answer/internal/service/user_common"
"github.com/answerdev/answer/pkg/encryption"
"github.com/answerdev/answer/pkg/uid"
"github.com/jinzhu/copier"
"github.com/segmentfault/pacman/errors"
"github.com/segmentfault/pacman/log"
@ -97,6 +98,9 @@ func (cs *CommentService) AddComment(ctx context.Context, req *schema.AddComment
if err != nil {
return nil, err
}
objInfo.ObjectID = uid.DeShortID(objInfo.ObjectID)
objInfo.QuestionID = uid.DeShortID(objInfo.QuestionID)
objInfo.AnswerID = uid.DeShortID(objInfo.AnswerID)
if objInfo.ObjectType == constant.QuestionObjectType || objInfo.ObjectType == constant.AnswerObjectType {
comment.QuestionID = objInfo.QuestionID
}

View File

@ -12,6 +12,7 @@ import (
"github.com/answerdev/answer/internal/schema"
notficationcommon "github.com/answerdev/answer/internal/service/notification_common"
"github.com/answerdev/answer/internal/service/revision_common"
"github.com/answerdev/answer/pkg/uid"
"github.com/jinzhu/copier"
"github.com/segmentfault/pacman/i18n"
"github.com/segmentfault/pacman/log"
@ -140,6 +141,20 @@ func (ns *NotificationService) GetNotificationPage(ctx context.Context, searchCo
if notificationInfo.IsRead == schema.NotificationRead {
item.IsRead = true
}
answerID, ok := item.ObjectInfo.ObjectMap["answer"]
if ok {
if item.ObjectInfo.ObjectID == answerID {
item.ObjectInfo.ObjectID = uid.EnShortID(item.ObjectInfo.ObjectMap["answer"])
}
item.ObjectInfo.ObjectMap["answer"] = uid.EnShortID(item.ObjectInfo.ObjectMap["answer"])
}
questionID, ok := item.ObjectInfo.ObjectMap["question"]
if ok {
if item.ObjectInfo.ObjectID == questionID {
item.ObjectInfo.ObjectID = uid.EnShortID(item.ObjectInfo.ObjectMap["question"])
}
item.ObjectInfo.ObjectMap["question"] = uid.EnShortID(item.ObjectInfo.ObjectMap["question"])
}
resp = append(resp, item)
}
return pager.NewPageModel(total, resp), nil

View File

@ -14,6 +14,7 @@ import (
"github.com/answerdev/answer/internal/service/notice_queue"
"github.com/answerdev/answer/internal/service/object_info"
usercommon "github.com/answerdev/answer/internal/service/user_common"
"github.com/answerdev/answer/pkg/uid"
"github.com/goccy/go-json"
"github.com/jinzhu/copier"
"github.com/segmentfault/pacman/errors"
@ -81,12 +82,13 @@ func (ns *NotificationCommon) HandleNotification() {
// ObjectInfo.ObjectID
// ObjectInfo.ObjectType
func (ns *NotificationCommon) AddNotification(ctx context.Context, msg *schema.NotificationMsg) error {
req := &schema.NotificationContent{
TriggerUserID: msg.TriggerUserID,
ReceiverUserID: msg.ReceiverUserID,
ObjectInfo: schema.ObjectInfo{
Title: msg.Title,
ObjectID: msg.ObjectID,
ObjectID: uid.DeShortID(msg.ObjectID),
ObjectType: msg.ObjectType,
},
NotificationAction: msg.NotificationAction,
@ -100,8 +102,8 @@ func (ns *NotificationCommon) AddNotification(ctx context.Context, msg *schema.N
req.ObjectInfo.Title = objInfo.Title
questionID = objInfo.QuestionID
objectMap := make(map[string]string)
objectMap["question"] = objInfo.QuestionID
objectMap["answer"] = objInfo.AnswerID
objectMap["question"] = uid.DeShortID(objInfo.QuestionID)
objectMap["answer"] = uid.DeShortID(objInfo.AnswerID)
objectMap["comment"] = objInfo.CommentID
req.ObjectInfo.ObjectMap = objectMap
}

View File

@ -6,6 +6,7 @@ import (
"github.com/answerdev/answer/internal/base/reason"
"github.com/answerdev/answer/internal/service/revision"
usercommon "github.com/answerdev/answer/internal/service/user_common"
"github.com/answerdev/answer/pkg/uid"
"github.com/segmentfault/pacman/errors"
"github.com/segmentfault/pacman/log"
@ -20,7 +21,9 @@ type RevisionService struct {
userRepo usercommon.UserRepo
}
func NewRevisionService(revisionRepo revision.RevisionRepo, userRepo usercommon.UserRepo) *RevisionService {
func NewRevisionService(revisionRepo revision.RevisionRepo,
userRepo usercommon.UserRepo,
) *RevisionService {
return &RevisionService{
revisionRepo: revisionRepo,
userRepo: userRepo,
@ -42,6 +45,7 @@ func (rs *RevisionService) GetUnreviewedRevisionCount(ctx context.Context, req *
// 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) (
revisionID string, err error) {
req.ObjectID = uid.DeShortID(req.ObjectID)
rev := &entity.Revision{}
_ = copier.Copy(rev, req)
err = rs.revisionRepo.AddRevision(ctx, rev, autoUpdateRevisionID)
@ -67,6 +71,7 @@ func (rs *RevisionService) GetRevision(ctx context.Context, revisionID string) (
// ExistUnreviewedByObjectID
func (rs *RevisionService) ExistUnreviewedByObjectID(ctx context.Context, objectID string) (revision *entity.Revision, exist bool, err error) {
objectID = uid.DeShortID(objectID)
revision, exist, err = rs.revisionRepo.ExistUnreviewedByObjectID(ctx, objectID)
return revision, exist, err
}

102
pkg/uid/sid.go Normal file
View File

@ -0,0 +1,102 @@
package uid
import (
"strconv"
)
const salt = int64(0)
var AlphanumericSet = []rune{
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
}
var AlphanumericIndex map[rune]int
func init() {
AlphanumericIndex = make(map[rune]int, len(AlphanumericSet))
for i, ru := range AlphanumericSet {
AlphanumericIndex[ru] = i
}
}
// NumToString num to string
func NumToShortID(id int64) string {
sid := strconv.FormatInt(id, 10)
if len(sid) < 17 {
return ""
}
sTypeCode := sid[1:4]
sid = sid[4:int32(len(sid))]
id, err := strconv.ParseInt(sid, 10, 64)
if err != nil {
return ""
}
typeCode, err := strconv.ParseInt(sTypeCode, 10, 64)
if err != nil {
return ""
}
id = id + salt
// fmt.Println("[EN1]", typeCode, id)
var code []rune
var tcode []rune
for id > 0 {
idx := id % int64(len(AlphanumericSet))
code = append(code, AlphanumericSet[idx])
id = id / int64(len(AlphanumericSet))
}
for typeCode > 0 {
idx := typeCode % int64(len(AlphanumericSet))
tcode = append(tcode, AlphanumericSet[idx])
typeCode = typeCode / int64(len(AlphanumericSet))
}
// fmt.Println("[EN2]", string(tcode), string(code))
return string(tcode) + string(code)
}
// StringToNum string to num
func ShortIDToNum(code string) int64 {
if len(code) < 2 {
return 0
}
scodeType := code[0:1]
code = code[1:int32(len(code))]
// fmt.Println("[DE1]", scodeType, code)
var id, codeType int64
runes := []rune(code)
codeRunes := []rune(scodeType)
for i := len(runes) - 1; i >= 0; i-- {
ru := runes[i]
idx := AlphanumericIndex[ru]
id = id*int64(len(AlphanumericSet)) + int64(idx)
}
for i := len(codeRunes) - 1; i >= 0; i-- {
ru := codeRunes[i]
idx := AlphanumericIndex[ru]
codeType = codeType*int64(len(AlphanumericSet)) + int64(idx)
}
id = id - salt
// fmt.Println("[DE2]", codeType, id)
return 10000000000000000 + codeType*10000000000000 + id
}
func EnShortID(id string) string {
num, err := strconv.ParseInt(id, 10, 64)
if err != nil {
return ""
}
return NumToShortID(num)
}
func DeShortID(sid string) string {
num, err := strconv.ParseInt(sid, 10, 64)
if err != nil {
return strconv.FormatInt(ShortIDToNum(sid), 10)
}
if num < 10000000000000000 {
return strconv.FormatInt(ShortIDToNum(sid), 10)
}
return sid
}

43
pkg/uid/sid_test.go Normal file
View File

@ -0,0 +1,43 @@
package uid
import (
"fmt"
"strconv"
"testing"
)
func Test_ShortID(t *testing.T) {
nums := []int64{
10030000000000689, 10010000000000676, 10020000000000658, 10020000000000654,
10030000009000689, 10010000009000676, 10020000009000658, 10020000009999999,
10030000090000689, 10010000090000676, 10020000090000658, 10020000099999999,
10030000900000689, 10010000900000676, 10020000900000658, 10020000999999999,
10030009000000689, 10010009000000676, 10020009000000658, 10020009999999999,
10030090000000689, 10010090000000676, 10020090000000658, 10020099999999999,
10030900000000689, 10010900000000676, 10020900000000658, 10020999999999999,
10039000000000689, 10019000000000676, 10029000000000658, 10029999999999999,
10610000000000689, 10610000000000676, 10610000000000658, 10610000000000654,
}
for _, num := range nums {
code := NumToShortID(num)
denum := ShortIDToNum(code)
fmt.Println(num, code, denum)
}
}
func Test_EnDeShortID(t *testing.T) {
nums := []string{"0", "1", "10", "100", "1000", "10000", "100000", "1234567", "10000000000000000", "10010000000001316", "10030000000001316", "99999999999999999", "999999999999999999", "1999999999999999999"}
for _, num := range nums {
code := EnShortID(num)
denum := DeShortID(code)
fmt.Println(num, code, denum)
}
}
func Test_Demo(t *testing.T) {
nums := []int64{0, 1, 10, 100, 1000, 10000, 100000, 1000000001316, 9000000001316, 10000000000000000, 10010000000001316, 10030000000001316, 99999999999999999, 999999999999999999, 1999999999999999999}
for _, num := range nums {
code := strconv.FormatInt(num, 36) //10 yo 16
fmt.Println(num, code)
}
}