refactor(config): remove all config global variables and cache all config related data

This commit is contained in:
LinkinStars 2023-05-25 20:13:18 +08:00
parent f16207e30f
commit 879c781e35
27 changed files with 421 additions and 327 deletions

View File

@ -51,6 +51,7 @@ import (
"github.com/answerdev/answer/internal/service/collection_common" "github.com/answerdev/answer/internal/service/collection_common"
comment2 "github.com/answerdev/answer/internal/service/comment" comment2 "github.com/answerdev/answer/internal/service/comment"
"github.com/answerdev/answer/internal/service/comment_common" "github.com/answerdev/answer/internal/service/comment_common"
config2 "github.com/answerdev/answer/internal/service/config"
"github.com/answerdev/answer/internal/service/dashboard" "github.com/answerdev/answer/internal/service/dashboard"
export2 "github.com/answerdev/answer/internal/service/export" export2 "github.com/answerdev/answer/internal/service/export"
"github.com/answerdev/answer/internal/service/follow" "github.com/answerdev/answer/internal/service/follow"
@ -108,14 +109,15 @@ func initApplication(debug bool, serverConf *conf.Server, dbConf *data.Database,
langController := controller.NewLangController(i18nTranslator, siteInfoCommonService) langController := controller.NewLangController(i18nTranslator, siteInfoCommonService)
authRepo := auth.NewAuthRepo(dataData) authRepo := auth.NewAuthRepo(dataData)
authService := auth2.NewAuthService(authRepo) authService := auth2.NewAuthService(authRepo)
configRepo := config.NewConfigRepo(dataData) userRepo := user.NewUserRepo(dataData)
userRepo := user.NewUserRepo(dataData, configRepo)
uniqueIDRepo := unique.NewUniqueIDRepo(dataData) uniqueIDRepo := unique.NewUniqueIDRepo(dataData)
activityRepo := activity_common.NewActivityRepo(dataData, uniqueIDRepo, configRepo) configRepo := config.NewConfigRepo(dataData)
userRankRepo := rank.NewUserRankRepo(dataData, configRepo) configService := config2.NewConfigService(configRepo)
userActiveActivityRepo := activity.NewUserActiveActivityRepo(dataData, activityRepo, userRankRepo, configRepo) activityRepo := activity_common.NewActivityRepo(dataData, uniqueIDRepo, configService)
userRankRepo := rank.NewUserRankRepo(dataData, configService)
userActiveActivityRepo := activity.NewUserActiveActivityRepo(dataData, activityRepo, userRankRepo, configService)
emailRepo := export.NewEmailRepo(dataData) emailRepo := export.NewEmailRepo(dataData)
emailService := export2.NewEmailService(configRepo, emailRepo, siteInfoRepo) emailService := export2.NewEmailService(configService, emailRepo, siteInfoRepo)
userRoleRelRepo := role.NewUserRoleRelRepo(dataData) userRoleRelRepo := role.NewUserRoleRelRepo(dataData)
roleRepo := role.NewRoleRepo(dataData) roleRepo := role.NewRoleRepo(dataData)
roleService := role2.NewRoleService(roleRepo) roleService := role2.NewRoleService(roleRepo)
@ -143,13 +145,13 @@ func initApplication(debug bool, serverConf *conf.Server, dbConf *data.Database,
commentService := comment2.NewCommentService(commentRepo, commentCommonRepo, userCommon, objService, voteRepo, emailService, userRepo) commentService := comment2.NewCommentService(commentRepo, commentCommonRepo, userCommon, objService, voteRepo, emailService, userRepo)
rolePowerRelRepo := role.NewRolePowerRelRepo(dataData) rolePowerRelRepo := role.NewRolePowerRelRepo(dataData)
rolePowerRelService := role2.NewRolePowerRelService(rolePowerRelRepo, userRoleRelService) rolePowerRelService := role2.NewRolePowerRelService(rolePowerRelRepo, userRoleRelService)
rankService := rank2.NewRankService(userCommon, userRankRepo, objService, userRoleRelService, rolePowerRelService, configRepo) rankService := rank2.NewRankService(userCommon, userRankRepo, objService, userRoleRelService, rolePowerRelService, configService)
commentController := controller.NewCommentController(commentService, rankService) commentController := controller.NewCommentController(commentService, rankService)
reportRepo := report.NewReportRepo(dataData, uniqueIDRepo) reportRepo := report.NewReportRepo(dataData, uniqueIDRepo)
reportService := report2.NewReportService(reportRepo, objService) reportService := report2.NewReportService(reportRepo, objService)
reportController := controller.NewReportController(reportService, rankService) reportController := controller.NewReportController(reportService, rankService)
serviceVoteRepo := activity.NewVoteRepo(dataData, uniqueIDRepo, configRepo, activityRepo, userRankRepo, voteRepo) serviceVoteRepo := activity.NewVoteRepo(dataData, uniqueIDRepo, configService, activityRepo, userRankRepo, voteRepo)
voteService := service.NewVoteService(serviceVoteRepo, uniqueIDRepo, configRepo, questionRepo, answerRepo, commentCommonRepo, objService) voteService := service.NewVoteService(serviceVoteRepo, uniqueIDRepo, configService, questionRepo, answerRepo, commentCommonRepo, objService)
voteController := controller.NewVoteController(voteService, rankService) voteController := controller.NewVoteController(voteService, rankService)
followRepo := activity_common.NewFollowRepo(dataData, uniqueIDRepo, activityRepo) followRepo := activity_common.NewFollowRepo(dataData, uniqueIDRepo, activityRepo)
tagService := tag2.NewTagService(tagRepo, tagCommonService, revisionService, followRepo, siteInfoCommonService) tagService := tag2.NewTagService(tagRepo, tagCommonService, revisionService, followRepo, siteInfoCommonService)
@ -163,7 +165,7 @@ func initApplication(debug bool, serverConf *conf.Server, dbConf *data.Database,
answerCommon := answercommon.NewAnswerCommon(answerRepo) answerCommon := answercommon.NewAnswerCommon(answerRepo)
metaRepo := meta.NewMetaRepo(dataData) metaRepo := meta.NewMetaRepo(dataData)
metaService := meta2.NewMetaService(metaRepo) metaService := meta2.NewMetaService(metaRepo)
questionCommon := questioncommon.NewQuestionCommon(questionRepo, answerRepo, voteRepo, followRepo, tagCommonService, userCommon, collectionCommon, answerCommon, metaService, configRepo) questionCommon := questioncommon.NewQuestionCommon(questionRepo, answerRepo, voteRepo, followRepo, tagCommonService, userCommon, collectionCommon, answerCommon, metaService, configService)
collectionService := service.NewCollectionService(collectionRepo, collectionGroupRepo, questionCommon) collectionService := service.NewCollectionService(collectionRepo, collectionGroupRepo, questionCommon)
collectionController := controller.NewCollectionController(collectionService) collectionController := controller.NewCollectionController(collectionService)
answerActivityRepo := activity.NewAnswerActivityRepo(dataData, activityRepo, userRankRepo) answerActivityRepo := activity.NewAnswerActivityRepo(dataData, activityRepo, userRankRepo)
@ -172,7 +174,7 @@ func initApplication(debug bool, serverConf *conf.Server, dbConf *data.Database,
questionService := service.NewQuestionService(questionRepo, tagCommonService, questionCommon, userCommon, userRepo, revisionService, metaService, collectionCommon, answerActivityService, dataData, emailService) questionService := service.NewQuestionService(questionRepo, tagCommonService, questionCommon, userCommon, userRepo, revisionService, metaService, collectionCommon, answerActivityService, dataData, emailService)
answerService := service.NewAnswerService(answerRepo, questionRepo, questionCommon, userCommon, collectionCommon, userRepo, revisionService, answerActivityService, answerCommon, voteRepo, emailService, userRoleRelService) answerService := service.NewAnswerService(answerRepo, questionRepo, questionCommon, userCommon, collectionCommon, userRepo, revisionService, answerActivityService, answerCommon, voteRepo, emailService, userRoleRelService)
questionController := controller.NewQuestionController(questionService, answerService, rankService) questionController := controller.NewQuestionController(questionService, answerService, rankService)
dashboardService := dashboard.NewDashboardService(questionRepo, answerRepo, commentCommonRepo, voteRepo, userRepo, reportRepo, configRepo, siteInfoCommonService, serviceConf, dataData) dashboardService := dashboard.NewDashboardService(questionRepo, answerRepo, commentCommonRepo, voteRepo, userRepo, reportRepo, configService, siteInfoCommonService, serviceConf, dataData)
answerController := controller.NewAnswerController(answerService, rankService, dashboardService) answerController := controller.NewAnswerController(answerService, rankService, dashboardService)
searchParser := search_parser.NewSearchParser(tagCommonService, userCommon) searchParser := search_parser.NewSearchParser(tagCommonService, userCommon)
searchRepo := search_common.NewSearchRepo(dataData, uniqueIDRepo, userCommon) searchRepo := search_common.NewSearchRepo(dataData, uniqueIDRepo, userCommon)
@ -181,17 +183,17 @@ func initApplication(debug bool, serverConf *conf.Server, dbConf *data.Database,
serviceRevisionService := service.NewRevisionService(revisionRepo, userCommon, questionCommon, answerService, objService, questionRepo, answerRepo, tagRepo, tagCommonService) serviceRevisionService := service.NewRevisionService(revisionRepo, userCommon, questionCommon, answerService, objService, questionRepo, answerRepo, tagRepo, tagCommonService)
revisionController := controller.NewRevisionController(serviceRevisionService, rankService) revisionController := controller.NewRevisionController(serviceRevisionService, rankService)
rankController := controller.NewRankController(rankService) rankController := controller.NewRankController(rankService)
reportHandle := report_handle_admin.NewReportHandle(questionCommon, commentRepo, configRepo) reportHandle := report_handle_admin.NewReportHandle(questionCommon, commentRepo, configService)
reportAdminService := report_admin.NewReportAdminService(reportRepo, userCommon, answerRepo, questionRepo, commentCommonRepo, reportHandle, configRepo, objService) reportAdminService := report_admin.NewReportAdminService(reportRepo, userCommon, answerRepo, questionRepo, commentCommonRepo, reportHandle, configService, objService)
controller_adminReportController := controller_admin.NewReportController(reportAdminService) controller_adminReportController := controller_admin.NewReportController(reportAdminService)
userAdminRepo := user.NewUserAdminRepo(dataData, authRepo) userAdminRepo := user.NewUserAdminRepo(dataData, authRepo)
userAdminService := user_admin.NewUserAdminService(userAdminRepo, userRoleRelService, authService, userCommon, userActiveActivityRepo) userAdminService := user_admin.NewUserAdminService(userAdminRepo, userRoleRelService, authService, userCommon, userActiveActivityRepo)
userAdminController := controller_admin.NewUserAdminController(userAdminService) userAdminController := controller_admin.NewUserAdminController(userAdminService)
reasonRepo := reason.NewReasonRepo(configRepo) reasonRepo := reason.NewReasonRepo(configService)
reasonService := reason2.NewReasonService(reasonRepo) reasonService := reason2.NewReasonService(reasonRepo)
reasonController := controller.NewReasonController(reasonService) reasonController := controller.NewReasonController(reasonService)
themeController := controller_admin.NewThemeController() themeController := controller_admin.NewThemeController()
siteInfoService := siteinfo.NewSiteInfoService(siteInfoRepo, siteInfoCommonService, emailService, tagCommonService, configRepo) siteInfoService := siteinfo.NewSiteInfoService(siteInfoRepo, siteInfoCommonService, emailService, tagCommonService, configService)
siteInfoController := controller_admin.NewSiteInfoController(siteInfoService) siteInfoController := controller_admin.NewSiteInfoController(siteInfoService)
siteinfoController := controller.NewSiteinfoController(siteInfoCommonService) siteinfoController := controller.NewSiteinfoController(siteInfoCommonService)
notificationRepo := notification.NewNotificationRepo(dataData) notificationRepo := notification.NewNotificationRepo(dataData)
@ -201,13 +203,13 @@ func initApplication(debug bool, serverConf *conf.Server, dbConf *data.Database,
dashboardController := controller.NewDashboardController(dashboardService) dashboardController := controller.NewDashboardController(dashboardService)
uploadController := controller.NewUploadController(uploaderService) uploadController := controller.NewUploadController(uploaderService)
activityCommon := activity_common2.NewActivityCommon(activityRepo) activityCommon := activity_common2.NewActivityCommon(activityRepo)
activityActivityRepo := activity.NewActivityRepo(dataData) activityActivityRepo := activity.NewActivityRepo(dataData, configService)
commentCommonService := comment_common.NewCommentCommonService(commentCommonRepo) commentCommonService := comment_common.NewCommentCommonService(commentCommonRepo)
activityService := activity2.NewActivityService(activityActivityRepo, userCommon, activityCommon, tagCommonService, objService, commentCommonService, revisionService, metaService) activityService := activity2.NewActivityService(activityActivityRepo, userCommon, activityCommon, tagCommonService, objService, commentCommonService, revisionService, metaService, configService)
activityController := controller.NewActivityController(activityCommon, activityService) activityController := controller.NewActivityController(activityCommon, activityService)
roleController := controller_admin.NewRoleController(roleService) roleController := controller_admin.NewRoleController(roleService)
pluginConfigRepo := plugin_config.NewPluginConfigRepo(dataData) pluginConfigRepo := plugin_config.NewPluginConfigRepo(dataData)
pluginCommonService := plugin_common.NewPluginCommonService(pluginConfigRepo, configRepo) pluginCommonService := plugin_common.NewPluginCommonService(pluginConfigRepo, configService)
pluginController := controller_admin.NewPluginController(pluginCommonService) pluginController := controller_admin.NewPluginController(pluginCommonService)
answerAPIRouter := router.NewAnswerAPIRouter(langController, userController, commentController, reportController, voteController, tagController, followController, collectionController, questionController, answerController, searchController, revisionController, rankController, controller_adminReportController, userAdminController, reasonController, themeController, siteInfoController, siteinfoController, notificationController, dashboardController, uploadController, activityController, roleController, pluginController) answerAPIRouter := router.NewAnswerAPIRouter(langController, userController, commentController, reportController, voteController, tagController, followController, collectionController, questionController, answerController, searchController, revisionController, rankController, controller_adminReportController, userAdminController, reasonController, themeController, siteInfoController, siteinfoController, notificationController, dashboardController, uploadController, activityController, roleController, pluginController)
swaggerRouter := router.NewSwaggerRouter(swaggerConf) swaggerRouter := router.NewSwaggerRouter(swaggerConf)

View File

@ -1,5 +1,7 @@
package constant package constant
const ( const (
PluginStatus = "plugin.status" PluginStatus = "plugin.status"
ConfigID2KEYCacheKeyPrefix = "answer:config:id:"
ConfigKEY2ContentCacheKeyPrefix = "answer:config:key:"
) )

View File

@ -1,5 +1,11 @@
package entity package entity
import (
"encoding/json"
"github.com/answerdev/answer/pkg/converter"
)
// Config config // Config config
type Config struct { type Config struct {
ID int `xorm:"not null pk autoincr INT(11) id"` ID int `xorm:"not null pk autoincr INT(11) id"`
@ -8,6 +14,36 @@ type Config struct {
} }
// TableName config table name // TableName config table name
func (Config) TableName() string { func (c *Config) TableName() string {
return "config" return "config"
} }
func (c *Config) BuildByJSON(data []byte) {
cf := &Config{}
_ = json.Unmarshal(data, cf)
c.ID = cf.ID
c.Key = cf.Key
c.Value = cf.Value
}
func (c *Config) JsonString() string {
data, _ := json.Marshal(c)
return string(data)
}
// GetIntValue get int value
func (c *Config) GetIntValue() int {
return converter.StringToInt(c.Value)
}
// GetArrayStringValue get array string value
func (c *Config) GetArrayStringValue() []string {
var arr []string
_ = json.Unmarshal([]byte(c.Value), &arr)
return arr
}
// GetByteValue get byte value
func (c *Config) GetByteValue() []byte {
return []byte(c.Value)
}

View File

@ -8,22 +8,26 @@ import (
"github.com/answerdev/answer/internal/base/data" "github.com/answerdev/answer/internal/base/data"
"github.com/answerdev/answer/internal/base/reason" "github.com/answerdev/answer/internal/base/reason"
"github.com/answerdev/answer/internal/entity" "github.com/answerdev/answer/internal/entity"
"github.com/answerdev/answer/internal/repo/config"
"github.com/answerdev/answer/internal/service/activity" "github.com/answerdev/answer/internal/service/activity"
"github.com/answerdev/answer/internal/service/config"
"github.com/segmentfault/pacman/errors" "github.com/segmentfault/pacman/errors"
"github.com/segmentfault/pacman/log"
) )
// activityRepo activity repository // activityRepo activity repository
type activityRepo struct { type activityRepo struct {
data *data.Data data *data.Data
configService *config.ConfigService
} }
// NewActivityRepo new repository // NewActivityRepo new repository
func NewActivityRepo( func NewActivityRepo(
data *data.Data, data *data.Data,
configService *config.ConfigService,
) activity.ActivityRepo { ) activity.ActivityRepo {
return &activityRepo{ return &activityRepo{
data: data, data: data,
configService: configService,
} }
} }
@ -33,17 +37,7 @@ func (ar *activityRepo) GetObjectAllActivity(ctx context.Context, objectID strin
session := ar.data.DB.Context(ctx).Desc("created_at") session := ar.data.DB.Context(ctx).Desc("created_at")
if !showVote { if !showVote {
var activityTypeNotShown []int activityTypeNotShown := ar.getAllActivityType(ctx)
for _, obj := range []string{constant.AnswerObjectType, constant.QuestionObjectType, constant.CommentObjectType} {
for _, act := range []string{
constant.ActVotedDown,
constant.ActVotedUp,
constant.ActVoteDown,
constant.ActVoteUp,
} {
activityTypeNotShown = append(activityTypeNotShown, config.Key2IDMapping[fmt.Sprintf("%s.%s", obj, act)])
}
}
session.NotIn("activity_type", activityTypeNotShown) session.NotIn("activity_type", activityTypeNotShown)
} }
err = session.Find(&activityList, &entity.Activity{OriginalObjectID: objectID}) err = session.Find(&activityList, &entity.Activity{OriginalObjectID: objectID})
@ -52,3 +46,23 @@ func (ar *activityRepo) GetObjectAllActivity(ctx context.Context, objectID strin
} }
return activityList, nil return activityList, nil
} }
func (ar *activityRepo) getAllActivityType(ctx context.Context) (activityTypes []int) {
var activityTypeNotShown []int
for _, obj := range []string{constant.AnswerObjectType, constant.QuestionObjectType, constant.CommentObjectType} {
for _, act := range []string{
constant.ActVotedDown,
constant.ActVotedUp,
constant.ActVoteDown,
constant.ActVoteUp,
} {
id, err := ar.configService.GetIDByKey(ctx, fmt.Sprintf("%s.%s", obj, act))
if err != nil {
log.Error(err)
} else {
activityTypeNotShown = append(activityTypeNotShown, id)
}
}
}
return activityTypeNotShown
}

View File

@ -16,10 +16,10 @@ import (
// UserActiveActivityRepo answer accepted // UserActiveActivityRepo answer accepted
type UserActiveActivityRepo struct { type UserActiveActivityRepo struct {
data *data.Data data *data.Data
activityRepo activity_common.ActivityRepo activityRepo activity_common.ActivityRepo
userRankRepo rank.UserRankRepo userRankRepo rank.UserRankRepo
configRepo config.ConfigRepo configService *config.ConfigService
} }
const ( const (
@ -31,37 +31,36 @@ func NewUserActiveActivityRepo(
data *data.Data, data *data.Data,
activityRepo activity_common.ActivityRepo, activityRepo activity_common.ActivityRepo,
userRankRepo rank.UserRankRepo, userRankRepo rank.UserRankRepo,
configRepo config.ConfigRepo, configService *config.ConfigService,
) activity.UserActiveActivityRepo { ) activity.UserActiveActivityRepo {
return &UserActiveActivityRepo{ return &UserActiveActivityRepo{
data: data, data: data,
activityRepo: activityRepo, activityRepo: activityRepo,
userRankRepo: userRankRepo, userRankRepo: userRankRepo,
configRepo: configRepo, configService: configService,
} }
} }
// UserActive accept other answer // UserActive accept other answer
func (ar *UserActiveActivityRepo) UserActive(ctx context.Context, userID string) (err error) { func (ar *UserActiveActivityRepo) UserActive(ctx context.Context, userID string) (err error) {
cfg, err := ar.configService.GetConfigByKey(ctx, UserActivated)
if err != nil {
return err
}
activityType := cfg.ID
deltaRank := cfg.GetIntValue()
addActivity := &entity.Activity{
UserID: userID,
ObjectID: "0",
OriginalObjectID: "0",
ActivityType: activityType,
Rank: deltaRank,
HasRank: 1,
}
_, err = ar.data.DB.Transaction(func(session *xorm.Session) (result any, err error) { _, err = ar.data.DB.Transaction(func(session *xorm.Session) (result any, err error) {
session = session.Context(ctx) session = session.Context(ctx)
activityType, err := ar.configRepo.GetConfigType(UserActivated)
if err != nil {
return nil, err
}
deltaRank, err := ar.configRepo.GetInt(UserActivated)
if err != nil {
return nil, err
}
addActivity := &entity.Activity{
UserID: userID,
ObjectID: "0",
OriginalObjectID: "0",
ActivityType: activityType,
Rank: deltaRank,
HasRank: 1,
}
_, exists, err := ar.activityRepo.GetActivity(ctx, session, "0", addActivity.UserID, activityType) _, exists, err := ar.activityRepo.GetActivity(ctx, session, "0", addActivity.UserID, activityType)
if err != nil { if err != nil {
return nil, errors.InternalServer(reason.DatabaseError).WithError(err).WithStack() return nil, errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()

View File

@ -30,30 +30,30 @@ import (
// VoteRepo activity repository // VoteRepo activity repository
type VoteRepo struct { type VoteRepo struct {
data *data.Data data *data.Data
uniqueIDRepo unique.UniqueIDRepo uniqueIDRepo unique.UniqueIDRepo
configRepo config.ConfigRepo configService *config.ConfigService
activityRepo activity_common.ActivityRepo activityRepo activity_common.ActivityRepo
userRankRepo rank.UserRankRepo userRankRepo rank.UserRankRepo
voteCommon activity_common.VoteRepo voteCommon activity_common.VoteRepo
} }
// NewVoteRepo new repository // NewVoteRepo new repository
func NewVoteRepo( func NewVoteRepo(
data *data.Data, data *data.Data,
uniqueIDRepo unique.UniqueIDRepo, uniqueIDRepo unique.UniqueIDRepo,
configRepo config.ConfigRepo, configService *config.ConfigService,
activityRepo activity_common.ActivityRepo, activityRepo activity_common.ActivityRepo,
userRankRepo rank.UserRankRepo, userRankRepo rank.UserRankRepo,
voteCommon activity_common.VoteRepo, voteCommon activity_common.VoteRepo,
) service.VoteRepo { ) service.VoteRepo {
return &VoteRepo{ return &VoteRepo{
data: data, data: data,
uniqueIDRepo: uniqueIDRepo, uniqueIDRepo: uniqueIDRepo,
configRepo: configRepo, configService: configService,
activityRepo: activityRepo, activityRepo: activityRepo,
userRankRepo: userRankRepo, userRankRepo: userRankRepo,
voteCommon: voteCommon, voteCommon: voteCommon,
} }
} }

View File

@ -21,34 +21,37 @@ import (
// ActivityRepo activity repository // ActivityRepo activity repository
type ActivityRepo struct { type ActivityRepo struct {
data *data.Data data *data.Data
uniqueIDRepo unique.UniqueIDRepo uniqueIDRepo unique.UniqueIDRepo
configRepo config.ConfigRepo configService *config.ConfigService
} }
// NewActivityRepo new repository // NewActivityRepo new repository
func NewActivityRepo( func NewActivityRepo(
data *data.Data, data *data.Data,
uniqueIDRepo unique.UniqueIDRepo, uniqueIDRepo unique.UniqueIDRepo,
configRepo config.ConfigRepo, configService *config.ConfigService,
) activity_common.ActivityRepo { ) activity_common.ActivityRepo {
return &ActivityRepo{ return &ActivityRepo{
data: data, data: data,
uniqueIDRepo: uniqueIDRepo, uniqueIDRepo: uniqueIDRepo,
configRepo: configRepo, configService: configService,
} }
} }
func (ar *ActivityRepo) GetActivityTypeByObjID(ctx context.Context, objectID string, action string) (activityType, rank, hasRank int, err error) { func (ar *ActivityRepo) GetActivityTypeByObjID(ctx context.Context, objectID string, action string) (
activityType, rank, hasRank int, err error) {
objectKey, err := obj.GetObjectTypeStrByObjectID(objectID) objectKey, err := obj.GetObjectTypeStrByObjectID(objectID)
if err != nil { if err != nil {
return return
} }
confKey := fmt.Sprintf("%s.%s", objectKey, action) confKey := fmt.Sprintf("%s.%s", objectKey, action)
activityType, _ = ar.configRepo.GetConfigType(confKey) cfg, err := ar.configService.GetConfigByKey(ctx, confKey)
if err != nil {
rank, err = ar.configRepo.GetInt(confKey) return
}
rank = cfg.GetIntValue()
hasRank = 0 hasRank = 0
if rank != 0 { if rank != 0 {
hasRank = 1 hasRank = 1
@ -57,20 +60,20 @@ func (ar *ActivityRepo) GetActivityTypeByObjID(ctx context.Context, objectID str
} }
func (ar *ActivityRepo) GetActivityTypeByObjKey(ctx context.Context, objectKey, action string) (activityType int, err error) { func (ar *ActivityRepo) GetActivityTypeByObjKey(ctx context.Context, objectKey, action string) (activityType int, err error) {
confKey := fmt.Sprintf("%s.%s", objectKey, action) configKey := fmt.Sprintf("%s.%s", objectKey, action)
activityType, err = ar.configRepo.GetConfigType(confKey) cfg, err := ar.configService.GetConfigByKey(ctx, configKey)
if err != nil { if err != nil {
err = errors.InternalServer(reason.DatabaseError).WithError(err).WithStack() err = errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
} }
return return cfg.ID, nil
} }
func (ar *ActivityRepo) GetActivityTypeByConfigKey(ctx context.Context, configKey string) (activityType int, err error) { func (ar *ActivityRepo) GetActivityTypeByConfigKey(ctx context.Context, configKey string) (activityType int, err error) {
activityType, err = ar.configRepo.GetConfigType(configKey) cfg, err := ar.configService.GetConfigByKey(ctx, configKey)
if err != nil { if err != nil {
err = errors.InternalServer(reason.DatabaseError).WithError(err).WithStack() err = errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
} }
return return cfg.ID, nil
} }
func (ar *ActivityRepo) GetActivity(ctx context.Context, session *xorm.Session, func (ar *ActivityRepo) GetActivity(ctx context.Context, session *xorm.Session,
@ -134,9 +137,9 @@ func (ar *ActivityRepo) GetUsersWhoHasVoteMost(
actIDs := make([]int, 0) actIDs := make([]int, 0)
for _, act := range activity_type.ActivityTypeList { for _, act := range activity_type.ActivityTypeList {
configType, err := ar.configRepo.GetConfigType(act) cfg, err := ar.configService.GetConfigByKey(ctx, act)
if err == nil { if err == nil {
actIDs = append(actIDs, configType) actIDs = append(actIDs, cfg.ID)
} }
} }

View File

@ -2,29 +2,20 @@ package config
import ( import (
"context" "context"
"encoding/json"
"fmt" "fmt"
"sync"
"github.com/answerdev/answer/internal/service/config"
"github.com/answerdev/answer/pkg/converter"
"github.com/answerdev/answer/internal/base/constant"
"github.com/answerdev/answer/internal/base/data" "github.com/answerdev/answer/internal/base/data"
"github.com/answerdev/answer/internal/base/reason" "github.com/answerdev/answer/internal/base/reason"
"github.com/answerdev/answer/internal/entity" "github.com/answerdev/answer/internal/entity"
"github.com/answerdev/answer/internal/service/config"
"github.com/segmentfault/pacman/errors" "github.com/segmentfault/pacman/errors"
) "github.com/segmentfault/pacman/log"
var (
Key2ValueMapping = make(map[string]interface{})
Key2IDMapping = make(map[string]int)
ID2KeyMapping = make(map[int]string)
) )
// configRepo config repository // configRepo config repository
type configRepo struct { type configRepo struct {
data *data.Data data *data.Data
mu sync.Mutex
} }
// NewConfigRepo new repository // NewConfigRepo new repository
@ -32,110 +23,87 @@ func NewConfigRepo(data *data.Data) config.ConfigRepo {
repo := &configRepo{ repo := &configRepo{
data: data, data: data,
} }
repo.init()
return repo return repo
} }
// init initializes the Key2ValueMapping map data structures func (cr configRepo) GetConfigByID(ctx context.Context, id int) (c *entity.Config, err error) {
func (cr *configRepo) init() { cacheKey := fmt.Sprintf("%s%d", constant.ConfigID2KEYCacheKeyPrefix, id)
cr.mu.Lock() if cacheData, err := cr.data.Cache.GetString(ctx, cacheKey); err == nil && len(cacheData) > 0 {
defer cr.mu.Unlock() c = &entity.Config{}
rows := &[]entity.Config{} c.BuildByJSON([]byte(cacheData))
err := cr.data.DB.Context(context.TODO()).Find(rows) if c.ID > 0 {
if err == nil { return c, nil
for _, row := range *rows {
Key2ValueMapping[row.Key] = row.Value
Key2IDMapping[row.Key] = row.ID
ID2KeyMapping[row.ID] = row.Key
} }
} }
}
// Get Base method for getting the config value c = &entity.Config{}
// Key string exist, err := cr.data.DB.ID(id).Get(c)
func (cr *configRepo) Get(key string) (interface{}, error) {
value, ok := Key2ValueMapping[key]
if ok {
return value, nil
} else {
return value, errors.InternalServer(reason.DatabaseError).WithMsg(fmt.Sprintf("no such config key: %v", key))
}
}
// GetString method for getting the config value to string
// key string
func (cr *configRepo) GetString(key string) (string, error) {
value, err := cr.Get(key)
if err != nil { if err != nil {
return "", err return nil, errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
} }
str, ok := value.(string) if !exist {
if !ok { return nil, errors.BadRequest(reason.ObjectNotFound)
return "", errors.InternalServer(reason.DatabaseError).WithMsg(fmt.Sprintf("config value is wrong type: %v", key))
} }
return str, nil
// update cache
if err := cr.data.Cache.SetString(ctx, cacheKey, c.JsonString(), -1); err != nil {
log.Error(err)
}
return c, nil
} }
// GetInt method for getting the config value to int64 func (cr configRepo) GetConfigByKey(ctx context.Context, key string) (c *entity.Config, err error) {
// key string cacheKey := constant.ConfigKEY2ContentCacheKeyPrefix + key
func (cr *configRepo) GetInt(key string) (int, error) { if cacheData, err := cr.data.Cache.GetString(ctx, cacheKey); err == nil && len(cacheData) > 0 {
value, err := cr.GetString(key) c = &entity.Config{}
if err != nil { c.BuildByJSON([]byte(cacheData))
return 0, err if c.ID > 0 {
return c, nil
}
} }
return converter.StringToInt(value), nil
c = &entity.Config{Key: key}
exist, err := cr.data.DB.Context(ctx).Get(c)
if err != nil {
return nil, errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
}
if !exist {
return nil, errors.BadRequest(reason.ObjectNotFound)
}
// update cache
if err := cr.data.Cache.SetString(ctx, cacheKey, c.JsonString(), -1); err != nil {
log.Error(err)
}
return c, nil
} }
// GetArrayString method for getting the config value to string array func (cr configRepo) UpdateConfig(ctx context.Context, key string, value string) (err error) {
func (cr *configRepo) GetArrayString(key string) ([]string, error) { // check if key exists
arr := &[]string{} cf := &entity.Config{}
value, err := cr.GetString(key) exist, err := cr.data.DB.Context(ctx).Get(cf)
if err != nil { if err != nil {
return nil, err return errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
} }
err = json.Unmarshal([]byte(value), arr) if !exist {
return *arr, err return errors.BadRequest(reason.ObjectNotFound)
}
// GetConfigType method for getting the config type
func (cr *configRepo) GetConfigType(key string) (int, error) {
value, ok := Key2IDMapping[key]
if !ok {
return 0, errors.InternalServer(reason.DatabaseError).WithMsg(fmt.Sprintf("no such config type: %v", key))
}
return value, nil
}
// GetJsonConfigByIDAndSetToObject get config key from config id
func (cr *configRepo) GetJsonConfigByIDAndSetToObject(id int, object any) (err error) {
key, ok := ID2KeyMapping[id]
if !ok {
return errors.InternalServer(reason.DatabaseError).WithMsg(fmt.Sprintf("no such config id: %v", id))
} }
conf, err := cr.Get(key) // update database
_, err = cr.data.DB.Context(ctx).ID(cf.ID).Update(&entity.Config{Value: value})
if err != nil { if err != nil {
return errors.InternalServer(reason.DatabaseError).WithError(err) return errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
} }
str, ok := conf.(string)
if !ok { cacheVal := cf.JsonString()
return errors.InternalServer(reason.DatabaseError).WithMsg(fmt.Sprintf("no such config id: %v", id)) // update cache
if err := cr.data.Cache.SetString(ctx,
constant.ConfigKEY2ContentCacheKeyPrefix+key, cacheVal, -1); err != nil {
log.Error(err)
} }
err = json.Unmarshal([]byte(str), object) if err := cr.data.Cache.SetString(ctx,
if err != nil { fmt.Sprintf("%s%d", constant.ConfigID2KEYCacheKeyPrefix, cf.ID), cacheVal, -1); err != nil {
err = errors.InternalServer(reason.DatabaseError).WithMsg(fmt.Sprintf("no such config id: %v", id)) log.Error(err)
}
return
}
// SetConfig set config
func (cr *configRepo) SetConfig(ctx context.Context, key, value string) (err error) {
id := Key2IDMapping[key]
_, err = cr.data.DB.Context(ctx).ID(id).Update(&entity.Config{Value: value})
if err != nil {
err = errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
} else {
Key2ValueMapping[key] = value
} }
return return
} }

View File

@ -19,15 +19,15 @@ import (
// UserRankRepo user rank repository // UserRankRepo user rank repository
type UserRankRepo struct { type UserRankRepo struct {
data *data.Data data *data.Data
configRepo config.ConfigRepo configService *config.ConfigService
} }
// NewUserRankRepo new repository // NewUserRankRepo new repository
func NewUserRankRepo(data *data.Data, configRepo config.ConfigRepo) rank.UserRankRepo { func NewUserRankRepo(data *data.Data, configService *config.ConfigService) rank.UserRankRepo {
return &UserRankRepo{ return &UserRankRepo{
data: data, data: data,
configRepo: configRepo, configService: configService,
} }
} }
@ -94,14 +94,13 @@ func (ur *UserRankRepo) checkUserTodayRank(ctx context.Context,
session *xorm.Session, userID string, activityType int, session *xorm.Session, userID string, activityType int,
) (isReachStandard bool, err error) { ) (isReachStandard bool, err error) {
// exclude daily rank // exclude daily rank
exclude, _ := ur.configRepo.GetArrayString("daily_rank_limit.exclude") exclude, _ := ur.configService.GetArrayStringValue(ctx, "daily_rank_limit.exclude")
for _, item := range exclude { for _, item := range exclude {
var excludeActivityType int cfg, err := ur.configService.GetConfigByKey(ctx, item)
excludeActivityType, err = ur.configRepo.GetInt(item)
if err != nil { if err != nil {
return false, err return false, err
} }
if activityType == excludeActivityType { if activityType == cfg.ID {
return false, nil return false, nil
} }
} }
@ -121,7 +120,7 @@ func (ur *UserRankRepo) checkUserTodayRank(ctx context.Context,
} }
// max rank // max rank
maxDailyRank, err := ur.configRepo.GetInt("daily_rank_limit") maxDailyRank, err := ur.configService.GetIntValue(ctx, "daily_rank_limit")
if err != nil { if err != nil {
return false, err return false, err
} }

View File

@ -13,12 +13,12 @@ import (
) )
type reasonRepo struct { type reasonRepo struct {
configRepo config.ConfigRepo configService *config.ConfigService
} }
func NewReasonRepo(configRepo config.ConfigRepo) reason_common.ReasonRepo { func NewReasonRepo(configService *config.ConfigService) reason_common.ReasonRepo {
return &reasonRepo{ return &reasonRepo{
configRepo: configRepo, configService: configService,
} }
} }
@ -27,31 +27,25 @@ func (rr *reasonRepo) ListReasons(ctx context.Context, objectType, action string
reasonAction := fmt.Sprintf("%s.%s.reasons", objectType, action) reasonAction := fmt.Sprintf("%s.%s.reasons", objectType, action)
resp = make([]*schema.ReasonItem, 0) resp = make([]*schema.ReasonItem, 0)
reasonKeys, err := rr.configRepo.GetArrayString(reasonAction) reasonKeys, err := rr.configService.GetArrayStringValue(ctx, reasonAction)
if err != nil { if err != nil {
return nil, err return nil, err
} }
for _, reasonKey := range reasonKeys { for _, reasonKey := range reasonKeys {
cfgValue, err := rr.configRepo.GetString(reasonKey) cfg, err := rr.configService.GetConfigByKey(ctx, reasonKey)
if err != nil { if err != nil {
log.Error(err) log.Error(err)
continue continue
} }
reason := &schema.ReasonItem{} reason := &schema.ReasonItem{}
err = json.Unmarshal([]byte(cfgValue), reason) err = json.Unmarshal(cfg.GetByteValue(), reason)
if err != nil { if err != nil {
log.Error(err) log.Error(err)
continue continue
} }
reason.Translate(reasonKey, lang) reason.Translate(reasonKey, lang)
reason.ReasonType = cfg.ID
reason.ReasonType, err = rr.configRepo.GetConfigType(reasonKey)
if err != nil {
log.Error(err)
continue
}
resp = append(resp, reason) resp = append(resp, reason)
} }
return resp, nil return resp, nil

View File

@ -3,19 +3,18 @@ package repo_test
import ( import (
"testing" "testing"
"github.com/answerdev/answer/internal/repo/config"
"github.com/answerdev/answer/internal/schema" "github.com/answerdev/answer/internal/schema"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
func Test_configRepo_Get(t *testing.T) { func Test_configRepo_Get(t *testing.T) {
configRepo := config.NewConfigRepo(testDataSource) configRepo := config_common.NewConfigRepo(testDataSource)
_, err := configRepo.Get("email.config") _, err := configRepo.Get("email.config")
assert.NoError(t, err) assert.NoError(t, err)
} }
func Test_configRepo_GetArrayString(t *testing.T) { func Test_configRepo_GetArrayString(t *testing.T) {
configRepo := config.NewConfigRepo(testDataSource) configRepo := config_common.NewConfigRepo(testDataSource)
got, err := configRepo.GetArrayString("daily_rank_limit.exclude") got, err := configRepo.GetArrayString("daily_rank_limit.exclude")
assert.NoError(t, err) assert.NoError(t, err)
assert.Equal(t, 1, len(got)) assert.Equal(t, 1, len(got))
@ -23,7 +22,7 @@ func Test_configRepo_GetArrayString(t *testing.T) {
} }
func Test_configRepo_GetConfigById(t *testing.T) { func Test_configRepo_GetConfigById(t *testing.T) {
configRepo := config.NewConfigRepo(testDataSource) configRepo := config_common.NewConfigRepo(testDataSource)
closeInfo := &schema.GetReportTypeResp{} closeInfo := &schema.GetReportTypeResp{}
err := configRepo.GetJsonConfigByIDAndSetToObject(74, closeInfo) err := configRepo.GetJsonConfigByIDAndSetToObject(74, closeInfo)
@ -33,27 +32,27 @@ func Test_configRepo_GetConfigById(t *testing.T) {
} }
func Test_configRepo_GetConfigType(t *testing.T) { func Test_configRepo_GetConfigType(t *testing.T) {
configRepo := config.NewConfigRepo(testDataSource) configRepo := config_common.NewConfigRepo(testDataSource)
configType, err := configRepo.GetConfigType("answer.accepted") configType, err := configRepo.GetConfigType("answer.accepted")
assert.NoError(t, err) assert.NoError(t, err)
assert.Equal(t, 1, configType) assert.Equal(t, 1, configType)
} }
func Test_configRepo_GetInt(t *testing.T) { func Test_configRepo_GetInt(t *testing.T) {
configRepo := config.NewConfigRepo(testDataSource) configRepo := config_common.NewConfigRepo(testDataSource)
got, err := configRepo.GetInt("answer.accepted") got, err := configRepo.GetInt("answer.accepted")
assert.NoError(t, err) assert.NoError(t, err)
assert.Equal(t, 15, got) assert.Equal(t, 15, got)
} }
func Test_configRepo_GetString(t *testing.T) { func Test_configRepo_GetString(t *testing.T) {
configRepo := config.NewConfigRepo(testDataSource) configRepo := config_common.NewConfigRepo(testDataSource)
_, err := configRepo.GetString("email.config") _, err := configRepo.GetString("email.config")
assert.NoError(t, err) assert.NoError(t, err)
} }
func Test_configRepo_SetConfig(t *testing.T) { func Test_configRepo_SetConfig(t *testing.T) {
configRepo := config.NewConfigRepo(testDataSource) configRepo := config_common.NewConfigRepo(testDataSource)
got, err := configRepo.GetString("email.config") got, err := configRepo.GetString("email.config")
assert.NoError(t, err) assert.NoError(t, err)

View File

@ -4,13 +4,12 @@ import (
"context" "context"
"testing" "testing"
"github.com/answerdev/answer/internal/repo/config"
"github.com/answerdev/answer/internal/repo/reason" "github.com/answerdev/answer/internal/repo/reason"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
func Test_reasonRepo_ListReasons(t *testing.T) { func Test_reasonRepo_ListReasons(t *testing.T) {
configRepo := config.NewConfigRepo(testDataSource) configRepo := config_common.NewConfigRepo(testDataSource)
reasonRepo := reason.NewReasonRepo(configRepo) reasonRepo := reason.NewReasonRepo(configRepo)
reasonItems, err := reasonRepo.ListReasons(context.TODO(), "question", "close") reasonItems, err := reasonRepo.ListReasons(context.TODO(), "question", "close")
assert.NoError(t, err) assert.NoError(t, err)

View File

@ -5,13 +5,12 @@ import (
"testing" "testing"
"github.com/answerdev/answer/internal/entity" "github.com/answerdev/answer/internal/entity"
"github.com/answerdev/answer/internal/repo/config"
"github.com/answerdev/answer/internal/repo/user" "github.com/answerdev/answer/internal/repo/user"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
func Test_userRepo_AddUser(t *testing.T) { func Test_userRepo_AddUser(t *testing.T) {
userRepo := user.NewUserRepo(testDataSource, config.NewConfigRepo(testDataSource)) userRepo := user.NewUserRepo(testDataSource, config_common.NewConfigRepo(testDataSource))
userInfo := &entity.User{ userInfo := &entity.User{
Username: "answer", Username: "answer",
Pass: "answer", Pass: "answer",
@ -26,7 +25,7 @@ func Test_userRepo_AddUser(t *testing.T) {
} }
func Test_userRepo_BatchGetByID(t *testing.T) { func Test_userRepo_BatchGetByID(t *testing.T) {
userRepo := user.NewUserRepo(testDataSource, config.NewConfigRepo(testDataSource)) userRepo := user.NewUserRepo(testDataSource, config_common.NewConfigRepo(testDataSource))
got, err := userRepo.BatchGetByID(context.TODO(), []string{"1"}) got, err := userRepo.BatchGetByID(context.TODO(), []string{"1"})
assert.NoError(t, err) assert.NoError(t, err)
assert.Equal(t, 1, len(got)) assert.Equal(t, 1, len(got))
@ -34,7 +33,7 @@ func Test_userRepo_BatchGetByID(t *testing.T) {
} }
func Test_userRepo_GetByEmail(t *testing.T) { func Test_userRepo_GetByEmail(t *testing.T) {
userRepo := user.NewUserRepo(testDataSource, config.NewConfigRepo(testDataSource)) userRepo := user.NewUserRepo(testDataSource, config_common.NewConfigRepo(testDataSource))
got, exist, err := userRepo.GetByEmail(context.TODO(), "admin@admin.com") got, exist, err := userRepo.GetByEmail(context.TODO(), "admin@admin.com")
assert.NoError(t, err) assert.NoError(t, err)
assert.True(t, exist) assert.True(t, exist)
@ -42,7 +41,7 @@ func Test_userRepo_GetByEmail(t *testing.T) {
} }
func Test_userRepo_GetByUserID(t *testing.T) { func Test_userRepo_GetByUserID(t *testing.T) {
userRepo := user.NewUserRepo(testDataSource, config.NewConfigRepo(testDataSource)) userRepo := user.NewUserRepo(testDataSource, config_common.NewConfigRepo(testDataSource))
got, exist, err := userRepo.GetByUserID(context.TODO(), "1") got, exist, err := userRepo.GetByUserID(context.TODO(), "1")
assert.NoError(t, err) assert.NoError(t, err)
assert.True(t, exist) assert.True(t, exist)
@ -50,7 +49,7 @@ func Test_userRepo_GetByUserID(t *testing.T) {
} }
func Test_userRepo_GetByUsername(t *testing.T) { func Test_userRepo_GetByUsername(t *testing.T) {
userRepo := user.NewUserRepo(testDataSource, config.NewConfigRepo(testDataSource)) userRepo := user.NewUserRepo(testDataSource, config_common.NewConfigRepo(testDataSource))
got, exist, err := userRepo.GetByUsername(context.TODO(), "admin") got, exist, err := userRepo.GetByUsername(context.TODO(), "admin")
assert.NoError(t, err) assert.NoError(t, err)
assert.True(t, exist) assert.True(t, exist)
@ -58,7 +57,7 @@ func Test_userRepo_GetByUsername(t *testing.T) {
} }
func Test_userRepo_IncreaseAnswerCount(t *testing.T) { func Test_userRepo_IncreaseAnswerCount(t *testing.T) {
userRepo := user.NewUserRepo(testDataSource, config.NewConfigRepo(testDataSource)) userRepo := user.NewUserRepo(testDataSource, config_common.NewConfigRepo(testDataSource))
err := userRepo.IncreaseAnswerCount(context.TODO(), "1", 1) err := userRepo.IncreaseAnswerCount(context.TODO(), "1", 1)
assert.NoError(t, err) assert.NoError(t, err)
@ -69,7 +68,7 @@ func Test_userRepo_IncreaseAnswerCount(t *testing.T) {
} }
func Test_userRepo_IncreaseQuestionCount(t *testing.T) { func Test_userRepo_IncreaseQuestionCount(t *testing.T) {
userRepo := user.NewUserRepo(testDataSource, config.NewConfigRepo(testDataSource)) userRepo := user.NewUserRepo(testDataSource, config_common.NewConfigRepo(testDataSource))
err := userRepo.IncreaseQuestionCount(context.TODO(), "1", 1) err := userRepo.IncreaseQuestionCount(context.TODO(), "1", 1)
assert.NoError(t, err) assert.NoError(t, err)
@ -80,19 +79,19 @@ func Test_userRepo_IncreaseQuestionCount(t *testing.T) {
} }
func Test_userRepo_UpdateEmail(t *testing.T) { func Test_userRepo_UpdateEmail(t *testing.T) {
userRepo := user.NewUserRepo(testDataSource, config.NewConfigRepo(testDataSource)) userRepo := user.NewUserRepo(testDataSource, config_common.NewConfigRepo(testDataSource))
err := userRepo.UpdateEmail(context.TODO(), "1", "admin@admin.com") err := userRepo.UpdateEmail(context.TODO(), "1", "admin@admin.com")
assert.NoError(t, err) assert.NoError(t, err)
} }
func Test_userRepo_UpdateEmailStatus(t *testing.T) { func Test_userRepo_UpdateEmailStatus(t *testing.T) {
userRepo := user.NewUserRepo(testDataSource, config.NewConfigRepo(testDataSource)) userRepo := user.NewUserRepo(testDataSource, config_common.NewConfigRepo(testDataSource))
err := userRepo.UpdateEmailStatus(context.TODO(), "1", entity.EmailStatusToBeVerified) err := userRepo.UpdateEmailStatus(context.TODO(), "1", entity.EmailStatusToBeVerified)
assert.NoError(t, err) assert.NoError(t, err)
} }
func Test_userRepo_UpdateInfo(t *testing.T) { func Test_userRepo_UpdateInfo(t *testing.T) {
userRepo := user.NewUserRepo(testDataSource, config.NewConfigRepo(testDataSource)) userRepo := user.NewUserRepo(testDataSource, config_common.NewConfigRepo(testDataSource))
err := userRepo.UpdateInfo(context.TODO(), &entity.User{ID: "1", Bio: "test"}) err := userRepo.UpdateInfo(context.TODO(), &entity.User{ID: "1", Bio: "test"})
assert.NoError(t, err) assert.NoError(t, err)
@ -103,19 +102,19 @@ func Test_userRepo_UpdateInfo(t *testing.T) {
} }
func Test_userRepo_UpdateLastLoginDate(t *testing.T) { func Test_userRepo_UpdateLastLoginDate(t *testing.T) {
userRepo := user.NewUserRepo(testDataSource, config.NewConfigRepo(testDataSource)) userRepo := user.NewUserRepo(testDataSource, config_common.NewConfigRepo(testDataSource))
err := userRepo.UpdateLastLoginDate(context.TODO(), "1") err := userRepo.UpdateLastLoginDate(context.TODO(), "1")
assert.NoError(t, err) assert.NoError(t, err)
} }
func Test_userRepo_UpdateNoticeStatus(t *testing.T) { func Test_userRepo_UpdateNoticeStatus(t *testing.T) {
userRepo := user.NewUserRepo(testDataSource, config.NewConfigRepo(testDataSource)) userRepo := user.NewUserRepo(testDataSource, config_common.NewConfigRepo(testDataSource))
err := userRepo.UpdateNoticeStatus(context.TODO(), "1", 1) err := userRepo.UpdateNoticeStatus(context.TODO(), "1", 1)
assert.NoError(t, err) assert.NoError(t, err)
} }
func Test_userRepo_UpdatePass(t *testing.T) { func Test_userRepo_UpdatePass(t *testing.T) {
userRepo := user.NewUserRepo(testDataSource, config.NewConfigRepo(testDataSource)) userRepo := user.NewUserRepo(testDataSource, config_common.NewConfigRepo(testDataSource))
err := userRepo.UpdatePass(context.TODO(), "1", "admin") err := userRepo.UpdatePass(context.TODO(), "1", "admin")
assert.NoError(t, err) assert.NoError(t, err)
} }

View File

@ -8,7 +8,6 @@ import (
"github.com/answerdev/answer/internal/base/reason" "github.com/answerdev/answer/internal/base/reason"
"github.com/answerdev/answer/internal/entity" "github.com/answerdev/answer/internal/entity"
"github.com/answerdev/answer/internal/schema" "github.com/answerdev/answer/internal/schema"
"github.com/answerdev/answer/internal/service/config"
usercommon "github.com/answerdev/answer/internal/service/user_common" usercommon "github.com/answerdev/answer/internal/service/user_common"
"github.com/answerdev/answer/pkg/converter" "github.com/answerdev/answer/pkg/converter"
"github.com/answerdev/answer/plugin" "github.com/answerdev/answer/plugin"
@ -19,15 +18,13 @@ import (
// userRepo user repository // userRepo user repository
type userRepo struct { type userRepo struct {
data *data.Data data *data.Data
configRepo config.ConfigRepo
} }
// NewUserRepo new repository // NewUserRepo new repository
func NewUserRepo(data *data.Data, configRepo config.ConfigRepo) usercommon.UserRepo { func NewUserRepo(data *data.Data) usercommon.UserRepo {
return &userRepo{ return &userRepo{
data: data, data: data,
configRepo: configRepo,
} }
} }

View File

@ -8,10 +8,10 @@ import (
"github.com/answerdev/answer/internal/base/constant" "github.com/answerdev/answer/internal/base/constant"
"github.com/answerdev/answer/internal/entity" "github.com/answerdev/answer/internal/entity"
"github.com/answerdev/answer/internal/repo/config"
"github.com/answerdev/answer/internal/schema" "github.com/answerdev/answer/internal/schema"
"github.com/answerdev/answer/internal/service/activity_common" "github.com/answerdev/answer/internal/service/activity_common"
"github.com/answerdev/answer/internal/service/comment_common" "github.com/answerdev/answer/internal/service/comment_common"
"github.com/answerdev/answer/internal/service/config"
"github.com/answerdev/answer/internal/service/meta" "github.com/answerdev/answer/internal/service/meta"
"github.com/answerdev/answer/internal/service/object_info" "github.com/answerdev/answer/internal/service/object_info"
"github.com/answerdev/answer/internal/service/revision_common" "github.com/answerdev/answer/internal/service/revision_common"
@ -38,6 +38,7 @@ type ActivityService struct {
commentCommonService *comment_common.CommentCommonService commentCommonService *comment_common.CommentCommonService
revisionService *revision_common.RevisionService revisionService *revision_common.RevisionService
metaService *meta.MetaService metaService *meta.MetaService
configService *config.ConfigService
} }
// NewActivityService new activity service // NewActivityService new activity service
@ -50,6 +51,7 @@ func NewActivityService(
commentCommonService *comment_common.CommentCommonService, commentCommonService *comment_common.CommentCommonService,
revisionService *revision_common.RevisionService, revisionService *revision_common.RevisionService,
metaService *meta.MetaService, metaService *meta.MetaService,
configService *config.ConfigService,
) *ActivityService { ) *ActivityService {
return &ActivityService{ return &ActivityService{
objectInfoService: objectInfoService, objectInfoService: objectInfoService,
@ -60,6 +62,7 @@ func NewActivityService(
commentCommonService: commentCommonService, commentCommonService: commentCommonService,
revisionService: revisionService, revisionService: revisionService,
metaService: metaService, metaService: metaService,
configService: configService,
} }
} }
@ -97,9 +100,15 @@ func (as *ActivityService) GetObjectTimeline(ctx context.Context, req *schema.Ge
item.ObjectID = uid.EnShortID(act.ObjectID) item.ObjectID = uid.EnShortID(act.ObjectID)
} }
cfg, err := as.configService.GetConfigByID(ctx, act.ActivityType)
if err == nil {
log.Error(err)
} else {
item.ActivityType = cfg.Key
}
// database save activity type is number, change to activity type string is like "question.asked". // database save activity type is number, change to activity type string is like "question.asked".
// so we need to cut the front part of '.' // so we need to cut the front part of '.', only need string like 'asked'
_, item.ActivityType, _ = strings.Cut(config.ID2KeyMapping[act.ActivityType], ".") _, item.ActivityType, _ = strings.Cut(cfg.Key, ".")
// format activity type string to show // format activity type string to show
if isHidden, formattedActivityType := formatActivity(item.ActivityType); isHidden { if isHidden, formattedActivityType := formatActivity(item.ActivityType); isHidden {
continue continue

View File

@ -1,9 +1,5 @@
package activity_type package activity_type
import (
"github.com/answerdev/answer/internal/repo/config"
)
const ( const (
QuestionVoteUp = "question.vote_up" QuestionVoteUp = "question.vote_up"
QuestionVoteDown = "question.vote_down" QuestionVoteDown = "question.vote_down"
@ -51,10 +47,11 @@ var (
) )
func Format(activityTypeID int) string { func Format(activityTypeID int) string {
activityTypeStr := config.ID2KeyMapping[activityTypeID] return ""
activityTypeFlag := activityTypeFlagMapping[activityTypeStr] //activityTypeStr := config_common.ID2KeyMapping[activityTypeID]
if len(activityTypeFlag) == 0 { //activityTypeFlag := activityTypeFlagMapping[activityTypeStr]
return "edit" // to edit //if len(activityTypeFlag) == 0 {
} // return "edit" // to edit
return activityTypeFlag // todo i18n support //}
//return activityTypeFlag // todo i18n support
} }

View File

@ -1,16 +1,18 @@
package config package config
import "context" import (
"context"
"encoding/json"
"fmt"
"github.com/answerdev/answer/internal/entity"
)
// ConfigRepo config repository // ConfigRepo config repository
type ConfigRepo interface { type ConfigRepo interface {
Get(key string) (interface{}, error) GetConfigByID(ctx context.Context, id int) (c *entity.Config, err error)
GetString(key string) (string, error) GetConfigByKey(ctx context.Context, key string) (c *entity.Config, err error)
GetInt(key string) (int, error) UpdateConfig(ctx context.Context, key, value string) (err error)
GetArrayString(key string) ([]string, error)
GetConfigType(key string) (int, error)
GetJsonConfigByIDAndSetToObject(id int, value any) (err error)
SetConfig(ctx context.Context, key, value string) (err error)
} }
// ConfigService user service // ConfigService user service
@ -18,8 +20,70 @@ type ConfigService struct {
configRepo ConfigRepo configRepo ConfigRepo
} }
// NewConfigService new config service
func NewConfigService(configRepo ConfigRepo) *ConfigService { func NewConfigService(configRepo ConfigRepo) *ConfigService {
return &ConfigService{ return &ConfigService{
configRepo: configRepo, configRepo: configRepo,
} }
} }
// GetIntValue get config int value
func (cs *ConfigService) GetIntValue(ctx context.Context, key string) (val int, err error) {
cf, err := cs.configRepo.GetConfigByKey(ctx, key)
if err != nil {
return 0, err
}
return cf.GetIntValue(), nil
}
// GetStringValue get config string value
func (cs *ConfigService) GetStringValue(ctx context.Context, key string) (val string, err error) {
cf, err := cs.configRepo.GetConfigByKey(ctx, key)
if err != nil {
return "", err
}
return cf.Value, nil
}
// GetArrayStringValue get config array string value
func (cs *ConfigService) GetArrayStringValue(ctx context.Context, key string) (val []string, err error) {
cf, err := cs.configRepo.GetConfigByKey(ctx, key)
if err != nil {
return nil, err
}
return cf.GetArrayStringValue(), nil
}
func (cs *ConfigService) GetJsonConfigByIDAndSetToObject(ctx context.Context, id int, obj any) (err error) {
cf, err := cs.configRepo.GetConfigByID(ctx, id)
if err != nil {
return err
}
err = json.Unmarshal([]byte(cf.Value), obj)
if err != nil {
return fmt.Errorf("[%s] config value is not json format", cf.Key)
}
return nil
}
// GetConfigByID get config by id
func (cs *ConfigService) GetConfigByID(ctx context.Context, id int) (c *entity.Config, err error) {
return cs.configRepo.GetConfigByID(ctx, id)
}
func (cs *ConfigService) GetConfigByKey(ctx context.Context, key string) (c *entity.Config, err error) {
return cs.configRepo.GetConfigByKey(ctx, key)
}
// GetIDByKey get config id by key
func (cs *ConfigService) GetIDByKey(ctx context.Context, key string) (id int, err error) {
cf, err := cs.configRepo.GetConfigByKey(ctx, key)
if err != nil {
return 0, err
}
return cf.ID, nil
}
func (cs *ConfigService) UpdateConfig(ctx context.Context, key, value string) (err error) {
return cs.configRepo.UpdateConfig(ctx, key, value)
}

View File

@ -35,7 +35,7 @@ type DashboardService struct {
voteRepo activity_common.VoteRepo voteRepo activity_common.VoteRepo
userRepo usercommon.UserRepo userRepo usercommon.UserRepo
reportRepo report_common.ReportRepo reportRepo report_common.ReportRepo
configRepo config.ConfigRepo configService *config.ConfigService
siteInfoService *siteinfo_common.SiteInfoCommonService siteInfoService *siteinfo_common.SiteInfoCommonService
serviceConfig *service_config.ServiceConfig serviceConfig *service_config.ServiceConfig
@ -49,7 +49,7 @@ func NewDashboardService(
voteRepo activity_common.VoteRepo, voteRepo activity_common.VoteRepo,
userRepo usercommon.UserRepo, userRepo usercommon.UserRepo,
reportRepo report_common.ReportRepo, reportRepo report_common.ReportRepo,
configRepo config.ConfigRepo, configService *config.ConfigService,
siteInfoService *siteinfo_common.SiteInfoCommonService, siteInfoService *siteinfo_common.SiteInfoCommonService,
serviceConfig *service_config.ServiceConfig, serviceConfig *service_config.ServiceConfig,
@ -62,7 +62,7 @@ func NewDashboardService(
voteRepo: voteRepo, voteRepo: voteRepo,
userRepo: userRepo, userRepo: userRepo,
reportRepo: reportRepo, reportRepo: reportRepo,
configRepo: configRepo, configService: configService,
siteInfoService: siteInfoService, siteInfoService: siteInfoService,
serviceConfig: serviceConfig, serviceConfig: serviceConfig,
@ -131,12 +131,11 @@ func (ds *DashboardService) Statistical(ctx context.Context) (*schema.DashboardI
var activityTypes []int var activityTypes []int
for _, typeKey := range typeKeys { for _, typeKey := range typeKeys {
var t int cfg, err := ds.configService.GetConfigByKey(ctx, typeKey)
t, err = ds.configRepo.GetConfigType(typeKey)
if err != nil { if err != nil {
continue continue
} }
activityTypes = append(activityTypes, t) activityTypes = append(activityTypes, cfg.ID)
} }
voteCount, err := ds.voteRepo.GetVoteCount(ctx, activityTypes) voteCount, err := ds.voteRepo.GetVoteCount(ctx, activityTypes)
@ -166,7 +165,7 @@ func (ds *DashboardService) Statistical(ctx context.Context) (*schema.DashboardI
dashboardInfo.ReportCount = reportCount dashboardInfo.ReportCount = reportCount
dashboardInfo.UploadingFiles = true dashboardInfo.UploadingFiles = true
emailconfig, err := ds.GetEmailConfig() emailconfig, err := ds.GetEmailConfig(ctx)
if err != nil { if err != nil {
return dashboardInfo, err return dashboardInfo, err
} }
@ -225,8 +224,8 @@ func (ds *DashboardService) RemoteVersion(ctx context.Context) string {
return remoteVersion.Release.Version return remoteVersion.Release.Version
} }
func (ds *DashboardService) GetEmailConfig() (ec *export.EmailConfig, err error) { func (ds *DashboardService) GetEmailConfig(ctx context.Context) (ec *export.EmailConfig, err error) {
emailConf, err := ds.configRepo.GetString("email.config") emailConf, err := ds.configService.GetStringValue(ctx, "email.config")
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -24,9 +24,9 @@ import (
// EmailService kit service // EmailService kit service
type EmailService struct { type EmailService struct {
configRepo config.ConfigRepo configService *config.ConfigService
emailRepo EmailRepo emailRepo EmailRepo
siteInfoRepo siteinfo_common.SiteInfoRepo siteInfoRepo siteinfo_common.SiteInfoRepo
} }
// EmailRepo email repository // EmailRepo email repository
@ -36,11 +36,11 @@ type EmailRepo interface {
} }
// NewEmailService email service // NewEmailService email service
func NewEmailService(configRepo config.ConfigRepo, emailRepo EmailRepo, siteInfoRepo siteinfo_common.SiteInfoRepo) *EmailService { func NewEmailService(configService *config.ConfigService, emailRepo EmailRepo, siteInfoRepo siteinfo_common.SiteInfoRepo) *EmailService {
return &EmailService{ return &EmailService{
configRepo: configRepo, configService: configService,
emailRepo: emailRepo, emailRepo: emailRepo,
siteInfoRepo: siteInfoRepo, siteInfoRepo: siteInfoRepo,
} }
} }
@ -114,7 +114,7 @@ func (es *EmailService) SendAndSaveCodeWithTime(
// Send email send // Send email send
func (es *EmailService) Send(ctx context.Context, toEmailAddr, subject, body string) { func (es *EmailService) Send(ctx context.Context, toEmailAddr, subject, body string) {
log.Infof("try to send email to %s", toEmailAddr) log.Infof("try to send email to %s", toEmailAddr)
ec, err := es.GetEmailConfig() ec, err := es.GetEmailConfig(ctx)
if err != nil { if err != nil {
log.Errorf("get email config failed: %s", err) log.Errorf("get email config failed: %s", err)
return return
@ -298,8 +298,8 @@ func (es *EmailService) NewCommentTemplate(ctx context.Context, raw *schema.NewC
return title, body, nil return title, body, nil
} }
func (es *EmailService) GetEmailConfig() (ec *EmailConfig, err error) { func (es *EmailService) GetEmailConfig(ctx context.Context) (ec *EmailConfig, err error) {
emailConf, err := es.configRepo.GetString("email.config") emailConf, err := es.configService.GetStringValue(ctx, "email.config")
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -314,5 +314,5 @@ func (es *EmailService) GetEmailConfig() (ec *EmailConfig, err error) {
// SetEmailConfig set email config // SetEmailConfig set email config
func (es *EmailService) SetEmailConfig(ctx context.Context, ec *EmailConfig) (err error) { func (es *EmailService) SetEmailConfig(ctx context.Context, ec *EmailConfig) (err error) {
data, _ := json.Marshal(ec) data, _ := json.Marshal(ec)
return es.configRepo.SetConfig(ctx, "email.config", string(data)) return es.configService.UpdateConfig(ctx, "email.config", string(data))
} }

View File

@ -21,17 +21,17 @@ type PluginConfigRepo interface {
// PluginCommonService user service // PluginCommonService user service
type PluginCommonService struct { type PluginCommonService struct {
configRepo config.ConfigRepo configService *config.ConfigService
pluginConfigRepo PluginConfigRepo pluginConfigRepo PluginConfigRepo
} }
// NewPluginCommonService new report service // NewPluginCommonService new report service
func NewPluginCommonService( func NewPluginCommonService(
pluginConfigRepo PluginConfigRepo, pluginConfigRepo PluginConfigRepo,
configRepo config.ConfigRepo) *PluginCommonService { configService *config.ConfigService) *PluginCommonService {
// init plugin status // init plugin status
pluginStatus, err := configRepo.GetString(constant.PluginStatus) pluginStatus, err := configService.GetStringValue(context.TODO(), constant.PluginStatus)
if err != nil { if err != nil {
log.Error(err) log.Error(err)
} else { } else {
@ -59,7 +59,7 @@ func NewPluginCommonService(
} }
return &PluginCommonService{ return &PluginCommonService{
configRepo: configRepo, configService: configService,
pluginConfigRepo: pluginConfigRepo, pluginConfigRepo: pluginConfigRepo,
} }
} }
@ -70,7 +70,7 @@ func (ps *PluginCommonService) UpdatePluginStatus(ctx context.Context) (err erro
if err != nil { if err != nil {
return errors.InternalServer(reason.UnknownError).WithError(err) return errors.InternalServer(reason.UnknownError).WithError(err)
} }
return ps.configRepo.SetConfig(ctx, constant.PluginStatus, string(content)) return ps.configService.UpdateConfig(ctx, constant.PluginStatus, string(content))
} }
// UpdatePluginConfig update plugin config // UpdatePluginConfig update plugin config

View File

@ -9,6 +9,7 @@ import (
collectioncommon "github.com/answerdev/answer/internal/service/collection_common" collectioncommon "github.com/answerdev/answer/internal/service/collection_common"
"github.com/answerdev/answer/internal/service/comment" "github.com/answerdev/answer/internal/service/comment"
"github.com/answerdev/answer/internal/service/comment_common" "github.com/answerdev/answer/internal/service/comment_common"
"github.com/answerdev/answer/internal/service/config"
"github.com/answerdev/answer/internal/service/dashboard" "github.com/answerdev/answer/internal/service/dashboard"
"github.com/answerdev/answer/internal/service/export" "github.com/answerdev/answer/internal/service/export"
"github.com/answerdev/answer/internal/service/follow" "github.com/answerdev/answer/internal/service/follow"
@ -84,4 +85,5 @@ var ProviderSetService = wire.NewSet(
user_external_login.NewUserExternalLoginService, user_external_login.NewUserExternalLoginService,
user_external_login.NewUserCenterLoginService, user_external_login.NewUserCenterLoginService,
plugin_common.NewPluginCommonService, plugin_common.NewPluginCommonService,
config.NewConfigService,
) )

View File

@ -6,6 +6,7 @@ import (
"time" "time"
"github.com/answerdev/answer/internal/base/constant" "github.com/answerdev/answer/internal/base/constant"
"github.com/answerdev/answer/internal/base/handler"
"github.com/answerdev/answer/internal/base/reason" "github.com/answerdev/answer/internal/base/reason"
"github.com/answerdev/answer/internal/service/activity_common" "github.com/answerdev/answer/internal/service/activity_common"
"github.com/answerdev/answer/internal/service/activity_queue" "github.com/answerdev/answer/internal/service/activity_queue"
@ -62,7 +63,7 @@ type QuestionCommon struct {
collectionCommon *collectioncommon.CollectionCommon collectionCommon *collectioncommon.CollectionCommon
AnswerCommon *answercommon.AnswerCommon AnswerCommon *answercommon.AnswerCommon
metaService *meta.MetaService metaService *meta.MetaService
configRepo config.ConfigRepo configService *config.ConfigService
} }
func NewQuestionCommon(questionRepo QuestionRepo, func NewQuestionCommon(questionRepo QuestionRepo,
@ -74,7 +75,7 @@ func NewQuestionCommon(questionRepo QuestionRepo,
collectionCommon *collectioncommon.CollectionCommon, collectionCommon *collectioncommon.CollectionCommon,
answerCommon *answercommon.AnswerCommon, answerCommon *answercommon.AnswerCommon,
metaService *meta.MetaService, metaService *meta.MetaService,
configRepo config.ConfigRepo, configService *config.ConfigService,
) *QuestionCommon { ) *QuestionCommon {
return &QuestionCommon{ return &QuestionCommon{
questionRepo: questionRepo, questionRepo: questionRepo,
@ -86,7 +87,7 @@ func NewQuestionCommon(questionRepo QuestionRepo,
collectionCommon: collectionCommon, collectionCommon: collectionCommon,
AnswerCommon: answerCommon, AnswerCommon: answerCommon,
metaService: metaService, metaService: metaService,
configRepo: configRepo, configService: configService,
} }
} }
@ -201,14 +202,16 @@ func (qs *QuestionCommon) Info(ctx context.Context, questionID string, loginUser
if err != nil { if err != nil {
log.Error("json.Unmarshal CloseQuestionMeta error", err.Error()) log.Error("json.Unmarshal CloseQuestionMeta error", err.Error())
} else { } else {
closeinfo := &schema.GetReportTypeResp{} cfg, err := qs.configService.GetConfigByID(ctx, closemsg.CloseType)
err = qs.configRepo.GetJsonConfigByIDAndSetToObject(closemsg.CloseType, closeinfo)
if err != nil { if err != nil {
log.Error("json.Unmarshal QuestionCloseJson error", err.Error()) log.Error("json.Unmarshal QuestionCloseJson error", err.Error())
} else { } else {
reasonItem := &schema.ReasonItem{}
_ = json.Unmarshal(cfg.GetByteValue(), reasonItem)
reasonItem.Translate(cfg.Key, handler.GetLangByCtx(ctx))
operation := &schema.Operation{} operation := &schema.Operation{}
operation.Type = closeinfo.Name operation.Type = reasonItem.Name
operation.Description = closeinfo.Description operation.Description = reasonItem.Description
operation.Msg = closemsg.CloseMsg operation.Msg = closemsg.CloseMsg
operation.Time = metainfo.CreatedAt.Unix() operation.Time = metainfo.CreatedAt.Unix()
operation.Level = schema.OperationLevelInfo operation.Level = schema.OperationLevelInfo

View File

@ -34,7 +34,7 @@ type UserRankRepo interface {
// RankService rank service // RankService rank service
type RankService struct { type RankService struct {
userCommon *usercommon.UserCommon userCommon *usercommon.UserCommon
configRepo config.ConfigRepo configService *config.ConfigService
userRankRepo UserRankRepo userRankRepo UserRankRepo
objectInfoService *object_info.ObjService objectInfoService *object_info.ObjService
roleService *role.UserRoleRelService roleService *role.UserRoleRelService
@ -48,10 +48,10 @@ func NewRankService(
objectInfoService *object_info.ObjService, objectInfoService *object_info.ObjService,
roleService *role.UserRoleRelService, roleService *role.UserRoleRelService,
rolePowerService *role.RolePowerRelService, rolePowerService *role.RolePowerRelService,
configRepo config.ConfigRepo) *RankService { configService *config.ConfigService) *RankService {
return &RankService{ return &RankService{
userCommon: userCommon, userCommon: userCommon,
configRepo: configRepo, configService: configService,
userRankRepo: userRankRepo, userRankRepo: userRankRepo,
objectInfoService: objectInfoService, objectInfoService: objectInfoService,
roleService: roleService, roleService: roleService,
@ -213,7 +213,7 @@ func (rs *RankService) getUserPowerMapping(ctx context.Context, userID string) (
func (rs *RankService) checkUserRank(ctx context.Context, userID string, userRank int, action string) ( func (rs *RankService) checkUserRank(ctx context.Context, userID string, userRank int, action string) (
can bool, rank int) { can bool, rank int) {
// get the amount of rank required for the current operation // get the amount of rank required for the current operation
requireRank, err := rs.configRepo.GetInt(action) requireRank, err := rs.configService.GetIntValue(ctx, action)
if err != nil { if err != nil {
log.Error(err) log.Error(err)
return false, requireRank return false, requireRank

View File

@ -2,9 +2,9 @@ package report_admin
import ( import (
"context" "context"
"encoding/json"
"github.com/answerdev/answer/internal/base/handler" "github.com/answerdev/answer/internal/base/handler"
configrepo "github.com/answerdev/answer/internal/repo/config"
"github.com/answerdev/answer/internal/service/config" "github.com/answerdev/answer/internal/service/config"
"github.com/answerdev/answer/internal/service/object_info" "github.com/answerdev/answer/internal/service/object_info"
"github.com/answerdev/answer/pkg/htmltext" "github.com/answerdev/answer/pkg/htmltext"
@ -32,7 +32,7 @@ type ReportAdminService struct {
questionRepo questioncommon.QuestionRepo questionRepo questioncommon.QuestionRepo
commentCommonRepo comment_common.CommentCommonRepo commentCommonRepo comment_common.CommentCommonRepo
reportHandle *report_handle_admin.ReportHandle reportHandle *report_handle_admin.ReportHandle
configRepo config.ConfigRepo configService *config.ConfigService
objectInfoService *object_info.ObjService objectInfoService *object_info.ObjService
} }
@ -44,7 +44,7 @@ func NewReportAdminService(
questionRepo questioncommon.QuestionRepo, questionRepo questioncommon.QuestionRepo,
commentCommonRepo comment_common.CommentCommonRepo, commentCommonRepo comment_common.CommentCommonRepo,
reportHandle *report_handle_admin.ReportHandle, reportHandle *report_handle_admin.ReportHandle,
configRepo config.ConfigRepo, configService *config.ConfigService,
objectInfoService *object_info.ObjService) *ReportAdminService { objectInfoService *object_info.ObjService) *ReportAdminService {
return &ReportAdminService{ return &ReportAdminService{
reportRepo: reportRepo, reportRepo: reportRepo,
@ -53,7 +53,7 @@ func NewReportAdminService(
questionRepo: questionRepo, questionRepo: questionRepo,
commentCommonRepo: commentCommonRepo, commentCommonRepo: commentCommonRepo,
reportHandle: reportHandle, reportHandle: reportHandle,
configRepo: configRepo, configService: configService,
objectInfoService: objectInfoService, objectInfoService: objectInfoService,
} }
} }
@ -151,21 +151,25 @@ func (rs *ReportAdminService) decorateReportResp(ctx context.Context, resp *sche
resp.CommentID = objectInfo.CommentID resp.CommentID = objectInfo.CommentID
resp.Title = objectInfo.Title resp.Title = objectInfo.Title
resp.Excerpt = htmltext.FetchExcerpt(objectInfo.Content, "...", 240) resp.Excerpt = htmltext.FetchExcerpt(objectInfo.Content, "...", 240)
resp.Reason.Translate(configrepo.ID2KeyMapping[resp.ReportType], lang)
if resp.ReportType > 0 { if resp.ReportType > 0 {
resp.Reason = &schema.ReasonItem{ReasonType: resp.ReportType} resp.Reason = &schema.ReasonItem{ReasonType: resp.ReportType}
err = rs.configRepo.GetJsonConfigByIDAndSetToObject(resp.ReportType, resp.Reason) cf, err := rs.configService.GetConfigByID(ctx, resp.ReportType)
if err != nil { if err != nil {
log.Error(err) log.Error(err)
} else {
_ = json.Unmarshal([]byte(cf.Value), resp.Reason)
resp.Reason.Translate(cf.Key, lang)
} }
} }
if resp.FlaggedType > 0 { if resp.FlaggedType > 0 {
resp.FlaggedReason = &schema.ReasonItem{ReasonType: resp.FlaggedType} resp.FlaggedReason = &schema.ReasonItem{ReasonType: resp.FlaggedType}
err = rs.configRepo.GetJsonConfigByIDAndSetToObject(resp.FlaggedType, resp.FlaggedReason) cf, err := rs.configService.GetConfigByID(ctx, resp.FlaggedType)
if err != nil { if err != nil {
log.Error(err) log.Error(err)
} else {
_ = json.Unmarshal([]byte(cf.Value), resp.Reason)
resp.Reason.Translate(cf.Key, lang)
} }
resp.Reason.Translate(configrepo.ID2KeyMapping[resp.ReportType], lang)
} }
} }

View File

@ -17,28 +17,34 @@ import (
type ReportHandle struct { type ReportHandle struct {
questionCommon *questioncommon.QuestionCommon questionCommon *questioncommon.QuestionCommon
commentRepo comment.CommentRepo commentRepo comment.CommentRepo
configRepo config.ConfigRepo configService *config.ConfigService
} }
func NewReportHandle( func NewReportHandle(
questionCommon *questioncommon.QuestionCommon, questionCommon *questioncommon.QuestionCommon,
commentRepo comment.CommentRepo, commentRepo comment.CommentRepo,
configRepo config.ConfigRepo) *ReportHandle { configService *config.ConfigService) *ReportHandle {
return &ReportHandle{ return &ReportHandle{
questionCommon: questionCommon, questionCommon: questionCommon,
commentRepo: commentRepo, commentRepo: commentRepo,
configRepo: configRepo, configService: configService,
} }
} }
// HandleObject this handle object status // HandleObject this handle object status
func (rh *ReportHandle) HandleObject(ctx context.Context, reported *entity.Report, req schema.ReportHandleReq) (err error) { func (rh *ReportHandle) HandleObject(ctx context.Context, reported *entity.Report, req schema.ReportHandleReq) (err error) {
reasonDeleteCfg, err := rh.configService.GetConfigByKey(ctx, "reason.needs_delete")
if err != nil {
return err
}
reasonCloseCfg, err := rh.configService.GetConfigByKey(ctx, "reason.needs_close")
if err != nil {
return err
}
var ( var (
objectID = reported.ObjectID objectID = reported.ObjectID
reportedUserID = reported.ReportedUserID reportedUserID = reported.ReportedUserID
objectKey string objectKey string
reasonDelete, _ = rh.configRepo.GetConfigType("reason.needs_delete")
reasonClose, _ = rh.configRepo.GetConfigType("reason.needs_close")
) )
objectKey, err = obj.GetObjectTypeStrByObjectID(objectID) objectKey, err = obj.GetObjectTypeStrByObjectID(objectID)
@ -48,9 +54,9 @@ func (rh *ReportHandle) HandleObject(ctx context.Context, reported *entity.Repor
switch objectKey { switch objectKey {
case "question": case "question":
switch req.FlaggedType { switch req.FlaggedType {
case reasonDelete: case reasonDeleteCfg.ID:
err = rh.questionCommon.RemoveQuestion(ctx, &schema.RemoveQuestionReq{ID: objectID}) err = rh.questionCommon.RemoveQuestion(ctx, &schema.RemoveQuestionReq{ID: objectID})
case reasonClose: case reasonCloseCfg.ID:
err = rh.questionCommon.CloseQuestion(ctx, &schema.CloseQuestionReq{ err = rh.questionCommon.CloseQuestion(ctx, &schema.CloseQuestionReq{
ID: objectID, ID: objectID,
CloseType: req.FlaggedType, CloseType: req.FlaggedType,
@ -59,12 +65,12 @@ func (rh *ReportHandle) HandleObject(ctx context.Context, reported *entity.Repor
} }
case "answer": case "answer":
switch req.FlaggedType { switch req.FlaggedType {
case reasonDelete: case reasonDeleteCfg.ID:
err = rh.questionCommon.RemoveAnswer(ctx, objectID) err = rh.questionCommon.RemoveAnswer(ctx, objectID)
} }
case "comment": case "comment":
switch req.FlaggedType { switch req.FlaggedType {
case reasonDelete: case reasonCloseCfg.ID:
err = rh.commentRepo.RemoveComment(ctx, objectID) err = rh.commentRepo.RemoveComment(ctx, objectID)
rh.sendNotification(ctx, reportedUserID, objectID, constant.NotificationYourCommentWasDeleted) rh.sendNotification(ctx, reportedUserID, objectID, constant.NotificationYourCommentWasDeleted)
} }

View File

@ -26,7 +26,7 @@ type SiteInfoService struct {
siteInfoCommonService *siteinfo_common.SiteInfoCommonService siteInfoCommonService *siteinfo_common.SiteInfoCommonService
emailService *export.EmailService emailService *export.EmailService
tagCommonService *tagcommon.TagCommonService tagCommonService *tagcommon.TagCommonService
configRepo config.ConfigRepo configService *config.ConfigService
} }
func NewSiteInfoService( func NewSiteInfoService(
@ -34,7 +34,7 @@ func NewSiteInfoService(
siteInfoCommonService *siteinfo_common.SiteInfoCommonService, siteInfoCommonService *siteinfo_common.SiteInfoCommonService,
emailService *export.EmailService, emailService *export.EmailService,
tagCommonService *tagcommon.TagCommonService, tagCommonService *tagcommon.TagCommonService,
configRepo config.ConfigRepo, configService *config.ConfigService,
) *SiteInfoService { ) *SiteInfoService {
usersSiteInfo, _ := siteInfoCommonService.GetSiteUsers(context.Background()) usersSiteInfo, _ := siteInfoCommonService.GetSiteUsers(context.Background())
if usersSiteInfo != nil { if usersSiteInfo != nil {
@ -51,7 +51,7 @@ func NewSiteInfoService(
siteInfoCommonService: siteInfoCommonService, siteInfoCommonService: siteInfoCommonService,
emailService: emailService, emailService: emailService,
tagCommonService: tagCommonService, tagCommonService: tagCommonService,
configRepo: configRepo, configService: configService,
} }
} }
@ -239,7 +239,7 @@ func (s *SiteInfoService) SaveSiteUsers(ctx context.Context, req *schema.SiteUse
func (s *SiteInfoService) GetSMTPConfig(ctx context.Context) ( func (s *SiteInfoService) GetSMTPConfig(ctx context.Context) (
resp *schema.GetSMTPConfigResp, err error, resp *schema.GetSMTPConfigResp, err error,
) { ) {
emailConfig, err := s.emailService.GetEmailConfig() emailConfig, err := s.emailService.GetEmailConfig(ctx)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -250,7 +250,7 @@ func (s *SiteInfoService) GetSMTPConfig(ctx context.Context) (
// UpdateSMTPConfig get smtp config // UpdateSMTPConfig get smtp config
func (s *SiteInfoService) UpdateSMTPConfig(ctx context.Context, req *schema.UpdateSMTPConfigReq) (err error) { func (s *SiteInfoService) UpdateSMTPConfig(ctx context.Context, req *schema.UpdateSMTPConfigReq) (err error) {
oldEmailConfig, err := s.emailService.GetEmailConfig() oldEmailConfig, err := s.emailService.GetEmailConfig(ctx)
if err != nil { if err != nil {
return err return err
} }
@ -372,7 +372,7 @@ func (s *SiteInfoService) UpdatePrivilegesConfig(ctx context.Context, req *schem
// update privilege in config // update privilege in config
for _, privilege := range chooseOption.Privileges { for _, privilege := range chooseOption.Privileges {
err = s.configRepo.SetConfig(ctx, privilege.Key, fmt.Sprintf("%d", privilege.Value)) err = s.configService.UpdateConfig(ctx, privilege.Key, fmt.Sprintf("%d", privilege.Value))
if err != nil { if err != nil {
return err return err
} }

View File

@ -35,7 +35,7 @@ type VoteRepo interface {
type VoteService struct { type VoteService struct {
voteRepo VoteRepo voteRepo VoteRepo
UniqueIDRepo unique.UniqueIDRepo UniqueIDRepo unique.UniqueIDRepo
configRepo config.ConfigRepo configService *config.ConfigService
questionRepo questioncommon.QuestionRepo questionRepo questioncommon.QuestionRepo
answerRepo answercommon.AnswerRepo answerRepo answercommon.AnswerRepo
commentCommonRepo comment_common.CommentCommonRepo commentCommonRepo comment_common.CommentCommonRepo
@ -45,7 +45,7 @@ type VoteService struct {
func NewVoteService( func NewVoteService(
VoteRepo VoteRepo, VoteRepo VoteRepo,
uniqueIDRepo unique.UniqueIDRepo, uniqueIDRepo unique.UniqueIDRepo,
configRepo config.ConfigRepo, configService *config.ConfigService,
questionRepo questioncommon.QuestionRepo, questionRepo questioncommon.QuestionRepo,
answerRepo answercommon.AnswerRepo, answerRepo answercommon.AnswerRepo,
commentCommonRepo comment_common.CommentCommonRepo, commentCommonRepo comment_common.CommentCommonRepo,
@ -54,7 +54,7 @@ func NewVoteService(
return &VoteService{ return &VoteService{
voteRepo: VoteRepo, voteRepo: VoteRepo,
UniqueIDRepo: uniqueIDRepo, UniqueIDRepo: uniqueIDRepo,
configRepo: configRepo, configService: configService,
questionRepo: questionRepo, questionRepo: questionRepo,
answerRepo: answerRepo, answerRepo: answerRepo,
commentCommonRepo: commentCommonRepo, commentCommonRepo: commentCommonRepo,
@ -163,12 +163,11 @@ func (vs *VoteService) ListUserVotes(ctx context.Context, req schema.GetVoteWith
) )
for _, typeKey := range typeKeys { for _, typeKey := range typeKeys {
var t int cfg, err := vs.configService.GetConfigByKey(ctx, typeKey)
t, err = vs.configRepo.GetConfigType(typeKey)
if err != nil { if err != nil {
continue continue
} }
activityTypes = append(activityTypes, t) activityTypes = append(activityTypes, cfg.GetIntValue())
} }
voteList, total, err := vs.voteRepo.ListUserVotes(ctx, req.UserID, req, activityTypes) voteList, total, err := vs.voteRepo.ListUserVotes(ctx, req.UserID, req, activityTypes)