From 6e000bb5f105221fcac914508931f787aff9cfc5 Mon Sep 17 00:00:00 2001 From: aichy126 <16996097+aichy126@users.noreply.github.com> Date: Mon, 5 Dec 2022 17:18:56 +0800 Subject: [PATCH] update seo config --- cmd/answer/wire_gen.go | 2 +- docs/docs.go | 113 ++++++++++++++++++ docs/swagger.json | 113 ++++++++++++++++++ docs/swagger.yaml | 68 +++++++++++ internal/base/constant/constant.go | 2 +- internal/base/server/http.go | 7 +- .../siteinfo_controller.go | 49 ++++++++ internal/router/answer_api_router.go | 2 + internal/router/template_router.go | 7 ++ internal/schema/siteinfo_schema.go | 6 + internal/service/siteinfo/siteinfo_service.go | 30 +++++ 11 files changed, 394 insertions(+), 5 deletions(-) diff --git a/cmd/answer/wire_gen.go b/cmd/answer/wire_gen.go index 016d73eb..0f908a60 100644 --- a/cmd/answer/wire_gen.go +++ b/cmd/answer/wire_gen.go @@ -192,7 +192,7 @@ func initApplication(debug bool, serverConf *conf.Server, dbConf *data.Database, avatarMiddleware := middleware.NewAvatarMiddleware(serviceConf, uploaderService) templateRenderController := templaterender.NewTemplateRenderController(questionService, userService, tagService, answerService, commentService) templateController := controller.NewTemplateController(templateRenderController, siteInfoCommonService) - templateRouter := router.NewTemplateRouter(templateController, templateRenderController) + templateRouter := router.NewTemplateRouter(templateController, templateRenderController, siteInfoController) ginEngine := server.NewHTTPServer(debug, staticRouter, answerAPIRouter, swaggerRouter, uiRouter, authUserMiddleware, avatarMiddleware, templateRouter) application := newApplication(serverConf, ginEngine) return application, func() { diff --git a/docs/docs.go b/docs/docs.go index 389e0df0..a1fe4c82 100644 --- a/docs/docs.go +++ b/docs/docs.go @@ -787,6 +787,77 @@ const docTemplate = `{ } } }, + "/answer/admin/api/siteinfo/seo": { + "get": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "get site seo information", + "produces": [ + "application/json" + ], + "tags": [ + "admin" + ], + "summary": "get site seo information", + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/handler.RespBody" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/schema.SiteSeoResp" + } + } + } + ] + } + } + } + }, + "put": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "update site seo information", + "produces": [ + "application/json" + ], + "tags": [ + "admin" + ], + "summary": "update site seo information", + "parameters": [ + { + "description": "seo", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/schema.SiteSeoReq" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/handler.RespBody" + } + } + } + } + }, "/answer/admin/api/siteinfo/write": { "get": { "security": [ @@ -4337,6 +4408,26 @@ const docTemplate = `{ } } } + }, + "/robots.txt": { + "get": { + "description": "get site robots information", + "produces": [ + "application/json" + ], + "tags": [ + "site" + ], + "summary": "get site robots information", + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "string" + } + } + } + } } }, "definitions": { @@ -6037,6 +6128,28 @@ const docTemplate = `{ } } }, + "schema.SiteSeoReq": { + "type": "object", + "required": [ + "robots" + ], + "properties": { + "robots": { + "type": "string" + } + } + }, + "schema.SiteSeoResp": { + "type": "object", + "required": [ + "robots" + ], + "properties": { + "robots": { + "type": "string" + } + } + }, "schema.SiteWriteReq": { "type": "object", "properties": { diff --git a/docs/swagger.json b/docs/swagger.json index a91beb70..08b798fb 100644 --- a/docs/swagger.json +++ b/docs/swagger.json @@ -775,6 +775,77 @@ } } }, + "/answer/admin/api/siteinfo/seo": { + "get": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "get site seo information", + "produces": [ + "application/json" + ], + "tags": [ + "admin" + ], + "summary": "get site seo information", + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/handler.RespBody" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/schema.SiteSeoResp" + } + } + } + ] + } + } + } + }, + "put": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "update site seo information", + "produces": [ + "application/json" + ], + "tags": [ + "admin" + ], + "summary": "update site seo information", + "parameters": [ + { + "description": "seo", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/schema.SiteSeoReq" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/handler.RespBody" + } + } + } + } + }, "/answer/admin/api/siteinfo/write": { "get": { "security": [ @@ -4325,6 +4396,26 @@ } } } + }, + "/robots.txt": { + "get": { + "description": "get site robots information", + "produces": [ + "application/json" + ], + "tags": [ + "site" + ], + "summary": "get site robots information", + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "string" + } + } + } + } } }, "definitions": { @@ -6025,6 +6116,28 @@ } } }, + "schema.SiteSeoReq": { + "type": "object", + "required": [ + "robots" + ], + "properties": { + "robots": { + "type": "string" + } + } + }, + "schema.SiteSeoResp": { + "type": "object", + "required": [ + "robots" + ], + "properties": { + "robots": { + "type": "string" + } + } + }, "schema.SiteWriteReq": { "type": "object", "properties": { diff --git a/docs/swagger.yaml b/docs/swagger.yaml index 6ec43e18..a03f6364 100644 --- a/docs/swagger.yaml +++ b/docs/swagger.yaml @@ -1223,6 +1223,20 @@ definitions: terms_of_service_parsed_text: type: string type: object + schema.SiteSeoReq: + properties: + robots: + type: string + required: + - robots + type: object + schema.SiteSeoResp: + properties: + robots: + type: string + required: + - robots + type: object schema.SiteWriteReq: properties: recommend_tags: @@ -2071,6 +2085,47 @@ paths: summary: update site legal info tags: - admin + /answer/admin/api/siteinfo/seo: + get: + description: get site seo information + produces: + - application/json + responses: + "200": + description: OK + schema: + allOf: + - $ref: '#/definitions/handler.RespBody' + - properties: + data: + $ref: '#/definitions/schema.SiteSeoResp' + type: object + security: + - ApiKeyAuth: [] + summary: get site seo information + tags: + - admin + put: + description: update site seo information + parameters: + - description: seo + in: body + name: data + required: true + schema: + $ref: '#/definitions/schema.SiteSeoReq' + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/handler.RespBody' + security: + - ApiKeyAuth: [] + summary: update site seo information + tags: + - admin /answer/admin/api/siteinfo/write: get: description: get site interface @@ -4230,6 +4285,19 @@ paths: summary: UserList tags: - api-question + /robots.txt: + get: + description: get site robots information + produces: + - application/json + responses: + "200": + description: OK + schema: + type: string + summary: get site robots information + tags: + - site securityDefinitions: ApiKeyAuth: in: header diff --git a/internal/base/constant/constant.go b/internal/base/constant/constant.go index c36a0f7f..de3850e8 100644 --- a/internal/base/constant/constant.go +++ b/internal/base/constant/constant.go @@ -56,5 +56,5 @@ const ( SiteTypeBranding = "branding" SiteTypeWrite = "write" SiteTypeLegal = "legal" + SiteTypeSeo = "seo" ) - diff --git a/internal/base/server/http.go b/internal/base/server/http.go index 2fdb3c9b..7e724607 100644 --- a/internal/base/server/http.go +++ b/internal/base/server/http.go @@ -1,9 +1,6 @@ package server import ( - "github.com/answerdev/answer/internal/schema" - "github.com/answerdev/answer/pkg/converter" - "github.com/answerdev/answer/pkg/day" "html/template" "io/fs" "math" @@ -12,6 +9,10 @@ import ( "strings" "time" + "github.com/answerdev/answer/internal/schema" + "github.com/answerdev/answer/pkg/converter" + "github.com/answerdev/answer/pkg/day" + brotli "github.com/anargu/gin-brotli" "github.com/answerdev/answer/internal/base/middleware" "github.com/answerdev/answer/internal/base/translator" diff --git a/internal/controller_backyard/siteinfo_controller.go b/internal/controller_backyard/siteinfo_controller.go index 0950c225..a8323504 100644 --- a/internal/controller_backyard/siteinfo_controller.go +++ b/internal/controller_backyard/siteinfo_controller.go @@ -1,6 +1,8 @@ package controller_backyard import ( + "net/http" + "github.com/answerdev/answer/internal/base/handler" "github.com/answerdev/answer/internal/base/middleware" "github.com/answerdev/answer/internal/schema" @@ -85,6 +87,53 @@ func (sc *SiteInfoController) GetSiteLegal(ctx *gin.Context) { handler.HandleResponse(ctx, err, resp) } +// GetSeo get site seo information +// @Summary get site seo information +// @Description get site seo information +// @Security ApiKeyAuth +// @Tags admin +// @Produce json +// @Success 200 {object} handler.RespBody{data=schema.SiteSeoResp} +// @Router /answer/admin/api/siteinfo/seo [get] +func (sc *SiteInfoController) GetSeo(ctx *gin.Context) { + resp, err := sc.siteInfoService.GetSeo(ctx) + handler.HandleResponse(ctx, err, resp) +} + +// GetRobots get site robots information +// @Summary get site robots information +// @Description get site robots information +// @Tags site +// @Produce json +// @Success 200 {string} txt "" +// @Router /robots.txt [get] +func (sc *SiteInfoController) GetRobots(ctx *gin.Context) { + resp, err := sc.siteInfoService.GetSeo(ctx) + if err != nil { + ctx.String(http.StatusOK, "") + return + } + ctx.String(http.StatusOK, resp.Robots) +} + +// UpdateSeo update site seo information +// @Summary update site seo information +// @Description update site seo information +// @Security ApiKeyAuth +// @Tags admin +// @Produce json +// @Param data body schema.SiteSeoReq true "seo" +// @Success 200 {object} handler.RespBody{} +// @Router /answer/admin/api/siteinfo/seo [put] +func (sc *SiteInfoController) UpdateSeo(ctx *gin.Context) { + req := schema.SiteSeoReq{} + if handler.BindAndCheck(ctx, &req) { + return + } + err := sc.siteInfoService.SaveSeo(ctx, req) + handler.HandleResponse(ctx, err, nil) +} + // UpdateGeneral update site general information // @Summary update site general information // @Description update site general information diff --git a/internal/router/answer_api_router.go b/internal/router/answer_api_router.go index 7640dc0f..fbf96d02 100644 --- a/internal/router/answer_api_router.go +++ b/internal/router/answer_api_router.go @@ -231,11 +231,13 @@ func (a *AnswerAPIRouter) RegisterAnswerCmsAPIRouter(r *gin.RouterGroup) { r.GET("/siteinfo/branding", a.siteInfoController.GetSiteBranding) r.GET("/siteinfo/write", a.siteInfoController.GetSiteWrite) r.GET("/siteinfo/legal", a.siteInfoController.GetSiteLegal) + r.GET("/siteinfo/seo", a.siteInfoController.GetSeo) r.PUT("/siteinfo/general", a.siteInfoController.UpdateGeneral) r.PUT("/siteinfo/interface", a.siteInfoController.UpdateInterface) r.PUT("/siteinfo/branding", a.siteInfoController.UpdateBranding) r.PUT("/siteinfo/write", a.siteInfoController.UpdateSiteWrite) r.PUT("/siteinfo/legal", a.siteInfoController.UpdateSiteLegal) + r.PUT("/siteinfo/seo", a.siteInfoController.UpdateSeo) r.GET("/setting/smtp", a.siteInfoController.GetSMTPConfig) r.PUT("/setting/smtp", a.siteInfoController.UpdateSMTPConfig) diff --git a/internal/router/template_router.go b/internal/router/template_router.go index b72a54d4..af108081 100644 --- a/internal/router/template_router.go +++ b/internal/router/template_router.go @@ -3,27 +3,34 @@ package router import ( "github.com/answerdev/answer/internal/controller" templaterender "github.com/answerdev/answer/internal/controller/template_render" + "github.com/answerdev/answer/internal/controller_backyard" "github.com/gin-gonic/gin" ) type TemplateRouter struct { templateController *controller.TemplateController templateRenderController *templaterender.TemplateRenderController + siteInfoController *controller_backyard.SiteInfoController } func NewTemplateRouter( templateController *controller.TemplateController, templateRenderController *templaterender.TemplateRenderController, + siteInfoController *controller_backyard.SiteInfoController, + ) *TemplateRouter { return &TemplateRouter{ templateController: templateController, templateRenderController: templateRenderController, + siteInfoController: siteInfoController, } } // TemplateRouter template router func (a *TemplateRouter) RegisterTemplateRouter(r *gin.RouterGroup) { + r.GET("/robots.txt", a.siteInfoController.GetRobots) + r.GET("/", a.templateController.Index) r.GET("/index", a.templateController.Index) diff --git a/internal/schema/siteinfo_schema.go b/internal/schema/siteinfo_schema.go index b92213f5..9e77a0f4 100644 --- a/internal/schema/siteinfo_schema.go +++ b/internal/schema/siteinfo_schema.go @@ -18,6 +18,10 @@ type SiteGeneralReq struct { PermaLink int `validate:"required,lte=3,gte=0" form:"permalink" json:"permalink"` } +type SiteSeoReq struct { + Robots string `validate:"required" form:"robots" json:"robots"` +} + func (r *SiteGeneralReq) FormatSiteUrl() { parsedUrl, err := url.Parse(r.SiteUrl) if err != nil { @@ -93,6 +97,8 @@ type SiteWriteResp SiteWriteReq // SiteLegalResp site write response type SiteLegalResp SiteLegalReq +type SiteSeoResp SiteSeoReq + // SiteInfoResp get site info response type SiteInfoResp struct { General *SiteGeneralResp `json:"general"` diff --git a/internal/service/siteinfo/siteinfo_service.go b/internal/service/siteinfo/siteinfo_service.go index 256906fe..e9460a4d 100644 --- a/internal/service/siteinfo/siteinfo_service.go +++ b/internal/service/siteinfo/siteinfo_service.go @@ -241,3 +241,33 @@ func (s *SiteInfoService) UpdateSMTPConfig(ctx context.Context, req *schema.Upda } return } + +func (s *SiteInfoService) GetSeo(ctx context.Context) (resp *schema.SiteSeoResp, err error) { + resp = &schema.SiteSeoResp{} + siteInfo, exist, err := s.siteInfoRepo.GetByType(ctx, constant.SiteTypeSeo) + if err != nil { + log.Error(err) + return resp, nil + } + if !exist { + return resp, nil + } + _ = json.Unmarshal([]byte(siteInfo.Content), resp) + return resp, nil +} + +func (s *SiteInfoService) SaveSeo(ctx context.Context, req schema.SiteSeoReq) (err error) { + var ( + siteType = constant.SiteTypeSeo + content []byte + ) + content, _ = json.Marshal(req) + + data := entity.SiteInfo{ + Type: siteType, + Content: string(content), + } + + err = s.siteInfoRepo.SaveByType(ctx, siteType, &data) + return +}