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"
comment2 "github.com/answerdev/answer/internal/service/comment"
"github.com/answerdev/answer/internal/service/comment_common"
config2 "github.com/answerdev/answer/internal/service/config"
"github.com/answerdev/answer/internal/service/dashboard"
export2 "github.com/answerdev/answer/internal/service/export"
"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)
authRepo := auth.NewAuthRepo(dataData)
authService := auth2.NewAuthService(authRepo)
configRepo := config.NewConfigRepo(dataData)
userRepo := user.NewUserRepo(dataData, configRepo)
userRepo := user.NewUserRepo(dataData)
uniqueIDRepo := unique.NewUniqueIDRepo(dataData)
activityRepo := activity_common.NewActivityRepo(dataData, uniqueIDRepo, configRepo)
userRankRepo := rank.NewUserRankRepo(dataData, configRepo)
userActiveActivityRepo := activity.NewUserActiveActivityRepo(dataData, activityRepo, userRankRepo, configRepo)
configRepo := config.NewConfigRepo(dataData)
configService := config2.NewConfigService(configRepo)
activityRepo := activity_common.NewActivityRepo(dataData, uniqueIDRepo, configService)
userRankRepo := rank.NewUserRankRepo(dataData, configService)
userActiveActivityRepo := activity.NewUserActiveActivityRepo(dataData, activityRepo, userRankRepo, configService)
emailRepo := export.NewEmailRepo(dataData)
emailService := export2.NewEmailService(configRepo, emailRepo, siteInfoRepo)
emailService := export2.NewEmailService(configService, emailRepo, siteInfoRepo)
userRoleRelRepo := role.NewUserRoleRelRepo(dataData)
roleRepo := role.NewRoleRepo(dataData)
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)
rolePowerRelRepo := role.NewRolePowerRelRepo(dataData)
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)
reportRepo := report.NewReportRepo(dataData, uniqueIDRepo)
reportService := report2.NewReportService(reportRepo, objService)
reportController := controller.NewReportController(reportService, rankService)
serviceVoteRepo := activity.NewVoteRepo(dataData, uniqueIDRepo, configRepo, activityRepo, userRankRepo, voteRepo)
voteService := service.NewVoteService(serviceVoteRepo, uniqueIDRepo, configRepo, questionRepo, answerRepo, commentCommonRepo, objService)
serviceVoteRepo := activity.NewVoteRepo(dataData, uniqueIDRepo, configService, activityRepo, userRankRepo, voteRepo)
voteService := service.NewVoteService(serviceVoteRepo, uniqueIDRepo, configService, questionRepo, answerRepo, commentCommonRepo, objService)
voteController := controller.NewVoteController(voteService, rankService)
followRepo := activity_common.NewFollowRepo(dataData, uniqueIDRepo, activityRepo)
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)
metaRepo := meta.NewMetaRepo(dataData)
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)
collectionController := controller.NewCollectionController(collectionService)
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)
answerService := service.NewAnswerService(answerRepo, questionRepo, questionCommon, userCommon, collectionCommon, userRepo, revisionService, answerActivityService, answerCommon, voteRepo, emailService, userRoleRelService)
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)
searchParser := search_parser.NewSearchParser(tagCommonService, 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)
revisionController := controller.NewRevisionController(serviceRevisionService, rankService)
rankController := controller.NewRankController(rankService)
reportHandle := report_handle_admin.NewReportHandle(questionCommon, commentRepo, configRepo)
reportAdminService := report_admin.NewReportAdminService(reportRepo, userCommon, answerRepo, questionRepo, commentCommonRepo, reportHandle, configRepo, objService)
reportHandle := report_handle_admin.NewReportHandle(questionCommon, commentRepo, configService)
reportAdminService := report_admin.NewReportAdminService(reportRepo, userCommon, answerRepo, questionRepo, commentCommonRepo, reportHandle, configService, objService)
controller_adminReportController := controller_admin.NewReportController(reportAdminService)
userAdminRepo := user.NewUserAdminRepo(dataData, authRepo)
userAdminService := user_admin.NewUserAdminService(userAdminRepo, userRoleRelService, authService, userCommon, userActiveActivityRepo)
userAdminController := controller_admin.NewUserAdminController(userAdminService)
reasonRepo := reason.NewReasonRepo(configRepo)
reasonRepo := reason.NewReasonRepo(configService)
reasonService := reason2.NewReasonService(reasonRepo)
reasonController := controller.NewReasonController(reasonService)
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.NewSiteinfoController(siteInfoCommonService)
notificationRepo := notification.NewNotificationRepo(dataData)
@ -201,13 +203,13 @@ func initApplication(debug bool, serverConf *conf.Server, dbConf *data.Database,
dashboardController := controller.NewDashboardController(dashboardService)
uploadController := controller.NewUploadController(uploaderService)
activityCommon := activity_common2.NewActivityCommon(activityRepo)
activityActivityRepo := activity.NewActivityRepo(dataData)
activityActivityRepo := activity.NewActivityRepo(dataData, configService)
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)
roleController := controller_admin.NewRoleController(roleService)
pluginConfigRepo := plugin_config.NewPluginConfigRepo(dataData)
pluginCommonService := plugin_common.NewPluginCommonService(pluginConfigRepo, configRepo)
pluginCommonService := plugin_common.NewPluginCommonService(pluginConfigRepo, configService)
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)
swaggerRouter := router.NewSwaggerRouter(swaggerConf)

View File

@ -2,4 +2,6 @@ package constant
const (
PluginStatus = "plugin.status"
ConfigID2KEYCacheKeyPrefix = "answer:config:id:"
ConfigKEY2ContentCacheKeyPrefix = "answer:config:key:"
)

View File

@ -1,5 +1,11 @@
package entity
import (
"encoding/json"
"github.com/answerdev/answer/pkg/converter"
)
// Config config
type Config struct {
ID int `xorm:"not null pk autoincr INT(11) id"`
@ -8,6 +14,36 @@ type Config struct {
}
// TableName config table name
func (Config) TableName() string {
func (c *Config) TableName() string {
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/reason"
"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/config"
"github.com/segmentfault/pacman/errors"
"github.com/segmentfault/pacman/log"
)
// activityRepo activity repository
type activityRepo struct {
data *data.Data
configService *config.ConfigService
}
// NewActivityRepo new repository
func NewActivityRepo(
data *data.Data,
configService *config.ConfigService,
) activity.ActivityRepo {
return &activityRepo{
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")
if !showVote {
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,
} {
activityTypeNotShown = append(activityTypeNotShown, config.Key2IDMapping[fmt.Sprintf("%s.%s", obj, act)])
}
}
activityTypeNotShown := ar.getAllActivityType(ctx)
session.NotIn("activity_type", activityTypeNotShown)
}
err = session.Find(&activityList, &entity.Activity{OriginalObjectID: objectID})
@ -52,3 +46,23 @@ func (ar *activityRepo) GetObjectAllActivity(ctx context.Context, objectID strin
}
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

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

View File

@ -32,7 +32,7 @@ import (
type VoteRepo struct {
data *data.Data
uniqueIDRepo unique.UniqueIDRepo
configRepo config.ConfigRepo
configService *config.ConfigService
activityRepo activity_common.ActivityRepo
userRankRepo rank.UserRankRepo
voteCommon activity_common.VoteRepo
@ -42,7 +42,7 @@ type VoteRepo struct {
func NewVoteRepo(
data *data.Data,
uniqueIDRepo unique.UniqueIDRepo,
configRepo config.ConfigRepo,
configService *config.ConfigService,
activityRepo activity_common.ActivityRepo,
userRankRepo rank.UserRankRepo,
voteCommon activity_common.VoteRepo,
@ -50,7 +50,7 @@ func NewVoteRepo(
return &VoteRepo{
data: data,
uniqueIDRepo: uniqueIDRepo,
configRepo: configRepo,
configService: configService,
activityRepo: activityRepo,
userRankRepo: userRankRepo,
voteCommon: voteCommon,

View File

@ -23,32 +23,35 @@ import (
type ActivityRepo struct {
data *data.Data
uniqueIDRepo unique.UniqueIDRepo
configRepo config.ConfigRepo
configService *config.ConfigService
}
// NewActivityRepo new repository
func NewActivityRepo(
data *data.Data,
uniqueIDRepo unique.UniqueIDRepo,
configRepo config.ConfigRepo,
configService *config.ConfigService,
) activity_common.ActivityRepo {
return &ActivityRepo{
data: data,
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)
if err != nil {
return
}
confKey := fmt.Sprintf("%s.%s", objectKey, action)
activityType, _ = ar.configRepo.GetConfigType(confKey)
rank, err = ar.configRepo.GetInt(confKey)
cfg, err := ar.configService.GetConfigByKey(ctx, confKey)
if err != nil {
return
}
rank = cfg.GetIntValue()
hasRank = 0
if rank != 0 {
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) {
confKey := fmt.Sprintf("%s.%s", objectKey, action)
activityType, err = ar.configRepo.GetConfigType(confKey)
configKey := fmt.Sprintf("%s.%s", objectKey, action)
cfg, err := ar.configService.GetConfigByKey(ctx, configKey)
if err != nil {
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) {
activityType, err = ar.configRepo.GetConfigType(configKey)
cfg, err := ar.configService.GetConfigByKey(ctx, configKey)
if err != nil {
err = errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
}
return
return cfg.ID, nil
}
func (ar *ActivityRepo) GetActivity(ctx context.Context, session *xorm.Session,
@ -134,9 +137,9 @@ func (ar *ActivityRepo) GetUsersWhoHasVoteMost(
actIDs := make([]int, 0)
for _, act := range activity_type.ActivityTypeList {
configType, err := ar.configRepo.GetConfigType(act)
cfg, err := ar.configService.GetConfigByKey(ctx, act)
if err == nil {
actIDs = append(actIDs, configType)
actIDs = append(actIDs, cfg.ID)
}
}

View File

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

View File

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

View File

@ -13,12 +13,12 @@ import (
)
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{
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)
resp = make([]*schema.ReasonItem, 0)
reasonKeys, err := rr.configRepo.GetArrayString(reasonAction)
reasonKeys, err := rr.configService.GetArrayStringValue(ctx, reasonAction)
if err != nil {
return nil, err
}
for _, reasonKey := range reasonKeys {
cfgValue, err := rr.configRepo.GetString(reasonKey)
cfg, err := rr.configService.GetConfigByKey(ctx, reasonKey)
if err != nil {
log.Error(err)
continue
}
reason := &schema.ReasonItem{}
err = json.Unmarshal([]byte(cfgValue), reason)
err = json.Unmarshal(cfg.GetByteValue(), reason)
if err != nil {
log.Error(err)
continue
}
reason.Translate(reasonKey, lang)
reason.ReasonType, err = rr.configRepo.GetConfigType(reasonKey)
if err != nil {
log.Error(err)
continue
}
reason.ReasonType = cfg.ID
resp = append(resp, reason)
}
return resp, nil

View File

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

View File

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

View File

@ -5,13 +5,12 @@ import (
"testing"
"github.com/answerdev/answer/internal/entity"
"github.com/answerdev/answer/internal/repo/config"
"github.com/answerdev/answer/internal/repo/user"
"github.com/stretchr/testify/assert"
)
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{
Username: "answer",
Pass: "answer",
@ -26,7 +25,7 @@ func Test_userRepo_AddUser(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"})
assert.NoError(t, err)
assert.Equal(t, 1, len(got))
@ -34,7 +33,7 @@ func Test_userRepo_BatchGetByID(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")
assert.NoError(t, err)
assert.True(t, exist)
@ -42,7 +41,7 @@ func Test_userRepo_GetByEmail(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")
assert.NoError(t, err)
assert.True(t, exist)
@ -50,7 +49,7 @@ func Test_userRepo_GetByUserID(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")
assert.NoError(t, err)
assert.True(t, exist)
@ -58,7 +57,7 @@ func Test_userRepo_GetByUsername(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)
assert.NoError(t, err)
@ -69,7 +68,7 @@ func Test_userRepo_IncreaseAnswerCount(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)
assert.NoError(t, err)
@ -80,19 +79,19 @@ func Test_userRepo_IncreaseQuestionCount(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")
assert.NoError(t, err)
}
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)
assert.NoError(t, err)
}
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"})
assert.NoError(t, err)
@ -103,19 +102,19 @@ func Test_userRepo_UpdateInfo(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")
assert.NoError(t, err)
}
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)
assert.NoError(t, err)
}
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")
assert.NoError(t, err)
}

View File

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

View File

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

View File

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

View File

@ -1,16 +1,18 @@
package config
import "context"
import (
"context"
"encoding/json"
"fmt"
"github.com/answerdev/answer/internal/entity"
)
// ConfigRepo config repository
type ConfigRepo interface {
Get(key string) (interface{}, error)
GetString(key string) (string, error)
GetInt(key string) (int, 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)
GetConfigByID(ctx context.Context, id int) (c *entity.Config, err error)
GetConfigByKey(ctx context.Context, key string) (c *entity.Config, err error)
UpdateConfig(ctx context.Context, key, value string) (err error)
}
// ConfigService user service
@ -18,8 +20,70 @@ type ConfigService struct {
configRepo ConfigRepo
}
// NewConfigService new config service
func NewConfigService(configRepo ConfigRepo) *ConfigService {
return &ConfigService{
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
userRepo usercommon.UserRepo
reportRepo report_common.ReportRepo
configRepo config.ConfigRepo
configService *config.ConfigService
siteInfoService *siteinfo_common.SiteInfoCommonService
serviceConfig *service_config.ServiceConfig
@ -49,7 +49,7 @@ func NewDashboardService(
voteRepo activity_common.VoteRepo,
userRepo usercommon.UserRepo,
reportRepo report_common.ReportRepo,
configRepo config.ConfigRepo,
configService *config.ConfigService,
siteInfoService *siteinfo_common.SiteInfoCommonService,
serviceConfig *service_config.ServiceConfig,
@ -62,7 +62,7 @@ func NewDashboardService(
voteRepo: voteRepo,
userRepo: userRepo,
reportRepo: reportRepo,
configRepo: configRepo,
configService: configService,
siteInfoService: siteInfoService,
serviceConfig: serviceConfig,
@ -131,12 +131,11 @@ func (ds *DashboardService) Statistical(ctx context.Context) (*schema.DashboardI
var activityTypes []int
for _, typeKey := range typeKeys {
var t int
t, err = ds.configRepo.GetConfigType(typeKey)
cfg, err := ds.configService.GetConfigByKey(ctx, typeKey)
if err != nil {
continue
}
activityTypes = append(activityTypes, t)
activityTypes = append(activityTypes, cfg.ID)
}
voteCount, err := ds.voteRepo.GetVoteCount(ctx, activityTypes)
@ -166,7 +165,7 @@ func (ds *DashboardService) Statistical(ctx context.Context) (*schema.DashboardI
dashboardInfo.ReportCount = reportCount
dashboardInfo.UploadingFiles = true
emailconfig, err := ds.GetEmailConfig()
emailconfig, err := ds.GetEmailConfig(ctx)
if err != nil {
return dashboardInfo, err
}
@ -225,8 +224,8 @@ func (ds *DashboardService) RemoteVersion(ctx context.Context) string {
return remoteVersion.Release.Version
}
func (ds *DashboardService) GetEmailConfig() (ec *export.EmailConfig, err error) {
emailConf, err := ds.configRepo.GetString("email.config")
func (ds *DashboardService) GetEmailConfig(ctx context.Context) (ec *export.EmailConfig, err error) {
emailConf, err := ds.configService.GetStringValue(ctx, "email.config")
if err != nil {
return nil, err
}

View File

@ -24,7 +24,7 @@ import (
// EmailService kit service
type EmailService struct {
configRepo config.ConfigRepo
configService *config.ConfigService
emailRepo EmailRepo
siteInfoRepo siteinfo_common.SiteInfoRepo
}
@ -36,9 +36,9 @@ type EmailRepo interface {
}
// 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{
configRepo: configRepo,
configService: configService,
emailRepo: emailRepo,
siteInfoRepo: siteInfoRepo,
}
@ -114,7 +114,7 @@ func (es *EmailService) SendAndSaveCodeWithTime(
// Send email send
func (es *EmailService) Send(ctx context.Context, toEmailAddr, subject, body string) {
log.Infof("try to send email to %s", toEmailAddr)
ec, err := es.GetEmailConfig()
ec, err := es.GetEmailConfig(ctx)
if err != nil {
log.Errorf("get email config failed: %s", err)
return
@ -298,8 +298,8 @@ func (es *EmailService) NewCommentTemplate(ctx context.Context, raw *schema.NewC
return title, body, nil
}
func (es *EmailService) GetEmailConfig() (ec *EmailConfig, err error) {
emailConf, err := es.configRepo.GetString("email.config")
func (es *EmailService) GetEmailConfig(ctx context.Context) (ec *EmailConfig, err error) {
emailConf, err := es.configService.GetStringValue(ctx, "email.config")
if err != nil {
return nil, err
}
@ -314,5 +314,5 @@ func (es *EmailService) GetEmailConfig() (ec *EmailConfig, err error) {
// SetEmailConfig set email config
func (es *EmailService) SetEmailConfig(ctx context.Context, ec *EmailConfig) (err error) {
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
type PluginCommonService struct {
configRepo config.ConfigRepo
configService *config.ConfigService
pluginConfigRepo PluginConfigRepo
}
// NewPluginCommonService new report service
func NewPluginCommonService(
pluginConfigRepo PluginConfigRepo,
configRepo config.ConfigRepo) *PluginCommonService {
configService *config.ConfigService) *PluginCommonService {
// init plugin status
pluginStatus, err := configRepo.GetString(constant.PluginStatus)
pluginStatus, err := configService.GetStringValue(context.TODO(), constant.PluginStatus)
if err != nil {
log.Error(err)
} else {
@ -59,7 +59,7 @@ func NewPluginCommonService(
}
return &PluginCommonService{
configRepo: configRepo,
configService: configService,
pluginConfigRepo: pluginConfigRepo,
}
}
@ -70,7 +70,7 @@ func (ps *PluginCommonService) UpdatePluginStatus(ctx context.Context) (err erro
if err != nil {
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

View File

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

View File

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

View File

@ -34,7 +34,7 @@ type UserRankRepo interface {
// RankService rank service
type RankService struct {
userCommon *usercommon.UserCommon
configRepo config.ConfigRepo
configService *config.ConfigService
userRankRepo UserRankRepo
objectInfoService *object_info.ObjService
roleService *role.UserRoleRelService
@ -48,10 +48,10 @@ func NewRankService(
objectInfoService *object_info.ObjService,
roleService *role.UserRoleRelService,
rolePowerService *role.RolePowerRelService,
configRepo config.ConfigRepo) *RankService {
configService *config.ConfigService) *RankService {
return &RankService{
userCommon: userCommon,
configRepo: configRepo,
configService: configService,
userRankRepo: userRankRepo,
objectInfoService: objectInfoService,
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) (
can bool, rank int) {
// 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 {
log.Error(err)
return false, requireRank

View File

@ -2,9 +2,9 @@ package report_admin
import (
"context"
"encoding/json"
"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/object_info"
"github.com/answerdev/answer/pkg/htmltext"
@ -32,7 +32,7 @@ type ReportAdminService struct {
questionRepo questioncommon.QuestionRepo
commentCommonRepo comment_common.CommentCommonRepo
reportHandle *report_handle_admin.ReportHandle
configRepo config.ConfigRepo
configService *config.ConfigService
objectInfoService *object_info.ObjService
}
@ -44,7 +44,7 @@ func NewReportAdminService(
questionRepo questioncommon.QuestionRepo,
commentCommonRepo comment_common.CommentCommonRepo,
reportHandle *report_handle_admin.ReportHandle,
configRepo config.ConfigRepo,
configService *config.ConfigService,
objectInfoService *object_info.ObjService) *ReportAdminService {
return &ReportAdminService{
reportRepo: reportRepo,
@ -53,7 +53,7 @@ func NewReportAdminService(
questionRepo: questionRepo,
commentCommonRepo: commentCommonRepo,
reportHandle: reportHandle,
configRepo: configRepo,
configService: configService,
objectInfoService: objectInfoService,
}
}
@ -151,21 +151,25 @@ func (rs *ReportAdminService) decorateReportResp(ctx context.Context, resp *sche
resp.CommentID = objectInfo.CommentID
resp.Title = objectInfo.Title
resp.Excerpt = htmltext.FetchExcerpt(objectInfo.Content, "...", 240)
resp.Reason.Translate(configrepo.ID2KeyMapping[resp.ReportType], lang)
if resp.ReportType > 0 {
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 {
log.Error(err)
} else {
_ = json.Unmarshal([]byte(cf.Value), resp.Reason)
resp.Reason.Translate(cf.Key, lang)
}
}
if resp.FlaggedType > 0 {
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 {
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 {
questionCommon *questioncommon.QuestionCommon
commentRepo comment.CommentRepo
configRepo config.ConfigRepo
configService *config.ConfigService
}
func NewReportHandle(
questionCommon *questioncommon.QuestionCommon,
commentRepo comment.CommentRepo,
configRepo config.ConfigRepo) *ReportHandle {
configService *config.ConfigService) *ReportHandle {
return &ReportHandle{
questionCommon: questionCommon,
commentRepo: commentRepo,
configRepo: configRepo,
configService: configService,
}
}
// HandleObject this handle object status
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 (
objectID = reported.ObjectID
reportedUserID = reported.ReportedUserID
objectKey string
reasonDelete, _ = rh.configRepo.GetConfigType("reason.needs_delete")
reasonClose, _ = rh.configRepo.GetConfigType("reason.needs_close")
)
objectKey, err = obj.GetObjectTypeStrByObjectID(objectID)
@ -48,9 +54,9 @@ func (rh *ReportHandle) HandleObject(ctx context.Context, reported *entity.Repor
switch objectKey {
case "question":
switch req.FlaggedType {
case reasonDelete:
case reasonDeleteCfg.ID:
err = rh.questionCommon.RemoveQuestion(ctx, &schema.RemoveQuestionReq{ID: objectID})
case reasonClose:
case reasonCloseCfg.ID:
err = rh.questionCommon.CloseQuestion(ctx, &schema.CloseQuestionReq{
ID: objectID,
CloseType: req.FlaggedType,
@ -59,12 +65,12 @@ func (rh *ReportHandle) HandleObject(ctx context.Context, reported *entity.Repor
}
case "answer":
switch req.FlaggedType {
case reasonDelete:
case reasonDeleteCfg.ID:
err = rh.questionCommon.RemoveAnswer(ctx, objectID)
}
case "comment":
switch req.FlaggedType {
case reasonDelete:
case reasonCloseCfg.ID:
err = rh.commentRepo.RemoveComment(ctx, objectID)
rh.sendNotification(ctx, reportedUserID, objectID, constant.NotificationYourCommentWasDeleted)
}

View File

@ -26,7 +26,7 @@ type SiteInfoService struct {
siteInfoCommonService *siteinfo_common.SiteInfoCommonService
emailService *export.EmailService
tagCommonService *tagcommon.TagCommonService
configRepo config.ConfigRepo
configService *config.ConfigService
}
func NewSiteInfoService(
@ -34,7 +34,7 @@ func NewSiteInfoService(
siteInfoCommonService *siteinfo_common.SiteInfoCommonService,
emailService *export.EmailService,
tagCommonService *tagcommon.TagCommonService,
configRepo config.ConfigRepo,
configService *config.ConfigService,
) *SiteInfoService {
usersSiteInfo, _ := siteInfoCommonService.GetSiteUsers(context.Background())
if usersSiteInfo != nil {
@ -51,7 +51,7 @@ func NewSiteInfoService(
siteInfoCommonService: siteInfoCommonService,
emailService: emailService,
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) (
resp *schema.GetSMTPConfigResp, err error,
) {
emailConfig, err := s.emailService.GetEmailConfig()
emailConfig, err := s.emailService.GetEmailConfig(ctx)
if err != nil {
return nil, err
}
@ -250,7 +250,7 @@ func (s *SiteInfoService) GetSMTPConfig(ctx context.Context) (
// UpdateSMTPConfig get smtp config
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 {
return err
}
@ -372,7 +372,7 @@ func (s *SiteInfoService) UpdatePrivilegesConfig(ctx context.Context, req *schem
// update privilege in config
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 {
return err
}

View File

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