mirror of https://gitee.com/answerdev/answer.git
Merge branch 'test' into 'ai_0.3_install_api'
# Conflicts: # internal/router/ui.go
This commit is contained in:
commit
6d9e5578dc
|
@ -44,6 +44,7 @@ import (
|
|||
auth2 "github.com/answerdev/answer/internal/service/auth"
|
||||
"github.com/answerdev/answer/internal/service/collection_common"
|
||||
comment2 "github.com/answerdev/answer/internal/service/comment"
|
||||
"github.com/answerdev/answer/internal/service/dashboard"
|
||||
export2 "github.com/answerdev/answer/internal/service/export"
|
||||
"github.com/answerdev/answer/internal/service/follow"
|
||||
meta2 "github.com/answerdev/answer/internal/service/meta"
|
||||
|
@ -76,7 +77,6 @@ func initApplication(debug bool, serverConf *conf.Server, dbConf *data.Database,
|
|||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
langController := controller.NewLangController(i18nTranslator)
|
||||
engine, err := data.NewDB(debug, dbConf)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
|
@ -90,17 +90,19 @@ func initApplication(debug bool, serverConf *conf.Server, dbConf *data.Database,
|
|||
cleanup()
|
||||
return nil, nil, err
|
||||
}
|
||||
siteInfoRepo := site_info.NewSiteInfo(dataData)
|
||||
configRepo := config.NewConfigRepo(dataData)
|
||||
emailRepo := export.NewEmailRepo(dataData)
|
||||
emailService := export2.NewEmailService(configRepo, emailRepo, siteInfoRepo)
|
||||
siteInfoService := service.NewSiteInfoService(siteInfoRepo, emailService)
|
||||
langController := controller.NewLangController(i18nTranslator, siteInfoService)
|
||||
authRepo := auth.NewAuthRepo(dataData)
|
||||
authService := auth2.NewAuthService(authRepo)
|
||||
configRepo := config.NewConfigRepo(dataData)
|
||||
userRepo := user.NewUserRepo(dataData, configRepo)
|
||||
uniqueIDRepo := unique.NewUniqueIDRepo(dataData)
|
||||
activityRepo := activity_common.NewActivityRepo(dataData, uniqueIDRepo, configRepo)
|
||||
userRankRepo := rank.NewUserRankRepo(dataData, configRepo)
|
||||
userActiveActivityRepo := activity.NewUserActiveActivityRepo(dataData, activityRepo, userRankRepo, configRepo)
|
||||
emailRepo := export.NewEmailRepo(dataData)
|
||||
siteInfoRepo := site_info.NewSiteInfo(dataData)
|
||||
emailService := export2.NewEmailService(configRepo, emailRepo, siteInfoRepo)
|
||||
userService := service.NewUserService(userRepo, userActiveActivityRepo, emailService, authService, serviceConf)
|
||||
captchaRepo := captcha.NewCaptchaRepo(dataData)
|
||||
captchaService := action.NewCaptchaService(captchaRepo)
|
||||
|
@ -148,7 +150,8 @@ func initApplication(debug bool, serverConf *conf.Server, dbConf *data.Database,
|
|||
questionService := service.NewQuestionService(questionRepo, tagCommonService, questionCommon, userCommon, revisionService, metaService, collectionCommon, answerActivityService)
|
||||
questionController := controller.NewQuestionController(questionService, rankService)
|
||||
answerService := service.NewAnswerService(answerRepo, questionRepo, questionCommon, userCommon, collectionCommon, userRepo, revisionService, answerActivityService, answerCommon, voteRepo)
|
||||
answerController := controller.NewAnswerController(answerService, rankService)
|
||||
dashboardService := dashboard.NewDashboardService(questionRepo, answerRepo, commentCommonRepo, voteRepo, userRepo, reportRepo, configRepo)
|
||||
answerController := controller.NewAnswerController(answerService, rankService, dashboardService)
|
||||
searchRepo := search_common.NewSearchRepo(dataData, uniqueIDRepo, userCommon)
|
||||
searchService := service.NewSearchService(searchRepo, tagRepo, userCommon, followRepo)
|
||||
searchController := controller.NewSearchController(searchService)
|
||||
|
@ -166,14 +169,14 @@ func initApplication(debug bool, serverConf *conf.Server, dbConf *data.Database,
|
|||
reasonService := reason2.NewReasonService(reasonRepo)
|
||||
reasonController := controller.NewReasonController(reasonService)
|
||||
themeController := controller_backyard.NewThemeController()
|
||||
siteInfoService := service.NewSiteInfoService(siteInfoRepo, emailService)
|
||||
siteInfoController := controller_backyard.NewSiteInfoController(siteInfoService)
|
||||
siteinfoController := controller.NewSiteinfoController(siteInfoService)
|
||||
notificationRepo := notification.NewNotificationRepo(dataData)
|
||||
notificationCommon := notificationcommon.NewNotificationCommon(dataData, notificationRepo, userCommon, activityRepo, followRepo, objService)
|
||||
notificationService := notification2.NewNotificationService(dataData, notificationRepo, notificationCommon)
|
||||
notificationController := controller.NewNotificationController(notificationService)
|
||||
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 := controller.NewDashboardController(dashboardService)
|
||||
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)
|
||||
swaggerRouter := router.NewSwaggerRouter(swaggerConf)
|
||||
uiRouter := router.NewUIRouter()
|
||||
authUserMiddleware := middleware.NewAuthUserMiddleware(authService)
|
||||
|
|
138
docs/docs.go
138
docs/docs.go
|
@ -119,13 +119,36 @@ const docTemplate = `{
|
|||
}
|
||||
}
|
||||
},
|
||||
"/answer/admin/api/language/options": {
|
||||
"/answer/admin/api/dashboard": {
|
||||
"get": {
|
||||
"security": [
|
||||
{
|
||||
"ApiKeyAuth": []
|
||||
}
|
||||
],
|
||||
"description": "DashboardInfo",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"admin"
|
||||
],
|
||||
"summary": "DashboardInfo",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/handler.RespBody"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/answer/admin/api/language/options": {
|
||||
"get": {
|
||||
"description": "Get language options",
|
||||
"produces": [
|
||||
"application/json"
|
||||
|
@ -487,14 +510,14 @@ const docTemplate = `{
|
|||
"ApiKeyAuth": []
|
||||
}
|
||||
],
|
||||
"description": "Get siteinfo general",
|
||||
"description": "get site general information",
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"admin"
|
||||
],
|
||||
"summary": "Get siteinfo general",
|
||||
"summary": "get site general information",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
|
@ -522,14 +545,14 @@ const docTemplate = `{
|
|||
"ApiKeyAuth": []
|
||||
}
|
||||
],
|
||||
"description": "Get siteinfo interface",
|
||||
"description": "update site general information",
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"admin"
|
||||
],
|
||||
"summary": "Get siteinfo interface",
|
||||
"summary": "update site general information",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "general",
|
||||
|
@ -558,25 +581,14 @@ const docTemplate = `{
|
|||
"ApiKeyAuth": []
|
||||
}
|
||||
],
|
||||
"description": "Get siteinfo interface",
|
||||
"description": "get site interface",
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"admin"
|
||||
],
|
||||
"summary": "Get siteinfo interface",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "general",
|
||||
"name": "data",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/schema.AddCommentReq"
|
||||
}
|
||||
}
|
||||
],
|
||||
"summary": "get site interface",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
|
@ -604,14 +616,14 @@ const docTemplate = `{
|
|||
"ApiKeyAuth": []
|
||||
}
|
||||
],
|
||||
"description": "Get siteinfo interface",
|
||||
"description": "update site info interface",
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"admin"
|
||||
],
|
||||
"summary": "Get siteinfo interface",
|
||||
"summary": "update site info interface",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "general",
|
||||
|
@ -1432,11 +1444,6 @@ const docTemplate = `{
|
|||
},
|
||||
"/answer/api/v1/language/options": {
|
||||
"get": {
|
||||
"security": [
|
||||
{
|
||||
"ApiKeyAuth": []
|
||||
}
|
||||
],
|
||||
"description": "Get language options",
|
||||
"produces": [
|
||||
"application/json"
|
||||
|
@ -3391,6 +3398,52 @@ const docTemplate = `{
|
|||
}
|
||||
}
|
||||
},
|
||||
"/answer/api/v1/user/interface": {
|
||||
"put": {
|
||||
"security": [
|
||||
{
|
||||
"ApiKeyAuth": []
|
||||
}
|
||||
],
|
||||
"description": "UserUpdateInterface update user interface config",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"User"
|
||||
],
|
||||
"summary": "UserUpdateInterface update user interface config",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "access-token",
|
||||
"name": "Authorization",
|
||||
"in": "header",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"description": "UpdateInfoRequest",
|
||||
"name": "data",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/schema.UpdateUserInterfaceRequest"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/handler.RespBody"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/answer/api/v1/user/login/email": {
|
||||
"post": {
|
||||
"description": "UserEmailLogin",
|
||||
|
@ -4822,6 +4875,10 @@ const docTemplate = `{
|
|||
"description": "is admin",
|
||||
"type": "boolean"
|
||||
},
|
||||
"language": {
|
||||
"description": "language",
|
||||
"type": "string"
|
||||
},
|
||||
"last_login_date": {
|
||||
"description": "last login date",
|
||||
"type": "integer"
|
||||
|
@ -4918,6 +4975,10 @@ const docTemplate = `{
|
|||
"description": "is admin",
|
||||
"type": "boolean"
|
||||
},
|
||||
"language": {
|
||||
"description": "language",
|
||||
"type": "string"
|
||||
},
|
||||
"last_login_date": {
|
||||
"description": "last login date",
|
||||
"type": "integer"
|
||||
|
@ -5326,7 +5387,8 @@ const docTemplate = `{
|
|||
"type": "object",
|
||||
"required": [
|
||||
"language",
|
||||
"theme"
|
||||
"theme",
|
||||
"time_zone"
|
||||
],
|
||||
"properties": {
|
||||
"language": {
|
||||
|
@ -5340,6 +5402,10 @@ const docTemplate = `{
|
|||
"theme": {
|
||||
"type": "string",
|
||||
"maxLength": 128
|
||||
},
|
||||
"time_zone": {
|
||||
"type": "string",
|
||||
"maxLength": 128
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -5347,7 +5413,8 @@ const docTemplate = `{
|
|||
"type": "object",
|
||||
"required": [
|
||||
"language",
|
||||
"theme"
|
||||
"theme",
|
||||
"time_zone"
|
||||
],
|
||||
"properties": {
|
||||
"language": {
|
||||
|
@ -5361,6 +5428,10 @@ const docTemplate = `{
|
|||
"theme": {
|
||||
"type": "string",
|
||||
"maxLength": 128
|
||||
},
|
||||
"time_zone": {
|
||||
"type": "string",
|
||||
"maxLength": 128
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -5573,6 +5644,19 @@ const docTemplate = `{
|
|||
}
|
||||
}
|
||||
},
|
||||
"schema.UpdateUserInterfaceRequest": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"language"
|
||||
],
|
||||
"properties": {
|
||||
"language": {
|
||||
"description": "language",
|
||||
"type": "string",
|
||||
"maxLength": 100
|
||||
}
|
||||
}
|
||||
},
|
||||
"schema.UpdateUserStatusReq": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
|
|
|
@ -107,13 +107,36 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"/answer/admin/api/language/options": {
|
||||
"/answer/admin/api/dashboard": {
|
||||
"get": {
|
||||
"security": [
|
||||
{
|
||||
"ApiKeyAuth": []
|
||||
}
|
||||
],
|
||||
"description": "DashboardInfo",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"admin"
|
||||
],
|
||||
"summary": "DashboardInfo",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/handler.RespBody"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/answer/admin/api/language/options": {
|
||||
"get": {
|
||||
"description": "Get language options",
|
||||
"produces": [
|
||||
"application/json"
|
||||
|
@ -475,14 +498,14 @@
|
|||
"ApiKeyAuth": []
|
||||
}
|
||||
],
|
||||
"description": "Get siteinfo general",
|
||||
"description": "get site general information",
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"admin"
|
||||
],
|
||||
"summary": "Get siteinfo general",
|
||||
"summary": "get site general information",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
|
@ -510,14 +533,14 @@
|
|||
"ApiKeyAuth": []
|
||||
}
|
||||
],
|
||||
"description": "Get siteinfo interface",
|
||||
"description": "update site general information",
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"admin"
|
||||
],
|
||||
"summary": "Get siteinfo interface",
|
||||
"summary": "update site general information",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "general",
|
||||
|
@ -546,25 +569,14 @@
|
|||
"ApiKeyAuth": []
|
||||
}
|
||||
],
|
||||
"description": "Get siteinfo interface",
|
||||
"description": "get site interface",
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"admin"
|
||||
],
|
||||
"summary": "Get siteinfo interface",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "general",
|
||||
"name": "data",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/schema.AddCommentReq"
|
||||
}
|
||||
}
|
||||
],
|
||||
"summary": "get site interface",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
|
@ -592,14 +604,14 @@
|
|||
"ApiKeyAuth": []
|
||||
}
|
||||
],
|
||||
"description": "Get siteinfo interface",
|
||||
"description": "update site info interface",
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"admin"
|
||||
],
|
||||
"summary": "Get siteinfo interface",
|
||||
"summary": "update site info interface",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "general",
|
||||
|
@ -1420,11 +1432,6 @@
|
|||
},
|
||||
"/answer/api/v1/language/options": {
|
||||
"get": {
|
||||
"security": [
|
||||
{
|
||||
"ApiKeyAuth": []
|
||||
}
|
||||
],
|
||||
"description": "Get language options",
|
||||
"produces": [
|
||||
"application/json"
|
||||
|
@ -3379,6 +3386,52 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"/answer/api/v1/user/interface": {
|
||||
"put": {
|
||||
"security": [
|
||||
{
|
||||
"ApiKeyAuth": []
|
||||
}
|
||||
],
|
||||
"description": "UserUpdateInterface update user interface config",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"User"
|
||||
],
|
||||
"summary": "UserUpdateInterface update user interface config",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "access-token",
|
||||
"name": "Authorization",
|
||||
"in": "header",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"description": "UpdateInfoRequest",
|
||||
"name": "data",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/schema.UpdateUserInterfaceRequest"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/handler.RespBody"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/answer/api/v1/user/login/email": {
|
||||
"post": {
|
||||
"description": "UserEmailLogin",
|
||||
|
@ -4810,6 +4863,10 @@
|
|||
"description": "is admin",
|
||||
"type": "boolean"
|
||||
},
|
||||
"language": {
|
||||
"description": "language",
|
||||
"type": "string"
|
||||
},
|
||||
"last_login_date": {
|
||||
"description": "last login date",
|
||||
"type": "integer"
|
||||
|
@ -4906,6 +4963,10 @@
|
|||
"description": "is admin",
|
||||
"type": "boolean"
|
||||
},
|
||||
"language": {
|
||||
"description": "language",
|
||||
"type": "string"
|
||||
},
|
||||
"last_login_date": {
|
||||
"description": "last login date",
|
||||
"type": "integer"
|
||||
|
@ -5314,7 +5375,8 @@
|
|||
"type": "object",
|
||||
"required": [
|
||||
"language",
|
||||
"theme"
|
||||
"theme",
|
||||
"time_zone"
|
||||
],
|
||||
"properties": {
|
||||
"language": {
|
||||
|
@ -5328,6 +5390,10 @@
|
|||
"theme": {
|
||||
"type": "string",
|
||||
"maxLength": 128
|
||||
},
|
||||
"time_zone": {
|
||||
"type": "string",
|
||||
"maxLength": 128
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -5335,7 +5401,8 @@
|
|||
"type": "object",
|
||||
"required": [
|
||||
"language",
|
||||
"theme"
|
||||
"theme",
|
||||
"time_zone"
|
||||
],
|
||||
"properties": {
|
||||
"language": {
|
||||
|
@ -5349,6 +5416,10 @@
|
|||
"theme": {
|
||||
"type": "string",
|
||||
"maxLength": 128
|
||||
},
|
||||
"time_zone": {
|
||||
"type": "string",
|
||||
"maxLength": 128
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -5561,6 +5632,19 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"schema.UpdateUserInterfaceRequest": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"language"
|
||||
],
|
||||
"properties": {
|
||||
"language": {
|
||||
"description": "language",
|
||||
"type": "string",
|
||||
"maxLength": 100
|
||||
}
|
||||
}
|
||||
},
|
||||
"schema.UpdateUserStatusReq": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
|
|
|
@ -652,6 +652,9 @@ definitions:
|
|||
is_admin:
|
||||
description: is admin
|
||||
type: boolean
|
||||
language:
|
||||
description: language
|
||||
type: string
|
||||
last_login_date:
|
||||
description: last login date
|
||||
type: integer
|
||||
|
@ -723,6 +726,9 @@ definitions:
|
|||
is_admin:
|
||||
description: is admin
|
||||
type: boolean
|
||||
language:
|
||||
description: language
|
||||
type: string
|
||||
last_login_date:
|
||||
description: last login date
|
||||
type: integer
|
||||
|
@ -1024,9 +1030,13 @@ definitions:
|
|||
theme:
|
||||
maxLength: 128
|
||||
type: string
|
||||
time_zone:
|
||||
maxLength: 128
|
||||
type: string
|
||||
required:
|
||||
- language
|
||||
- theme
|
||||
- time_zone
|
||||
type: object
|
||||
schema.SiteInterfaceResp:
|
||||
properties:
|
||||
|
@ -1039,9 +1049,13 @@ definitions:
|
|||
theme:
|
||||
maxLength: 128
|
||||
type: string
|
||||
time_zone:
|
||||
maxLength: 128
|
||||
type: string
|
||||
required:
|
||||
- language
|
||||
- theme
|
||||
- time_zone
|
||||
type: object
|
||||
schema.TagItem:
|
||||
properties:
|
||||
|
@ -1195,6 +1209,15 @@ definitions:
|
|||
- synonym_tag_list
|
||||
- tag_id
|
||||
type: object
|
||||
schema.UpdateUserInterfaceRequest:
|
||||
properties:
|
||||
language:
|
||||
description: language
|
||||
maxLength: 100
|
||||
type: string
|
||||
required:
|
||||
- language
|
||||
type: object
|
||||
schema.UpdateUserStatusReq:
|
||||
properties:
|
||||
status:
|
||||
|
@ -1434,6 +1457,23 @@ paths:
|
|||
summary: AdminSetAnswerStatus
|
||||
tags:
|
||||
- admin
|
||||
/answer/admin/api/dashboard:
|
||||
get:
|
||||
consumes:
|
||||
- application/json
|
||||
description: DashboardInfo
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/handler.RespBody'
|
||||
security:
|
||||
- ApiKeyAuth: []
|
||||
summary: DashboardInfo
|
||||
tags:
|
||||
- admin
|
||||
/answer/admin/api/language/options:
|
||||
get:
|
||||
description: Get language options
|
||||
|
@ -1444,8 +1484,6 @@ paths:
|
|||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/handler.RespBody'
|
||||
security:
|
||||
- ApiKeyAuth: []
|
||||
summary: Get language options
|
||||
tags:
|
||||
- Lang
|
||||
|
@ -1662,7 +1700,7 @@ paths:
|
|||
- admin
|
||||
/answer/admin/api/siteinfo/general:
|
||||
get:
|
||||
description: Get siteinfo general
|
||||
description: get site general information
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
|
@ -1677,11 +1715,11 @@ paths:
|
|||
type: object
|
||||
security:
|
||||
- ApiKeyAuth: []
|
||||
summary: Get siteinfo general
|
||||
summary: get site general information
|
||||
tags:
|
||||
- admin
|
||||
put:
|
||||
description: Get siteinfo interface
|
||||
description: update site general information
|
||||
parameters:
|
||||
- description: general
|
||||
in: body
|
||||
|
@ -1698,19 +1736,12 @@ paths:
|
|||
$ref: '#/definitions/handler.RespBody'
|
||||
security:
|
||||
- ApiKeyAuth: []
|
||||
summary: Get siteinfo interface
|
||||
summary: update site general information
|
||||
tags:
|
||||
- admin
|
||||
/answer/admin/api/siteinfo/interface:
|
||||
get:
|
||||
description: Get siteinfo interface
|
||||
parameters:
|
||||
- description: general
|
||||
in: body
|
||||
name: data
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/schema.AddCommentReq'
|
||||
description: get site interface
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
|
@ -1725,11 +1756,11 @@ paths:
|
|||
type: object
|
||||
security:
|
||||
- ApiKeyAuth: []
|
||||
summary: Get siteinfo interface
|
||||
summary: get site interface
|
||||
tags:
|
||||
- admin
|
||||
put:
|
||||
description: Get siteinfo interface
|
||||
description: update site info interface
|
||||
parameters:
|
||||
- description: general
|
||||
in: body
|
||||
|
@ -1746,7 +1777,7 @@ paths:
|
|||
$ref: '#/definitions/handler.RespBody'
|
||||
security:
|
||||
- ApiKeyAuth: []
|
||||
summary: Get siteinfo interface
|
||||
summary: update site info interface
|
||||
tags:
|
||||
- admin
|
||||
/answer/admin/api/theme/options:
|
||||
|
@ -2237,8 +2268,6 @@ paths:
|
|||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/handler.RespBody'
|
||||
security:
|
||||
- ApiKeyAuth: []
|
||||
summary: Get language options
|
||||
tags:
|
||||
- Lang
|
||||
|
@ -3425,6 +3454,35 @@ paths:
|
|||
summary: UserUpdateInfo update user info
|
||||
tags:
|
||||
- User
|
||||
/answer/api/v1/user/interface:
|
||||
put:
|
||||
consumes:
|
||||
- application/json
|
||||
description: UserUpdateInterface update user interface config
|
||||
parameters:
|
||||
- description: access-token
|
||||
in: header
|
||||
name: Authorization
|
||||
required: true
|
||||
type: string
|
||||
- description: UpdateInfoRequest
|
||||
in: body
|
||||
name: data
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/schema.UpdateUserInterfaceRequest'
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/handler.RespBody'
|
||||
security:
|
||||
- ApiKeyAuth: []
|
||||
summary: UserUpdateInterface update user interface config
|
||||
tags:
|
||||
- User
|
||||
/answer/api/v1/user/login/email:
|
||||
post:
|
||||
consumes:
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
# all support language
|
||||
language_options:
|
||||
- label: "简体中文(CN)"
|
||||
value: "zh_CN"
|
||||
- label: "English(US)"
|
||||
value: "en_US"
|
|
@ -1,17 +1,58 @@
|
|||
package translator
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/google/wire"
|
||||
myTran "github.com/segmentfault/pacman/contrib/i18n"
|
||||
"github.com/segmentfault/pacman/i18n"
|
||||
"sigs.k8s.io/yaml"
|
||||
)
|
||||
|
||||
// ProviderSet is providers.
|
||||
var ProviderSet = wire.NewSet(NewTranslator)
|
||||
var GlobalTrans i18n.Translator
|
||||
|
||||
// LangOption language option
|
||||
type LangOption struct {
|
||||
Label string `json:"label"`
|
||||
Value string `json:"value"`
|
||||
}
|
||||
|
||||
// LanguageOptions language
|
||||
var LanguageOptions []*LangOption
|
||||
|
||||
// NewTranslator new a translator
|
||||
func NewTranslator(c *I18n) (tr i18n.Translator, err error) {
|
||||
GlobalTrans, err = myTran.NewTranslator(c.BundleDir)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
i18nFile, err := os.ReadFile(filepath.Join(c.BundleDir, "i18n.yaml"))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("read i18n file failed: %s", err)
|
||||
}
|
||||
|
||||
s := struct {
|
||||
LangOption []*LangOption `json:"language_options"`
|
||||
}{}
|
||||
err = yaml.Unmarshal(i18nFile, &s)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("i18n file parsing failed: %s", err)
|
||||
}
|
||||
LanguageOptions = s.LangOption
|
||||
return GlobalTrans, err
|
||||
}
|
||||
|
||||
// CheckLanguageIsValid check user input language is valid
|
||||
func CheckLanguageIsValid(lang string) bool {
|
||||
for _, option := range LanguageOptions {
|
||||
if option.Value == lang {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ import (
|
|||
"github.com/answerdev/answer/internal/entity"
|
||||
"github.com/answerdev/answer/internal/schema"
|
||||
"github.com/answerdev/answer/internal/service"
|
||||
"github.com/answerdev/answer/internal/service/dashboard"
|
||||
"github.com/answerdev/answer/internal/service/rank"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/segmentfault/pacman/errors"
|
||||
|
@ -16,13 +17,21 @@ import (
|
|||
|
||||
// AnswerController answer controller
|
||||
type AnswerController struct {
|
||||
answerService *service.AnswerService
|
||||
rankService *rank.RankService
|
||||
answerService *service.AnswerService
|
||||
rankService *rank.RankService
|
||||
dashboardService *dashboard.DashboardService
|
||||
}
|
||||
|
||||
// NewAnswerController new controller
|
||||
func NewAnswerController(answerService *service.AnswerService, rankService *rank.RankService) *AnswerController {
|
||||
return &AnswerController{answerService: answerService, rankService: rankService}
|
||||
func NewAnswerController(answerService *service.AnswerService,
|
||||
rankService *rank.RankService,
|
||||
dashboardService *dashboard.DashboardService,
|
||||
) *AnswerController {
|
||||
return &AnswerController{
|
||||
answerService: answerService,
|
||||
rankService: rankService,
|
||||
dashboardService: dashboardService,
|
||||
}
|
||||
}
|
||||
|
||||
// RemoveAnswer delete answer
|
||||
|
|
|
@ -20,4 +20,5 @@ var ProviderSetController = wire.NewSet(
|
|||
NewReasonController,
|
||||
NewNotificationController,
|
||||
NewSiteinfoController,
|
||||
NewDashboardController,
|
||||
)
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
package controller
|
||||
|
||||
import (
|
||||
"github.com/answerdev/answer/internal/base/handler"
|
||||
"github.com/answerdev/answer/internal/service/dashboard"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
type DashboardController struct {
|
||||
dashboardService *dashboard.DashboardService
|
||||
}
|
||||
|
||||
// NewDashboardController new controller
|
||||
func NewDashboardController(
|
||||
dashboardService *dashboard.DashboardService,
|
||||
) *DashboardController {
|
||||
return &DashboardController{
|
||||
dashboardService: dashboardService,
|
||||
}
|
||||
}
|
||||
|
||||
// DashboardInfo godoc
|
||||
// @Summary DashboardInfo
|
||||
// @Description DashboardInfo
|
||||
// @Tags admin
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /answer/admin/api/dashboard [get]
|
||||
// @Success 200 {object} handler.RespBody
|
||||
func (ac *DashboardController) DashboardInfo(ctx *gin.Context) {
|
||||
info, err := ac.dashboardService.Statistical(ctx)
|
||||
handler.HandleResponse(ctx, err, gin.H{
|
||||
"info": info,
|
||||
})
|
||||
}
|
|
@ -4,18 +4,20 @@ import (
|
|||
"encoding/json"
|
||||
|
||||
"github.com/answerdev/answer/internal/base/handler"
|
||||
"github.com/answerdev/answer/internal/schema"
|
||||
"github.com/answerdev/answer/internal/base/translator"
|
||||
"github.com/answerdev/answer/internal/service"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/segmentfault/pacman/i18n"
|
||||
)
|
||||
|
||||
type LangController struct {
|
||||
translator i18n.Translator
|
||||
translator i18n.Translator
|
||||
siteInfoService *service.SiteInfoService
|
||||
}
|
||||
|
||||
// NewLangController new language controller.
|
||||
func NewLangController(tr i18n.Translator) *LangController {
|
||||
return &LangController{translator: tr}
|
||||
func NewLangController(tr i18n.Translator, siteInfoService *service.SiteInfoService) *LangController {
|
||||
return &LangController{translator: tr, siteInfoService: siteInfoService}
|
||||
}
|
||||
|
||||
// GetLangMapping get language config mapping
|
||||
|
@ -33,15 +35,38 @@ func (u *LangController) GetLangMapping(ctx *gin.Context) {
|
|||
handler.HandleResponse(ctx, nil, resp)
|
||||
}
|
||||
|
||||
// GetLangOptions Get language options
|
||||
// GetAdminLangOptions Get language options
|
||||
// @Summary Get language options
|
||||
// @Description Get language options
|
||||
// @Security ApiKeyAuth
|
||||
// @Tags Lang
|
||||
// @Produce json
|
||||
// @Success 200 {object} handler.RespBody{}
|
||||
// @Router /answer/api/v1/language/options [get]
|
||||
// @Router /answer/admin/api/language/options [get]
|
||||
func (u *LangController) GetLangOptions(ctx *gin.Context) {
|
||||
handler.HandleResponse(ctx, nil, schema.GetLangOptions)
|
||||
func (u *LangController) GetAdminLangOptions(ctx *gin.Context) {
|
||||
handler.HandleResponse(ctx, nil, translator.LanguageOptions)
|
||||
}
|
||||
|
||||
// GetUserLangOptions Get language options
|
||||
// @Summary Get language options
|
||||
// @Description Get language options
|
||||
// @Tags Lang
|
||||
// @Produce json
|
||||
// @Success 200 {object} handler.RespBody{}
|
||||
// @Router /answer/api/v1/language/options [get]
|
||||
func (u *LangController) GetUserLangOptions(ctx *gin.Context) {
|
||||
siteInterfaceResp, err := u.siteInfoService.GetSiteInterface(ctx)
|
||||
if err != nil {
|
||||
handler.HandleResponse(ctx, err, nil)
|
||||
return
|
||||
}
|
||||
|
||||
options := translator.LanguageOptions
|
||||
if len(siteInterfaceResp.Language) > 0 {
|
||||
defaultOption := []*translator.LangOption{
|
||||
{Label: "Default", Value: siteInterfaceResp.Language},
|
||||
}
|
||||
options = append(defaultOption, options...)
|
||||
}
|
||||
handler.HandleResponse(ctx, nil, options)
|
||||
}
|
||||
|
|
|
@ -373,6 +373,27 @@ func (uc *UserController) UserUpdateInfo(ctx *gin.Context) {
|
|||
handler.HandleResponse(ctx, err, nil)
|
||||
}
|
||||
|
||||
// UserUpdateInterface update user interface config
|
||||
// @Summary UserUpdateInterface update user interface config
|
||||
// @Description UserUpdateInterface update user interface config
|
||||
// @Tags User
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Security ApiKeyAuth
|
||||
// @Param Authorization header string true "access-token"
|
||||
// @Param data body schema.UpdateUserInterfaceRequest true "UpdateInfoRequest"
|
||||
// @Success 200 {object} handler.RespBody
|
||||
// @Router /answer/api/v1/user/interface [put]
|
||||
func (uc *UserController) UserUpdateInterface(ctx *gin.Context) {
|
||||
req := &schema.UpdateUserInterfaceRequest{}
|
||||
if handler.BindAndCheck(ctx, req) {
|
||||
return
|
||||
}
|
||||
req.UserId = middleware.GetLoginUserIDFromContext(ctx)
|
||||
err := uc.userService.UserUpdateInterface(ctx, req)
|
||||
handler.HandleResponse(ctx, err, nil)
|
||||
}
|
||||
|
||||
// UploadUserAvatar godoc
|
||||
// @Summary UserUpdateInfo
|
||||
// @Description UserUpdateInfo
|
||||
|
|
|
@ -18,9 +18,9 @@ func NewSiteInfoController(siteInfoService *service.SiteInfoService) *SiteInfoCo
|
|||
}
|
||||
}
|
||||
|
||||
// GetGeneral godoc
|
||||
// @Summary Get siteinfo general
|
||||
// @Description Get siteinfo general
|
||||
// GetGeneral get site general information
|
||||
// @Summary get site general information
|
||||
// @Description get site general information
|
||||
// @Security ApiKeyAuth
|
||||
// @Tags admin
|
||||
// @Produce json
|
||||
|
@ -31,23 +31,22 @@ func (sc *SiteInfoController) GetGeneral(ctx *gin.Context) {
|
|||
handler.HandleResponse(ctx, err, resp)
|
||||
}
|
||||
|
||||
// GetInterface godoc
|
||||
// @Summary Get siteinfo interface
|
||||
// @Description Get siteinfo interface
|
||||
// GetInterface get site interface
|
||||
// @Summary get site interface
|
||||
// @Description get site interface
|
||||
// @Security ApiKeyAuth
|
||||
// @Tags admin
|
||||
// @Produce json
|
||||
// @Success 200 {object} handler.RespBody{data=schema.SiteInterfaceResp}
|
||||
// @Router /answer/admin/api/siteinfo/interface [get]
|
||||
// @Param data body schema.AddCommentReq true "general"
|
||||
func (sc *SiteInfoController) GetInterface(ctx *gin.Context) {
|
||||
resp, err := sc.siteInfoService.GetSiteInterface(ctx)
|
||||
handler.HandleResponse(ctx, err, resp)
|
||||
}
|
||||
|
||||
// UpdateGeneral godoc
|
||||
// @Summary Get siteinfo interface
|
||||
// @Description Get siteinfo interface
|
||||
// UpdateGeneral update site general information
|
||||
// @Summary update site general information
|
||||
// @Description update site general information
|
||||
// @Security ApiKeyAuth
|
||||
// @Tags admin
|
||||
// @Produce json
|
||||
|
@ -63,9 +62,9 @@ func (sc *SiteInfoController) UpdateGeneral(ctx *gin.Context) {
|
|||
handler.HandleResponse(ctx, err, nil)
|
||||
}
|
||||
|
||||
// UpdateInterface godoc
|
||||
// @Summary Get siteinfo interface
|
||||
// @Description Get siteinfo interface
|
||||
// UpdateInterface update site interface
|
||||
// @Summary update site info interface
|
||||
// @Description update site info interface
|
||||
// @Security ApiKeyAuth
|
||||
// @Tags admin
|
||||
// @Produce json
|
||||
|
|
|
@ -45,6 +45,7 @@ type User struct {
|
|||
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"`
|
||||
}
|
||||
|
||||
// TableName user table name
|
||||
|
|
|
@ -5,7 +5,6 @@ import (
|
|||
|
||||
"github.com/answerdev/answer/internal/base/data"
|
||||
"github.com/answerdev/answer/internal/entity"
|
||||
"github.com/segmentfault/pacman/log"
|
||||
"xorm.io/xorm"
|
||||
)
|
||||
|
||||
|
@ -43,6 +42,7 @@ var noopMigration = func(_ *xorm.Engine) error { return nil }
|
|||
var migrations = []Migration{
|
||||
// 0->1
|
||||
NewMigration("this is first version, no operation", noopMigration),
|
||||
NewMigration("add user language", addUserLanguage),
|
||||
}
|
||||
|
||||
// GetCurrentDBVersion returns the current db version
|
||||
|
@ -86,17 +86,17 @@ func Migrate(dataConf *data.Database) error {
|
|||
expectedVersion := ExpectedVersion()
|
||||
|
||||
for currentDBVersion < expectedVersion {
|
||||
log.Infof("[migrate] current db version is %d, try to migrate version %d, latest version is %d",
|
||||
fmt.Printf("[migrate] current db version is %d, try to migrate version %d, latest version is %d\n",
|
||||
currentDBVersion, currentDBVersion+1, expectedVersion)
|
||||
migrationFunc := migrations[currentDBVersion]
|
||||
log.Infof("[migrate] try to migrate db version %d, description: %s", currentDBVersion+1, migrationFunc.Description())
|
||||
fmt.Printf("[migrate] try to migrate db version %d, description: %s\n", currentDBVersion+1, migrationFunc.Description())
|
||||
if err := migrationFunc.Migrate(engine); err != nil {
|
||||
log.Errorf("[migrate] migrate to db version %d failed: ", currentDBVersion+1, err.Error())
|
||||
fmt.Printf("[migrate] migrate to db version %d failed: %s\n", currentDBVersion+1, err.Error())
|
||||
return err
|
||||
}
|
||||
log.Infof("[migrate] migrate to db version %d success", currentDBVersion+1)
|
||||
fmt.Printf("[migrate] migrate to db version %d success\n", currentDBVersion+1)
|
||||
if _, err := engine.Update(&entity.Version{ID: 1, VersionNumber: currentDBVersion + 1}); err != nil {
|
||||
log.Errorf("[migrate] migrate to db version %d, update failed: %s", currentDBVersion+1, err.Error())
|
||||
fmt.Printf("[migrate] migrate to db version %d, update failed: %s", currentDBVersion+1, err.Error())
|
||||
return err
|
||||
}
|
||||
currentDBVersion++
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
package migrations
|
||||
|
||||
import (
|
||||
"xorm.io/xorm"
|
||||
)
|
||||
|
||||
func addUserLanguage(x *xorm.Engine) error {
|
||||
type User struct {
|
||||
Language string `xorm:"not null default '' VARCHAR(100) language"`
|
||||
}
|
||||
return x.Sync(new(User))
|
||||
}
|
|
@ -4,8 +4,10 @@ import (
|
|||
"context"
|
||||
|
||||
"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/activity_common"
|
||||
"github.com/segmentfault/pacman/errors"
|
||||
)
|
||||
|
||||
// VoteRepo activity repository
|
||||
|
@ -39,3 +41,12 @@ func (vr *VoteRepo) GetVoteStatus(ctx context.Context, objectID, userID string)
|
|||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (vr *VoteRepo) GetVoteCount(ctx context.Context, activityTypes []int) (count int64, err error) {
|
||||
list := make([]*entity.Activity, 0)
|
||||
count, err = vr.data.DB.Where("cancelled =0").In("activity_type", activityTypes).FindAndCount(&list)
|
||||
if err != nil {
|
||||
return count, errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
|
||||
}
|
||||
return
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ import (
|
|||
"strings"
|
||||
"time"
|
||||
"unicode"
|
||||
|
||||
"xorm.io/builder"
|
||||
|
||||
"github.com/answerdev/answer/internal/base/constant"
|
||||
|
@ -102,6 +103,16 @@ func (ar *answerRepo) GetAnswer(ctx context.Context, id string) (
|
|||
return
|
||||
}
|
||||
|
||||
// GetQuestionCount
|
||||
func (ar *answerRepo) GetAnswerCount(ctx context.Context) (count int64, err error) {
|
||||
list := make([]*entity.Answer, 0)
|
||||
count, err = ar.data.DB.Where("status = ?", entity.AnswerStatusAvailable).FindAndCount(&list)
|
||||
if err != nil {
|
||||
return count, errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// GetAnswerList get answer list all
|
||||
func (ar *answerRepo) GetAnswerList(ctx context.Context, answer *entity.Answer) (answerList []*entity.Answer, err error) {
|
||||
answerList = make([]*entity.Answer, 0)
|
||||
|
|
|
@ -79,6 +79,15 @@ func (cr *commentRepo) GetComment(ctx context.Context, commentID string) (
|
|||
return
|
||||
}
|
||||
|
||||
func (cr *commentRepo) GetCommentCount(ctx context.Context) (count int64, err error) {
|
||||
list := make([]*entity.Comment, 0)
|
||||
count, err = cr.data.DB.Where("status = ?", entity.CommentStatusAvailable).FindAndCount(&list)
|
||||
if err != nil {
|
||||
return count, errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// GetCommentPage get comment page
|
||||
func (cr *commentRepo) GetCommentPage(ctx context.Context, commentQuery *comment.CommentQuery) (
|
||||
commentList []*entity.Comment, total int64, err error,
|
||||
|
|
|
@ -5,6 +5,7 @@ import (
|
|||
"strings"
|
||||
"time"
|
||||
"unicode"
|
||||
|
||||
"xorm.io/builder"
|
||||
|
||||
"github.com/answerdev/answer/internal/base/constant"
|
||||
|
@ -162,6 +163,16 @@ func (qr *questionRepo) GetQuestionList(ctx context.Context, question *entity.Qu
|
|||
return
|
||||
}
|
||||
|
||||
func (qr *questionRepo) GetQuestionCount(ctx context.Context) (count int64, err error) {
|
||||
questionList := make([]*entity.Question, 0)
|
||||
|
||||
count, err = qr.data.DB.In("question.status", []int{entity.QuestionStatusAvailable, entity.QuestionStatusclosed}).FindAndCount(&questionList)
|
||||
if err != nil {
|
||||
return count, errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// GetQuestionPage get question page
|
||||
func (qr *questionRepo) GetQuestionPage(ctx context.Context, page, pageSize int, question *entity.Question) (questionList []*entity.Question, total int64, err error) {
|
||||
questionList = make([]*entity.Question, 0)
|
||||
|
|
|
@ -94,3 +94,12 @@ func (ar *reportRepo) UpdateByID(
|
|||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (vr *reportRepo) GetReportCount(ctx context.Context) (count int64, err error) {
|
||||
list := make([]*entity.Report, 0)
|
||||
count, err = vr.data.DB.Where("status =?", entity.ReportStatusPending).FindAndCount(&list)
|
||||
if err != nil {
|
||||
return count, errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
|
||||
}
|
||||
return
|
||||
}
|
||||
|
|
|
@ -101,6 +101,14 @@ func (ur *userRepo) UpdateEmail(ctx context.Context, userID, email string) (err
|
|||
return
|
||||
}
|
||||
|
||||
func (ur *userRepo) UpdateLanguage(ctx context.Context, userID, language string) (err error) {
|
||||
_, err = ur.data.DB.Where("id = ?", userID).Update(&entity.User{Language: language})
|
||||
if err != nil {
|
||||
err = errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// UpdateInfo update user info
|
||||
func (ur *userRepo) UpdateInfo(ctx context.Context, userInfo *entity.User) (err error) {
|
||||
_, err = ur.data.DB.Where("id = ?", userInfo.ID).
|
||||
|
@ -149,3 +157,12 @@ func (ur *userRepo) GetByEmail(ctx context.Context, email string) (userInfo *ent
|
|||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (vr *userRepo) GetUserCount(ctx context.Context) (count int64, err error) {
|
||||
list := make([]*entity.User, 0)
|
||||
count, err = vr.data.DB.Where("mail_status =?", entity.EmailStatusAvailable).And("status =?", entity.UserStatusAvailable).FindAndCount(&list)
|
||||
if err != nil {
|
||||
return count, errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
|
||||
}
|
||||
return
|
||||
}
|
||||
|
|
|
@ -27,6 +27,7 @@ type AnswerAPIRouter struct {
|
|||
siteInfoController *controller_backyard.SiteInfoController
|
||||
siteinfoController *controller.SiteinfoController
|
||||
notificationController *controller.NotificationController
|
||||
dashboardController *controller.DashboardController
|
||||
}
|
||||
|
||||
func NewAnswerAPIRouter(
|
||||
|
@ -50,6 +51,7 @@ func NewAnswerAPIRouter(
|
|||
siteInfoController *controller_backyard.SiteInfoController,
|
||||
siteinfoController *controller.SiteinfoController,
|
||||
notificationController *controller.NotificationController,
|
||||
dashboardController *controller.DashboardController,
|
||||
|
||||
) *AnswerAPIRouter {
|
||||
return &AnswerAPIRouter{
|
||||
|
@ -73,13 +75,14 @@ func NewAnswerAPIRouter(
|
|||
siteInfoController: siteInfoController,
|
||||
notificationController: notificationController,
|
||||
siteinfoController: siteinfoController,
|
||||
dashboardController: dashboardController,
|
||||
}
|
||||
}
|
||||
|
||||
func (a *AnswerAPIRouter) RegisterUnAuthAnswerAPIRouter(r *gin.RouterGroup) {
|
||||
// i18n
|
||||
r.GET("/language/config", a.langController.GetLangMapping)
|
||||
r.GET("/language/options", a.langController.GetLangOptions)
|
||||
r.GET("/language/options", a.langController.GetUserLangOptions)
|
||||
|
||||
// comment
|
||||
r.GET("/comment/page", a.commentController.GetCommentWithPage)
|
||||
|
@ -177,6 +180,7 @@ func (a *AnswerAPIRouter) RegisterAnswerAPIRouter(r *gin.RouterGroup) {
|
|||
// user
|
||||
r.PUT("/user/password", a.userController.UserModifyPassWord)
|
||||
r.PUT("/user/info", a.userController.UserUpdateInfo)
|
||||
r.PUT("/user/interface", a.userController.UserUpdateInterface)
|
||||
r.POST("/user/avatar/upload", a.userController.UploadUserAvatar)
|
||||
r.POST("/user/post/file", a.userController.UploadUserPostFile)
|
||||
r.POST("/user/notice/set", a.userController.UserNoticeSet)
|
||||
|
@ -213,7 +217,7 @@ func (a *AnswerAPIRouter) RegisterAnswerCmsAPIRouter(r *gin.RouterGroup) {
|
|||
r.GET("/reasons", a.reasonController.Reasons)
|
||||
|
||||
// language
|
||||
r.GET("/language/options", a.langController.GetLangOptions)
|
||||
r.GET("/language/options", a.langController.GetAdminLangOptions)
|
||||
|
||||
// theme
|
||||
r.GET("/theme/options", a.themeController.GetThemeOptions)
|
||||
|
@ -225,4 +229,7 @@ func (a *AnswerAPIRouter) RegisterAnswerCmsAPIRouter(r *gin.RouterGroup) {
|
|||
r.PUT("/siteinfo/interface", a.siteInfoController.UpdateInterface)
|
||||
r.GET("/setting/smtp", a.siteInfoController.GetSMTPConfig)
|
||||
r.PUT("/setting/smtp", a.siteInfoController.UpdateSMTPConfig)
|
||||
|
||||
//dashboard
|
||||
r.GET("/dashboard", a.dashboardController.DashboardInfo)
|
||||
}
|
||||
|
|
|
@ -7,7 +7,9 @@ import (
|
|||
"net/http"
|
||||
"os"
|
||||
|
||||
|
||||
"github.com/answerdev/answer/internal/base/handler"
|
||||
"github.com/answerdev/answer/i18n"
|
||||
"github.com/answerdev/answer/ui"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/segmentfault/pacman/log"
|
||||
|
@ -41,6 +43,7 @@ func (r *_resource) Open(name string) (fs.File, error) {
|
|||
// Register a new static resource which generated by ui directory
|
||||
func (a *UIRouter) Register(r *gin.Engine) {
|
||||
staticPath := os.Getenv("ANSWER_STATIC_PATH")
|
||||
r.StaticFS("/i18n/", http.FS(i18n.I18n))
|
||||
|
||||
// if ANSWER_STATIC_PATH is set and not empty, ignore embed resource
|
||||
if staticPath != "" {
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
package schema
|
||||
|
||||
type DashboardInfo struct {
|
||||
QuestionCount int64 `json:"question_count"`
|
||||
AnswerCount int64 `json:"answer_count"`
|
||||
CommentCount int64 `json:"comment_count"`
|
||||
VoteCount int64 `json:"vote_count"`
|
||||
UserCount int64 `json:"user_count"`
|
||||
ReportCount int64 `json:"report_count"`
|
||||
UploadingFiles string `json:"uploading_files"` //Allowed or Not allowed
|
||||
SMTP string `json:"smtp"` //Enabled or Disabled
|
||||
TimeZone string `json:"time_zone"`
|
||||
OccupyingStorageSpace string `json:"occupying_storage_space"`
|
||||
AppStartTime string `json:"app_start_time"`
|
||||
}
|
|
@ -1,18 +0,0 @@
|
|||
package schema
|
||||
|
||||
// GetLangOption get label option
|
||||
type GetLangOption struct {
|
||||
Label string `json:"label"`
|
||||
Value string `json:"value"`
|
||||
}
|
||||
|
||||
var GetLangOptions = []*GetLangOption{
|
||||
{
|
||||
Label: "English(US)",
|
||||
Value: "en_US",
|
||||
},
|
||||
{
|
||||
Label: "中文(CN)",
|
||||
Value: "zh_CN",
|
||||
},
|
||||
}
|
|
@ -2,16 +2,17 @@ package schema
|
|||
|
||||
// SiteGeneralReq site general request
|
||||
type SiteGeneralReq struct {
|
||||
Name string `validate:"required,gt=1,lte=128" comment:"site name" form:"name" json:"name"`
|
||||
ShortDescription string `validate:"required,gt=3,lte=255" comment:"short site description" form:"short_description" json:"short_description"`
|
||||
Description string `validate:"required,gt=3,lte=2000" comment:"site description" form:"description" json:"description"`
|
||||
Name string `validate:"required,gt=1,lte=128" form:"name" json:"name"`
|
||||
ShortDescription string `validate:"required,gt=3,lte=255" form:"short_description" json:"short_description"`
|
||||
Description string `validate:"required,gt=3,lte=2000" form:"description" json:"description"`
|
||||
}
|
||||
|
||||
// SiteInterfaceReq site interface request
|
||||
type SiteInterfaceReq struct {
|
||||
Logo string `validate:"omitempty,gt=0,lte=256" comment:"logo" form:"logo" json:"logo"`
|
||||
Theme string `validate:"required,gt=1,lte=128" comment:"theme" form:"theme" json:"theme"`
|
||||
Language string `validate:"required,gt=1,lte=128" comment:"interface language" form:"language" json:"language"`
|
||||
Logo string `validate:"omitempty,gt=0,lte=256" form:"logo" json:"logo"`
|
||||
Theme string `validate:"required,gt=1,lte=128" form:"theme" json:"theme"`
|
||||
Language string `validate:"required,gt=1,lte=128" form:"language" json:"language"`
|
||||
TimeZone string `validate:"required,gt=1,lte=128" form:"time_zone" json:"time_zone"`
|
||||
}
|
||||
|
||||
// SiteGeneralResp site general response
|
||||
|
|
|
@ -62,6 +62,8 @@ type GetUserResp struct {
|
|||
Location string `json:"location"`
|
||||
// ip info
|
||||
IPInfo string `json:"ip_info"`
|
||||
// language
|
||||
Language string `json:"language"`
|
||||
// access token
|
||||
AccessToken string `json:"access_token"`
|
||||
// is admin
|
||||
|
@ -305,6 +307,14 @@ func (u *UpdateInfoRequest) Check() (errField *validator.ErrorField, err error)
|
|||
return nil, nil
|
||||
}
|
||||
|
||||
// UpdateUserInterfaceRequest update user interface request
|
||||
type UpdateUserInterfaceRequest struct {
|
||||
// language
|
||||
Language string `validate:"required,gt=1,lte=100" json:"language"`
|
||||
// user id
|
||||
UserId string `json:"-" `
|
||||
}
|
||||
|
||||
type UserRetrievePassWordRequest struct {
|
||||
Email string `validate:"required,email,gt=0,lte=500" json:"e_mail" ` // e_mail
|
||||
CaptchaID string `json:"captcha_id" ` // captcha_id
|
||||
|
|
|
@ -7,4 +7,5 @@ import (
|
|||
// VoteRepo activity repository
|
||||
type VoteRepo interface {
|
||||
GetVoteStatus(ctx context.Context, objectId, userId string) (status string)
|
||||
GetVoteCount(ctx context.Context, activityTypes []int) (count int64, err error)
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@ type AnswerRepo interface {
|
|||
SearchList(ctx context.Context, search *entity.AnswerSearch) ([]*entity.Answer, int64, error)
|
||||
CmsSearchList(ctx context.Context, search *entity.CmsAnswerSearch) ([]*entity.Answer, int64, error)
|
||||
UpdateAnswerStatus(ctx context.Context, answer *entity.Answer) (err error)
|
||||
GetAnswerCount(ctx context.Context) (count int64, err error)
|
||||
}
|
||||
|
||||
// AnswerCommon user service
|
||||
|
|
|
@ -12,6 +12,7 @@ import (
|
|||
// CommentCommonRepo comment repository
|
||||
type CommentCommonRepo interface {
|
||||
GetComment(ctx context.Context, commentID string) (comment *entity.Comment, exist bool, err error)
|
||||
GetCommentCount(ctx context.Context) (count int64, err error)
|
||||
}
|
||||
|
||||
// CommentCommonService user service
|
||||
|
|
|
@ -0,0 +1,105 @@
|
|||
package dashboard
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/answerdev/answer/internal/schema"
|
||||
"github.com/answerdev/answer/internal/service/activity_common"
|
||||
answercommon "github.com/answerdev/answer/internal/service/answer_common"
|
||||
"github.com/answerdev/answer/internal/service/comment_common"
|
||||
"github.com/answerdev/answer/internal/service/config"
|
||||
questioncommon "github.com/answerdev/answer/internal/service/question_common"
|
||||
"github.com/answerdev/answer/internal/service/report_common"
|
||||
usercommon "github.com/answerdev/answer/internal/service/user_common"
|
||||
)
|
||||
|
||||
type DashboardService struct {
|
||||
questionRepo questioncommon.QuestionRepo
|
||||
answerRepo answercommon.AnswerRepo
|
||||
commentRepo comment_common.CommentCommonRepo
|
||||
voteRepo activity_common.VoteRepo
|
||||
userRepo usercommon.UserRepo
|
||||
reportRepo report_common.ReportRepo
|
||||
configRepo config.ConfigRepo
|
||||
}
|
||||
|
||||
func NewDashboardService(
|
||||
questionRepo questioncommon.QuestionRepo,
|
||||
answerRepo answercommon.AnswerRepo,
|
||||
commentRepo comment_common.CommentCommonRepo,
|
||||
voteRepo activity_common.VoteRepo,
|
||||
userRepo usercommon.UserRepo,
|
||||
reportRepo report_common.ReportRepo,
|
||||
configRepo config.ConfigRepo,
|
||||
|
||||
) *DashboardService {
|
||||
return &DashboardService{
|
||||
questionRepo: questionRepo,
|
||||
answerRepo: answerRepo,
|
||||
commentRepo: commentRepo,
|
||||
voteRepo: voteRepo,
|
||||
userRepo: userRepo,
|
||||
reportRepo: reportRepo,
|
||||
configRepo: configRepo,
|
||||
}
|
||||
}
|
||||
|
||||
// Statistical
|
||||
func (ds *DashboardService) Statistical(ctx context.Context) (*schema.DashboardInfo, error) {
|
||||
dashboardInfo := &schema.DashboardInfo{}
|
||||
questionCount, err := ds.questionRepo.GetQuestionCount(ctx)
|
||||
if err != nil {
|
||||
return dashboardInfo, err
|
||||
}
|
||||
answerCount, err := ds.answerRepo.GetAnswerCount(ctx)
|
||||
if err != nil {
|
||||
return dashboardInfo, err
|
||||
}
|
||||
commentCount, err := ds.commentRepo.GetCommentCount(ctx)
|
||||
if err != nil {
|
||||
return dashboardInfo, err
|
||||
}
|
||||
|
||||
typeKeys := []string{
|
||||
"question.vote_up",
|
||||
"question.vote_down",
|
||||
"answer.vote_up",
|
||||
"answer.vote_down",
|
||||
}
|
||||
var activityTypes []int
|
||||
|
||||
for _, typeKey := range typeKeys {
|
||||
var t int
|
||||
t, err = ds.configRepo.GetConfigType(typeKey)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
activityTypes = append(activityTypes, t)
|
||||
}
|
||||
|
||||
voteCount, err := ds.voteRepo.GetVoteCount(ctx, activityTypes)
|
||||
if err != nil {
|
||||
return dashboardInfo, err
|
||||
}
|
||||
userCount, err := ds.userRepo.GetUserCount(ctx)
|
||||
if err != nil {
|
||||
return dashboardInfo, err
|
||||
}
|
||||
|
||||
reportCount, err := ds.reportRepo.GetReportCount(ctx)
|
||||
if err != nil {
|
||||
return dashboardInfo, err
|
||||
}
|
||||
dashboardInfo.QuestionCount = questionCount
|
||||
dashboardInfo.AnswerCount = answerCount
|
||||
dashboardInfo.CommentCount = commentCount
|
||||
dashboardInfo.VoteCount = voteCount
|
||||
dashboardInfo.UserCount = userCount
|
||||
dashboardInfo.ReportCount = reportCount
|
||||
|
||||
dashboardInfo.UploadingFiles = "Allowed"
|
||||
dashboardInfo.SMTP = "Enabled"
|
||||
dashboardInfo.OccupyingStorageSpace = "1MB"
|
||||
dashboardInfo.AppStartTime = "102"
|
||||
return dashboardInfo, nil
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
package dashboard
|
|
@ -8,6 +8,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/dashboard"
|
||||
"github.com/answerdev/answer/internal/service/export"
|
||||
"github.com/answerdev/answer/internal/service/follow"
|
||||
"github.com/answerdev/answer/internal/service/meta"
|
||||
|
@ -65,4 +66,5 @@ var ProviderSetService = wire.NewSet(
|
|||
notficationcommon.NewNotificationCommon,
|
||||
notification.NewNotificationService,
|
||||
activity.NewAnswerActivityService,
|
||||
dashboard.NewDashboardService,
|
||||
)
|
||||
|
|
|
@ -38,6 +38,7 @@ type QuestionRepo interface {
|
|||
UpdateLastAnswer(ctx context.Context, question *entity.Question) (err error)
|
||||
FindByID(ctx context.Context, id []string) (questionList []*entity.Question, err error)
|
||||
CmsSearchList(ctx context.Context, search *schema.CmsQuestionSearch) ([]*entity.Question, int64, error)
|
||||
GetQuestionCount(ctx context.Context) (count int64, err error)
|
||||
}
|
||||
|
||||
// QuestionCommon user service
|
||||
|
|
|
@ -2,6 +2,7 @@ package report_common
|
|||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/answerdev/answer/internal/entity"
|
||||
"github.com/answerdev/answer/internal/schema"
|
||||
)
|
||||
|
@ -12,4 +13,5 @@ type ReportRepo interface {
|
|||
GetReportListPage(ctx context.Context, query schema.GetReportListPageDTO) (reports []entity.Report, total int64, err error)
|
||||
GetByID(ctx context.Context, id string) (report entity.Report, exist bool, err error)
|
||||
UpdateByID(ctx context.Context, id string, handleData entity.Report) (err error)
|
||||
GetReportCount(ctx context.Context) (count int64, err error)
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ import (
|
|||
"encoding/json"
|
||||
|
||||
"github.com/answerdev/answer/internal/base/reason"
|
||||
"github.com/answerdev/answer/internal/base/translator"
|
||||
"github.com/answerdev/answer/internal/entity"
|
||||
"github.com/answerdev/answer/internal/schema"
|
||||
"github.com/answerdev/answer/internal/service/export"
|
||||
|
@ -77,10 +78,9 @@ func (s *SiteInfoService) SaveSiteGeneral(ctx context.Context, req schema.SiteGe
|
|||
|
||||
func (s *SiteInfoService) SaveSiteInterface(ctx context.Context, req schema.SiteInterfaceReq) (err error) {
|
||||
var (
|
||||
siteType = "interface"
|
||||
themeExist,
|
||||
langExist bool
|
||||
content []byte
|
||||
siteType = "interface"
|
||||
themeExist bool
|
||||
content []byte
|
||||
)
|
||||
|
||||
// check theme
|
||||
|
@ -96,13 +96,7 @@ func (s *SiteInfoService) SaveSiteInterface(ctx context.Context, req schema.Site
|
|||
}
|
||||
|
||||
// check language
|
||||
for _, lang := range schema.GetLangOptions {
|
||||
if lang.Value == req.Language {
|
||||
langExist = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !langExist {
|
||||
if !translator.CheckLanguageIsValid(req.Language) {
|
||||
err = errors.BadRequest(reason.LangNotFound)
|
||||
return
|
||||
}
|
||||
|
|
|
@ -15,12 +15,14 @@ type UserRepo interface {
|
|||
UpdateEmailStatus(ctx context.Context, userID string, emailStatus int) error
|
||||
UpdateNoticeStatus(ctx context.Context, userID string, noticeStatus int) error
|
||||
UpdateEmail(ctx context.Context, userID, email string) error
|
||||
UpdateLanguage(ctx context.Context, userID, language string) error
|
||||
UpdatePass(ctx context.Context, userID, pass string) error
|
||||
UpdateInfo(ctx context.Context, userInfo *entity.User) (err error)
|
||||
GetByUserID(ctx context.Context, userID string) (userInfo *entity.User, exist bool, err error)
|
||||
BatchGetByID(ctx context.Context, ids []string) ([]*entity.User, error)
|
||||
GetByUsername(ctx context.Context, username string) (userInfo *entity.User, exist bool, err error)
|
||||
GetByEmail(ctx context.Context, email string) (userInfo *entity.User, exist bool, err error)
|
||||
GetUserCount(ctx context.Context) (count int64, err error)
|
||||
}
|
||||
|
||||
// UserCommon user service
|
||||
|
|
|
@ -11,6 +11,7 @@ import (
|
|||
|
||||
"github.com/Chain-Zhang/pinyin"
|
||||
"github.com/answerdev/answer/internal/base/reason"
|
||||
"github.com/answerdev/answer/internal/base/translator"
|
||||
"github.com/answerdev/answer/internal/entity"
|
||||
"github.com/answerdev/answer/internal/schema"
|
||||
"github.com/answerdev/answer/internal/service/activity"
|
||||
|
@ -283,6 +284,18 @@ func (us *UserService) UserEmailHas(ctx context.Context, email string) (bool, er
|
|||
return has, nil
|
||||
}
|
||||
|
||||
// UserUpdateInterface update user interface
|
||||
func (us *UserService) UserUpdateInterface(ctx context.Context, req *schema.UpdateUserInterfaceRequest) (err error) {
|
||||
if !translator.CheckLanguageIsValid(req.Language) {
|
||||
return errors.BadRequest(reason.LangNotFound)
|
||||
}
|
||||
err = us.userRepo.UpdateLanguage(ctx, req.UserId, req.Language)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// UserRegisterByEmail user register
|
||||
func (us *UserService) UserRegisterByEmail(ctx context.Context, registerUserInfo *schema.UserRegisterReq) (
|
||||
resp *schema.GetUserResp, err error,
|
||||
|
|
Loading…
Reference in New Issue