You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@answer.apache.org by ku...@apache.org on 2026/01/20 06:55:03 UTC
(answer) branch feat/1.8.0/menu created (now 29ec29bd)
This is an automated email from the ASF dual-hosted git repository.
kumfo pushed a change to branch feat/1.8.0/menu
in repository https://gitbox.apache.org/repos/asf/answer.git
at 29ec29bd feat(menu): update admin menu settings to include questions, tags, and advanced options
This branch includes the following new commits:
new 29ec29bd feat(menu): update admin menu settings to include questions, tags, and advanced options
The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
(answer) 01/01: feat(menu): update admin menu settings to include questions, tags, and advanced options
Posted by ku...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
kumfo pushed a commit to branch feat/1.8.0/menu
in repository https://gitbox.apache.org/repos/asf/answer.git
commit 29ec29bde770542efe2a0f299f00d7466f4fb8c9
Author: kumfo <ku...@sifou.com>
AuthorDate: Tue Jan 20 14:54:52 2026 +0800
feat(menu): update admin menu settings to include questions, tags, and advanced options
---
cmd/wire_gen.go | 74 ++++-----
go.mod | 2 +-
internal/base/constant/site_type.go | 3 +
internal/controller/answer_controller.go | 2 +-
internal/controller/siteinfo_controller.go | 10 +-
internal/controller_admin/siteinfo_controller.go | 94 +++++++++--
internal/migrations/migrations.go | 1 +
internal/migrations/v30.go | 173 +++++++++++++++++++++
internal/router/answer_api_router.go | 10 +-
internal/schema/siteinfo_schema.go | 41 ++++-
internal/service/mock/siteinfo_repo_mock.go | 81 +++++++---
internal/service/question_common/question.go | 2 +-
internal/service/siteinfo/siteinfo_service.go | 51 ++++--
.../service/siteinfo_common/siteinfo_service.go | 30 ++++
internal/service/tag_common/tag_common.go | 8 +-
internal/service/uploader/upload.go | 32 ++--
16 files changed, 490 insertions(+), 124 deletions(-)
diff --git a/cmd/wire_gen.go b/cmd/wire_gen.go
index 22a70f29..2808619b 100644
--- a/cmd/wire_gen.go
+++ b/cmd/wire_gen.go
@@ -1,28 +1,8 @@
-//go:build !wireinject
-// +build !wireinject
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
// Code generated by Wire. DO NOT EDIT.
-//go:generate go run github.com/google/wire/cmd/wire
+//go:generate go run -mod=mod github.com/google/wire/cmd/wire
+//go:build !wireinject
+// +build !wireinject
package answercmd
@@ -172,29 +152,29 @@ func initApplication(debug bool, serverConf *conf.Server, dbConf *data.Database,
tagRepo := tag.NewTagRepo(dataData, uniqueIDRepo)
revisionRepo := revision.NewRevisionRepo(dataData, uniqueIDRepo)
revisionService := revision_common.NewRevisionService(revisionRepo, userRepo)
- v := activityqueue.NewService()
- tagCommonService := tag_common2.NewTagCommonService(tagCommonRepo, tagRelRepo, tagRepo, revisionService, siteInfoCommonService, v)
+ service := activityqueue.NewService()
+ tagCommonService := tag_common2.NewTagCommonService(tagCommonRepo, tagRelRepo, tagRepo, revisionService, siteInfoCommonService, service)
collectionRepo := collection.NewCollectionRepo(dataData, uniqueIDRepo)
collectionCommon := collectioncommon.NewCollectionCommon(collectionRepo)
answerCommon := answercommon.NewAnswerCommon(answerRepo)
metaRepo := meta.NewMetaRepo(dataData)
metaCommonService := metacommon.NewMetaCommonService(metaRepo)
- questionCommon := questioncommon.NewQuestionCommon(questionRepo, answerRepo, voteRepo, followRepo, tagCommonService, userCommon, collectionCommon, answerCommon, metaCommonService, configService, v, revisionRepo, siteInfoCommonService, dataData)
- v2 := eventqueue.NewService()
+ questionCommon := questioncommon.NewQuestionCommon(questionRepo, answerRepo, voteRepo, followRepo, tagCommonService, userCommon, collectionCommon, answerCommon, metaCommonService, configService, service, revisionRepo, siteInfoCommonService, dataData)
+ eventqueueService := eventqueue.NewService()
fileRecordRepo := file_record.NewFileRecordRepo(dataData)
fileRecordService := file_record2.NewFileRecordService(fileRecordRepo, revisionRepo, serviceConf, siteInfoCommonService, userCommon)
- userService := content.NewUserService(userRepo, userActiveActivityRepo, activityRepo, emailService, authService, siteInfoCommonService, userRoleRelService, userCommon, userExternalLoginService, userNotificationConfigRepo, userNotificationConfigService, questionCommon, v2, fileRecordService)
+ userService := content.NewUserService(userRepo, userActiveActivityRepo, activityRepo, emailService, authService, siteInfoCommonService, userRoleRelService, userCommon, userExternalLoginService, userNotificationConfigRepo, userNotificationConfigService, questionCommon, eventqueueService, fileRecordService)
captchaRepo := captcha.NewCaptchaRepo(dataData)
captchaService := action.NewCaptchaService(captchaRepo)
userController := controller.NewUserController(authService, userService, captchaService, emailService, siteInfoCommonService, userNotificationConfigService)
commentRepo := comment.NewCommentRepo(dataData, uniqueIDRepo)
commentCommonRepo := comment.NewCommentCommonRepo(dataData, uniqueIDRepo)
objService := object_info.NewObjService(answerRepo, questionRepo, commentCommonRepo, tagCommonRepo, tagCommonService)
- v3 := noticequeue.NewService()
- v4 := noticequeue.NewExternalService()
+ noticequeueService := noticequeue.NewService()
+ externalService := noticequeue.NewExternalService()
reviewRepo := review.NewReviewRepo(dataData)
- reviewService := review2.NewReviewService(reviewRepo, objService, userCommon, userRepo, questionRepo, answerRepo, userRoleRelService, v4, tagCommonService, questionCommon, v3, siteInfoCommonService, commentCommonRepo)
- commentService := comment2.NewCommentService(commentRepo, commentCommonRepo, userCommon, objService, voteRepo, emailService, userRepo, v3, v4, v, v2, reviewService)
+ reviewService := review2.NewReviewService(reviewRepo, objService, userCommon, userRepo, questionRepo, answerRepo, userRoleRelService, externalService, tagCommonService, questionCommon, noticequeueService, siteInfoCommonService, commentCommonRepo)
+ commentService := comment2.NewCommentService(commentRepo, commentCommonRepo, userCommon, objService, voteRepo, emailService, userRepo, noticequeueService, externalService, service, eventqueueService, reviewService)
rolePowerRelRepo := role.NewRolePowerRelRepo(dataData)
rolePowerRelService := role2.NewRolePowerRelService(rolePowerRelRepo, userRoleRelService)
rankService := rank2.NewRankService(userCommon, userRankRepo, objService, userRoleRelService, rolePowerRelService, configService)
@@ -202,17 +182,17 @@ func initApplication(debug bool, serverConf *conf.Server, dbConf *data.Database,
rateLimitMiddleware := middleware.NewRateLimitMiddleware(limitRepo)
commentController := controller.NewCommentController(commentService, rankService, captchaService, rateLimitMiddleware)
reportRepo := report.NewReportRepo(dataData, uniqueIDRepo)
- tagService := tag2.NewTagService(tagRepo, tagCommonService, revisionService, followRepo, siteInfoCommonService, v)
- answerActivityRepo := activity.NewAnswerActivityRepo(dataData, activityRepo, userRankRepo, v3)
+ tagService := tag2.NewTagService(tagRepo, tagCommonService, revisionService, followRepo, siteInfoCommonService, service)
+ answerActivityRepo := activity.NewAnswerActivityRepo(dataData, activityRepo, userRankRepo, noticequeueService)
answerActivityService := activity2.NewAnswerActivityService(answerActivityRepo, configService)
- externalNotificationService := notification.NewExternalNotificationService(dataData, userNotificationConfigRepo, followRepo, emailService, userRepo, v4, userExternalLoginRepo, siteInfoCommonService)
- questionService := content.NewQuestionService(activityRepo, questionRepo, answerRepo, tagCommonService, tagService, questionCommon, userCommon, userRepo, userRoleRelService, revisionService, metaCommonService, collectionCommon, answerActivityService, emailService, v3, v4, v, siteInfoCommonService, externalNotificationService, reviewService, configService, v2, reviewRepo)
- answerService := content.NewAnswerService(answerRepo, questionRepo, questionCommon, userCommon, collectionCommon, userRepo, revisionService, answerActivityService, answerCommon, voteRepo, emailService, userRoleRelService, v3, v4, v, reviewService, v2)
+ externalNotificationService := notification.NewExternalNotificationService(dataData, userNotificationConfigRepo, followRepo, emailService, userRepo, externalService, userExternalLoginRepo, siteInfoCommonService)
+ questionService := content.NewQuestionService(activityRepo, questionRepo, answerRepo, tagCommonService, tagService, questionCommon, userCommon, userRepo, userRoleRelService, revisionService, metaCommonService, collectionCommon, answerActivityService, emailService, noticequeueService, externalService, service, siteInfoCommonService, externalNotificationService, reviewService, configService, eventqueueService, reviewRepo)
+ answerService := content.NewAnswerService(answerRepo, questionRepo, questionCommon, userCommon, collectionCommon, userRepo, revisionService, answerActivityService, answerCommon, voteRepo, emailService, userRoleRelService, noticequeueService, externalService, service, reviewService, eventqueueService)
reportHandle := report_handle.NewReportHandle(questionService, answerService, commentService)
- reportService := report2.NewReportService(reportRepo, objService, userCommon, answerRepo, questionRepo, commentCommonRepo, reportHandle, configService, v2)
+ reportService := report2.NewReportService(reportRepo, objService, userCommon, answerRepo, questionRepo, commentCommonRepo, reportHandle, configService, eventqueueService)
reportController := controller.NewReportController(reportService, rankService, captchaService)
- contentVoteRepo := activity.NewVoteRepo(dataData, activityRepo, userRankRepo, v3)
- voteService := content.NewVoteService(contentVoteRepo, configService, questionRepo, answerRepo, commentCommonRepo, objService, v2)
+ contentVoteRepo := activity.NewVoteRepo(dataData, activityRepo, userRankRepo, noticequeueService)
+ voteService := content.NewVoteService(contentVoteRepo, configService, questionRepo, answerRepo, commentCommonRepo, objService, eventqueueService)
voteController := controller.NewVoteController(voteService, rankService, captchaService)
tagController := controller.NewTagController(tagService, tagCommonService, rankService)
followFollowRepo := activity.NewFollowRepo(dataData, uniqueIDRepo, activityRepo)
@@ -228,7 +208,7 @@ func initApplication(debug bool, serverConf *conf.Server, dbConf *data.Database,
searchService := content.NewSearchService(searchParser, searchRepo)
searchController := controller.NewSearchController(searchService, captchaService)
reviewActivityRepo := activity.NewReviewActivityRepo(dataData, activityRepo, userRankRepo, configService)
- contentRevisionService := content.NewRevisionService(revisionRepo, userCommon, questionCommon, answerService, objService, questionRepo, answerRepo, tagRepo, tagCommonService, v3, v, reportRepo, reviewService, reviewActivityRepo)
+ contentRevisionService := content.NewRevisionService(revisionRepo, userCommon, questionCommon, answerService, objService, questionRepo, answerRepo, tagRepo, tagCommonService, noticequeueService, service, reportRepo, reviewService, reviewActivityRepo)
revisionController := controller.NewRevisionController(contentRevisionService, rankService)
rankController := controller.NewRankController(rankService)
userAdminRepo := user.NewUserAdminRepo(dataData, authRepo)
@@ -244,7 +224,7 @@ func initApplication(debug bool, serverConf *conf.Server, dbConf *data.Database,
siteInfoService := siteinfo.NewSiteInfoService(siteInfoRepo, siteInfoCommonService, emailService, tagCommonService, configService, questionCommon, fileRecordService)
siteInfoController := controller_admin.NewSiteInfoController(siteInfoService)
controllerSiteInfoController := controller.NewSiteInfoController(siteInfoCommonService)
- notificationCommon := notificationcommon.NewNotificationCommon(dataData, notificationRepo, userCommon, activityRepo, followRepo, objService, v3, userExternalLoginRepo, siteInfoCommonService)
+ notificationCommon := notificationcommon.NewNotificationCommon(dataData, notificationRepo, userCommon, activityRepo, followRepo, objService, noticequeueService, userExternalLoginRepo, siteInfoCommonService)
badgeRepo := badge.NewBadgeRepo(dataData, uniqueIDRepo)
notificationService := notification.NewNotificationService(dataData, notificationRepo, notificationCommon, revisionService, userRepo, reportRepo, reviewService, badgeRepo)
notificationController := controller.NewNotificationController(notificationService, rankService)
@@ -253,7 +233,7 @@ func initApplication(debug bool, serverConf *conf.Server, dbConf *data.Database,
uploaderService := uploader.NewUploaderService(serviceConf, siteInfoCommonService, fileRecordService)
uploadController := controller.NewUploadController(uploaderService)
activityActivityRepo := activity.NewActivityRepo(dataData, configService)
- activityCommon := activity_common2.NewActivityCommon(activityRepo, v)
+ activityCommon := activity_common2.NewActivityCommon(activityRepo, service)
commentCommonService := comment_common.NewCommentCommonService(commentCommonRepo)
activityService := activity2.NewActivityService(activityActivityRepo, userCommon, activityCommon, tagCommonService, objService, commentCommonService, revisionService, metaCommonService, configService)
activityController := controller.NewActivityController(activityService)
@@ -265,12 +245,12 @@ func initApplication(debug bool, serverConf *conf.Server, dbConf *data.Database,
permissionController := controller.NewPermissionController(rankService)
userPluginController := controller.NewUserPluginController(pluginCommonService)
reviewController := controller.NewReviewController(reviewService, rankService, captchaService)
- metaService := meta2.NewMetaService(metaCommonService, userCommon, answerRepo, questionRepo, v2)
+ metaService := meta2.NewMetaService(metaCommonService, userCommon, answerRepo, questionRepo, eventqueueService)
metaController := controller.NewMetaController(metaService)
badgeGroupRepo := badge_group.NewBadgeGroupRepo(dataData, uniqueIDRepo)
eventRuleRepo := badge.NewEventRuleRepo(dataData)
- badgeAwardService := badge2.NewBadgeAwardService(badgeAwardRepo, badgeRepo, userCommon, objService, v3)
- badgeEventService := badge2.NewBadgeEventService(dataData, v2, badgeRepo, eventRuleRepo, badgeAwardService)
+ badgeAwardService := badge2.NewBadgeAwardService(badgeAwardRepo, badgeRepo, userCommon, objService, noticequeueService)
+ badgeEventService := badge2.NewBadgeEventService(dataData, eventqueueService, badgeRepo, eventRuleRepo, badgeAwardService)
badgeService := badge2.NewBadgeService(badgeRepo, badgeGroupRepo, badgeAwardRepo, badgeEventService, siteInfoCommonService)
badgeController := controller.NewBadgeController(badgeService, badgeAwardService)
controller_adminBadgeController := controller_admin.NewBadgeController(badgeService)
@@ -281,7 +261,7 @@ func initApplication(debug bool, serverConf *conf.Server, dbConf *data.Database,
avatarMiddleware := middleware.NewAvatarMiddleware(serviceConf, uploaderService)
shortIDMiddleware := middleware.NewShortIDMiddleware(siteInfoCommonService)
templateRenderController := templaterender.NewTemplateRenderController(questionService, userService, tagService, answerService, commentService, siteInfoCommonService, questionRepo)
- templateController := controller.NewTemplateController(templateRenderController, siteInfoCommonService, v2, userService, questionService)
+ templateController := controller.NewTemplateController(templateRenderController, siteInfoCommonService, eventqueueService, userService, questionService)
templateRouter := router.NewTemplateRouter(templateController, templateRenderController, siteInfoController, authUserMiddleware)
connectorController := controller.NewConnectorController(siteInfoCommonService, emailService, userExternalLoginService)
userCenterLoginService := user_external_login2.NewUserCenterLoginService(userRepo, userCommon, userExternalLoginRepo, userActiveActivityRepo, siteInfoCommonService)
diff --git a/go.mod b/go.mod
index 52d64c73..d2430295 100644
--- a/go.mod
+++ b/go.mod
@@ -37,6 +37,7 @@ require (
github.com/grokify/html-strip-tags-go v0.1.0
github.com/jinzhu/copier v0.4.0
github.com/jinzhu/now v1.1.5
+ github.com/joho/godotenv v1.5.1
github.com/lib/pq v1.10.9
github.com/microcosm-cc/bluemonday v1.0.27
github.com/mozillazg/go-pinyin v0.20.0
@@ -117,7 +118,6 @@ require (
github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
- github.com/joho/godotenv v1.5.1 // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/klauspost/cpuid/v2 v2.2.8 // indirect
diff --git a/internal/base/constant/site_type.go b/internal/base/constant/site_type.go
index 65b487c5..6106b190 100644
--- a/internal/base/constant/site_type.go
+++ b/internal/base/constant/site_type.go
@@ -31,4 +31,7 @@ const (
SiteTypeTheme = "theme"
SiteTypePrivileges = "privileges"
SiteTypeUsers = "users"
+ SiteTypeAdvanced = "advanced"
+ SiteTypeQuestions = "questions"
+ SiteTypeTags = "tags"
)
diff --git a/internal/controller/answer_controller.go b/internal/controller/answer_controller.go
index e76b02cc..99c89b77 100644
--- a/internal/controller/answer_controller.go
+++ b/internal/controller/answer_controller.go
@@ -242,7 +242,7 @@ func (ac *AnswerController) AddAnswer(ctx *gin.Context) {
return
}
- write, err := ac.siteInfoCommonService.GetSiteWrite(ctx)
+ write, err := ac.siteInfoCommonService.GetSiteQuestion(ctx)
if err != nil {
handler.HandleResponse(ctx, err, nil)
return
diff --git a/internal/controller/siteinfo_controller.go b/internal/controller/siteinfo_controller.go
index a336fb24..8035275a 100644
--- a/internal/controller/siteinfo_controller.go
+++ b/internal/controller/siteinfo_controller.go
@@ -87,7 +87,15 @@ func (sc *SiteInfoController) GetSiteInfo(ctx *gin.Context) {
if err != nil {
log.Error(err)
}
- resp.Write, err = sc.siteInfoService.GetSiteWrite(ctx)
+ resp.Questions, err = sc.siteInfoService.GetSiteQuestion(ctx)
+ if err != nil {
+ log.Error(err)
+ }
+ resp.Tags, err = sc.siteInfoService.GetSiteTag(ctx)
+ if err != nil {
+ log.Error(err)
+ }
+ resp.Advanced, err = sc.siteInfoService.GetSiteAdvanced(ctx)
if err != nil {
log.Error(err)
}
diff --git a/internal/controller_admin/siteinfo_controller.go b/internal/controller_admin/siteinfo_controller.go
index 8a92daba..bbab9794 100644
--- a/internal/controller_admin/siteinfo_controller.go
+++ b/internal/controller_admin/siteinfo_controller.go
@@ -82,16 +82,42 @@ func (sc *SiteInfoController) GetSiteBranding(ctx *gin.Context) {
handler.HandleResponse(ctx, err, resp)
}
-// GetSiteWrite get site interface
-// @Summary get site interface
-// @Description get site interface
+// GetSiteTag get site tags setting
+// @Summary get site tags setting
+// @Description get site tags setting
+// @Security ApiKeyAuth
+// @Tags admin
+// @Produce json
+// @Success 200 {object} handler.RespBody{data=schema.SiteTagsResp}
+// @Router /answer/admin/api/siteinfo/tag [get]
+func (sc *SiteInfoController) GetSiteTag(ctx *gin.Context) {
+ resp, err := sc.siteInfoService.GetSiteTag(ctx)
+ handler.HandleResponse(ctx, err, resp)
+}
+
+// GetSiteQuestion get site questions setting
+// @Summary get site questions setting
+// @Description get site questions setting
+// @Security ApiKeyAuth
+// @Tags admin
+// @Produce json
+// @Success 200 {object} handler.RespBody{data=schema.SiteQuestionsResp}
+// @Router /answer/admin/api/siteinfo/question [get]
+func (sc *SiteInfoController) GetSiteQuestion(ctx *gin.Context) {
+ resp, err := sc.siteInfoService.GetSiteQuestion(ctx)
+ handler.HandleResponse(ctx, err, resp)
+}
+
+// GetSiteAdvanced get site advanced setting
+// @Summary get site advanced setting
+// @Description get site advanced setting
// @Security ApiKeyAuth
// @Tags admin
// @Produce json
-// @Success 200 {object} handler.RespBody{data=schema.SiteWriteResp}
-// @Router /answer/admin/api/siteinfo/write [get]
-func (sc *SiteInfoController) GetSiteWrite(ctx *gin.Context) {
- resp, err := sc.siteInfoService.GetSiteWrite(ctx)
+// @Success 200 {object} handler.RespBody{data=schema.SiteAdvancedResp}
+// @Router /answer/admin/api/siteinfo/advanced [get]
+func (sc *SiteInfoController) GetSiteAdvanced(ctx *gin.Context) {
+ resp, err := sc.siteInfoService.GetSiteAdvanced(ctx)
handler.HandleResponse(ctx, err, resp)
}
@@ -288,23 +314,61 @@ func (sc *SiteInfoController) UpdateBranding(ctx *gin.Context) {
handler.HandleResponse(ctx, saveErr, nil)
}
-// UpdateSiteWrite update site write info
-// @Summary update site write info
-// @Description update site write info
+// UpdateSiteQuestion update site question settings
+// @Summary update site question settings
+// @Description update site question settings
+// @Security ApiKeyAuth
+// @Tags admin
+// @Produce json
+// @Param data body schema.SiteQuestionsReq true "questions settings"
+// @Success 200 {object} handler.RespBody{}
+// @Router /answer/admin/api/siteinfo/question [put]
+func (sc *SiteInfoController) UpdateSiteQuestion(ctx *gin.Context) {
+ req := &schema.SiteQuestionsReq{}
+ if handler.BindAndCheck(ctx, req) {
+ return
+ }
+
+ resp, err := sc.siteInfoService.SaveSiteQuestions(ctx, req)
+ handler.HandleResponse(ctx, err, resp)
+}
+
+// UpdateSiteTag update site tag settings
+// @Summary update site tag settings
+// @Description update site tag settings
// @Security ApiKeyAuth
// @Tags admin
// @Produce json
-// @Param data body schema.SiteWriteReq true "write info"
+// @Param data body schema.SiteTagsReq true "tags settings"
// @Success 200 {object} handler.RespBody{}
-// @Router /answer/admin/api/siteinfo/write [put]
-func (sc *SiteInfoController) UpdateSiteWrite(ctx *gin.Context) {
- req := &schema.SiteWriteReq{}
+// @Router /answer/admin/api/siteinfo/tag [put]
+func (sc *SiteInfoController) UpdateSiteTag(ctx *gin.Context) {
+ req := &schema.SiteTagsReq{}
if handler.BindAndCheck(ctx, req) {
return
}
req.UserID = middleware.GetLoginUserIDFromContext(ctx)
- resp, err := sc.siteInfoService.SaveSiteWrite(ctx, req)
+ resp, err := sc.siteInfoService.SaveSiteTags(ctx, req)
+ handler.HandleResponse(ctx, err, resp)
+}
+
+// UpdateSiteAdvanced update site advanced info
+// @Summary update site advanced info
+// @Description update site advanced info
+// @Security ApiKeyAuth
+// @Tags admin
+// @Produce json
+// @Param data body schema.SiteAdvancedReq true "advanced settings"
+// @Success 200 {object} handler.RespBody{}
+// @Router /answer/admin/api/siteinfo/advanced [put]
+func (sc *SiteInfoController) UpdateSiteAdvanced(ctx *gin.Context) {
+ req := &schema.SiteAdvancedReq{}
+ if handler.BindAndCheck(ctx, req) {
+ return
+ }
+
+ resp, err := sc.siteInfoService.SaveSiteAdvanced(ctx, req)
handler.HandleResponse(ctx, err, resp)
}
diff --git a/internal/migrations/migrations.go b/internal/migrations/migrations.go
index 9fda8c34..783332df 100644
--- a/internal/migrations/migrations.go
+++ b/internal/migrations/migrations.go
@@ -105,6 +105,7 @@ var migrations = []Migration{
NewMigration("v1.6.0", "move user config to interface", moveUserConfigToInterface, true),
NewMigration("v1.7.0", "add optional tags", addOptionalTags, true),
NewMigration("v1.7.2", "expand avatar column length", expandAvatarColumnLength, false),
+ NewMigration("v1.8.0", "change admin menu", updateAdminMenuSettings, true),
}
func GetMigrations() []Migration {
diff --git a/internal/migrations/v30.go b/internal/migrations/v30.go
new file mode 100644
index 00000000..5d5d5223
--- /dev/null
+++ b/internal/migrations/v30.go
@@ -0,0 +1,173 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package migrations
+
+import (
+ "context"
+ "encoding/json"
+
+ "github.com/apache/answer/internal/base/constant"
+ "github.com/apache/answer/internal/base/reason"
+ "github.com/apache/answer/internal/entity"
+ "github.com/apache/answer/internal/schema"
+ "github.com/segmentfault/pacman/errors"
+ "xorm.io/builder"
+ "xorm.io/xorm"
+)
+
+func updateAdminMenuSettings(ctx context.Context, x *xorm.Engine) (err error) {
+ err = splitWriteMenu(ctx, x)
+ if err != nil {
+ return
+ }
+ return
+}
+
+// splitWriteMenu splits the site write settings into advanced, questions, and tags settings
+func splitWriteMenu(ctx context.Context, x *xorm.Engine) error {
+ var (
+ siteInfo = &entity.SiteInfo{}
+ siteInfoAdvanced = &entity.SiteInfo{}
+ siteInfoQuestions = &entity.SiteInfo{}
+ siteInfoTags = &entity.SiteInfo{}
+ )
+ exist, err := x.Context(ctx).Where(builder.Eq{"type": constant.SiteTypeWrite}).Get(siteInfo)
+ if err != nil {
+ err = errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
+ return err
+ }
+ if !exist {
+ return nil
+ }
+ siteWrite := &schema.SiteWriteResp{}
+ if err := json.Unmarshal([]byte(siteInfo.Content), siteWrite); err != nil {
+ return err
+ }
+ // site advanced settings
+ siteAdvanced := &schema.SiteAdvancedResp{
+ MaxImageSize: siteWrite.MaxImageSize,
+ MaxAttachmentSize: siteWrite.MaxAttachmentSize,
+ MaxImageMegapixel: siteWrite.MaxImageMegapixel,
+ AuthorizedImageExtensions: siteWrite.AuthorizedImageExtensions,
+ AuthorizedAttachmentExtensions: siteWrite.AuthorizedAttachmentExtensions,
+ }
+ // site questions settings
+ siteQuestions := &schema.SiteQuestionsResp{
+ MinimumContent: siteWrite.MinimumContent,
+ RestrictAnswer: siteWrite.RestrictAnswer,
+ }
+ // site tags settings
+ siteTags := &schema.SiteTagsResp{
+ ReservedTags: siteWrite.ReservedTags,
+ RecommendTags: siteWrite.RecommendTags,
+ MinimumTags: siteWrite.MinimumTags,
+ RequiredTag: siteWrite.RequiredTag,
+ }
+
+ // save site settings
+ // save advanced settings
+ existsAdvanced, err := x.Context(ctx).Where(builder.Eq{"type": constant.SiteTypeWrite}).Get(siteInfoAdvanced)
+ if err != nil {
+ return err
+ }
+ advancedContent, err := json.Marshal(siteAdvanced)
+ if err != nil {
+ return err
+ }
+ if existsAdvanced {
+ _, err = x.Context(ctx).ID(siteInfoAdvanced.ID).Update(&entity.SiteInfo{
+ Type: constant.SiteTypeAdvanced,
+ Content: string(advancedContent),
+ Status: 1,
+ })
+ if err != nil {
+ return err
+ }
+ } else {
+ _, err = x.Context(ctx).Insert(&entity.SiteInfo{
+ Type: constant.SiteTypeAdvanced,
+ Content: string(advancedContent),
+ Status: 1,
+ })
+ if err != nil {
+ return err
+ }
+ }
+
+ // save questions settings
+ existsQuestions, err := x.Context(ctx).Where(builder.Eq{"type": constant.SiteTypeQuestions}).Get(siteInfoQuestions)
+ if err != nil {
+ return err
+ }
+ questionsContent, err := json.Marshal(siteQuestions)
+ if err != nil {
+ return err
+ }
+ if existsQuestions {
+ _, err = x.Context(ctx).ID(siteInfoQuestions.ID).Update(&entity.SiteInfo{
+ Type: constant.SiteTypeQuestions,
+ Content: string(questionsContent),
+ Status: 1,
+ })
+ if err != nil {
+ return err
+ }
+ } else {
+ _, err = x.Context(ctx).Insert(&entity.SiteInfo{
+ Type: constant.SiteTypeQuestions,
+ Content: string(questionsContent),
+ Status: 1,
+ })
+ if err != nil {
+ return err
+ }
+ }
+
+ // save tags settings
+ existsTags, err := x.Context(ctx).Where(builder.Eq{"type": constant.SiteTypeTags}).Get(siteInfoTags)
+ if err != nil {
+ return err
+ }
+ tagsContent, err := json.Marshal(siteTags)
+ if err != nil {
+ return err
+ }
+ if existsTags {
+ _, err = x.Context(ctx).ID(siteInfoTags.ID).Update(&entity.SiteInfo{
+ Type: constant.SiteTypeTags,
+ Content: string(tagsContent),
+ Status: 1,
+ })
+ if err != nil {
+ return err
+ }
+ } else {
+ _, err = x.Context(ctx).Insert(&entity.SiteInfo{
+ Type: constant.SiteTypeTags,
+ Content: string(tagsContent),
+ Status: 1,
+ })
+ if err != nil {
+ return err
+ }
+ }
+
+ return nil
+}
diff --git a/internal/router/answer_api_router.go b/internal/router/answer_api_router.go
index 1191492b..d717bc9d 100644
--- a/internal/router/answer_api_router.go
+++ b/internal/router/answer_api_router.go
@@ -347,8 +347,14 @@ func (a *AnswerAPIRouter) RegisterAnswerAdminAPIRouter(r *gin.RouterGroup) {
r.PUT("/siteinfo/interface", a.adminSiteInfoController.UpdateInterface)
r.GET("/siteinfo/branding", a.adminSiteInfoController.GetSiteBranding)
r.PUT("/siteinfo/branding", a.adminSiteInfoController.UpdateBranding)
- r.GET("/siteinfo/write", a.adminSiteInfoController.GetSiteWrite)
- r.PUT("/siteinfo/write", a.adminSiteInfoController.UpdateSiteWrite)
+
+ r.GET("/siteinfo/question", a.adminSiteInfoController.GetSiteQuestion)
+ r.PUT("/siteinfo/question", a.adminSiteInfoController.UpdateSiteQuestion)
+ r.GET("/siteinfo/tag", a.adminSiteInfoController.GetSiteTag)
+ r.PUT("/siteinfo/tag", a.adminSiteInfoController.UpdateSiteTag)
+ r.GET("/siteinfo/advanced", a.adminSiteInfoController.GetSiteAdvanced)
+ r.PUT("/siteinfo/advanced", a.adminSiteInfoController.UpdateSiteAdvanced)
+
r.GET("/siteinfo/legal", a.adminSiteInfoController.GetSiteLegal)
r.PUT("/siteinfo/legal", a.adminSiteInfoController.UpdateSiteLegal)
r.GET("/siteinfo/seo", a.adminSiteInfoController.GetSeo)
diff --git a/internal/schema/siteinfo_schema.go b/internal/schema/siteinfo_schema.go
index 7ab65751..daf49146 100644
--- a/internal/schema/siteinfo_schema.go
+++ b/internal/schema/siteinfo_schema.go
@@ -89,21 +89,47 @@ type SiteWriteReq struct {
UserID string `json:"-"`
}
-func (s *SiteWriteResp) GetMaxImageSize() int64 {
+type SiteWriteResp SiteWriteReq
+
+// SiteQuestionsReq site questions settings request
+type SiteQuestionsReq struct {
+ MinimumContent int `validate:"omitempty,gte=0,lte=65535" json:"min_content"`
+ RestrictAnswer bool `validate:"omitempty" json:"restrict_answer"`
+}
+
+// SiteAdvancedReq site advanced settings request
+type SiteAdvancedReq struct {
+ MaxImageSize int `validate:"omitempty,gt=0" json:"max_image_size"`
+ MaxAttachmentSize int `validate:"omitempty,gt=0" json:"max_attachment_size"`
+ MaxImageMegapixel int `validate:"omitempty,gt=0" json:"max_image_megapixel"`
+ AuthorizedImageExtensions []string `validate:"omitempty" json:"authorized_image_extensions"`
+ AuthorizedAttachmentExtensions []string `validate:"omitempty" json:"authorized_attachment_extensions"`
+}
+
+// SiteTagsReq site tags settings request
+type SiteTagsReq struct {
+ ReservedTags []*SiteWriteTag `validate:"omitempty,dive" json:"reserved_tags"`
+ RecommendTags []*SiteWriteTag `validate:"omitempty,dive" json:"recommend_tags"`
+ MinimumTags int `validate:"omitempty,gte=0,lte=5" json:"min_tags"`
+ RequiredTag bool `validate:"omitempty" json:"required_tag"`
+ UserID string `json:"-"`
+}
+
+func (s *SiteAdvancedResp) GetMaxImageSize() int64 {
if s.MaxImageSize <= 0 {
return constant.DefaultMaxImageSize
}
return int64(s.MaxImageSize) * 1024 * 1024
}
-func (s *SiteWriteResp) GetMaxAttachmentSize() int64 {
+func (s *SiteAdvancedResp) GetMaxAttachmentSize() int64 {
if s.MaxAttachmentSize <= 0 {
return constant.DefaultMaxAttachmentSize
}
return int64(s.MaxAttachmentSize) * 1024 * 1024
}
-func (s *SiteWriteResp) GetMaxImageMegapixel() int {
+func (s *SiteAdvancedResp) GetMaxImageMegapixel() int {
if s.MaxImageMegapixel <= 0 {
return constant.DefaultMaxImageMegapixel
}
@@ -236,8 +262,9 @@ type ThemeOption struct {
Value string `json:"value"`
}
-// SiteWriteResp site write response
-type SiteWriteResp SiteWriteReq
+type SiteQuestionsResp SiteQuestionsReq
+type SiteAdvancedResp SiteAdvancedReq
+type SiteTagsResp SiteTagsReq
// SiteLegalResp site write response
type SiteLegalResp SiteLegalReq
@@ -260,7 +287,9 @@ type SiteInfoResp struct {
CustomCssHtml *SiteCustomCssHTMLResp `json:"custom_css_html"`
SiteSeo *SiteSeoResp `json:"site_seo"`
SiteUsers *SiteUsersResp `json:"site_users"`
- Write *SiteWriteResp `json:"site_write"`
+ Advanced *SiteAdvancedResp `json:"site_advanced"`
+ Questions *SiteQuestionsResp `json:"site_questions"`
+ Tags *SiteTagsResp `json:"site_tags"`
Legal *SiteLegalSimpleResp `json:"site_legal"`
Version string `json:"version"`
Revision string `json:"revision"`
diff --git a/internal/service/mock/siteinfo_repo_mock.go b/internal/service/mock/siteinfo_repo_mock.go
index a98ceb68..5d5429ba 100644
--- a/internal/service/mock/siteinfo_repo_mock.go
+++ b/internal/service/mock/siteinfo_repo_mock.go
@@ -41,7 +41,6 @@ import (
type MockSiteInfoRepo struct {
ctrl *gomock.Controller
recorder *MockSiteInfoRepoMockRecorder
- isgomock struct{}
}
// MockSiteInfoRepoMockRecorder is the mock recorder for MockSiteInfoRepo.
@@ -72,7 +71,7 @@ func (m *MockSiteInfoRepo) GetByType(ctx context.Context, siteType string) (*ent
}
// GetByType indicates an expected call of GetByType.
-func (mr *MockSiteInfoRepoMockRecorder) GetByType(ctx, siteType any) *gomock.Call {
+func (mr *MockSiteInfoRepoMockRecorder) GetByType(ctx, siteType interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetByType", reflect.TypeOf((*MockSiteInfoRepo)(nil).GetByType), ctx, siteType)
}
@@ -87,7 +86,7 @@ func (m *MockSiteInfoRepo) IsBrandingFileUsed(ctx context.Context, filePath stri
}
// IsBrandingFileUsed indicates an expected call of IsBrandingFileUsed.
-func (mr *MockSiteInfoRepoMockRecorder) IsBrandingFileUsed(ctx, filePath any) *gomock.Call {
+func (mr *MockSiteInfoRepoMockRecorder) IsBrandingFileUsed(ctx, filePath interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IsBrandingFileUsed", reflect.TypeOf((*MockSiteInfoRepo)(nil).IsBrandingFileUsed), ctx, filePath)
}
@@ -101,7 +100,7 @@ func (m *MockSiteInfoRepo) SaveByType(ctx context.Context, siteType string, data
}
// SaveByType indicates an expected call of SaveByType.
-func (mr *MockSiteInfoRepoMockRecorder) SaveByType(ctx, siteType, data any) *gomock.Call {
+func (mr *MockSiteInfoRepoMockRecorder) SaveByType(ctx, siteType, data interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SaveByType", reflect.TypeOf((*MockSiteInfoRepo)(nil).SaveByType), ctx, siteType, data)
}
@@ -110,7 +109,6 @@ func (mr *MockSiteInfoRepoMockRecorder) SaveByType(ctx, siteType, data any) *gom
type MockSiteInfoCommonService struct {
ctrl *gomock.Controller
recorder *MockSiteInfoCommonServiceMockRecorder
- isgomock struct{}
}
// MockSiteInfoCommonServiceMockRecorder is the mock recorder for MockSiteInfoCommonService.
@@ -139,7 +137,7 @@ func (m *MockSiteInfoCommonService) FormatAvatar(ctx context.Context, originalAv
}
// FormatAvatar indicates an expected call of FormatAvatar.
-func (mr *MockSiteInfoCommonServiceMockRecorder) FormatAvatar(ctx, originalAvatarData, email, userStatus any) *gomock.Call {
+func (mr *MockSiteInfoCommonServiceMockRecorder) FormatAvatar(ctx, originalAvatarData, email, userStatus interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FormatAvatar", reflect.TypeOf((*MockSiteInfoCommonService)(nil).FormatAvatar), ctx, originalAvatarData, email, userStatus)
}
@@ -153,11 +151,26 @@ func (m *MockSiteInfoCommonService) FormatListAvatar(ctx context.Context, userLi
}
// FormatListAvatar indicates an expected call of FormatListAvatar.
-func (mr *MockSiteInfoCommonServiceMockRecorder) FormatListAvatar(ctx, userList any) *gomock.Call {
+func (mr *MockSiteInfoCommonServiceMockRecorder) FormatListAvatar(ctx, userList interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FormatListAvatar", reflect.TypeOf((*MockSiteInfoCommonService)(nil).FormatListAvatar), ctx, userList)
}
+// GetSiteAdvanced mocks base method.
+func (m *MockSiteInfoCommonService) GetSiteAdvanced(ctx context.Context) (*schema.SiteAdvancedResp, error) {
+ m.ctrl.T.Helper()
+ ret := m.ctrl.Call(m, "GetSiteAdvanced", ctx)
+ ret0, _ := ret[0].(*schema.SiteAdvancedResp)
+ ret1, _ := ret[1].(error)
+ return ret0, ret1
+}
+
+// GetSiteAdvanced indicates an expected call of GetSiteAdvanced.
+func (mr *MockSiteInfoCommonServiceMockRecorder) GetSiteAdvanced(ctx interface{}) *gomock.Call {
+ mr.mock.ctrl.T.Helper()
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSiteAdvanced", reflect.TypeOf((*MockSiteInfoCommonService)(nil).GetSiteAdvanced), ctx)
+}
+
// GetSiteBranding mocks base method.
func (m *MockSiteInfoCommonService) GetSiteBranding(ctx context.Context) (*schema.SiteBrandingResp, error) {
m.ctrl.T.Helper()
@@ -168,7 +181,7 @@ func (m *MockSiteInfoCommonService) GetSiteBranding(ctx context.Context) (*schem
}
// GetSiteBranding indicates an expected call of GetSiteBranding.
-func (mr *MockSiteInfoCommonServiceMockRecorder) GetSiteBranding(ctx any) *gomock.Call {
+func (mr *MockSiteInfoCommonServiceMockRecorder) GetSiteBranding(ctx interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSiteBranding", reflect.TypeOf((*MockSiteInfoCommonService)(nil).GetSiteBranding), ctx)
}
@@ -183,7 +196,7 @@ func (m *MockSiteInfoCommonService) GetSiteCustomCssHTML(ctx context.Context) (*
}
// GetSiteCustomCssHTML indicates an expected call of GetSiteCustomCssHTML.
-func (mr *MockSiteInfoCommonServiceMockRecorder) GetSiteCustomCssHTML(ctx any) *gomock.Call {
+func (mr *MockSiteInfoCommonServiceMockRecorder) GetSiteCustomCssHTML(ctx interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSiteCustomCssHTML", reflect.TypeOf((*MockSiteInfoCommonService)(nil).GetSiteCustomCssHTML), ctx)
}
@@ -198,7 +211,7 @@ func (m *MockSiteInfoCommonService) GetSiteGeneral(ctx context.Context) (*schema
}
// GetSiteGeneral indicates an expected call of GetSiteGeneral.
-func (mr *MockSiteInfoCommonServiceMockRecorder) GetSiteGeneral(ctx any) *gomock.Call {
+func (mr *MockSiteInfoCommonServiceMockRecorder) GetSiteGeneral(ctx interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSiteGeneral", reflect.TypeOf((*MockSiteInfoCommonService)(nil).GetSiteGeneral), ctx)
}
@@ -212,7 +225,7 @@ func (m *MockSiteInfoCommonService) GetSiteInfoByType(ctx context.Context, siteT
}
// GetSiteInfoByType indicates an expected call of GetSiteInfoByType.
-func (mr *MockSiteInfoCommonServiceMockRecorder) GetSiteInfoByType(ctx, siteType, resp any) *gomock.Call {
+func (mr *MockSiteInfoCommonServiceMockRecorder) GetSiteInfoByType(ctx, siteType, resp interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSiteInfoByType", reflect.TypeOf((*MockSiteInfoCommonService)(nil).GetSiteInfoByType), ctx, siteType, resp)
}
@@ -227,7 +240,7 @@ func (m *MockSiteInfoCommonService) GetSiteInterface(ctx context.Context) (*sche
}
// GetSiteInterface indicates an expected call of GetSiteInterface.
-func (mr *MockSiteInfoCommonServiceMockRecorder) GetSiteInterface(ctx any) *gomock.Call {
+func (mr *MockSiteInfoCommonServiceMockRecorder) GetSiteInterface(ctx interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSiteInterface", reflect.TypeOf((*MockSiteInfoCommonService)(nil).GetSiteInterface), ctx)
}
@@ -242,7 +255,7 @@ func (m *MockSiteInfoCommonService) GetSiteLegal(ctx context.Context) (*schema.S
}
// GetSiteLegal indicates an expected call of GetSiteLegal.
-func (mr *MockSiteInfoCommonServiceMockRecorder) GetSiteLegal(ctx any) *gomock.Call {
+func (mr *MockSiteInfoCommonServiceMockRecorder) GetSiteLegal(ctx interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSiteLegal", reflect.TypeOf((*MockSiteInfoCommonService)(nil).GetSiteLegal), ctx)
}
@@ -257,11 +270,26 @@ func (m *MockSiteInfoCommonService) GetSiteLogin(ctx context.Context) (*schema.S
}
// GetSiteLogin indicates an expected call of GetSiteLogin.
-func (mr *MockSiteInfoCommonServiceMockRecorder) GetSiteLogin(ctx any) *gomock.Call {
+func (mr *MockSiteInfoCommonServiceMockRecorder) GetSiteLogin(ctx interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSiteLogin", reflect.TypeOf((*MockSiteInfoCommonService)(nil).GetSiteLogin), ctx)
}
+// GetSiteQuestion mocks base method.
+func (m *MockSiteInfoCommonService) GetSiteQuestion(ctx context.Context) (*schema.SiteQuestionsResp, error) {
+ m.ctrl.T.Helper()
+ ret := m.ctrl.Call(m, "GetSiteQuestion", ctx)
+ ret0, _ := ret[0].(*schema.SiteQuestionsResp)
+ ret1, _ := ret[1].(error)
+ return ret0, ret1
+}
+
+// GetSiteQuestion indicates an expected call of GetSiteQuestion.
+func (mr *MockSiteInfoCommonServiceMockRecorder) GetSiteQuestion(ctx interface{}) *gomock.Call {
+ mr.mock.ctrl.T.Helper()
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSiteQuestion", reflect.TypeOf((*MockSiteInfoCommonService)(nil).GetSiteQuestion), ctx)
+}
+
// GetSiteSeo mocks base method.
func (m *MockSiteInfoCommonService) GetSiteSeo(ctx context.Context) (*schema.SiteSeoResp, error) {
m.ctrl.T.Helper()
@@ -272,11 +300,26 @@ func (m *MockSiteInfoCommonService) GetSiteSeo(ctx context.Context) (*schema.Sit
}
// GetSiteSeo indicates an expected call of GetSiteSeo.
-func (mr *MockSiteInfoCommonServiceMockRecorder) GetSiteSeo(ctx any) *gomock.Call {
+func (mr *MockSiteInfoCommonServiceMockRecorder) GetSiteSeo(ctx interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSiteSeo", reflect.TypeOf((*MockSiteInfoCommonService)(nil).GetSiteSeo), ctx)
}
+// GetSiteTag mocks base method.
+func (m *MockSiteInfoCommonService) GetSiteTag(ctx context.Context) (*schema.SiteTagsResp, error) {
+ m.ctrl.T.Helper()
+ ret := m.ctrl.Call(m, "GetSiteTag", ctx)
+ ret0, _ := ret[0].(*schema.SiteTagsResp)
+ ret1, _ := ret[1].(error)
+ return ret0, ret1
+}
+
+// GetSiteTag indicates an expected call of GetSiteTag.
+func (mr *MockSiteInfoCommonServiceMockRecorder) GetSiteTag(ctx interface{}) *gomock.Call {
+ mr.mock.ctrl.T.Helper()
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSiteTag", reflect.TypeOf((*MockSiteInfoCommonService)(nil).GetSiteTag), ctx)
+}
+
// GetSiteTheme mocks base method.
func (m *MockSiteInfoCommonService) GetSiteTheme(ctx context.Context) (*schema.SiteThemeResp, error) {
m.ctrl.T.Helper()
@@ -287,7 +330,7 @@ func (m *MockSiteInfoCommonService) GetSiteTheme(ctx context.Context) (*schema.S
}
// GetSiteTheme indicates an expected call of GetSiteTheme.
-func (mr *MockSiteInfoCommonServiceMockRecorder) GetSiteTheme(ctx any) *gomock.Call {
+func (mr *MockSiteInfoCommonServiceMockRecorder) GetSiteTheme(ctx interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSiteTheme", reflect.TypeOf((*MockSiteInfoCommonService)(nil).GetSiteTheme), ctx)
}
@@ -302,7 +345,7 @@ func (m *MockSiteInfoCommonService) GetSiteUsers(ctx context.Context) (*schema.S
}
// GetSiteUsers indicates an expected call of GetSiteUsers.
-func (mr *MockSiteInfoCommonServiceMockRecorder) GetSiteUsers(ctx any) *gomock.Call {
+func (mr *MockSiteInfoCommonServiceMockRecorder) GetSiteUsers(ctx interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSiteUsers", reflect.TypeOf((*MockSiteInfoCommonService)(nil).GetSiteUsers), ctx)
}
@@ -317,7 +360,7 @@ func (m *MockSiteInfoCommonService) GetSiteWrite(ctx context.Context) (*schema.S
}
// GetSiteWrite indicates an expected call of GetSiteWrite.
-func (mr *MockSiteInfoCommonServiceMockRecorder) GetSiteWrite(ctx any) *gomock.Call {
+func (mr *MockSiteInfoCommonServiceMockRecorder) GetSiteWrite(ctx interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSiteWrite", reflect.TypeOf((*MockSiteInfoCommonService)(nil).GetSiteWrite), ctx)
}
@@ -331,7 +374,7 @@ func (m *MockSiteInfoCommonService) IsBrandingFileUsed(ctx context.Context, file
}
// IsBrandingFileUsed indicates an expected call of IsBrandingFileUsed.
-func (mr *MockSiteInfoCommonServiceMockRecorder) IsBrandingFileUsed(ctx, filePath any) *gomock.Call {
+func (mr *MockSiteInfoCommonServiceMockRecorder) IsBrandingFileUsed(ctx, filePath interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IsBrandingFileUsed", reflect.TypeOf((*MockSiteInfoCommonService)(nil).IsBrandingFileUsed), ctx, filePath)
}
diff --git a/internal/service/question_common/question.go b/internal/service/question_common/question.go
index 557a5db1..3a730634 100644
--- a/internal/service/question_common/question.go
+++ b/internal/service/question_common/question.go
@@ -900,7 +900,7 @@ func (qs *QuestionCommon) tryToGetQuestionIDFromMsg(ctx context.Context, closeMs
}
func (qs *QuestionCommon) GetMinimumContentLength(ctx context.Context) (int, error) {
- siteInfo, err := qs.siteInfoService.GetSiteWrite(ctx)
+ siteInfo, err := qs.siteInfoService.GetSiteQuestion(ctx)
if err != nil {
return 6, err
}
diff --git a/internal/service/siteinfo/siteinfo_service.go b/internal/service/siteinfo/siteinfo_service.go
index f355d09f..b633ed42 100644
--- a/internal/service/siteinfo/siteinfo_service.go
+++ b/internal/service/siteinfo/siteinfo_service.go
@@ -103,17 +103,14 @@ func (s *SiteInfoService) GetSiteUsers(ctx context.Context) (resp *schema.SiteUs
return s.siteInfoCommonService.GetSiteUsers(ctx)
}
-// GetSiteWrite get site info write
-func (s *SiteInfoService) GetSiteWrite(ctx context.Context) (resp *schema.SiteWriteResp, err error) {
- resp = &schema.SiteWriteResp{}
- siteInfo, exist, err := s.siteInfoRepo.GetByType(ctx, constant.SiteTypeWrite)
+// GetSiteTag get site info write
+func (s *SiteInfoService) GetSiteTag(ctx context.Context) (resp *schema.SiteTagsResp, err error) {
+ resp = &schema.SiteTagsResp{}
+ _, err = s.siteInfoCommonService.GetSiteTag(ctx)
if err != nil {
log.Error(err)
return resp, nil
}
- if exist {
- _ = json.Unmarshal([]byte(siteInfo.Content), resp)
- }
resp.RecommendTags, err = s.tagCommonService.GetSiteWriteRecommendTag(ctx)
if err != nil {
@@ -126,6 +123,16 @@ func (s *SiteInfoService) GetSiteWrite(ctx context.Context) (resp *schema.SiteWr
return resp, nil
}
+// GetSiteQuestion get site questions settings
+func (s *SiteInfoService) GetSiteQuestion(ctx context.Context) (resp *schema.SiteQuestionsResp, err error) {
+ return s.siteInfoCommonService.GetSiteQuestion(ctx)
+}
+
+// GetSiteAdvanced get site advanced settings
+func (s *SiteInfoService) GetSiteAdvanced(ctx context.Context) (resp *schema.SiteAdvancedResp, err error) {
+ return s.siteInfoCommonService.GetSiteAdvanced(ctx)
+}
+
// GetSiteLegal get site legal info
func (s *SiteInfoService) GetSiteLegal(ctx context.Context) (resp *schema.SiteLegalResp, err error) {
return s.siteInfoCommonService.GetSiteLegal(ctx)
@@ -182,8 +189,30 @@ func (s *SiteInfoService) SaveSiteBranding(ctx context.Context, req *schema.Site
return s.siteInfoRepo.SaveByType(ctx, constant.SiteTypeBranding, data)
}
-// SaveSiteWrite save site configuration about write
-func (s *SiteInfoService) SaveSiteWrite(ctx context.Context, req *schema.SiteWriteReq) (resp any, err error) {
+// SaveSiteAdvanced save site advanced configuration
+func (s *SiteInfoService) SaveSiteAdvanced(ctx context.Context, req *schema.SiteAdvancedReq) (resp any, err error) {
+ content, _ := json.Marshal(req)
+ data := &entity.SiteInfo{
+ Type: constant.SiteTypeAdvanced,
+ Content: string(content),
+ Status: 1,
+ }
+ return nil, s.siteInfoRepo.SaveByType(ctx, constant.SiteTypeAdvanced, data)
+}
+
+// SaveSiteQuestions save site questions configuration
+func (s *SiteInfoService) SaveSiteQuestions(ctx context.Context, req *schema.SiteQuestionsReq) (resp any, err error) {
+ content, _ := json.Marshal(req)
+ data := &entity.SiteInfo{
+ Type: constant.SiteTypeQuestions,
+ Content: string(content),
+ Status: 1,
+ }
+ return nil, s.siteInfoRepo.SaveByType(ctx, constant.SiteTypeQuestions, data)
+}
+
+// SaveSiteTags save site tags configuration
+func (s *SiteInfoService) SaveSiteTags(ctx context.Context, req *schema.SiteTagsReq) (resp any, err error) {
recommendTags, reservedTags := make([]string, 0), make([]string, 0)
recommendTagMapping, reservedTagMapping := make(map[string]bool), make(map[string]bool)
for _, tag := range req.ReservedTags {
@@ -210,11 +239,11 @@ func (s *SiteInfoService) SaveSiteWrite(ctx context.Context, req *schema.SiteWri
content, _ := json.Marshal(req)
data := &entity.SiteInfo{
- Type: constant.SiteTypeWrite,
+ Type: constant.SiteTypeTags,
Content: string(content),
Status: 1,
}
- return nil, s.siteInfoRepo.SaveByType(ctx, constant.SiteTypeWrite, data)
+ return nil, s.siteInfoRepo.SaveByType(ctx, constant.SiteTypeTags, data)
}
// SaveSiteLegal save site legal configuration
diff --git a/internal/service/siteinfo_common/siteinfo_service.go b/internal/service/siteinfo_common/siteinfo_service.go
index fda11722..87bc7ee1 100644
--- a/internal/service/siteinfo_common/siteinfo_service.go
+++ b/internal/service/siteinfo_common/siteinfo_service.go
@@ -51,6 +51,9 @@ type SiteInfoCommonService interface {
FormatAvatar(ctx context.Context, originalAvatarData, email string, userStatus int) *schema.AvatarInfo
FormatListAvatar(ctx context.Context, userList []*entity.User) (userID2AvatarMapping map[string]*schema.AvatarInfo)
GetSiteWrite(ctx context.Context) (resp *schema.SiteWriteResp, err error)
+ GetSiteAdvanced(ctx context.Context) (resp *schema.SiteAdvancedResp, err error)
+ GetSiteQuestion(ctx context.Context) (resp *schema.SiteQuestionsResp, err error)
+ GetSiteTag(ctx context.Context) (resp *schema.SiteTagsResp, err error)
GetSiteLegal(ctx context.Context) (resp *schema.SiteLegalResp, err error)
GetSiteLogin(ctx context.Context) (resp *schema.SiteLoginResp, err error)
GetSiteCustomCssHTML(ctx context.Context) (resp *schema.SiteCustomCssHTMLResp, err error)
@@ -167,6 +170,33 @@ func (s *siteInfoCommonService) GetSiteWrite(ctx context.Context) (resp *schema.
return resp, nil
}
+// GetSiteAdvanced get site info advanced
+func (s *siteInfoCommonService) GetSiteAdvanced(ctx context.Context) (resp *schema.SiteAdvancedResp, err error) {
+ resp = &schema.SiteAdvancedResp{}
+ if err = s.GetSiteInfoByType(ctx, constant.SiteTypeAdvanced, resp); err != nil {
+ return nil, err
+ }
+ return resp, nil
+}
+
+// GetSiteQuestion get site info question
+func (s *siteInfoCommonService) GetSiteQuestion(ctx context.Context) (resp *schema.SiteQuestionsResp, err error) {
+ resp = &schema.SiteQuestionsResp{}
+ if err = s.GetSiteInfoByType(ctx, constant.SiteTypeQuestions, resp); err != nil {
+ return nil, err
+ }
+ return resp, nil
+}
+
+// GetSiteTag get site info tag
+func (s *siteInfoCommonService) GetSiteTag(ctx context.Context) (resp *schema.SiteTagsResp, err error) {
+ resp = &schema.SiteTagsResp{}
+ if err = s.GetSiteInfoByType(ctx, constant.SiteTypeTags, resp); err != nil {
+ return nil, err
+ }
+ return resp, nil
+}
+
// GetSiteLegal get site info write
func (s *siteInfoCommonService) GetSiteLegal(ctx context.Context) (resp *schema.SiteLegalResp, err error) {
resp = &schema.SiteLegalResp{}
diff --git a/internal/service/tag_common/tag_common.go b/internal/service/tag_common/tag_common.go
index 9ca8e100..0da9f6fd 100644
--- a/internal/service/tag_common/tag_common.go
+++ b/internal/service/tag_common/tag_common.go
@@ -270,7 +270,7 @@ func (ts *TagCommonService) GetTagListByNames(ctx context.Context, tagNames []st
}
func (ts *TagCommonService) ExistRecommend(ctx context.Context, tags []*schema.TagItem) (bool, error) {
- taginfo, err := ts.siteInfoService.GetSiteWrite(ctx)
+ taginfo, err := ts.siteInfoService.GetSiteTag(ctx)
if err != nil {
return false, err
}
@@ -295,7 +295,7 @@ func (ts *TagCommonService) ExistRecommend(ctx context.Context, tags []*schema.T
}
func (ts *TagCommonService) GetMinimumTags(ctx context.Context) (int, error) {
- siteInfo, err := ts.siteInfoService.GetSiteWrite(ctx)
+ siteInfo, err := ts.siteInfoService.GetSiteTag(ctx)
if err != nil {
return 1, err
}
@@ -469,7 +469,7 @@ func (ts *TagCommonService) TagsFormatRecommendAndReserved(ctx context.Context,
if len(tagList) == 0 {
return
}
- tagConfig, err := ts.siteInfoService.GetSiteWrite(ctx)
+ tagConfig, err := ts.siteInfoService.GetSiteTag(ctx)
if err != nil {
log.Error(err)
return
@@ -485,7 +485,7 @@ func (ts *TagCommonService) tagFormatRecommendAndReserved(ctx context.Context, t
if tag == nil {
return
}
- tagConfig, err := ts.siteInfoService.GetSiteWrite(ctx)
+ tagConfig, err := ts.siteInfoService.GetSiteTag(ctx)
if err != nil {
log.Error(err)
return
diff --git a/internal/service/uploader/upload.go b/internal/service/uploader/upload.go
index 8dea746c..58f80846 100644
--- a/internal/service/uploader/upload.go
+++ b/internal/service/uploader/upload.go
@@ -109,12 +109,12 @@ func (us *uploaderService) UploadAvatarFile(ctx *gin.Context, userID string) (ur
return url, nil
}
- siteWrite, err := us.siteInfoService.GetSiteWrite(ctx)
+ siteAdvanced, err := us.siteInfoService.GetSiteAdvanced(ctx)
if err != nil {
return "", err
}
- ctx.Request.Body = http.MaxBytesReader(ctx.Writer, ctx.Request.Body, siteWrite.GetMaxImageSize())
+ ctx.Request.Body = http.MaxBytesReader(ctx.Writer, ctx.Request.Body, siteAdvanced.GetMaxImageSize())
file, fileHeader, err := ctx.Request.FormFile("file")
if err != nil {
return "", errors.BadRequest(reason.RequestFormatError).WithError(err)
@@ -201,12 +201,12 @@ func (us *uploaderService) UploadPostFile(ctx *gin.Context, userID string) (
return url, nil
}
- siteWrite, err := us.siteInfoService.GetSiteWrite(ctx)
+ siteAdvanced, err := us.siteInfoService.GetSiteAdvanced(ctx)
if err != nil {
return "", err
}
- ctx.Request.Body = http.MaxBytesReader(ctx.Writer, ctx.Request.Body, siteWrite.GetMaxImageSize())
+ ctx.Request.Body = http.MaxBytesReader(ctx.Writer, ctx.Request.Body, siteAdvanced.GetMaxImageSize())
file, fileHeader, err := ctx.Request.FormFile("file")
if err != nil {
return "", errors.BadRequest(reason.RequestFormatError).WithError(err)
@@ -214,7 +214,7 @@ func (us *uploaderService) UploadPostFile(ctx *gin.Context, userID string) (
defer func() {
_ = file.Close()
}()
- if checker.IsUnAuthorizedExtension(fileHeader.Filename, siteWrite.AuthorizedImageExtensions) {
+ if checker.IsUnAuthorizedExtension(fileHeader.Filename, siteAdvanced.AuthorizedImageExtensions) {
return "", errors.BadRequest(reason.RequestFormatError).WithError(err)
}
@@ -239,7 +239,7 @@ func (us *uploaderService) UploadPostAttachment(ctx *gin.Context, userID string)
return url, nil
}
- resp, err := us.siteInfoService.GetSiteWrite(ctx)
+ resp, err := us.siteInfoService.GetSiteAdvanced(ctx)
if err != nil {
return "", err
}
@@ -277,12 +277,12 @@ func (us *uploaderService) UploadBrandingFile(ctx *gin.Context, userID string) (
return url, nil
}
- siteWrite, err := us.siteInfoService.GetSiteWrite(ctx)
+ siteAdvanced, err := us.siteInfoService.GetSiteAdvanced(ctx)
if err != nil {
return "", err
}
- ctx.Request.Body = http.MaxBytesReader(ctx.Writer, ctx.Request.Body, siteWrite.GetMaxImageSize())
+ ctx.Request.Body = http.MaxBytesReader(ctx.Writer, ctx.Request.Body, siteAdvanced.GetMaxImageSize())
file, fileHeader, err := ctx.Request.FormFile("file")
if err != nil {
return "", errors.BadRequest(reason.RequestFormatError).WithError(err)
@@ -311,7 +311,7 @@ func (us *uploaderService) uploadImageFile(ctx *gin.Context, file *multipart.Fil
if err != nil {
return "", err
}
- siteWrite, err := us.siteInfoService.GetSiteWrite(ctx)
+ siteAdvanced, err := us.siteInfoService.GetSiteAdvanced(ctx)
if err != nil {
return "", err
}
@@ -328,7 +328,7 @@ func (us *uploaderService) uploadImageFile(ctx *gin.Context, file *multipart.Fil
_ = src.Close()
}()
- if !checker.DecodeAndCheckImageFile(filePath, siteWrite.GetMaxImageMegapixel()) {
+ if !checker.DecodeAndCheckImageFile(filePath, siteAdvanced.GetMaxImageMegapixel()) {
return "", errors.BadRequest(reason.UploadFileUnsupportedFileFormat)
}
@@ -364,17 +364,17 @@ func (us *uploaderService) uploadAttachmentFile(ctx *gin.Context, file *multipar
func (us *uploaderService) tryToUploadByPlugin(ctx *gin.Context, source plugin.UploadSource) (
url string, err error) {
- siteWrite, err := us.siteInfoService.GetSiteWrite(ctx)
+ siteAdvanced, err := us.siteInfoService.GetSiteAdvanced(ctx)
if err != nil {
return "", err
}
cond := plugin.UploadFileCondition{
Source: source,
- MaxImageSize: siteWrite.MaxImageSize,
- MaxAttachmentSize: siteWrite.MaxAttachmentSize,
- MaxImageMegapixel: siteWrite.MaxImageMegapixel,
- AuthorizedImageExtensions: siteWrite.AuthorizedImageExtensions,
- AuthorizedAttachmentExtensions: siteWrite.AuthorizedAttachmentExtensions,
+ MaxImageSize: siteAdvanced.MaxImageSize,
+ MaxAttachmentSize: siteAdvanced.MaxAttachmentSize,
+ MaxImageMegapixel: siteAdvanced.MaxImageMegapixel,
+ AuthorizedImageExtensions: siteAdvanced.AuthorizedImageExtensions,
+ AuthorizedAttachmentExtensions: siteAdvanced.AuthorizedAttachmentExtensions,
}
_ = plugin.CallStorage(func(fn plugin.Storage) error {
resp := fn.UploadFile(ctx, cond)