mirror of https://gitee.com/answerdev/answer.git
Merge remote-tracking branch 'origin/feat/0.7.0/user-manage' into test
This commit is contained in:
commit
1d3c6e531c
|
@ -116,14 +116,14 @@ func initApplication(debug bool, serverConf *conf.Server, dbConf *data.Database,
|
|||
roleRepo := role.NewRoleRepo(dataData)
|
||||
roleService := role2.NewRoleService(roleRepo)
|
||||
userRoleRelService := role2.NewUserRoleRelService(userRoleRelRepo, roleService)
|
||||
userService := service.NewUserService(userRepo, userActiveActivityRepo, emailService, authService, serviceConf, siteInfoCommonService, userRoleRelService)
|
||||
userCommon := usercommon.NewUserCommon(userRepo)
|
||||
userService := service.NewUserService(userRepo, userActiveActivityRepo, emailService, authService, serviceConf, siteInfoCommonService, userRoleRelService, userCommon)
|
||||
captchaRepo := captcha.NewCaptchaRepo(dataData)
|
||||
captchaService := action.NewCaptchaService(captchaRepo)
|
||||
uploaderService := uploader.NewUploaderService(serviceConf, siteInfoCommonService)
|
||||
userController := controller.NewUserController(authService, userService, captchaService, emailService, uploaderService)
|
||||
userController := controller.NewUserController(authService, userService, captchaService, emailService, uploaderService, siteInfoCommonService)
|
||||
commentRepo := comment.NewCommentRepo(dataData, uniqueIDRepo)
|
||||
commentCommonRepo := comment.NewCommentCommonRepo(dataData, uniqueIDRepo)
|
||||
userCommon := usercommon.NewUserCommon(userRepo)
|
||||
answerRepo := answer.NewAnswerRepo(dataData, uniqueIDRepo, userRankRepo, activityRepo)
|
||||
questionRepo := question.NewQuestionRepo(dataData, uniqueIDRepo)
|
||||
tagCommonRepo := tag_common.NewTagCommonRepo(dataData, uniqueIDRepo)
|
||||
|
@ -180,13 +180,13 @@ func initApplication(debug bool, serverConf *conf.Server, dbConf *data.Database,
|
|||
reportBackyardService := report_backyard.NewReportBackyardService(reportRepo, userCommon, commonRepo, answerRepo, questionRepo, commentCommonRepo, reportHandle, configRepo)
|
||||
controller_backyardReportController := controller_backyard.NewReportController(reportBackyardService)
|
||||
userBackyardRepo := user.NewUserBackyardRepo(dataData, authRepo)
|
||||
userBackyardService := user_backyard.NewUserBackyardService(userBackyardRepo, userRoleRelService, authService)
|
||||
userBackyardService := user_backyard.NewUserBackyardService(userBackyardRepo, userRoleRelService, authService, userCommon)
|
||||
userBackyardController := controller_backyard.NewUserBackyardController(userBackyardService)
|
||||
reasonRepo := reason.NewReasonRepo(configRepo)
|
||||
reasonService := reason2.NewReasonService(reasonRepo)
|
||||
reasonController := controller.NewReasonController(reasonService)
|
||||
themeController := controller_backyard.NewThemeController()
|
||||
siteInfoService := siteinfo.NewSiteInfoService(siteInfoRepo, emailService, tagCommonService)
|
||||
siteInfoService := siteinfo.NewSiteInfoService(siteInfoRepo, siteInfoCommonService, emailService, tagCommonService)
|
||||
siteInfoController := controller_backyard.NewSiteInfoController(siteInfoService)
|
||||
siteinfoController := controller.NewSiteinfoController(siteInfoCommonService)
|
||||
notificationRepo := notification.NewNotificationRepo(dataData)
|
||||
|
@ -204,7 +204,7 @@ func initApplication(debug bool, serverConf *conf.Server, dbConf *data.Database,
|
|||
answerAPIRouter := router.NewAnswerAPIRouter(langController, userController, commentController, reportController, voteController, tagController, followController, collectionController, questionController, answerController, searchController, revisionController, rankController, controller_backyardReportController, userBackyardController, reasonController, themeController, siteInfoController, siteinfoController, notificationController, dashboardController, uploadController, activityController, roleController)
|
||||
swaggerRouter := router.NewSwaggerRouter(swaggerConf)
|
||||
uiRouter := router.NewUIRouter(siteinfoController)
|
||||
authUserMiddleware := middleware.NewAuthUserMiddleware(authService)
|
||||
authUserMiddleware := middleware.NewAuthUserMiddleware(authService, siteInfoCommonService)
|
||||
avatarMiddleware := middleware.NewAvatarMiddleware(serviceConf, uploaderService)
|
||||
templateRenderController := templaterender.NewTemplateRenderController(questionService, userService, tagService, answerService, commentService)
|
||||
templateController := controller.NewTemplateController(templateRenderController, siteInfoCommonService)
|
||||
|
|
449
docs/docs.go
449
docs/docs.go
|
@ -609,6 +609,77 @@ const docTemplate = `{
|
|||
}
|
||||
}
|
||||
},
|
||||
"/answer/admin/api/siteinfo/custom-css-html": {
|
||||
"get": {
|
||||
"security": [
|
||||
{
|
||||
"ApiKeyAuth": []
|
||||
}
|
||||
],
|
||||
"description": "get site info custom html css config",
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"admin"
|
||||
],
|
||||
"summary": "get site info custom html css config",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/handler.RespBody"
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"data": {
|
||||
"$ref": "#/definitions/schema.SiteCustomCssHTMLResp"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"put": {
|
||||
"security": [
|
||||
{
|
||||
"ApiKeyAuth": []
|
||||
}
|
||||
],
|
||||
"description": "update site custom css html config",
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"admin"
|
||||
],
|
||||
"summary": "update site custom css html config",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "login info",
|
||||
"name": "data",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/schema.SiteCustomCssHTMLReq"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/handler.RespBody"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/answer/admin/api/siteinfo/general": {
|
||||
"get": {
|
||||
"security": [
|
||||
|
@ -822,6 +893,77 @@ const docTemplate = `{
|
|||
}
|
||||
}
|
||||
},
|
||||
"/answer/admin/api/siteinfo/login": {
|
||||
"get": {
|
||||
"security": [
|
||||
{
|
||||
"ApiKeyAuth": []
|
||||
}
|
||||
],
|
||||
"description": "get site info login config",
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"admin"
|
||||
],
|
||||
"summary": "get site info login config",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/handler.RespBody"
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"data": {
|
||||
"$ref": "#/definitions/schema.SiteLoginResp"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"put": {
|
||||
"security": [
|
||||
{
|
||||
"ApiKeyAuth": []
|
||||
}
|
||||
],
|
||||
"description": "update site login",
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"admin"
|
||||
],
|
||||
"summary": "update site login",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "login info",
|
||||
"name": "data",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/schema.SiteLoginReq"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/handler.RespBody"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/answer/admin/api/siteinfo/seo": {
|
||||
"get": {
|
||||
"security": [
|
||||
|
@ -893,6 +1035,77 @@ const docTemplate = `{
|
|||
}
|
||||
}
|
||||
},
|
||||
"/answer/admin/api/siteinfo/theme": {
|
||||
"get": {
|
||||
"security": [
|
||||
{
|
||||
"ApiKeyAuth": []
|
||||
}
|
||||
],
|
||||
"description": "get site info theme config",
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"admin"
|
||||
],
|
||||
"summary": "get site info theme config",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/handler.RespBody"
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"data": {
|
||||
"$ref": "#/definitions/schema.SiteThemeResp"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"put": {
|
||||
"security": [
|
||||
{
|
||||
"ApiKeyAuth": []
|
||||
}
|
||||
],
|
||||
"description": "update site custom css html config",
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"admin"
|
||||
],
|
||||
"summary": "update site custom css html config",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "login info",
|
||||
"name": "data",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/schema.SiteThemeReq"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/handler.RespBody"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/answer/admin/api/siteinfo/write": {
|
||||
"get": {
|
||||
"security": [
|
||||
|
@ -989,6 +1202,84 @@ const docTemplate = `{
|
|||
}
|
||||
}
|
||||
},
|
||||
"/answer/admin/api/user": {
|
||||
"post": {
|
||||
"security": [
|
||||
{
|
||||
"ApiKeyAuth": []
|
||||
}
|
||||
],
|
||||
"description": "add user",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"admin"
|
||||
],
|
||||
"summary": "add user",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "user",
|
||||
"name": "data",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/schema.AddUserReq"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/handler.RespBody"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/answer/admin/api/user/password": {
|
||||
"put": {
|
||||
"security": [
|
||||
{
|
||||
"ApiKeyAuth": []
|
||||
}
|
||||
],
|
||||
"description": "update user password",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"admin"
|
||||
],
|
||||
"summary": "update user password",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "user",
|
||||
"name": "data",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/schema.UpdateUserPasswordReq"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/handler.RespBody"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/answer/admin/api/user/role": {
|
||||
"put": {
|
||||
"security": [
|
||||
|
@ -3456,7 +3747,7 @@ const docTemplate = `{
|
|||
"type": "object",
|
||||
"properties": {
|
||||
"data": {
|
||||
"$ref": "#/definitions/schema.SiteGeneralResp"
|
||||
"$ref": "#/definitions/schema.SiteInfoResp"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5059,6 +5350,29 @@ const docTemplate = `{
|
|||
}
|
||||
}
|
||||
},
|
||||
"schema.AddUserReq": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"display_name",
|
||||
"email",
|
||||
"password"
|
||||
],
|
||||
"properties": {
|
||||
"display_name": {
|
||||
"type": "string",
|
||||
"maxLength": 30
|
||||
},
|
||||
"email": {
|
||||
"type": "string",
|
||||
"maxLength": 500
|
||||
},
|
||||
"password": {
|
||||
"type": "string",
|
||||
"maxLength": 32,
|
||||
"minLength": 8
|
||||
}
|
||||
}
|
||||
},
|
||||
"schema.AdminSetAnswerStatusRequest": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
|
@ -6470,6 +6784,48 @@ const docTemplate = `{
|
|||
}
|
||||
}
|
||||
},
|
||||
"schema.SiteCustomCssHTMLReq": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"custom_css": {
|
||||
"type": "string",
|
||||
"maxLength": 65536
|
||||
},
|
||||
"custom_footer": {
|
||||
"type": "string",
|
||||
"maxLength": 65536
|
||||
},
|
||||
"custom_head": {
|
||||
"type": "string",
|
||||
"maxLength": 65536
|
||||
},
|
||||
"custom_header": {
|
||||
"type": "string",
|
||||
"maxLength": 65536
|
||||
}
|
||||
}
|
||||
},
|
||||
"schema.SiteCustomCssHTMLResp": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"custom_css": {
|
||||
"type": "string",
|
||||
"maxLength": 65536
|
||||
},
|
||||
"custom_footer": {
|
||||
"type": "string",
|
||||
"maxLength": 65536
|
||||
},
|
||||
"custom_head": {
|
||||
"type": "string",
|
||||
"maxLength": 65536
|
||||
},
|
||||
"custom_header": {
|
||||
"type": "string",
|
||||
"maxLength": 65536
|
||||
}
|
||||
}
|
||||
},
|
||||
"schema.SiteGeneralReq": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
|
@ -6542,6 +6898,26 @@ const docTemplate = `{
|
|||
}
|
||||
}
|
||||
},
|
||||
"schema.SiteInfoResp": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"branding": {
|
||||
"$ref": "#/definitions/schema.SiteBrandingResp"
|
||||
},
|
||||
"general": {
|
||||
"$ref": "#/definitions/schema.SiteGeneralResp"
|
||||
},
|
||||
"interface": {
|
||||
"$ref": "#/definitions/schema.SiteInterfaceResp"
|
||||
},
|
||||
"login": {
|
||||
"$ref": "#/definitions/schema.SiteLoginResp"
|
||||
},
|
||||
"theme": {
|
||||
"$ref": "#/definitions/schema.SiteThemeResp"
|
||||
}
|
||||
}
|
||||
},
|
||||
"schema.SiteInterfaceReq": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
|
@ -6620,6 +6996,28 @@ const docTemplate = `{
|
|||
}
|
||||
}
|
||||
},
|
||||
"schema.SiteLoginReq": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"allow_new_registrations": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"login_required": {
|
||||
"type": "boolean"
|
||||
}
|
||||
}
|
||||
},
|
||||
"schema.SiteLoginResp": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"allow_new_registrations": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"login_required": {
|
||||
"type": "boolean"
|
||||
}
|
||||
}
|
||||
},
|
||||
"schema.SiteSeoReq": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
|
@ -6642,6 +7040,38 @@ const docTemplate = `{
|
|||
}
|
||||
}
|
||||
},
|
||||
"schema.SiteThemeReq": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"theme"
|
||||
],
|
||||
"properties": {
|
||||
"theme": {
|
||||
"type": "string",
|
||||
"maxLength": 255
|
||||
},
|
||||
"theme_config": {
|
||||
"type": "object",
|
||||
"additionalProperties": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"schema.SiteThemeResp": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"theme"
|
||||
],
|
||||
"properties": {
|
||||
"theme": {
|
||||
"type": "string",
|
||||
"maxLength": 255
|
||||
},
|
||||
"theme_config": {
|
||||
"type": "object",
|
||||
"additionalProperties": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"schema.SiteWriteReq": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
|
@ -6954,6 +7384,23 @@ const docTemplate = `{
|
|||
}
|
||||
}
|
||||
},
|
||||
"schema.UpdateUserPasswordReq": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"password",
|
||||
"user_id"
|
||||
],
|
||||
"properties": {
|
||||
"password": {
|
||||
"type": "string",
|
||||
"maxLength": 32,
|
||||
"minLength": 8
|
||||
},
|
||||
"user_id": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"schema.UpdateUserRoleReq": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
|
|
|
@ -597,6 +597,77 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"/answer/admin/api/siteinfo/custom-css-html": {
|
||||
"get": {
|
||||
"security": [
|
||||
{
|
||||
"ApiKeyAuth": []
|
||||
}
|
||||
],
|
||||
"description": "get site info custom html css config",
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"admin"
|
||||
],
|
||||
"summary": "get site info custom html css config",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/handler.RespBody"
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"data": {
|
||||
"$ref": "#/definitions/schema.SiteCustomCssHTMLResp"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"put": {
|
||||
"security": [
|
||||
{
|
||||
"ApiKeyAuth": []
|
||||
}
|
||||
],
|
||||
"description": "update site custom css html config",
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"admin"
|
||||
],
|
||||
"summary": "update site custom css html config",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "login info",
|
||||
"name": "data",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/schema.SiteCustomCssHTMLReq"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/handler.RespBody"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/answer/admin/api/siteinfo/general": {
|
||||
"get": {
|
||||
"security": [
|
||||
|
@ -810,6 +881,77 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"/answer/admin/api/siteinfo/login": {
|
||||
"get": {
|
||||
"security": [
|
||||
{
|
||||
"ApiKeyAuth": []
|
||||
}
|
||||
],
|
||||
"description": "get site info login config",
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"admin"
|
||||
],
|
||||
"summary": "get site info login config",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/handler.RespBody"
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"data": {
|
||||
"$ref": "#/definitions/schema.SiteLoginResp"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"put": {
|
||||
"security": [
|
||||
{
|
||||
"ApiKeyAuth": []
|
||||
}
|
||||
],
|
||||
"description": "update site login",
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"admin"
|
||||
],
|
||||
"summary": "update site login",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "login info",
|
||||
"name": "data",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/schema.SiteLoginReq"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/handler.RespBody"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/answer/admin/api/siteinfo/seo": {
|
||||
"get": {
|
||||
"security": [
|
||||
|
@ -881,6 +1023,77 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"/answer/admin/api/siteinfo/theme": {
|
||||
"get": {
|
||||
"security": [
|
||||
{
|
||||
"ApiKeyAuth": []
|
||||
}
|
||||
],
|
||||
"description": "get site info theme config",
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"admin"
|
||||
],
|
||||
"summary": "get site info theme config",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/handler.RespBody"
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"data": {
|
||||
"$ref": "#/definitions/schema.SiteThemeResp"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"put": {
|
||||
"security": [
|
||||
{
|
||||
"ApiKeyAuth": []
|
||||
}
|
||||
],
|
||||
"description": "update site custom css html config",
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"admin"
|
||||
],
|
||||
"summary": "update site custom css html config",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "login info",
|
||||
"name": "data",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/schema.SiteThemeReq"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/handler.RespBody"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/answer/admin/api/siteinfo/write": {
|
||||
"get": {
|
||||
"security": [
|
||||
|
@ -977,6 +1190,84 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"/answer/admin/api/user": {
|
||||
"post": {
|
||||
"security": [
|
||||
{
|
||||
"ApiKeyAuth": []
|
||||
}
|
||||
],
|
||||
"description": "add user",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"admin"
|
||||
],
|
||||
"summary": "add user",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "user",
|
||||
"name": "data",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/schema.AddUserReq"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/handler.RespBody"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/answer/admin/api/user/password": {
|
||||
"put": {
|
||||
"security": [
|
||||
{
|
||||
"ApiKeyAuth": []
|
||||
}
|
||||
],
|
||||
"description": "update user password",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"admin"
|
||||
],
|
||||
"summary": "update user password",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "user",
|
||||
"name": "data",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/schema.UpdateUserPasswordReq"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/handler.RespBody"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/answer/admin/api/user/role": {
|
||||
"put": {
|
||||
"security": [
|
||||
|
@ -3444,7 +3735,7 @@
|
|||
"type": "object",
|
||||
"properties": {
|
||||
"data": {
|
||||
"$ref": "#/definitions/schema.SiteGeneralResp"
|
||||
"$ref": "#/definitions/schema.SiteInfoResp"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5047,6 +5338,29 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"schema.AddUserReq": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"display_name",
|
||||
"email",
|
||||
"password"
|
||||
],
|
||||
"properties": {
|
||||
"display_name": {
|
||||
"type": "string",
|
||||
"maxLength": 30
|
||||
},
|
||||
"email": {
|
||||
"type": "string",
|
||||
"maxLength": 500
|
||||
},
|
||||
"password": {
|
||||
"type": "string",
|
||||
"maxLength": 32,
|
||||
"minLength": 8
|
||||
}
|
||||
}
|
||||
},
|
||||
"schema.AdminSetAnswerStatusRequest": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
|
@ -6458,6 +6772,48 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"schema.SiteCustomCssHTMLReq": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"custom_css": {
|
||||
"type": "string",
|
||||
"maxLength": 65536
|
||||
},
|
||||
"custom_footer": {
|
||||
"type": "string",
|
||||
"maxLength": 65536
|
||||
},
|
||||
"custom_head": {
|
||||
"type": "string",
|
||||
"maxLength": 65536
|
||||
},
|
||||
"custom_header": {
|
||||
"type": "string",
|
||||
"maxLength": 65536
|
||||
}
|
||||
}
|
||||
},
|
||||
"schema.SiteCustomCssHTMLResp": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"custom_css": {
|
||||
"type": "string",
|
||||
"maxLength": 65536
|
||||
},
|
||||
"custom_footer": {
|
||||
"type": "string",
|
||||
"maxLength": 65536
|
||||
},
|
||||
"custom_head": {
|
||||
"type": "string",
|
||||
"maxLength": 65536
|
||||
},
|
||||
"custom_header": {
|
||||
"type": "string",
|
||||
"maxLength": 65536
|
||||
}
|
||||
}
|
||||
},
|
||||
"schema.SiteGeneralReq": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
|
@ -6530,6 +6886,26 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"schema.SiteInfoResp": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"branding": {
|
||||
"$ref": "#/definitions/schema.SiteBrandingResp"
|
||||
},
|
||||
"general": {
|
||||
"$ref": "#/definitions/schema.SiteGeneralResp"
|
||||
},
|
||||
"interface": {
|
||||
"$ref": "#/definitions/schema.SiteInterfaceResp"
|
||||
},
|
||||
"login": {
|
||||
"$ref": "#/definitions/schema.SiteLoginResp"
|
||||
},
|
||||
"theme": {
|
||||
"$ref": "#/definitions/schema.SiteThemeResp"
|
||||
}
|
||||
}
|
||||
},
|
||||
"schema.SiteInterfaceReq": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
|
@ -6608,6 +6984,28 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"schema.SiteLoginReq": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"allow_new_registrations": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"login_required": {
|
||||
"type": "boolean"
|
||||
}
|
||||
}
|
||||
},
|
||||
"schema.SiteLoginResp": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"allow_new_registrations": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"login_required": {
|
||||
"type": "boolean"
|
||||
}
|
||||
}
|
||||
},
|
||||
"schema.SiteSeoReq": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
|
@ -6630,6 +7028,38 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"schema.SiteThemeReq": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"theme"
|
||||
],
|
||||
"properties": {
|
||||
"theme": {
|
||||
"type": "string",
|
||||
"maxLength": 255
|
||||
},
|
||||
"theme_config": {
|
||||
"type": "object",
|
||||
"additionalProperties": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"schema.SiteThemeResp": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"theme"
|
||||
],
|
||||
"properties": {
|
||||
"theme": {
|
||||
"type": "string",
|
||||
"maxLength": 255
|
||||
},
|
||||
"theme_config": {
|
||||
"type": "object",
|
||||
"additionalProperties": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"schema.SiteWriteReq": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
|
@ -6942,6 +7372,23 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"schema.UpdateUserPasswordReq": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"password",
|
||||
"user_id"
|
||||
],
|
||||
"properties": {
|
||||
"password": {
|
||||
"type": "string",
|
||||
"maxLength": 32,
|
||||
"minLength": 8
|
||||
},
|
||||
"user_id": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"schema.UpdateUserRoleReq": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
|
|
|
@ -176,6 +176,23 @@ definitions:
|
|||
- object_id
|
||||
- report_type
|
||||
type: object
|
||||
schema.AddUserReq:
|
||||
properties:
|
||||
display_name:
|
||||
maxLength: 30
|
||||
type: string
|
||||
email:
|
||||
maxLength: 500
|
||||
type: string
|
||||
password:
|
||||
maxLength: 32
|
||||
minLength: 8
|
||||
type: string
|
||||
required:
|
||||
- display_name
|
||||
- email
|
||||
- password
|
||||
type: object
|
||||
schema.AdminSetAnswerStatusRequest:
|
||||
properties:
|
||||
answer_id:
|
||||
|
@ -1189,6 +1206,36 @@ definitions:
|
|||
- logo
|
||||
- square_icon
|
||||
type: object
|
||||
schema.SiteCustomCssHTMLReq:
|
||||
properties:
|
||||
custom_css:
|
||||
maxLength: 65536
|
||||
type: string
|
||||
custom_footer:
|
||||
maxLength: 65536
|
||||
type: string
|
||||
custom_head:
|
||||
maxLength: 65536
|
||||
type: string
|
||||
custom_header:
|
||||
maxLength: 65536
|
||||
type: string
|
||||
type: object
|
||||
schema.SiteCustomCssHTMLResp:
|
||||
properties:
|
||||
custom_css:
|
||||
maxLength: 65536
|
||||
type: string
|
||||
custom_footer:
|
||||
maxLength: 65536
|
||||
type: string
|
||||
custom_head:
|
||||
maxLength: 65536
|
||||
type: string
|
||||
custom_header:
|
||||
maxLength: 65536
|
||||
type: string
|
||||
type: object
|
||||
schema.SiteGeneralReq:
|
||||
properties:
|
||||
contact_email:
|
||||
|
@ -1243,6 +1290,19 @@ definitions:
|
|||
- permalink
|
||||
- site_url
|
||||
type: object
|
||||
schema.SiteInfoResp:
|
||||
properties:
|
||||
branding:
|
||||
$ref: '#/definitions/schema.SiteBrandingResp'
|
||||
general:
|
||||
$ref: '#/definitions/schema.SiteGeneralResp'
|
||||
interface:
|
||||
$ref: '#/definitions/schema.SiteInterfaceResp'
|
||||
login:
|
||||
$ref: '#/definitions/schema.SiteLoginResp'
|
||||
theme:
|
||||
$ref: '#/definitions/schema.SiteThemeResp'
|
||||
type: object
|
||||
schema.SiteInterfaceReq:
|
||||
properties:
|
||||
language:
|
||||
|
@ -1297,6 +1357,20 @@ definitions:
|
|||
terms_of_service_parsed_text:
|
||||
type: string
|
||||
type: object
|
||||
schema.SiteLoginReq:
|
||||
properties:
|
||||
allow_new_registrations:
|
||||
type: boolean
|
||||
login_required:
|
||||
type: boolean
|
||||
type: object
|
||||
schema.SiteLoginResp:
|
||||
properties:
|
||||
allow_new_registrations:
|
||||
type: boolean
|
||||
login_required:
|
||||
type: boolean
|
||||
type: object
|
||||
schema.SiteSeoReq:
|
||||
properties:
|
||||
robots:
|
||||
|
@ -1311,6 +1385,28 @@ definitions:
|
|||
required:
|
||||
- robots
|
||||
type: object
|
||||
schema.SiteThemeReq:
|
||||
properties:
|
||||
theme:
|
||||
maxLength: 255
|
||||
type: string
|
||||
theme_config:
|
||||
additionalProperties: true
|
||||
type: object
|
||||
required:
|
||||
- theme
|
||||
type: object
|
||||
schema.SiteThemeResp:
|
||||
properties:
|
||||
theme:
|
||||
maxLength: 255
|
||||
type: string
|
||||
theme_config:
|
||||
additionalProperties: true
|
||||
type: object
|
||||
required:
|
||||
- theme
|
||||
type: object
|
||||
schema.SiteWriteReq:
|
||||
properties:
|
||||
recommend_tags:
|
||||
|
@ -1533,6 +1629,18 @@ definitions:
|
|||
required:
|
||||
- language
|
||||
type: object
|
||||
schema.UpdateUserPasswordReq:
|
||||
properties:
|
||||
password:
|
||||
maxLength: 32
|
||||
minLength: 8
|
||||
type: string
|
||||
user_id:
|
||||
type: string
|
||||
required:
|
||||
- password
|
||||
- user_id
|
||||
type: object
|
||||
schema.UpdateUserRoleReq:
|
||||
properties:
|
||||
role_id:
|
||||
|
@ -2102,6 +2210,47 @@ paths:
|
|||
summary: update site info branding
|
||||
tags:
|
||||
- admin
|
||||
/answer/admin/api/siteinfo/custom-css-html:
|
||||
get:
|
||||
description: get site info custom html css config
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
allOf:
|
||||
- $ref: '#/definitions/handler.RespBody'
|
||||
- properties:
|
||||
data:
|
||||
$ref: '#/definitions/schema.SiteCustomCssHTMLResp'
|
||||
type: object
|
||||
security:
|
||||
- ApiKeyAuth: []
|
||||
summary: get site info custom html css config
|
||||
tags:
|
||||
- admin
|
||||
put:
|
||||
description: update site custom css html config
|
||||
parameters:
|
||||
- description: login info
|
||||
in: body
|
||||
name: data
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/schema.SiteCustomCssHTMLReq'
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/handler.RespBody'
|
||||
security:
|
||||
- ApiKeyAuth: []
|
||||
summary: update site custom css html config
|
||||
tags:
|
||||
- admin
|
||||
/answer/admin/api/siteinfo/general:
|
||||
get:
|
||||
description: get site general information
|
||||
|
@ -2225,6 +2374,47 @@ paths:
|
|||
summary: update site legal info
|
||||
tags:
|
||||
- admin
|
||||
/answer/admin/api/siteinfo/login:
|
||||
get:
|
||||
description: get site info login config
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
allOf:
|
||||
- $ref: '#/definitions/handler.RespBody'
|
||||
- properties:
|
||||
data:
|
||||
$ref: '#/definitions/schema.SiteLoginResp'
|
||||
type: object
|
||||
security:
|
||||
- ApiKeyAuth: []
|
||||
summary: get site info login config
|
||||
tags:
|
||||
- admin
|
||||
put:
|
||||
description: update site login
|
||||
parameters:
|
||||
- description: login info
|
||||
in: body
|
||||
name: data
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/schema.SiteLoginReq'
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/handler.RespBody'
|
||||
security:
|
||||
- ApiKeyAuth: []
|
||||
summary: update site login
|
||||
tags:
|
||||
- admin
|
||||
/answer/admin/api/siteinfo/seo:
|
||||
get:
|
||||
description: get site seo information
|
||||
|
@ -2266,6 +2456,47 @@ paths:
|
|||
summary: update site seo information
|
||||
tags:
|
||||
- admin
|
||||
/answer/admin/api/siteinfo/theme:
|
||||
get:
|
||||
description: get site info theme config
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
allOf:
|
||||
- $ref: '#/definitions/handler.RespBody'
|
||||
- properties:
|
||||
data:
|
||||
$ref: '#/definitions/schema.SiteThemeResp'
|
||||
type: object
|
||||
security:
|
||||
- ApiKeyAuth: []
|
||||
summary: get site info theme config
|
||||
tags:
|
||||
- admin
|
||||
put:
|
||||
description: update site custom css html config
|
||||
parameters:
|
||||
- description: login info
|
||||
in: body
|
||||
name: data
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/schema.SiteThemeReq'
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/handler.RespBody'
|
||||
security:
|
||||
- ApiKeyAuth: []
|
||||
summary: update site custom css html config
|
||||
tags:
|
||||
- admin
|
||||
/answer/admin/api/siteinfo/write:
|
||||
get:
|
||||
description: get site interface
|
||||
|
@ -2322,6 +2553,54 @@ paths:
|
|||
summary: Get theme options
|
||||
tags:
|
||||
- admin
|
||||
/answer/admin/api/user:
|
||||
post:
|
||||
consumes:
|
||||
- application/json
|
||||
description: add user
|
||||
parameters:
|
||||
- description: user
|
||||
in: body
|
||||
name: data
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/schema.AddUserReq'
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/handler.RespBody'
|
||||
security:
|
||||
- ApiKeyAuth: []
|
||||
summary: add user
|
||||
tags:
|
||||
- admin
|
||||
/answer/admin/api/user/password:
|
||||
put:
|
||||
consumes:
|
||||
- application/json
|
||||
description: update user password
|
||||
parameters:
|
||||
- description: user
|
||||
in: body
|
||||
name: data
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/schema.UpdateUserPasswordReq'
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/handler.RespBody'
|
||||
security:
|
||||
- ApiKeyAuth: []
|
||||
summary: update user password
|
||||
tags:
|
||||
- admin
|
||||
/answer/admin/api/user/role:
|
||||
put:
|
||||
consumes:
|
||||
|
@ -3824,7 +4103,7 @@ paths:
|
|||
- $ref: '#/definitions/handler.RespBody'
|
||||
- properties:
|
||||
data:
|
||||
$ref: '#/definitions/schema.SiteGeneralResp'
|
||||
$ref: '#/definitions/schema.SiteInfoResp'
|
||||
type: object
|
||||
summary: get site info
|
||||
tags:
|
||||
|
|
|
@ -145,6 +145,8 @@ backend:
|
|||
other: "Can’t create the config.yaml file."
|
||||
cannot_update_your_role:
|
||||
other: "You cannot modify your role."
|
||||
not_allowed_registration:
|
||||
other: "Currently the site is not open for registration"
|
||||
report:
|
||||
spam:
|
||||
name:
|
||||
|
|
|
@ -117,6 +117,8 @@ backend:
|
|||
other: "头像设置错误"
|
||||
cannot_update_your_role:
|
||||
other: "你无法修改自己的角色"
|
||||
not_allowed_registration:
|
||||
other: "目前该网站尚未开放注册"
|
||||
revision:
|
||||
review_underway:
|
||||
other: "目前无法编辑,有一个版本在审阅队列中。"
|
||||
|
|
|
@ -12,6 +12,8 @@ const (
|
|||
AdminTokenCacheTime = 7 * 24 * time.Hour
|
||||
AcceptLanguageFlag = "Accept-Language"
|
||||
UserTokenMappingCacheKey = "answer:user-token:mapping:"
|
||||
SiteInfoCacheKey = "answer:site-info:"
|
||||
SiteInfoCacheTime = 1 * time.Hour
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -54,12 +56,15 @@ var (
|
|||
)
|
||||
|
||||
const (
|
||||
SiteTypeGeneral = "general"
|
||||
SiteTypeInterface = "interface"
|
||||
SiteTypeBranding = "branding"
|
||||
SiteTypeWrite = "write"
|
||||
SiteTypeLegal = "legal"
|
||||
SiteTypeSeo = "seo"
|
||||
SiteTypeGeneral = "general"
|
||||
SiteTypeInterface = "interface"
|
||||
SiteTypeBranding = "branding"
|
||||
SiteTypeWrite = "write"
|
||||
SiteTypeLegal = "legal"
|
||||
SiteTypeSeo = "seo"
|
||||
SiteTypeLogin = "login"
|
||||
SiteTypeCustomCssHTML = "css-html"
|
||||
SiteTypeTheme = "theme"
|
||||
)
|
||||
|
||||
func ExistInPathIgnore(name string) bool {
|
||||
|
|
|
@ -4,6 +4,7 @@ import (
|
|||
"strings"
|
||||
|
||||
"github.com/answerdev/answer/internal/schema"
|
||||
"github.com/answerdev/answer/internal/service/siteinfo_common"
|
||||
|
||||
"github.com/answerdev/answer/internal/base/handler"
|
||||
"github.com/answerdev/answer/internal/base/reason"
|
||||
|
@ -18,13 +19,17 @@ var ctxUUIDKey = "ctxUuidKey"
|
|||
|
||||
// AuthUserMiddleware auth user middleware
|
||||
type AuthUserMiddleware struct {
|
||||
authService *auth.AuthService
|
||||
authService *auth.AuthService
|
||||
siteInfoCommonService *siteinfo_common.SiteInfoCommonService
|
||||
}
|
||||
|
||||
// NewAuthUserMiddleware new auth user middleware
|
||||
func NewAuthUserMiddleware(authService *auth.AuthService) *AuthUserMiddleware {
|
||||
func NewAuthUserMiddleware(
|
||||
authService *auth.AuthService,
|
||||
siteInfoCommonService *siteinfo_common.SiteInfoCommonService) *AuthUserMiddleware {
|
||||
return &AuthUserMiddleware{
|
||||
authService: authService,
|
||||
authService: authService,
|
||||
siteInfoCommonService: siteInfoCommonService,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -48,6 +53,29 @@ func (am *AuthUserMiddleware) Auth() gin.HandlerFunc {
|
|||
}
|
||||
}
|
||||
|
||||
// EjectUserBySiteInfo if admin config the site can access by nologin user, eject user.
|
||||
func (am *AuthUserMiddleware) EjectUserBySiteInfo() gin.HandlerFunc {
|
||||
return func(ctx *gin.Context) {
|
||||
mustLogin := false
|
||||
siteInfo, _ := am.siteInfoCommonService.GetSiteLogin(ctx)
|
||||
if siteInfo != nil {
|
||||
mustLogin = siteInfo.LoginRequired
|
||||
}
|
||||
if !mustLogin {
|
||||
ctx.Next()
|
||||
return
|
||||
}
|
||||
|
||||
_, isLogin := ctx.Get(ctxUUIDKey)
|
||||
if !isLogin {
|
||||
handler.HandleResponse(ctx, errors.Unauthorized(reason.UnauthorizedError), nil)
|
||||
ctx.Abort()
|
||||
return
|
||||
}
|
||||
ctx.Next()
|
||||
}
|
||||
}
|
||||
|
||||
// MustAuth auth user info. If the user does not log in, an unauthenticated error is displayed
|
||||
func (am *AuthUserMiddleware) MustAuth() gin.HandlerFunc {
|
||||
return func(ctx *gin.Context) {
|
||||
|
|
|
@ -59,4 +59,5 @@ const (
|
|||
RevisionNoPermission = "error.revision.no_permission"
|
||||
UserCannotUpdateYourRole = "error.user.cannot_update_your_role"
|
||||
TagCannotSetSynonymAsItself = "error.tag.cannot_set_synonym_as_itself"
|
||||
NotAllowedRegistration = "error.user.not_allowed_registration"
|
||||
)
|
||||
|
|
|
@ -52,9 +52,13 @@ func NewHTTPServer(debug bool,
|
|||
static.Use(avatarMiddleware.AvatarThumb())
|
||||
staticRouter.RegisterStaticRouter(static)
|
||||
|
||||
// The route must be available without logging in
|
||||
mustUnAuthV1 := r.Group("/answer/api/v1")
|
||||
answerRouter.RegisterMustUnAuthAnswerAPIRouter(mustUnAuthV1)
|
||||
|
||||
// register api that no need to login
|
||||
unAuthV1 := r.Group("/answer/api/v1")
|
||||
unAuthV1.Use(authUserMiddleware.Auth())
|
||||
unAuthV1.Use(authUserMiddleware.Auth(), authUserMiddleware.EjectUserBySiteInfo())
|
||||
answerRouter.RegisterUnAuthAnswerAPIRouter(unAuthV1)
|
||||
|
||||
// register api that must be authenticated
|
||||
|
|
|
@ -27,7 +27,7 @@ func NewSiteinfoController(siteInfoService *siteinfo_common.SiteInfoCommonServic
|
|||
// @Description get site info
|
||||
// @Tags site
|
||||
// @Produce json
|
||||
// @Success 200 {object} handler.RespBody{data=schema.SiteGeneralResp}
|
||||
// @Success 200 {object} handler.RespBody{data=schema.SiteInfoResp}
|
||||
// @Router /answer/api/v1/siteinfo [get]
|
||||
func (sc *SiteinfoController) GetSiteInfo(ctx *gin.Context) {
|
||||
var err error
|
||||
|
@ -45,6 +45,21 @@ func (sc *SiteinfoController) GetSiteInfo(ctx *gin.Context) {
|
|||
if err != nil {
|
||||
log.Error(err)
|
||||
}
|
||||
|
||||
resp.Login, err = sc.siteInfoService.GetSiteLogin(ctx)
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
}
|
||||
|
||||
resp.Theme, err = sc.siteInfoService.GetSiteTheme(ctx)
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
}
|
||||
|
||||
resp.CustomCssHtml, err = sc.siteInfoService.GetSiteCustomCssHTML(ctx)
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
}
|
||||
handler.HandleResponse(ctx, nil, resp)
|
||||
}
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@ import (
|
|||
"github.com/answerdev/answer/internal/service/action"
|
||||
"github.com/answerdev/answer/internal/service/auth"
|
||||
"github.com/answerdev/answer/internal/service/export"
|
||||
"github.com/answerdev/answer/internal/service/siteinfo_common"
|
||||
"github.com/answerdev/answer/internal/service/uploader"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/segmentfault/pacman/errors"
|
||||
|
@ -18,11 +19,12 @@ import (
|
|||
|
||||
// UserController user controller
|
||||
type UserController struct {
|
||||
userService *service.UserService
|
||||
authService *auth.AuthService
|
||||
actionService *action.CaptchaService
|
||||
uploaderService *uploader.UploaderService
|
||||
emailService *export.EmailService
|
||||
userService *service.UserService
|
||||
authService *auth.AuthService
|
||||
actionService *action.CaptchaService
|
||||
uploaderService *uploader.UploaderService
|
||||
emailService *export.EmailService
|
||||
siteInfoCommonService *siteinfo_common.SiteInfoCommonService
|
||||
}
|
||||
|
||||
// NewUserController new controller
|
||||
|
@ -32,13 +34,15 @@ func NewUserController(
|
|||
actionService *action.CaptchaService,
|
||||
emailService *export.EmailService,
|
||||
uploaderService *uploader.UploaderService,
|
||||
siteInfoCommonService *siteinfo_common.SiteInfoCommonService,
|
||||
) *UserController {
|
||||
return &UserController{
|
||||
authService: authService,
|
||||
userService: userService,
|
||||
actionService: actionService,
|
||||
uploaderService: uploaderService,
|
||||
emailService: emailService,
|
||||
authService: authService,
|
||||
userService: userService,
|
||||
actionService: actionService,
|
||||
uploaderService: uploaderService,
|
||||
emailService: emailService,
|
||||
siteInfoCommonService: siteInfoCommonService,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -203,6 +207,17 @@ func (uc *UserController) UserLogout(ctx *gin.Context) {
|
|||
// @Success 200 {object} handler.RespBody{data=schema.GetUserResp}
|
||||
// @Router /answer/api/v1/user/register/email [post]
|
||||
func (uc *UserController) UserRegisterByEmail(ctx *gin.Context) {
|
||||
// check whether site allow register or not
|
||||
siteInfo, err := uc.siteInfoCommonService.GetSiteLogin(ctx)
|
||||
if err != nil {
|
||||
handler.HandleResponse(ctx, err, nil)
|
||||
return
|
||||
}
|
||||
if !siteInfo.AllowNewRegistrations {
|
||||
handler.HandleResponse(ctx, errors.BadRequest(reason.NotAllowedRegistration), nil)
|
||||
return
|
||||
}
|
||||
|
||||
req := &schema.UserRegisterReq{}
|
||||
if handler.BindAndCheck(ctx, req) {
|
||||
return
|
||||
|
@ -473,3 +488,17 @@ func (uc *UserController) UserChangeEmailVerify(ctx *gin.Context) {
|
|||
uc.actionService.ActionRecordDel(ctx, schema.ActionRecordTypeEmail, ctx.ClientIP())
|
||||
handler.HandleResponse(ctx, err, nil)
|
||||
}
|
||||
|
||||
// UserRanking get user ranking
|
||||
// @Summary get user ranking
|
||||
// @Description get user ranking
|
||||
// @Tags User
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Security ApiKeyAuth
|
||||
// @Success 200 {object} handler.RespBody{data=schema.GetUserToSetShowResp}
|
||||
// @Router /answer/api/v1/user/ranking [get]
|
||||
func (uc *UserController) UserRanking(ctx *gin.Context) {
|
||||
resp, err := uc.userService.UserRanking(ctx)
|
||||
handler.HandleResponse(ctx, err, resp)
|
||||
}
|
||||
|
|
|
@ -100,6 +100,45 @@ func (sc *SiteInfoController) GetSeo(ctx *gin.Context) {
|
|||
handler.HandleResponse(ctx, err, resp)
|
||||
}
|
||||
|
||||
// GetSiteLogin get site info login config
|
||||
// @Summary get site info login config
|
||||
// @Description get site info login config
|
||||
// @Security ApiKeyAuth
|
||||
// @Tags admin
|
||||
// @Produce json
|
||||
// @Success 200 {object} handler.RespBody{data=schema.SiteLoginResp}
|
||||
// @Router /answer/admin/api/siteinfo/login [get]
|
||||
func (sc *SiteInfoController) GetSiteLogin(ctx *gin.Context) {
|
||||
resp, err := sc.siteInfoService.GetSiteLogin(ctx)
|
||||
handler.HandleResponse(ctx, err, resp)
|
||||
}
|
||||
|
||||
// GetSiteCustomCssHTML get site info custom html css config
|
||||
// @Summary get site info custom html css config
|
||||
// @Description get site info custom html css config
|
||||
// @Security ApiKeyAuth
|
||||
// @Tags admin
|
||||
// @Produce json
|
||||
// @Success 200 {object} handler.RespBody{data=schema.SiteCustomCssHTMLResp}
|
||||
// @Router /answer/admin/api/siteinfo/custom-css-html [get]
|
||||
func (sc *SiteInfoController) GetSiteCustomCssHTML(ctx *gin.Context) {
|
||||
resp, err := sc.siteInfoService.GetSiteCustomCssHTML(ctx)
|
||||
handler.HandleResponse(ctx, err, resp)
|
||||
}
|
||||
|
||||
// GetSiteTheme get site info theme config
|
||||
// @Summary get site info theme config
|
||||
// @Description get site info theme config
|
||||
// @Security ApiKeyAuth
|
||||
// @Tags admin
|
||||
// @Produce json
|
||||
// @Success 200 {object} handler.RespBody{data=schema.SiteThemeResp}
|
||||
// @Router /answer/admin/api/siteinfo/theme [get]
|
||||
func (sc *SiteInfoController) GetSiteTheme(ctx *gin.Context) {
|
||||
resp, err := sc.siteInfoService.GetSiteTheme(ctx)
|
||||
handler.HandleResponse(ctx, err, resp)
|
||||
}
|
||||
|
||||
// GetRobots get site robots information
|
||||
// @Summary get site robots information
|
||||
// @Description get site robots information
|
||||
|
@ -226,6 +265,60 @@ func (sc *SiteInfoController) UpdateSiteLegal(ctx *gin.Context) {
|
|||
handler.HandleResponse(ctx, err, nil)
|
||||
}
|
||||
|
||||
// UpdateSiteLogin update site login
|
||||
// @Summary update site login
|
||||
// @Description update site login
|
||||
// @Security ApiKeyAuth
|
||||
// @Tags admin
|
||||
// @Produce json
|
||||
// @Param data body schema.SiteLoginReq true "login info"
|
||||
// @Success 200 {object} handler.RespBody{}
|
||||
// @Router /answer/admin/api/siteinfo/login [put]
|
||||
func (sc *SiteInfoController) UpdateSiteLogin(ctx *gin.Context) {
|
||||
req := &schema.SiteLoginReq{}
|
||||
if handler.BindAndCheck(ctx, req) {
|
||||
return
|
||||
}
|
||||
err := sc.siteInfoService.SaveSiteLogin(ctx, req)
|
||||
handler.HandleResponse(ctx, err, nil)
|
||||
}
|
||||
|
||||
// UpdateSiteCustomCssHTML update site custom css html config
|
||||
// @Summary update site custom css html config
|
||||
// @Description update site custom css html config
|
||||
// @Security ApiKeyAuth
|
||||
// @Tags admin
|
||||
// @Produce json
|
||||
// @Param data body schema.SiteCustomCssHTMLReq true "login info"
|
||||
// @Success 200 {object} handler.RespBody{}
|
||||
// @Router /answer/admin/api/siteinfo/custom-css-html [put]
|
||||
func (sc *SiteInfoController) UpdateSiteCustomCssHTML(ctx *gin.Context) {
|
||||
req := &schema.SiteCustomCssHTMLReq{}
|
||||
if handler.BindAndCheck(ctx, req) {
|
||||
return
|
||||
}
|
||||
err := sc.siteInfoService.SaveSiteCustomCssHTML(ctx, req)
|
||||
handler.HandleResponse(ctx, err, nil)
|
||||
}
|
||||
|
||||
// SaveSiteTheme update site custom css html config
|
||||
// @Summary update site custom css html config
|
||||
// @Description update site custom css html config
|
||||
// @Security ApiKeyAuth
|
||||
// @Tags admin
|
||||
// @Produce json
|
||||
// @Param data body schema.SiteThemeReq true "login info"
|
||||
// @Success 200 {object} handler.RespBody{}
|
||||
// @Router /answer/admin/api/siteinfo/theme [put]
|
||||
func (sc *SiteInfoController) SaveSiteTheme(ctx *gin.Context) {
|
||||
req := &schema.SiteThemeReq{}
|
||||
if handler.BindAndCheck(ctx, req) {
|
||||
return
|
||||
}
|
||||
err := sc.siteInfoService.SaveSiteTheme(ctx, req)
|
||||
handler.HandleResponse(ctx, err, nil)
|
||||
}
|
||||
|
||||
// GetSMTPConfig get smtp config
|
||||
// @Summary GetSMTPConfig get smtp config
|
||||
// @Description GetSMTPConfig get smtp config
|
||||
|
|
|
@ -60,6 +60,50 @@ func (uc *UserBackyardController) UpdateUserRole(ctx *gin.Context) {
|
|||
handler.HandleResponse(ctx, err, nil)
|
||||
}
|
||||
|
||||
// AddUser add user
|
||||
// @Summary add user
|
||||
// @Description add user
|
||||
// @Security ApiKeyAuth
|
||||
// @Tags admin
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param data body schema.AddUserReq true "user"
|
||||
// @Success 200 {object} handler.RespBody
|
||||
// @Router /answer/admin/api/user [post]
|
||||
func (uc *UserBackyardController) AddUser(ctx *gin.Context) {
|
||||
req := &schema.AddUserReq{}
|
||||
if handler.BindAndCheck(ctx, req) {
|
||||
return
|
||||
}
|
||||
|
||||
req.LoginUserID = middleware.GetLoginUserIDFromContext(ctx)
|
||||
|
||||
err := uc.userService.AddUser(ctx, req)
|
||||
handler.HandleResponse(ctx, err, nil)
|
||||
}
|
||||
|
||||
// UpdateUserPassword update user password
|
||||
// @Summary update user password
|
||||
// @Description update user password
|
||||
// @Security ApiKeyAuth
|
||||
// @Tags admin
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param data body schema.UpdateUserPasswordReq true "user"
|
||||
// @Success 200 {object} handler.RespBody
|
||||
// @Router /answer/admin/api/user/password [put]
|
||||
func (uc *UserBackyardController) UpdateUserPassword(ctx *gin.Context) {
|
||||
req := &schema.UpdateUserPasswordReq{}
|
||||
if handler.BindAndCheck(ctx, req) {
|
||||
return
|
||||
}
|
||||
|
||||
req.LoginUserID = middleware.GetLoginUserIDFromContext(ctx)
|
||||
|
||||
err := uc.userService.UpdateUserPassword(ctx, req)
|
||||
handler.HandleResponse(ctx, err, nil)
|
||||
}
|
||||
|
||||
// GetUserPage get user page
|
||||
// @Summary get user page
|
||||
// @Description get user page
|
||||
|
|
|
@ -44,8 +44,8 @@ type User struct {
|
|||
Website string `xorm:"not null default '' VARCHAR(255) website"`
|
||||
Location string `xorm:"not null default '' VARCHAR(100) location"`
|
||||
IPInfo string `xorm:"not null default '' VARCHAR(255) ip_info"`
|
||||
//IsAdmin bool `xorm:"not null default false BOOL is_admin"`
|
||||
Language string `xorm:"not null default '' VARCHAR(100) language"`
|
||||
IsAdmin bool `xorm:"not null default false BOOL is_admin"`
|
||||
Language string `xorm:"not null default '' VARCHAR(100) language"`
|
||||
}
|
||||
|
||||
// TableName user table name
|
||||
|
|
|
@ -46,6 +46,7 @@ var migrations = []Migration{
|
|||
NewMigration("add recommend and reserved tag fields", addTagRecommendedAndReserved),
|
||||
NewMigration("add activity timeline", addActivityTimeline),
|
||||
NewMigration("add user role", addRoleFeatures),
|
||||
NewMigration("add theme and private mode", addThemeAndPrivateMode),
|
||||
}
|
||||
|
||||
// GetCurrentDBVersion returns the current db version
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
package migrations
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/answerdev/answer/internal/entity"
|
||||
"xorm.io/xorm"
|
||||
)
|
||||
|
||||
func addThemeAndPrivateMode(x *xorm.Engine) error {
|
||||
loginConfig := map[string]bool{
|
||||
"allow_new_registrations": true,
|
||||
"login_required": false,
|
||||
}
|
||||
loginConfigDataBytes, _ := json.Marshal(loginConfig)
|
||||
_, err := x.InsertOne(&entity.SiteInfo{
|
||||
Type: "login",
|
||||
Content: string(loginConfigDataBytes),
|
||||
Status: 1,
|
||||
})
|
||||
return err
|
||||
}
|
|
@ -3,6 +3,7 @@ package activity_common
|
|||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/answerdev/answer/internal/entity"
|
||||
"github.com/answerdev/answer/internal/service/activity_common"
|
||||
|
@ -106,3 +107,9 @@ func (ar *ActivityRepo) AddActivity(ctx context.Context, activity *entity.Activi
|
|||
}
|
||||
return
|
||||
}
|
||||
|
||||
// GetUsersWhoHasGainedTheMostReputation get users who has gained the most reputation over a period of time
|
||||
func (ar *ActivityRepo) GetUsersWhoHasGainedTheMostReputation(
|
||||
ctx context.Context, startTime, endTime time.Time, limit int) (userIDs []string, err error) {
|
||||
return
|
||||
}
|
||||
|
|
|
@ -2,12 +2,15 @@ package site_info
|
|||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
|
||||
"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/siteinfo_common"
|
||||
"github.com/segmentfault/pacman/errors"
|
||||
"github.com/segmentfault/pacman/log"
|
||||
"xorm.io/builder"
|
||||
)
|
||||
|
||||
|
@ -23,32 +26,55 @@ func NewSiteInfo(data *data.Data) siteinfo_common.SiteInfoRepo {
|
|||
|
||||
// SaveByType save site setting by type
|
||||
func (sr *siteInfoRepo) SaveByType(ctx context.Context, siteType string, data *entity.SiteInfo) (err error) {
|
||||
var (
|
||||
old = &entity.SiteInfo{}
|
||||
exist bool
|
||||
)
|
||||
exist, _ = sr.data.DB.Where(builder.Eq{"type": siteType}).Get(old)
|
||||
old := &entity.SiteInfo{}
|
||||
exist, err := sr.data.DB.Where(builder.Eq{"type": siteType}).Get(old)
|
||||
if err != nil {
|
||||
return errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
|
||||
}
|
||||
if exist {
|
||||
_, err = sr.data.DB.ID(old.ID).Update(data)
|
||||
if err != nil {
|
||||
err = errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
|
||||
}
|
||||
return
|
||||
} else {
|
||||
_, err = sr.data.DB.Insert(data)
|
||||
}
|
||||
|
||||
_, err = sr.data.DB.Insert(data)
|
||||
if err != nil {
|
||||
err = errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
|
||||
return errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
|
||||
}
|
||||
sr.setCache(ctx, siteType, data)
|
||||
return
|
||||
}
|
||||
|
||||
// GetByType get site info by type
|
||||
func (sr *siteInfoRepo) GetByType(ctx context.Context, siteType string) (siteInfo *entity.SiteInfo, exist bool, err error) {
|
||||
siteInfo = sr.getCache(ctx, siteType)
|
||||
if siteInfo != nil {
|
||||
return siteInfo, true, nil
|
||||
}
|
||||
siteInfo = &entity.SiteInfo{}
|
||||
exist, err = sr.data.DB.Where(builder.Eq{"type": siteType}).Get(siteInfo)
|
||||
if err != nil {
|
||||
err = errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
|
||||
}
|
||||
if exist {
|
||||
sr.setCache(ctx, siteType, siteInfo)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (sr *siteInfoRepo) getCache(ctx context.Context, siteType string) (siteInfo *entity.SiteInfo) {
|
||||
siteInfo = &entity.SiteInfo{}
|
||||
siteInfoCache, err := sr.data.Cache.GetString(ctx, constant.SiteInfoCacheKey+siteType)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
_ = json.Unmarshal([]byte(siteInfoCache), siteInfo)
|
||||
return siteInfo
|
||||
}
|
||||
|
||||
func (sr *siteInfoRepo) setCache(ctx context.Context, siteType string, siteInfo *entity.SiteInfo) {
|
||||
siteInfoCache, _ := json.Marshal(siteInfo)
|
||||
err := sr.data.Cache.SetString(ctx,
|
||||
constant.SiteInfoCacheKey+siteType, string(siteInfoCache), constant.SiteInfoCacheTime)
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -61,6 +61,24 @@ func (ur *userBackyardRepo) UpdateUserStatus(ctx context.Context, userID string,
|
|||
return
|
||||
}
|
||||
|
||||
// AddUser add user
|
||||
func (ur *userBackyardRepo) AddUser(ctx context.Context, user *entity.User) (err error) {
|
||||
_, err = ur.data.DB.Insert(user)
|
||||
if err != nil {
|
||||
err = errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// UpdateUserPassword update user password
|
||||
func (ur *userBackyardRepo) UpdateUserPassword(ctx context.Context, userID string, password string) (err error) {
|
||||
_, err = ur.data.DB.ID(userID).Update(&entity.User{Pass: password})
|
||||
if err != nil {
|
||||
return errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// GetUserInfo get user info
|
||||
func (ur *userBackyardRepo) GetUserInfo(ctx context.Context, userID string) (user *entity.User, exist bool, err error) {
|
||||
user = &entity.User{}
|
||||
|
|
|
@ -87,11 +87,17 @@ func NewAnswerAPIRouter(
|
|||
}
|
||||
}
|
||||
|
||||
func (a *AnswerAPIRouter) RegisterUnAuthAnswerAPIRouter(r *gin.RouterGroup) {
|
||||
func (a *AnswerAPIRouter) RegisterMustUnAuthAnswerAPIRouter(r *gin.RouterGroup) {
|
||||
// i18n
|
||||
r.GET("/language/config", a.langController.GetLangMapping)
|
||||
r.GET("/language/options", a.langController.GetUserLangOptions)
|
||||
|
||||
//siteinfo
|
||||
r.GET("/siteinfo", a.siteinfoController.GetSiteInfo)
|
||||
r.GET("/siteinfo/legal", a.siteinfoController.GetSiteLegalInfo)
|
||||
}
|
||||
|
||||
func (a *AnswerAPIRouter) RegisterUnAuthAnswerAPIRouter(r *gin.RouterGroup) {
|
||||
// comment
|
||||
r.GET("/comment/page", a.commentController.GetCommentWithPage)
|
||||
r.GET("/personal/comment/page", a.commentController.GetCommentPersonalWithPage)
|
||||
|
@ -110,6 +116,7 @@ func (a *AnswerAPIRouter) RegisterUnAuthAnswerAPIRouter(r *gin.RouterGroup) {
|
|||
r.GET("/user/logout", a.userController.UserLogout)
|
||||
r.PUT("/user/email", a.userController.UserChangeEmailVerify)
|
||||
r.POST("/user/email/change/code", a.userController.UserChangeEmailSendCode)
|
||||
r.GET("/user/ranking", a.userController.UserRanking)
|
||||
|
||||
//answer
|
||||
r.GET("/answer/info", a.answerController.Get)
|
||||
|
@ -139,11 +146,6 @@ func (a *AnswerAPIRouter) RegisterUnAuthAnswerAPIRouter(r *gin.RouterGroup) {
|
|||
|
||||
//rank
|
||||
r.GET("/personal/rank/page", a.rankController.GetRankPersonalWithPage)
|
||||
|
||||
//siteinfo
|
||||
r.GET("/siteinfo", a.siteinfoController.GetSiteInfo)
|
||||
r.GET("/siteinfo/legal", a.siteinfoController.GetSiteLegalInfo)
|
||||
|
||||
}
|
||||
|
||||
func (a *AnswerAPIRouter) RegisterAnswerAPIRouter(r *gin.RouterGroup) {
|
||||
|
@ -234,6 +236,8 @@ func (a *AnswerAPIRouter) RegisterAnswerCmsAPIRouter(r *gin.RouterGroup) {
|
|||
r.GET("/users/page", a.backyardUserController.GetUserPage)
|
||||
r.PUT("/user/status", a.backyardUserController.UpdateUserStatus)
|
||||
r.PUT("/user/role", a.backyardUserController.UpdateUserRole)
|
||||
r.POST("/user", a.backyardUserController.AddUser)
|
||||
r.PUT("/user/password", a.backyardUserController.UpdateUserPassword)
|
||||
|
||||
// reason
|
||||
r.GET("/reasons", a.reasonController.Reasons)
|
||||
|
@ -251,11 +255,17 @@ func (a *AnswerAPIRouter) RegisterAnswerCmsAPIRouter(r *gin.RouterGroup) {
|
|||
r.GET("/siteinfo/write", a.siteInfoController.GetSiteWrite)
|
||||
r.GET("/siteinfo/legal", a.siteInfoController.GetSiteLegal)
|
||||
r.GET("/siteinfo/seo", a.siteInfoController.GetSeo)
|
||||
r.GET("/siteinfo/login", a.siteInfoController.GetSiteLogin)
|
||||
r.GET("/siteinfo/custom-css-html", a.siteInfoController.GetSiteCustomCssHTML)
|
||||
r.GET("/siteinfo/theme", a.siteInfoController.GetSiteTheme)
|
||||
r.PUT("/siteinfo/general", a.siteInfoController.UpdateGeneral)
|
||||
r.PUT("/siteinfo/interface", a.siteInfoController.UpdateInterface)
|
||||
r.PUT("/siteinfo/branding", a.siteInfoController.UpdateBranding)
|
||||
r.PUT("/siteinfo/write", a.siteInfoController.UpdateSiteWrite)
|
||||
r.PUT("/siteinfo/legal", a.siteInfoController.UpdateSiteLegal)
|
||||
r.PUT("/siteinfo/login", a.siteInfoController.UpdateSiteLogin)
|
||||
r.PUT("/siteinfo/custom-css-html", a.siteInfoController.UpdateSiteCustomCssHTML)
|
||||
r.PUT("/siteinfo/theme", a.siteInfoController.SaveSiteTheme)
|
||||
r.PUT("/siteinfo/seo", a.siteInfoController.UpdateSeo)
|
||||
r.GET("/setting/smtp", a.siteInfoController.GetSMTPConfig)
|
||||
r.PUT("/setting/smtp", a.siteInfoController.UpdateSMTPConfig)
|
||||
|
|
|
@ -84,3 +84,18 @@ type UpdateUserRoleReq struct {
|
|||
// login user id
|
||||
LoginUserID string `json:"-"`
|
||||
}
|
||||
|
||||
// AddUserReq add user request
|
||||
type AddUserReq struct {
|
||||
DisplayName string `validate:"required,gt=4,lte=30" json:"display_name"`
|
||||
Email string `validate:"required,email,gt=0,lte=500" json:"email"`
|
||||
Password string `validate:"required,gte=8,lte=32" json:"password"`
|
||||
LoginUserID string `json:"-"`
|
||||
}
|
||||
|
||||
// UpdateUserPasswordReq update user password request
|
||||
type UpdateUserPasswordReq struct {
|
||||
UserID string `validate:"required" json:"user_id"`
|
||||
Password string `validate:"required,gte=8,lte=32" json:"password"`
|
||||
LoginUserID string `json:"-"`
|
||||
}
|
||||
|
|
|
@ -82,6 +82,26 @@ type GetSiteLegalInfoResp struct {
|
|||
PrivacyPolicyParsedText string `json:"privacy_policy_parsed_text,omitempty"`
|
||||
}
|
||||
|
||||
// SiteLoginReq site login request
|
||||
type SiteLoginReq struct {
|
||||
AllowNewRegistrations bool `json:"allow_new_registrations"`
|
||||
LoginRequired bool `json:"login_required"`
|
||||
}
|
||||
|
||||
// SiteCustomCssHTMLReq site custom css html
|
||||
type SiteCustomCssHTMLReq struct {
|
||||
CustomHead string `validate:"omitempty,gt=0,lte=65536" json:"custom_head"`
|
||||
CustomCss string `validate:"omitempty,gt=0,lte=65536" json:"custom_css"`
|
||||
CustomHeader string `validate:"omitempty,gt=0,lte=65536" json:"custom_header"`
|
||||
CustomFooter string `validate:"omitempty,gt=0,lte=65536" json:"custom_footer"`
|
||||
}
|
||||
|
||||
// SiteThemeReq site theme config
|
||||
type SiteThemeReq struct {
|
||||
Theme string `validate:"required,gt=0,lte=255" json:"theme"`
|
||||
ThemeConfig map[string]interface{} `validate:"omitempty" json:"theme_config"`
|
||||
}
|
||||
|
||||
// SiteGeneralResp site general response
|
||||
type SiteGeneralResp SiteGeneralReq
|
||||
|
||||
|
@ -91,19 +111,32 @@ type SiteInterfaceResp SiteInterfaceReq
|
|||
// SiteBrandingResp site branding response
|
||||
type SiteBrandingResp SiteBrandingReq
|
||||
|
||||
// SiteLoginResp site login response
|
||||
type SiteLoginResp SiteLoginReq
|
||||
|
||||
// SiteCustomCssHTMLResp site custom css html response
|
||||
type SiteCustomCssHTMLResp SiteCustomCssHTMLReq
|
||||
|
||||
// SiteThemeResp site theme response
|
||||
type SiteThemeResp SiteThemeReq
|
||||
|
||||
// SiteWriteResp site write response
|
||||
type SiteWriteResp SiteWriteReq
|
||||
|
||||
// SiteLegalResp site write response
|
||||
type SiteLegalResp SiteLegalReq
|
||||
|
||||
// SiteSeoResp site write response
|
||||
type SiteSeoResp SiteSeoReq
|
||||
|
||||
// SiteInfoResp get site info response
|
||||
type SiteInfoResp struct {
|
||||
General *SiteGeneralResp `json:"general"`
|
||||
Interface *SiteInterfaceResp `json:"interface"`
|
||||
Branding *SiteBrandingResp `json:"branding"`
|
||||
General *SiteGeneralResp `json:"general"`
|
||||
Interface *SiteInterfaceResp `json:"interface"`
|
||||
Branding *SiteBrandingResp `json:"branding"`
|
||||
Login *SiteLoginResp `json:"login"`
|
||||
Theme *SiteThemeResp `json:"theme"`
|
||||
CustomCssHtml *SiteCustomCssHTMLResp `json:"custom_css_html"`
|
||||
}
|
||||
type TemplateSiteInfoResp struct {
|
||||
General *SiteGeneralResp `json:"general"`
|
||||
|
|
|
@ -11,12 +11,4 @@ var GetThemeOptions = []*GetThemeOption{
|
|||
Label: "Default",
|
||||
Value: "default",
|
||||
},
|
||||
{
|
||||
Label: "Black",
|
||||
Value: "black",
|
||||
},
|
||||
{
|
||||
Label: "White",
|
||||
Value: "white",
|
||||
},
|
||||
}
|
||||
|
|
|
@ -417,3 +417,22 @@ type UserVerifyEmailSendReq struct {
|
|||
CaptchaID string `validate:"omitempty,gt=0,lte=500" json:"captcha_id"`
|
||||
CaptchaCode string `validate:"omitempty,gt=0,lte=500" json:"captcha_code"`
|
||||
}
|
||||
|
||||
// UserRankingResp user ranking response
|
||||
type UserRankingResp struct {
|
||||
UsersWithTheMostReputation []*UserRankingSimpleInfo `json:"users_with_the_most_reputation"`
|
||||
UsersWithTheMostVote []*UserRankingSimpleInfo `json:"users_with_the_most_vote"`
|
||||
Staffs []*UserRankingSimpleInfo `json:"staffs"`
|
||||
}
|
||||
|
||||
// UserRankingSimpleInfo user ranking simple info
|
||||
type UserRankingSimpleInfo struct {
|
||||
// username
|
||||
Username string `json:"username"`
|
||||
// rank
|
||||
Rank int `json:"rank"`
|
||||
// display name
|
||||
DisplayName string `json:"display_name"`
|
||||
// avatar
|
||||
Avatar string `json:"avatar"`
|
||||
}
|
||||
|
|
|
@ -18,65 +18,38 @@ import (
|
|||
)
|
||||
|
||||
type SiteInfoService struct {
|
||||
siteInfoRepo siteinfo_common.SiteInfoRepo
|
||||
emailService *export.EmailService
|
||||
tagCommonService *tagcommon.TagCommonService
|
||||
siteInfoRepo siteinfo_common.SiteInfoRepo
|
||||
siteInfoCommonService *siteinfo_common.SiteInfoCommonService
|
||||
emailService *export.EmailService
|
||||
tagCommonService *tagcommon.TagCommonService
|
||||
}
|
||||
|
||||
func NewSiteInfoService(
|
||||
siteInfoRepo siteinfo_common.SiteInfoRepo,
|
||||
siteInfoCommonService *siteinfo_common.SiteInfoCommonService,
|
||||
emailService *export.EmailService,
|
||||
tagCommonService *tagcommon.TagCommonService) *SiteInfoService {
|
||||
return &SiteInfoService{
|
||||
siteInfoRepo: siteInfoRepo,
|
||||
emailService: emailService,
|
||||
tagCommonService: tagCommonService,
|
||||
siteInfoRepo: siteInfoRepo,
|
||||
siteInfoCommonService: siteInfoCommonService,
|
||||
emailService: emailService,
|
||||
tagCommonService: tagCommonService,
|
||||
}
|
||||
}
|
||||
|
||||
// GetSiteGeneral get site info general
|
||||
func (s *SiteInfoService) GetSiteGeneral(ctx context.Context) (resp *schema.SiteGeneralResp, err error) {
|
||||
resp = &schema.SiteGeneralResp{}
|
||||
siteInfo, exist, err := s.siteInfoRepo.GetByType(ctx, constant.SiteTypeGeneral)
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
return resp, nil
|
||||
}
|
||||
if !exist {
|
||||
return resp, nil
|
||||
}
|
||||
_ = json.Unmarshal([]byte(siteInfo.Content), resp)
|
||||
return resp, nil
|
||||
return s.siteInfoCommonService.GetSiteGeneral(ctx)
|
||||
}
|
||||
|
||||
// GetSiteInterface get site info interface
|
||||
func (s *SiteInfoService) GetSiteInterface(ctx context.Context) (resp *schema.SiteInterfaceResp, err error) {
|
||||
resp = &schema.SiteInterfaceResp{}
|
||||
siteInfo, exist, err := s.siteInfoRepo.GetByType(ctx, constant.SiteTypeInterface)
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
return resp, nil
|
||||
}
|
||||
if !exist {
|
||||
return resp, nil
|
||||
}
|
||||
_ = json.Unmarshal([]byte(siteInfo.Content), resp)
|
||||
return resp, nil
|
||||
return s.siteInfoCommonService.GetSiteInterface(ctx)
|
||||
}
|
||||
|
||||
// GetSiteBranding get site info branding
|
||||
func (s *SiteInfoService) GetSiteBranding(ctx context.Context) (resp *schema.SiteBrandingReq, err error) {
|
||||
resp = &schema.SiteBrandingReq{}
|
||||
siteInfo, exist, err := s.siteInfoRepo.GetByType(ctx, constant.SiteTypeBranding)
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
return resp, nil
|
||||
}
|
||||
if !exist {
|
||||
return resp, nil
|
||||
}
|
||||
_ = json.Unmarshal([]byte(siteInfo.Content), resp)
|
||||
return resp, nil
|
||||
func (s *SiteInfoService) GetSiteBranding(ctx context.Context) (resp *schema.SiteBrandingResp, err error) {
|
||||
return s.siteInfoCommonService.GetSiteBranding(ctx)
|
||||
}
|
||||
|
||||
// GetSiteWrite get site info write
|
||||
|
@ -104,16 +77,22 @@ func (s *SiteInfoService) GetSiteWrite(ctx context.Context) (resp *schema.SiteWr
|
|||
|
||||
// GetSiteLegal get site legal info
|
||||
func (s *SiteInfoService) GetSiteLegal(ctx context.Context) (resp *schema.SiteLegalResp, err error) {
|
||||
resp = &schema.SiteLegalResp{}
|
||||
siteInfo, exist, err := s.siteInfoRepo.GetByType(ctx, constant.SiteTypeLegal)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !exist {
|
||||
return resp, nil
|
||||
}
|
||||
_ = json.Unmarshal([]byte(siteInfo.Content), resp)
|
||||
return resp, nil
|
||||
return s.siteInfoCommonService.GetSiteLegal(ctx)
|
||||
}
|
||||
|
||||
// GetSiteLogin get site login info
|
||||
func (s *SiteInfoService) GetSiteLogin(ctx context.Context) (resp *schema.SiteLoginResp, err error) {
|
||||
return s.siteInfoCommonService.GetSiteLogin(ctx)
|
||||
}
|
||||
|
||||
// GetSiteCustomCssHTML get site custom css html config
|
||||
func (s *SiteInfoService) GetSiteCustomCssHTML(ctx context.Context) (resp *schema.SiteCustomCssHTMLResp, err error) {
|
||||
return s.siteInfoCommonService.GetSiteCustomCssHTML(ctx)
|
||||
}
|
||||
|
||||
// GetSiteTheme get site theme config
|
||||
func (s *SiteInfoService) GetSiteTheme(ctx context.Context) (resp *schema.SiteThemeResp, err error) {
|
||||
return s.siteInfoCommonService.GetSiteTheme(ctx)
|
||||
}
|
||||
|
||||
func (s *SiteInfoService) SaveSiteGeneral(ctx context.Context, req schema.SiteGeneralReq) (err error) {
|
||||
|
@ -207,6 +186,39 @@ func (s *SiteInfoService) SaveSiteLegal(ctx context.Context, req *schema.SiteLeg
|
|||
return s.siteInfoRepo.SaveByType(ctx, constant.SiteTypeLegal, data)
|
||||
}
|
||||
|
||||
// SaveSiteLogin save site legal configuration
|
||||
func (s *SiteInfoService) SaveSiteLogin(ctx context.Context, req *schema.SiteLoginReq) (err error) {
|
||||
content, _ := json.Marshal(req)
|
||||
data := &entity.SiteInfo{
|
||||
Type: constant.SiteTypeLogin,
|
||||
Content: string(content),
|
||||
Status: 1,
|
||||
}
|
||||
return s.siteInfoRepo.SaveByType(ctx, constant.SiteTypeLogin, data)
|
||||
}
|
||||
|
||||
// SaveSiteCustomCssHTML save site custom html configuration
|
||||
func (s *SiteInfoService) SaveSiteCustomCssHTML(ctx context.Context, req *schema.SiteCustomCssHTMLReq) (err error) {
|
||||
content, _ := json.Marshal(req)
|
||||
data := &entity.SiteInfo{
|
||||
Type: constant.SiteTypeCustomCssHTML,
|
||||
Content: string(content),
|
||||
Status: 1,
|
||||
}
|
||||
return s.siteInfoRepo.SaveByType(ctx, constant.SiteTypeCustomCssHTML, data)
|
||||
}
|
||||
|
||||
// SaveSiteTheme save site custom html configuration
|
||||
func (s *SiteInfoService) SaveSiteTheme(ctx context.Context, req *schema.SiteThemeReq) (err error) {
|
||||
content, _ := json.Marshal(req)
|
||||
data := &entity.SiteInfo{
|
||||
Type: constant.SiteTypeTheme,
|
||||
Content: string(content),
|
||||
Status: 1,
|
||||
}
|
||||
return s.siteInfoRepo.SaveByType(ctx, constant.SiteTypeTheme, data)
|
||||
}
|
||||
|
||||
// GetSMTPConfig get smtp config
|
||||
func (s *SiteInfoService) GetSMTPConfig(ctx context.Context) (
|
||||
resp *schema.GetSMTPConfigResp, err error,
|
||||
|
@ -243,6 +255,18 @@ func (s *SiteInfoService) UpdateSMTPConfig(ctx context.Context, req *schema.Upda
|
|||
}
|
||||
|
||||
func (s *SiteInfoService) GetSeo(ctx context.Context) (resp *schema.SiteSeoResp, err error) {
|
||||
resp = &schema.SiteSeoResp{}
|
||||
loginConfig, err := s.GetSiteLogin(ctx)
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
return resp, nil
|
||||
}
|
||||
// If the site is set to privacy mode, prohibit crawling any page.
|
||||
if loginConfig.LoginRequired {
|
||||
resp.Robots = "User-agent: *\nDisallow: /"
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
resp = &schema.SiteSeoResp{}
|
||||
siteInfo, exist, err := s.siteInfoRepo.GetByType(ctx, constant.SiteTypeSeo)
|
||||
if err != nil {
|
||||
|
|
|
@ -1,12 +0,0 @@
|
|||
package siteinfo_common
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/answerdev/answer/internal/entity"
|
||||
)
|
||||
|
||||
type SiteInfoRepo interface {
|
||||
SaveByType(ctx context.Context, siteType string, data *entity.SiteInfo) (err error)
|
||||
GetByType(ctx context.Context, siteType string) (siteInfo *entity.SiteInfo, exist bool, err error)
|
||||
}
|
|
@ -5,13 +5,21 @@ import (
|
|||
"encoding/json"
|
||||
|
||||
"github.com/answerdev/answer/internal/base/constant"
|
||||
"github.com/answerdev/answer/internal/entity"
|
||||
"github.com/answerdev/answer/internal/schema"
|
||||
)
|
||||
|
||||
type SiteInfoRepo interface {
|
||||
SaveByType(ctx context.Context, siteType string, data *entity.SiteInfo) (err error)
|
||||
GetByType(ctx context.Context, siteType string) (siteInfo *entity.SiteInfo, exist bool, err error)
|
||||
}
|
||||
|
||||
// SiteInfoCommonService site info common service
|
||||
type SiteInfoCommonService struct {
|
||||
siteInfoRepo SiteInfoRepo
|
||||
}
|
||||
|
||||
// NewSiteInfoCommonService new site info common service
|
||||
func NewSiteInfoCommonService(siteInfoRepo SiteInfoRepo) *SiteInfoCommonService {
|
||||
return &SiteInfoCommonService{
|
||||
siteInfoRepo: siteInfoRepo,
|
||||
|
@ -21,69 +29,83 @@ func NewSiteInfoCommonService(siteInfoRepo SiteInfoRepo) *SiteInfoCommonService
|
|||
// GetSiteGeneral get site info general
|
||||
func (s *SiteInfoCommonService) GetSiteGeneral(ctx context.Context) (resp *schema.SiteGeneralResp, err error) {
|
||||
resp = &schema.SiteGeneralResp{}
|
||||
siteInfo, exist, err := s.siteInfoRepo.GetByType(ctx, constant.SiteTypeGeneral)
|
||||
if err != nil {
|
||||
return resp, err
|
||||
if err = s.getSiteInfoByType(ctx, constant.SiteTypeGeneral, resp); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !exist {
|
||||
return resp, nil
|
||||
}
|
||||
_ = json.Unmarshal([]byte(siteInfo.Content), resp)
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
// GetSiteInterface get site info interface
|
||||
func (s *SiteInfoCommonService) GetSiteInterface(ctx context.Context) (resp *schema.SiteInterfaceResp, err error) {
|
||||
resp = &schema.SiteInterfaceResp{}
|
||||
siteInfo, exist, err := s.siteInfoRepo.GetByType(ctx, constant.SiteTypeInterface)
|
||||
if err != nil {
|
||||
return resp, err
|
||||
if err = s.getSiteInfoByType(ctx, constant.SiteTypeInterface, resp); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !exist {
|
||||
return resp, nil
|
||||
}
|
||||
_ = json.Unmarshal([]byte(siteInfo.Content), resp)
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
// GetSiteBranding get site info branding
|
||||
func (s *SiteInfoCommonService) GetSiteBranding(ctx context.Context) (resp *schema.SiteBrandingResp, err error) {
|
||||
resp = &schema.SiteBrandingResp{}
|
||||
siteInfo, exist, err := s.siteInfoRepo.GetByType(ctx, constant.SiteTypeBranding)
|
||||
if err != nil {
|
||||
return resp, err
|
||||
if err = s.getSiteInfoByType(ctx, constant.SiteTypeBranding, resp); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !exist {
|
||||
return resp, nil
|
||||
}
|
||||
_ = json.Unmarshal([]byte(siteInfo.Content), resp)
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
// GetSiteWrite get site info write
|
||||
func (s *SiteInfoCommonService) GetSiteWrite(ctx context.Context) (resp *schema.SiteWriteResp, err error) {
|
||||
resp = &schema.SiteWriteResp{}
|
||||
siteInfo, exist, err := s.siteInfoRepo.GetByType(ctx, constant.SiteTypeWrite)
|
||||
if err != nil {
|
||||
return resp, err
|
||||
if err = s.getSiteInfoByType(ctx, constant.SiteTypeWrite, resp); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !exist {
|
||||
return resp, nil
|
||||
}
|
||||
_ = json.Unmarshal([]byte(siteInfo.Content), resp)
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
// GetSiteLegal get site info write
|
||||
func (s *SiteInfoCommonService) GetSiteLegal(ctx context.Context) (resp *schema.SiteLegalResp, err error) {
|
||||
resp = &schema.SiteLegalResp{}
|
||||
siteInfo, exist, err := s.siteInfoRepo.GetByType(ctx, constant.SiteTypeLegal)
|
||||
if err != nil {
|
||||
if err = s.getSiteInfoByType(ctx, constant.SiteTypeLegal, resp); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !exist {
|
||||
return resp, nil
|
||||
}
|
||||
_ = json.Unmarshal([]byte(siteInfo.Content), resp)
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
// GetSiteLogin get site login config
|
||||
func (s *SiteInfoCommonService) GetSiteLogin(ctx context.Context) (resp *schema.SiteLoginResp, err error) {
|
||||
resp = &schema.SiteLoginResp{}
|
||||
if err = s.getSiteInfoByType(ctx, constant.SiteTypeLogin, resp); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
// GetSiteCustomCssHTML get site custom css html config
|
||||
func (s *SiteInfoCommonService) GetSiteCustomCssHTML(ctx context.Context) (resp *schema.SiteCustomCssHTMLResp, err error) {
|
||||
resp = &schema.SiteCustomCssHTMLResp{}
|
||||
if err = s.getSiteInfoByType(ctx, constant.SiteTypeCustomCssHTML, resp); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
// GetSiteTheme get site theme
|
||||
func (s *SiteInfoCommonService) GetSiteTheme(ctx context.Context) (resp *schema.SiteThemeResp, err error) {
|
||||
resp = &schema.SiteThemeResp{}
|
||||
if err = s.getSiteInfoByType(ctx, constant.SiteTypeTheme, resp); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
func (s *SiteInfoCommonService) getSiteInfoByType(ctx context.Context, siteType string, resp interface{}) (err error) {
|
||||
siteInfo, exist, err := s.siteInfoRepo.GetByType(ctx, siteType)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !exist {
|
||||
return nil
|
||||
}
|
||||
_ = json.Unmarshal([]byte(siteInfo.Content), resp)
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -14,9 +14,11 @@ import (
|
|||
"github.com/answerdev/answer/internal/schema"
|
||||
"github.com/answerdev/answer/internal/service/auth"
|
||||
"github.com/answerdev/answer/internal/service/role"
|
||||
usercommon "github.com/answerdev/answer/internal/service/user_common"
|
||||
"github.com/jinzhu/copier"
|
||||
"github.com/segmentfault/pacman/errors"
|
||||
"github.com/segmentfault/pacman/log"
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
)
|
||||
|
||||
// UserBackyardRepo user repository
|
||||
|
@ -25,6 +27,8 @@ type UserBackyardRepo interface {
|
|||
GetUserInfo(ctx context.Context, userID string) (user *entity.User, exist bool, err error)
|
||||
GetUserPage(ctx context.Context, page, pageSize int, user *entity.User,
|
||||
usernameOrDisplayName string, isStaff bool) (users []*entity.User, total int64, err error)
|
||||
AddUser(ctx context.Context, user *entity.User) (err error)
|
||||
UpdateUserPassword(ctx context.Context, userID string, password string) (err error)
|
||||
}
|
||||
|
||||
// UserBackyardService user service
|
||||
|
@ -32,6 +36,7 @@ type UserBackyardService struct {
|
|||
userRepo UserBackyardRepo
|
||||
userRoleRelService *role.UserRoleRelService
|
||||
authService *auth.AuthService
|
||||
userCommonService *usercommon.UserCommon
|
||||
}
|
||||
|
||||
// NewUserBackyardService new user backyard service
|
||||
|
@ -39,11 +44,13 @@ func NewUserBackyardService(
|
|||
userRepo UserBackyardRepo,
|
||||
userRoleRelService *role.UserRoleRelService,
|
||||
authService *auth.AuthService,
|
||||
userCommonService *usercommon.UserCommon,
|
||||
) *UserBackyardService {
|
||||
return &UserBackyardService{
|
||||
userRepo: userRepo,
|
||||
userRoleRelService: userRoleRelService,
|
||||
authService: authService,
|
||||
userCommonService: userCommonService,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -94,6 +101,57 @@ func (us *UserBackyardService) UpdateUserRole(ctx context.Context, req *schema.U
|
|||
return
|
||||
}
|
||||
|
||||
// AddUser add user
|
||||
func (us *UserBackyardService) AddUser(ctx context.Context, req *schema.AddUserReq) (err error) {
|
||||
hashPwd, err := bcrypt.GenerateFromPassword([]byte(req.Password), bcrypt.DefaultCost)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
userInfo := &entity.User{}
|
||||
userInfo.EMail = req.Email
|
||||
userInfo.DisplayName = req.DisplayName
|
||||
userInfo.Pass = string(hashPwd)
|
||||
|
||||
userInfo.Username, err = us.userCommonService.MakeUsername(ctx, userInfo.DisplayName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
userInfo.MailStatus = entity.EmailStatusAvailable
|
||||
userInfo.Status = entity.UserStatusAvailable
|
||||
userInfo.Rank = 1
|
||||
|
||||
err = us.userRepo.AddUser(ctx, userInfo)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// UpdateUserPassword update user password
|
||||
func (us *UserBackyardService) UpdateUserPassword(ctx context.Context, req *schema.UpdateUserPasswordReq) (err error) {
|
||||
userInfo, exist, err := us.userRepo.GetUserInfo(ctx, req.UserID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !exist {
|
||||
return errors.BadRequest(reason.UserNotFound)
|
||||
}
|
||||
|
||||
hashPwd, err := bcrypt.GenerateFromPassword([]byte(req.Password), bcrypt.DefaultCost)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = us.userRepo.UpdateUserPassword(ctx, userInfo.ID, string(hashPwd))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// logout this user
|
||||
us.authService.RemoveAllUserTokens(ctx, req.UserID)
|
||||
return
|
||||
}
|
||||
|
||||
// GetUserInfo get user one
|
||||
func (us *UserBackyardService) GetUserInfo(ctx context.Context, userID string) (resp *schema.GetUserInfoResp, err error) {
|
||||
user, exist, err := us.userRepo.GetUserInfo(ctx, userID)
|
||||
|
|
|
@ -2,9 +2,17 @@ package usercommon
|
|||
|
||||
import (
|
||||
"context"
|
||||
"encoding/hex"
|
||||
"math/rand"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/Chain-Zhang/pinyin"
|
||||
"github.com/answerdev/answer/internal/base/reason"
|
||||
"github.com/answerdev/answer/internal/entity"
|
||||
"github.com/answerdev/answer/internal/schema"
|
||||
"github.com/answerdev/answer/pkg/checker"
|
||||
"github.com/segmentfault/pacman/errors"
|
||||
)
|
||||
|
||||
type UserRepo interface {
|
||||
|
@ -94,3 +102,41 @@ func (us *UserCommon) FormatUserBasicInfo(ctx context.Context, userInfo *entity.
|
|||
}
|
||||
return userBasicInfo
|
||||
}
|
||||
|
||||
// MakeUsername
|
||||
// Generate a unique Username based on the displayName
|
||||
func (us *UserCommon) MakeUsername(ctx context.Context, displayName string) (username string, err error) {
|
||||
// Chinese processing
|
||||
if has := checker.IsChinese(displayName); has {
|
||||
str, err := pinyin.New(displayName).Split("").Mode(pinyin.WithoutTone).Convert()
|
||||
if err != nil {
|
||||
return "", errors.BadRequest(reason.UsernameInvalid)
|
||||
} else {
|
||||
displayName = str
|
||||
}
|
||||
}
|
||||
|
||||
username = strings.ReplaceAll(displayName, " ", "_")
|
||||
username = strings.ToLower(username)
|
||||
suffix := ""
|
||||
|
||||
re := regexp.MustCompile(`^[a-z0-9._-]{4,30}$`)
|
||||
match := re.MatchString(username)
|
||||
if !match {
|
||||
return "", errors.BadRequest(reason.UsernameInvalid)
|
||||
}
|
||||
|
||||
for {
|
||||
_, has, err := us.userRepo.GetByUsername(ctx, username+suffix)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if !has {
|
||||
break
|
||||
}
|
||||
bytes := make([]byte, 2)
|
||||
_, _ = rand.Read(bytes)
|
||||
suffix = hex.EncodeToString(bytes)
|
||||
}
|
||||
return username + suffix, nil
|
||||
}
|
||||
|
|
|
@ -2,14 +2,9 @@ package service
|
|||
|
||||
import (
|
||||
"context"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/Chain-Zhang/pinyin"
|
||||
"github.com/answerdev/answer/internal/base/handler"
|
||||
"github.com/answerdev/answer/internal/base/reason"
|
||||
"github.com/answerdev/answer/internal/base/translator"
|
||||
|
@ -23,7 +18,6 @@ import (
|
|||
"github.com/answerdev/answer/internal/service/service_config"
|
||||
"github.com/answerdev/answer/internal/service/siteinfo_common"
|
||||
usercommon "github.com/answerdev/answer/internal/service/user_common"
|
||||
"github.com/answerdev/answer/pkg/checker"
|
||||
"github.com/google/uuid"
|
||||
"github.com/segmentfault/pacman/errors"
|
||||
"github.com/segmentfault/pacman/log"
|
||||
|
@ -34,13 +28,14 @@ import (
|
|||
|
||||
// UserService user service
|
||||
type UserService struct {
|
||||
userRepo usercommon.UserRepo
|
||||
userActivity activity.UserActiveActivityRepo
|
||||
serviceConfig *service_config.ServiceConfig
|
||||
emailService *export.EmailService
|
||||
authService *auth.AuthService
|
||||
siteInfoService *siteinfo_common.SiteInfoCommonService
|
||||
userRoleService *role.UserRoleRelService
|
||||
userCommonService *usercommon.UserCommon
|
||||
userRepo usercommon.UserRepo
|
||||
userActivity activity.UserActiveActivityRepo
|
||||
serviceConfig *service_config.ServiceConfig
|
||||
emailService *export.EmailService
|
||||
authService *auth.AuthService
|
||||
siteInfoService *siteinfo_common.SiteInfoCommonService
|
||||
userRoleService *role.UserRoleRelService
|
||||
}
|
||||
|
||||
func NewUserService(userRepo usercommon.UserRepo,
|
||||
|
@ -50,15 +45,17 @@ func NewUserService(userRepo usercommon.UserRepo,
|
|||
serviceConfig *service_config.ServiceConfig,
|
||||
siteInfoService *siteinfo_common.SiteInfoCommonService,
|
||||
userRoleService *role.UserRoleRelService,
|
||||
userCommonService *usercommon.UserCommon,
|
||||
) *UserService {
|
||||
return &UserService{
|
||||
userRepo: userRepo,
|
||||
userActivity: userActivity,
|
||||
emailService: emailService,
|
||||
serviceConfig: serviceConfig,
|
||||
authService: authService,
|
||||
siteInfoService: siteInfoService,
|
||||
userRoleService: userRoleService,
|
||||
userCommonService: userCommonService,
|
||||
userRepo: userRepo,
|
||||
userActivity: userActivity,
|
||||
emailService: emailService,
|
||||
serviceConfig: serviceConfig,
|
||||
authService: authService,
|
||||
siteInfoService: siteInfoService,
|
||||
userRoleService: userRoleService,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -307,7 +304,7 @@ func (us *UserService) UserRegisterByEmail(ctx context.Context, registerUserInfo
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
userInfo.Username, err = us.makeUsername(ctx, registerUserInfo.Name)
|
||||
userInfo.Username, err = us.userCommonService.MakeUsername(ctx, registerUserInfo.Name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -456,44 +453,6 @@ func (us *UserService) UserVerifyEmail(ctx context.Context, req *schema.UserVeri
|
|||
return resp, nil
|
||||
}
|
||||
|
||||
// makeUsername
|
||||
// Generate a unique Username based on the displayName
|
||||
func (us *UserService) makeUsername(ctx context.Context, displayName string) (username string, err error) {
|
||||
// Chinese processing
|
||||
if has := checker.IsChinese(displayName); has {
|
||||
str, err := pinyin.New(displayName).Split("").Mode(pinyin.WithoutTone).Convert()
|
||||
if err != nil {
|
||||
return "", err
|
||||
} else {
|
||||
displayName = str
|
||||
}
|
||||
}
|
||||
|
||||
username = strings.ReplaceAll(displayName, " ", "_")
|
||||
username = strings.ToLower(username)
|
||||
suffix := ""
|
||||
|
||||
re := regexp.MustCompile(`^[a-z0-9._-]{4,30}$`)
|
||||
match := re.MatchString(username)
|
||||
if !match {
|
||||
return "", errors.BadRequest(reason.UsernameInvalid)
|
||||
}
|
||||
|
||||
for {
|
||||
_, has, err := us.userRepo.GetByUsername(ctx, username+suffix)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if !has {
|
||||
break
|
||||
}
|
||||
bytes := make([]byte, 2)
|
||||
_, _ = rand.Read(bytes)
|
||||
suffix = hex.EncodeToString(bytes)
|
||||
}
|
||||
return username + suffix, nil
|
||||
}
|
||||
|
||||
// verifyPassword
|
||||
// Compare whether the password is correct
|
||||
func (us *UserService) verifyPassword(ctx context.Context, LoginPass, UserPass string) bool {
|
||||
|
@ -596,3 +555,9 @@ func (us *UserService) getSiteUrl(ctx context.Context) string {
|
|||
}
|
||||
return siteGeneral.SiteUrl
|
||||
}
|
||||
|
||||
// UserRanking get user ranking
|
||||
func (us *UserService) UserRanking(ctx context.Context) (resp []*schema.UserRankingResp, err error) {
|
||||
//us.userRepo.GetByUserID()
|
||||
return
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue