mirror of https://gitee.com/answerdev/answer.git
add question operation
This commit is contained in:
parent
5361f4e127
commit
b0d2cdc4a0
54
docs/docs.go
54
docs/docs.go
|
@ -3168,6 +3168,45 @@ const docTemplate = `{
|
|||
}
|
||||
}
|
||||
},
|
||||
"/answer/api/v1/question/operation": {
|
||||
"put": {
|
||||
"security": [
|
||||
{
|
||||
"ApiKeyAuth": []
|
||||
}
|
||||
],
|
||||
"description": "Operation question \\n operation [pin unpin hide show]",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"Question"
|
||||
],
|
||||
"summary": "Operation question",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "question",
|
||||
"name": "data",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/schema.OperationQuestionReq"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/handler.RespBody"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/answer/api/v1/question/page": {
|
||||
"get": {
|
||||
"description": "get questions by page",
|
||||
|
@ -6739,6 +6778,21 @@ const docTemplate = `{
|
|||
}
|
||||
}
|
||||
},
|
||||
"schema.OperationQuestionReq": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"id"
|
||||
],
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
"operation": {
|
||||
"description": "operation [pin unpin hide show]",
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"schema.PermissionMemberAction": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
|
|
|
@ -3156,6 +3156,45 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"/answer/api/v1/question/operation": {
|
||||
"put": {
|
||||
"security": [
|
||||
{
|
||||
"ApiKeyAuth": []
|
||||
}
|
||||
],
|
||||
"description": "Operation question \\n operation [pin unpin hide show]",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"Question"
|
||||
],
|
||||
"summary": "Operation question",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "question",
|
||||
"name": "data",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/schema.OperationQuestionReq"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/handler.RespBody"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/answer/api/v1/question/page": {
|
||||
"get": {
|
||||
"description": "get questions by page",
|
||||
|
@ -6727,6 +6766,21 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"schema.OperationQuestionReq": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"id"
|
||||
],
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
"operation": {
|
||||
"description": "operation [pin unpin hide show]",
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"schema.PermissionMemberAction": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
|
|
|
@ -983,6 +983,16 @@ definitions:
|
|||
description: inbox achievement
|
||||
type: string
|
||||
type: object
|
||||
schema.OperationQuestionReq:
|
||||
properties:
|
||||
id:
|
||||
type: string
|
||||
operation:
|
||||
description: operation [pin unpin hide show]
|
||||
type: string
|
||||
required:
|
||||
- id
|
||||
type: object
|
||||
schema.PermissionMemberAction:
|
||||
properties:
|
||||
action:
|
||||
|
@ -3888,6 +3898,30 @@ paths:
|
|||
summary: get question details
|
||||
tags:
|
||||
- Question
|
||||
/answer/api/v1/question/operation:
|
||||
put:
|
||||
consumes:
|
||||
- application/json
|
||||
description: Operation question \n operation [pin unpin hide show]
|
||||
parameters:
|
||||
- description: question
|
||||
in: body
|
||||
name: data
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/schema.OperationQuestionReq'
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/handler.RespBody'
|
||||
security:
|
||||
- ApiKeyAuth: []
|
||||
summary: Operation question
|
||||
tags:
|
||||
- Question
|
||||
/answer/api/v1/question/page:
|
||||
get:
|
||||
consumes:
|
||||
|
|
|
@ -70,6 +70,45 @@ func (qc *QuestionController) RemoveQuestion(ctx *gin.Context) {
|
|||
handler.HandleResponse(ctx, err, nil)
|
||||
}
|
||||
|
||||
// OperationQuestion Operation question
|
||||
// @Summary Operation question
|
||||
// @Description Operation question \n operation [pin unpin hide show]
|
||||
// @Tags Question
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Security ApiKeyAuth
|
||||
// @Param data body schema.OperationQuestionReq true "question"
|
||||
// @Success 200 {object} handler.RespBody
|
||||
// @Router /answer/api/v1/question/operation [put]
|
||||
func (qc *QuestionController) OperationQuestion(ctx *gin.Context) {
|
||||
req := &schema.OperationQuestionReq{}
|
||||
if handler.BindAndCheck(ctx, req) {
|
||||
return
|
||||
}
|
||||
req.ID = uid.DeShortID(req.ID)
|
||||
req.UserID = middleware.GetLoginUserIDFromContext(ctx)
|
||||
canList, err := qc.rankService.CheckOperationPermissions(ctx, req.UserID, []string{
|
||||
permission.QuestionPin,
|
||||
permission.QuestionHide,
|
||||
})
|
||||
if err != nil {
|
||||
handler.HandleResponse(ctx, err, nil)
|
||||
return
|
||||
}
|
||||
req.CanPin = canList[0]
|
||||
req.CanList = canList[1]
|
||||
if (req.Operation == schema.QuestionOperationPin || req.Operation == schema.QuestionOperationUnPin) && !req.CanPin {
|
||||
handler.HandleResponse(ctx, errors.Forbidden(reason.RankFailToMeetTheCondition), nil)
|
||||
return
|
||||
}
|
||||
if (req.Operation == schema.QuestionOperationHide || req.Operation == schema.QuestionOperationShow) && !req.CanList {
|
||||
handler.HandleResponse(ctx, errors.Forbidden(reason.RankFailToMeetTheCondition), nil)
|
||||
return
|
||||
}
|
||||
|
||||
handler.HandleResponse(ctx, nil, nil)
|
||||
}
|
||||
|
||||
// CloseQuestion Close question
|
||||
// @Summary Close question
|
||||
// @Description Close question
|
||||
|
|
|
@ -56,6 +56,7 @@ var migrations = []Migration{
|
|||
NewMigration("add user role", addRoleFeatures, false),
|
||||
NewMigration("add theme and private mode", addThemeAndPrivateMode, true),
|
||||
NewMigration("add new answer notification", addNewAnswerNotification, true),
|
||||
NewMigration("add user pin hide features", addRolePinAndHideFeatures, true),
|
||||
}
|
||||
|
||||
// GetCurrentDBVersion returns the current db version
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
package migrations
|
||||
|
||||
import (
|
||||
"github.com/answerdev/answer/internal/entity"
|
||||
"github.com/answerdev/answer/internal/service/permission"
|
||||
"xorm.io/xorm"
|
||||
)
|
||||
|
||||
func addRolePinAndHideFeatures(x *xorm.Engine) error {
|
||||
|
||||
powers := []*entity.Power{
|
||||
{ID: 34, Name: "question pin", PowerType: permission.QuestionPin, Description: "Top or untop the question"},
|
||||
{ID: 35, Name: "question hide", PowerType: permission.QuestionHide, Description: "hide or show the question"},
|
||||
}
|
||||
// insert default powers
|
||||
for _, power := range powers {
|
||||
exist, err := x.Get(&entity.Power{ID: power.ID})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if exist {
|
||||
_, err = x.ID(power.ID).Update(power)
|
||||
} else {
|
||||
_, err = x.Insert(power)
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
rolePowerRels := []*entity.RolePowerRel{
|
||||
|
||||
{RoleID: 2, PowerType: permission.QuestionPin},
|
||||
{RoleID: 2, PowerType: permission.QuestionHide},
|
||||
|
||||
{RoleID: 3, PowerType: permission.QuestionPin},
|
||||
{RoleID: 3, PowerType: permission.QuestionHide},
|
||||
}
|
||||
|
||||
// insert default powers
|
||||
for _, rel := range rolePowerRels {
|
||||
exist, err := x.Get(&entity.RolePowerRel{RoleID: rel.RoleID, PowerType: rel.PowerType})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if exist {
|
||||
continue
|
||||
}
|
||||
_, err = x.Insert(rel)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
|
@ -190,6 +190,7 @@ func (a *AnswerAPIRouter) RegisterAnswerAPIRouter(r *gin.RouterGroup) {
|
|||
r.PUT("/question", a.questionController.UpdateQuestion)
|
||||
r.DELETE("/question", a.questionController.RemoveQuestion)
|
||||
r.PUT("/question/status", a.questionController.CloseQuestion)
|
||||
r.PUT("/question/operation", a.questionController.OperationQuestion)
|
||||
r.PUT("/question/reopen", a.questionController.ReopenQuestion)
|
||||
r.GET("/question/similar", a.questionController.SearchByTitleLike)
|
||||
|
||||
|
|
|
@ -8,9 +8,13 @@ import (
|
|||
)
|
||||
|
||||
const (
|
||||
SitemapMaxSize = 50000
|
||||
SitemapCachekey = "answer@sitemap"
|
||||
SitemapPageCachekey = "answer@sitemap@page%d"
|
||||
SitemapMaxSize = 50000
|
||||
SitemapCachekey = "answer@sitemap"
|
||||
SitemapPageCachekey = "answer@sitemap@page%d"
|
||||
QuestionOperationPin = "pin"
|
||||
QuestionOperationUnPin = "unpin"
|
||||
QuestionOperationHide = "hide"
|
||||
QuestionOperationShow = "show"
|
||||
)
|
||||
|
||||
// RemoveQuestionReq delete question request
|
||||
|
@ -28,6 +32,14 @@ type CloseQuestionReq struct {
|
|||
UserID string `json:"-"` // user_id
|
||||
}
|
||||
|
||||
type OperationQuestionReq struct {
|
||||
ID string `validate:"required" json:"id"`
|
||||
Operation string `json:"operation"` // operation [pin unpin hide show]
|
||||
UserID string `json:"-"` // user_id
|
||||
CanPin bool `json:"-"`
|
||||
CanList bool `json:"-"`
|
||||
}
|
||||
|
||||
type CloseQuestionMeta struct {
|
||||
CloseType int `json:"close_type"`
|
||||
CloseMsg string `json:"close_msg"`
|
||||
|
|
|
@ -10,6 +10,8 @@ const (
|
|||
QuestionReopen = "question.reopen"
|
||||
QuestionVoteUp = "question.vote_up"
|
||||
QuestionVoteDown = "question.vote_down"
|
||||
QuestionPin = "question.pin" //Top or untop the question
|
||||
QuestionHide = "question.hide" //hide or show the question
|
||||
AnswerAdd = "answer.add"
|
||||
AnswerEdit = "answer.edit"
|
||||
AnswerEditWithoutReview = "answer.edit_without_review"
|
||||
|
|
Loading…
Reference in New Issue