mirror of https://gitee.com/answerdev/answer.git
Merge branch 'release/1.1.3'
This commit is contained in:
commit
818af49f27
2
Makefile
2
Makefile
|
@ -1,6 +1,6 @@
|
||||||
.PHONY: build clean ui
|
.PHONY: build clean ui
|
||||||
|
|
||||||
VERSION=1.1.2
|
VERSION=1.1.3
|
||||||
BIN=answer
|
BIN=answer
|
||||||
DIR_SRC=./cmd/answer
|
DIR_SRC=./cmd/answer
|
||||||
DOCKER_CMD=docker
|
DOCKER_CMD=docker
|
||||||
|
|
|
@ -130,10 +130,10 @@ func initApplication(debug bool, serverConf *conf.Server, dbConf *data.Database,
|
||||||
userExternalLoginRepo := user_external_login.NewUserExternalLoginRepo(dataData)
|
userExternalLoginRepo := user_external_login.NewUserExternalLoginRepo(dataData)
|
||||||
userExternalLoginService := user_external_login2.NewUserExternalLoginService(userRepo, userCommon, userExternalLoginRepo, emailService, siteInfoCommonService, userActiveActivityRepo)
|
userExternalLoginService := user_external_login2.NewUserExternalLoginService(userRepo, userCommon, userExternalLoginRepo, emailService, siteInfoCommonService, userActiveActivityRepo)
|
||||||
userNotificationConfigRepo := user_notification_config.NewUserNotificationConfigRepo(dataData)
|
userNotificationConfigRepo := user_notification_config.NewUserNotificationConfigRepo(dataData)
|
||||||
userService := service.NewUserService(userRepo, userActiveActivityRepo, activityRepo, emailService, authService, siteInfoCommonService, userRoleRelService, userCommon, userExternalLoginService, userNotificationConfigRepo)
|
userNotificationConfigService := user_notification_config2.NewUserNotificationConfigService(userRepo, userNotificationConfigRepo)
|
||||||
|
userService := service.NewUserService(userRepo, userActiveActivityRepo, activityRepo, emailService, authService, siteInfoCommonService, userRoleRelService, userCommon, userExternalLoginService, userNotificationConfigRepo, userNotificationConfigService)
|
||||||
captchaRepo := captcha.NewCaptchaRepo(dataData)
|
captchaRepo := captcha.NewCaptchaRepo(dataData)
|
||||||
captchaService := action.NewCaptchaService(captchaRepo)
|
captchaService := action.NewCaptchaService(captchaRepo)
|
||||||
userNotificationConfigService := user_notification_config2.NewUserNotificationConfigService(userRepo, userNotificationConfigRepo)
|
|
||||||
userController := controller.NewUserController(authService, userService, captchaService, emailService, siteInfoCommonService, userNotificationConfigService)
|
userController := controller.NewUserController(authService, userService, captchaService, emailService, siteInfoCommonService, userNotificationConfigService)
|
||||||
commentRepo := comment.NewCommentRepo(dataData, uniqueIDRepo)
|
commentRepo := comment.NewCommentRepo(dataData, uniqueIDRepo)
|
||||||
commentCommonRepo := comment.NewCommentCommonRepo(dataData, uniqueIDRepo)
|
commentCommonRepo := comment.NewCommentCommonRepo(dataData, uniqueIDRepo)
|
||||||
|
@ -184,7 +184,7 @@ func initApplication(debug bool, serverConf *conf.Server, dbConf *data.Database,
|
||||||
questionController := controller.NewQuestionController(questionService, answerService, rankService, siteInfoCommonService, captchaService)
|
questionController := controller.NewQuestionController(questionService, answerService, rankService, siteInfoCommonService, captchaService)
|
||||||
answerController := controller.NewAnswerController(answerService, rankService, captchaService)
|
answerController := controller.NewAnswerController(answerService, rankService, captchaService)
|
||||||
searchParser := search_parser.NewSearchParser(tagCommonService, userCommon)
|
searchParser := search_parser.NewSearchParser(tagCommonService, userCommon)
|
||||||
searchRepo := search_common.NewSearchRepo(dataData, uniqueIDRepo, userCommon)
|
searchRepo := search_common.NewSearchRepo(dataData, uniqueIDRepo, userCommon, tagCommonService)
|
||||||
searchService := service.NewSearchService(searchParser, searchRepo)
|
searchService := service.NewSearchService(searchParser, searchRepo)
|
||||||
searchController := controller.NewSearchController(searchService, captchaService)
|
searchController := controller.NewSearchController(searchService, captchaService)
|
||||||
serviceRevisionService := service.NewRevisionService(revisionRepo, userCommon, questionCommon, answerService, objService, questionRepo, answerRepo, tagRepo, tagCommonService, notificationQueueService, activityQueueService)
|
serviceRevisionService := service.NewRevisionService(revisionRepo, userCommon, questionCommon, answerService, objService, questionRepo, answerRepo, tagRepo, tagCommonService, notificationQueueService, activityQueueService)
|
||||||
|
|
36
go.mod
36
go.mod
|
@ -25,7 +25,7 @@ require (
|
||||||
github.com/lib/pq v1.10.7
|
github.com/lib/pq v1.10.7
|
||||||
github.com/microcosm-cc/bluemonday v1.0.21
|
github.com/microcosm-cc/bluemonday v1.0.21
|
||||||
github.com/mojocn/base64Captcha v1.3.5
|
github.com/mojocn/base64Captcha v1.3.5
|
||||||
github.com/ory/dockertest/v3 v3.9.1
|
github.com/ory/dockertest/v3 v3.10.0
|
||||||
github.com/robfig/cron/v3 v3.0.1
|
github.com/robfig/cron/v3 v3.0.1
|
||||||
github.com/scottleedavis/go-exif-remove v0.0.0-20230314195146-7e059d593405
|
github.com/scottleedavis/go-exif-remove v0.0.0-20230314195146-7e059d593405
|
||||||
github.com/segmentfault/pacman v1.0.5-0.20230822083413-c0075a2d401f
|
github.com/segmentfault/pacman v1.0.5-0.20230822083413-c0075a2d401f
|
||||||
|
@ -41,8 +41,8 @@ require (
|
||||||
github.com/swaggo/swag v1.16.1
|
github.com/swaggo/swag v1.16.1
|
||||||
github.com/tidwall/gjson v1.14.4
|
github.com/tidwall/gjson v1.14.4
|
||||||
github.com/yuin/goldmark v1.4.13
|
github.com/yuin/goldmark v1.4.13
|
||||||
golang.org/x/crypto v0.11.0
|
golang.org/x/crypto v0.13.0
|
||||||
golang.org/x/net v0.12.0
|
golang.org/x/net v0.15.0
|
||||||
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df
|
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df
|
||||||
gopkg.in/yaml.v3 v3.0.1
|
gopkg.in/yaml.v3 v3.0.1
|
||||||
modernc.org/sqlite v1.24.0
|
modernc.org/sqlite v1.24.0
|
||||||
|
@ -51,22 +51,22 @@ require (
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78 // indirect
|
github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 // indirect
|
||||||
github.com/KyleBanks/depth v1.2.1 // indirect
|
github.com/KyleBanks/depth v1.2.1 // indirect
|
||||||
github.com/LinkinStars/go-i18n/v2 v2.2.2 // indirect
|
github.com/LinkinStars/go-i18n/v2 v2.2.2 // indirect
|
||||||
github.com/Microsoft/go-winio v0.5.2 // indirect
|
github.com/Microsoft/go-winio v0.6.1 // indirect
|
||||||
github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 // indirect
|
github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 // indirect
|
||||||
github.com/andybalholm/brotli v1.0.4 // indirect
|
github.com/andybalholm/brotli v1.0.4 // indirect
|
||||||
github.com/aymerick/douceur v0.2.0 // indirect
|
github.com/aymerick/douceur v0.2.0 // indirect
|
||||||
github.com/bytedance/sonic v1.9.1 // indirect
|
github.com/bytedance/sonic v1.9.1 // indirect
|
||||||
github.com/cenkalti/backoff/v4 v4.1.3 // indirect
|
github.com/cenkalti/backoff/v4 v4.2.1 // indirect
|
||||||
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect
|
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect
|
||||||
github.com/containerd/continuity v0.3.0 // indirect
|
github.com/containerd/continuity v0.4.2 // indirect
|
||||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||||
github.com/docker/cli v20.10.14+incompatible // indirect
|
github.com/docker/cli v24.0.6+incompatible // indirect
|
||||||
github.com/docker/docker v20.10.7+incompatible // indirect
|
github.com/docker/docker v24.0.6+incompatible // indirect
|
||||||
github.com/docker/go-connections v0.4.0 // indirect
|
github.com/docker/go-connections v0.4.0 // indirect
|
||||||
github.com/docker/go-units v0.4.0 // indirect
|
github.com/docker/go-units v0.5.0 // indirect
|
||||||
github.com/dsoprea/go-exif v0.0.0-20190901173045-3ce78807c90f // indirect
|
github.com/dsoprea/go-exif v0.0.0-20190901173045-3ce78807c90f // indirect
|
||||||
github.com/dsoprea/go-jpeg-image-structure v0.0.0-20190422055009-d6f9ba25cf48 // indirect
|
github.com/dsoprea/go-jpeg-image-structure v0.0.0-20190422055009-d6f9ba25cf48 // indirect
|
||||||
github.com/dsoprea/go-logging v0.0.0-20190624164917-c4f10aab7696 // indirect
|
github.com/dsoprea/go-logging v0.0.0-20190624164917-c4f10aab7696 // indirect
|
||||||
|
@ -87,7 +87,7 @@ require (
|
||||||
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect
|
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect
|
||||||
github.com/gorilla/css v1.0.0 // indirect
|
github.com/gorilla/css v1.0.0 // indirect
|
||||||
github.com/hashicorp/hcl v1.0.0 // indirect
|
github.com/hashicorp/hcl v1.0.0 // indirect
|
||||||
github.com/imdario/mergo v0.3.12 // indirect
|
github.com/imdario/mergo v0.3.16 // indirect
|
||||||
github.com/inconshreveable/mousetrap v1.0.1 // indirect
|
github.com/inconshreveable/mousetrap v1.0.1 // indirect
|
||||||
github.com/josharian/intern v1.0.0 // indirect
|
github.com/josharian/intern v1.0.0 // indirect
|
||||||
github.com/json-iterator/go v1.1.12 // indirect
|
github.com/json-iterator/go v1.1.12 // indirect
|
||||||
|
@ -100,19 +100,19 @@ require (
|
||||||
github.com/mailru/easyjson v0.7.7 // indirect
|
github.com/mailru/easyjson v0.7.7 // indirect
|
||||||
github.com/mattn/go-isatty v0.0.19 // indirect
|
github.com/mattn/go-isatty v0.0.19 // indirect
|
||||||
github.com/mitchellh/mapstructure v1.5.0 // indirect
|
github.com/mitchellh/mapstructure v1.5.0 // indirect
|
||||||
github.com/moby/term v0.0.0-20201216013528-df9cb8a40635 // indirect
|
github.com/moby/term v0.5.0 // indirect
|
||||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||||
github.com/opencontainers/go-digest v1.0.0 // indirect
|
github.com/opencontainers/go-digest v1.0.0 // indirect
|
||||||
github.com/opencontainers/image-spec v1.0.2 // indirect
|
github.com/opencontainers/image-spec v1.0.2 // indirect
|
||||||
github.com/opencontainers/runc v1.1.2 // indirect
|
github.com/opencontainers/runc v1.1.9 // indirect
|
||||||
github.com/patrickmn/go-cache v2.1.0+incompatible // indirect
|
github.com/patrickmn/go-cache v2.1.0+incompatible // indirect
|
||||||
github.com/pelletier/go-toml v1.9.5 // indirect
|
github.com/pelletier/go-toml v1.9.5 // indirect
|
||||||
github.com/pelletier/go-toml/v2 v2.0.8 // indirect
|
github.com/pelletier/go-toml/v2 v2.0.8 // indirect
|
||||||
github.com/pkg/errors v0.9.1 // indirect
|
github.com/pkg/errors v0.9.1 // indirect
|
||||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||||
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
|
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
|
||||||
github.com/sirupsen/logrus v1.8.1 // indirect
|
github.com/sirupsen/logrus v1.9.3 // indirect
|
||||||
github.com/spf13/afero v1.9.2 // indirect
|
github.com/spf13/afero v1.9.2 // indirect
|
||||||
github.com/spf13/cast v1.5.0 // indirect
|
github.com/spf13/cast v1.5.0 // indirect
|
||||||
github.com/spf13/jwalterweatherman v1.1.0 // indirect
|
github.com/spf13/jwalterweatherman v1.1.0 // indirect
|
||||||
|
@ -124,7 +124,7 @@ require (
|
||||||
github.com/tidwall/pretty v1.2.0 // indirect
|
github.com/tidwall/pretty v1.2.0 // indirect
|
||||||
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
|
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
|
||||||
github.com/ugorji/go/codec v1.2.11 // indirect
|
github.com/ugorji/go/codec v1.2.11 // indirect
|
||||||
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f // indirect
|
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect
|
||||||
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
|
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
|
||||||
github.com/xeipuuv/gojsonschema v1.2.0 // indirect
|
github.com/xeipuuv/gojsonschema v1.2.0 // indirect
|
||||||
go.uber.org/atomic v1.10.0 // indirect
|
go.uber.org/atomic v1.10.0 // indirect
|
||||||
|
@ -133,9 +133,9 @@ require (
|
||||||
golang.org/x/arch v0.3.0 // indirect
|
golang.org/x/arch v0.3.0 // indirect
|
||||||
golang.org/x/image v0.1.0 // indirect
|
golang.org/x/image v0.1.0 // indirect
|
||||||
golang.org/x/mod v0.12.0 // indirect
|
golang.org/x/mod v0.12.0 // indirect
|
||||||
golang.org/x/sys v0.10.0 // indirect
|
golang.org/x/sys v0.12.0 // indirect
|
||||||
golang.org/x/text v0.11.0 // indirect
|
golang.org/x/text v0.13.0 // indirect
|
||||||
golang.org/x/tools v0.11.0 // indirect
|
golang.org/x/tools v0.13.0 // indirect
|
||||||
google.golang.org/protobuf v1.30.0 // indirect
|
google.golang.org/protobuf v1.30.0 // indirect
|
||||||
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect
|
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect
|
||||||
gopkg.in/ini.v1 v1.67.0 // indirect
|
gopkg.in/ini.v1 v1.67.0 // indirect
|
||||||
|
|
112
go.sum
112
go.sum
|
@ -39,8 +39,8 @@ dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7
|
||||||
gitea.com/xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a h1:lSA0F4e9A2NcQSqGqTOXqu2aRi/XEQxDCBwM8yJtE6s=
|
gitea.com/xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a h1:lSA0F4e9A2NcQSqGqTOXqu2aRi/XEQxDCBwM8yJtE6s=
|
||||||
gitea.com/xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a/go.mod h1:EXuID2Zs0pAQhH8yz+DNjUbjppKQzKFAn28TMYPB6IU=
|
gitea.com/xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a/go.mod h1:EXuID2Zs0pAQhH8yz+DNjUbjppKQzKFAn28TMYPB6IU=
|
||||||
gitee.com/travelliu/dm v1.8.11192/go.mod h1:DHTzyhCrM843x9VdKVbZ+GKXGRbKM2sJ4LxihRxShkE=
|
gitee.com/travelliu/dm v1.8.11192/go.mod h1:DHTzyhCrM843x9VdKVbZ+GKXGRbKM2sJ4LxihRxShkE=
|
||||||
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78 h1:w+iIsaOQNcT7OZ575w+acHgRric5iCyQh+xv+KJ4HB8=
|
github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 h1:L/gRVlceqvL25UVaW/CKtUDjefjrs0SPonmDGUVOYP0=
|
||||||
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8=
|
github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E=
|
||||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||||
github.com/BurntSushi/toml v1.0.0 h1:dtDWrepsVPfW9H/4y7dDgFc2MBUSeJhlaDtK13CxFlU=
|
github.com/BurntSushi/toml v1.0.0 h1:dtDWrepsVPfW9H/4y7dDgFc2MBUSeJhlaDtK13CxFlU=
|
||||||
github.com/BurntSushi/toml v1.0.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
|
github.com/BurntSushi/toml v1.0.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
|
||||||
|
@ -56,8 +56,8 @@ github.com/Machiel/slugify v1.0.1 h1:EfWSlRWstMadsgzmiV7d0yVd2IFlagWH68Q+DcYCm4E
|
||||||
github.com/Machiel/slugify v1.0.1/go.mod h1:fTFGn5uWEynW4CUMG7sWkYXOf1UgDxyTM3DbR6Qfg3k=
|
github.com/Machiel/slugify v1.0.1/go.mod h1:fTFGn5uWEynW4CUMG7sWkYXOf1UgDxyTM3DbR6Qfg3k=
|
||||||
github.com/Masterminds/semver/v3 v3.1.1 h1:hLg3sBzpNErnxhQtUy/mmLR2I9foDujNK030IGemrRc=
|
github.com/Masterminds/semver/v3 v3.1.1 h1:hLg3sBzpNErnxhQtUy/mmLR2I9foDujNK030IGemrRc=
|
||||||
github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs=
|
github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs=
|
||||||
github.com/Microsoft/go-winio v0.5.2 h1:a9IhgEQBCUEk6QCdml9CiJGhAws+YwffDHEMp1VMrpA=
|
github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow=
|
||||||
github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY=
|
github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM=
|
||||||
github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 h1:TngWCqHvy9oXAN6lEVMRuU21PR1EtLVZJmdB18Gu3Rw=
|
github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 h1:TngWCqHvy9oXAN6lEVMRuU21PR1EtLVZJmdB18Gu3Rw=
|
||||||
github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8D7ML55dXQrVaamCz2vxCfdQBasLZfHKk=
|
github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8D7ML55dXQrVaamCz2vxCfdQBasLZfHKk=
|
||||||
github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
|
github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
|
||||||
|
@ -91,7 +91,6 @@ github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZw
|
||||||
github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk=
|
github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk=
|
||||||
github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4=
|
github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4=
|
||||||
github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8=
|
github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8=
|
||||||
github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
|
|
||||||
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
||||||
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
|
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
|
||||||
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
||||||
|
@ -103,18 +102,16 @@ github.com/bytedance/sonic v1.9.1 h1:6iJ6NqdoxCDr6mbY8h18oSO+cShGSMRGCEo7F2h0x8s
|
||||||
github.com/bytedance/sonic v1.9.1/go.mod h1:i736AoUSYt75HyZLoJW9ERYxcy6eaN6h4BZXU064P/U=
|
github.com/bytedance/sonic v1.9.1/go.mod h1:i736AoUSYt75HyZLoJW9ERYxcy6eaN6h4BZXU064P/U=
|
||||||
github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ=
|
github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ=
|
||||||
github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM=
|
github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM=
|
||||||
github.com/cenkalti/backoff/v4 v4.1.3 h1:cFAlzYUlVYDysBEH2T5hyJZMh3+5+WCBvSnK6Q8UtC4=
|
github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM=
|
||||||
github.com/cenkalti/backoff/v4 v4.1.3/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw=
|
github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
|
||||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||||
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||||
github.com/checkpoint-restore/go-criu/v5 v5.3.0/go.mod h1:E/eQpaFtUKGOOSEBZgmKAcn+zUUwWxqcaKZlF54wK8E=
|
|
||||||
github.com/chenzhuoyu/base64x v0.0.0-20211019084208-fb5309c8db06/go.mod h1:DH46F32mSOjUmXrMHnKwZdA8wcEefY7UVqBKYGjpdQY=
|
github.com/chenzhuoyu/base64x v0.0.0-20211019084208-fb5309c8db06/go.mod h1:DH46F32mSOjUmXrMHnKwZdA8wcEefY7UVqBKYGjpdQY=
|
||||||
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 h1:qSGYFH7+jGhDF8vLC+iwCD4WpbV1EBDSzWkJODFLams=
|
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 h1:qSGYFH7+jGhDF8vLC+iwCD4WpbV1EBDSzWkJODFLams=
|
||||||
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311/go.mod h1:b583jCggY9gE99b6G5LEC39OIiVsWj+R97kbl5odCEk=
|
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311/go.mod h1:b583jCggY9gE99b6G5LEC39OIiVsWj+R97kbl5odCEk=
|
||||||
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
|
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
|
||||||
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
|
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
|
||||||
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
||||||
github.com/cilium/ebpf v0.7.0/go.mod h1:/oI2+1shJiTGAMgl6/RgJr36Eo1jzrRcAWbcXO2usCA=
|
|
||||||
github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE=
|
github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE=
|
||||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||||
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
||||||
|
@ -123,22 +120,18 @@ github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnht
|
||||||
github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ=
|
github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ=
|
||||||
github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8=
|
github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8=
|
||||||
github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI=
|
github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI=
|
||||||
github.com/containerd/console v1.0.3/go.mod h1:7LqA/THxQ86k76b8c/EMSiaJ3h1eZkMkXar0TQ1gf3U=
|
github.com/containerd/continuity v0.4.2 h1:v3y/4Yz5jwnvqPKJJ+7Wf93fyWoCB3F5EclWG023MDM=
|
||||||
github.com/containerd/continuity v0.3.0 h1:nisirsYROK15TAMVukJOUyGJjz4BNQJBVsNvAXZJ/eg=
|
github.com/containerd/continuity v0.4.2/go.mod h1:F6PTNCKepoxEaXLQp3wDAjygEnImnZ/7o4JzpodfroQ=
|
||||||
github.com/containerd/continuity v0.3.0/go.mod h1:wJEAIwKOm/pBZuBd0JmeTvnLquTB1Ag8espWhkykbPM=
|
|
||||||
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
|
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
|
||||||
github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
||||||
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
||||||
github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
||||||
github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
|
|
||||||
github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
|
github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
|
||||||
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||||
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||||
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
|
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
|
||||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||||
github.com/creack/pty v1.1.11 h1:07n33Z8lZxZ2qwegKbObQohDhXDQxiMMz1NOUGYlesw=
|
github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY=
|
||||||
github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
|
||||||
github.com/cyphar/filepath-securejoin v0.2.3/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4=
|
|
||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
@ -146,14 +139,14 @@ github.com/denisenkom/go-mssqldb v0.10.0/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27
|
||||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
||||||
github.com/disintegration/imaging v1.6.2 h1:w1LecBlG2Lnp8B3jk5zSuNqd7b4DXhcjwek1ei82L+c=
|
github.com/disintegration/imaging v1.6.2 h1:w1LecBlG2Lnp8B3jk5zSuNqd7b4DXhcjwek1ei82L+c=
|
||||||
github.com/disintegration/imaging v1.6.2/go.mod h1:44/5580QXChDfwIclfc/PCwrr44amcmDAg8hxG0Ewe4=
|
github.com/disintegration/imaging v1.6.2/go.mod h1:44/5580QXChDfwIclfc/PCwrr44amcmDAg8hxG0Ewe4=
|
||||||
github.com/docker/cli v20.10.14+incompatible h1:dSBKJOVesDgHo7rbxlYjYsXe7gPzrTT+/cKQgpDAazg=
|
github.com/docker/cli v24.0.6+incompatible h1:fF+XCQCgJjjQNIMjzaSmiKJSCcfcXb3TWTcc7GAneOY=
|
||||||
github.com/docker/cli v20.10.14+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
|
github.com/docker/cli v24.0.6+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
|
||||||
github.com/docker/docker v20.10.7+incompatible h1:Z6O9Nhsjv+ayUEeI1IojKbYcsGdgYSNqxe1s2MYzUhQ=
|
github.com/docker/docker v24.0.6+incompatible h1:hceabKCtUgDqPu+qm0NgsaXf28Ljf4/pWFL7xjWWDgE=
|
||||||
github.com/docker/docker v20.10.7+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
github.com/docker/docker v24.0.6+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||||
github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ=
|
github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ=
|
||||||
github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec=
|
github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec=
|
||||||
github.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw=
|
github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4=
|
||||||
github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
|
github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
|
||||||
github.com/dsoprea/go-exif v0.0.0-20190901173045-3ce78807c90f h1:vqfYiZ+xF0xJvl9SZ1kovmMgKjaGZIz/Hn8JDQdyd9A=
|
github.com/dsoprea/go-exif v0.0.0-20190901173045-3ce78807c90f h1:vqfYiZ+xF0xJvl9SZ1kovmMgKjaGZIz/Hn8JDQdyd9A=
|
||||||
github.com/dsoprea/go-exif v0.0.0-20190901173045-3ce78807c90f/go.mod h1:DmMpU91/Ax6BAwoRkjgRCr2rmgEgS4tsmatfV7M+U+c=
|
github.com/dsoprea/go-exif v0.0.0-20190901173045-3ce78807c90f/go.mod h1:DmMpU91/Ax6BAwoRkjgRCr2rmgEgS4tsmatfV7M+U+c=
|
||||||
github.com/dsoprea/go-jpeg-image-structure v0.0.0-20190422055009-d6f9ba25cf48 h1:9zARagUAxQJjibcDy+0+koUMR6sbX38L49Bk2Vni628=
|
github.com/dsoprea/go-jpeg-image-structure v0.0.0-20190422055009-d6f9ba25cf48 h1:9zARagUAxQJjibcDy+0+koUMR6sbX38L49Bk2Vni628=
|
||||||
|
@ -180,7 +173,6 @@ github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7
|
||||||
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
||||||
github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4=
|
github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4=
|
||||||
github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20=
|
github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20=
|
||||||
github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k=
|
|
||||||
github.com/frankban/quicktest v1.14.3 h1:FJKSZTDHjyhriyC81FLQ0LY93eSai0ZyR/ZIkd3ZUKE=
|
github.com/frankban/quicktest v1.14.3 h1:FJKSZTDHjyhriyC81FLQ0LY93eSai0ZyR/ZIkd3ZUKE=
|
||||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||||
github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY=
|
github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY=
|
||||||
|
@ -246,8 +238,6 @@ github.com/goccy/go-json v0.8.1/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGF
|
||||||
github.com/goccy/go-json v0.9.7/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
|
github.com/goccy/go-json v0.9.7/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
|
||||||
github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU=
|
github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU=
|
||||||
github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
|
github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
|
||||||
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
|
||||||
github.com/godbus/dbus/v5 v5.0.6/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
|
||||||
github.com/gofrs/uuid v3.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
|
github.com/gofrs/uuid v3.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
|
||||||
github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
|
github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
|
||||||
github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s=
|
github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s=
|
||||||
|
@ -375,8 +365,8 @@ github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpO
|
||||||
github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg=
|
github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg=
|
||||||
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||||
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||||
github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU=
|
github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4=
|
||||||
github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
|
github.com/imdario/mergo v0.3.16/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY=
|
||||||
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
||||||
github.com/inconshreveable/mousetrap v1.0.1 h1:U3uMjPSQEBMNp1lFxmllqCPM6P5u/Xq7Pgzkat/bFNc=
|
github.com/inconshreveable/mousetrap v1.0.1 h1:U3uMjPSQEBMNp1lFxmllqCPM6P5u/Xq7Pgzkat/bFNc=
|
||||||
github.com/inconshreveable/mousetrap v1.0.1/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
|
github.com/inconshreveable/mousetrap v1.0.1/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
|
||||||
|
@ -525,9 +515,8 @@ github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:F
|
||||||
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||||
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
|
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
|
||||||
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
||||||
github.com/moby/sys/mountinfo v0.5.0/go.mod h1:3bMD3Rg+zkqx8MRYPi7Pyb0Ie97QEBmdxbhnCLlSvSU=
|
github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0=
|
||||||
github.com/moby/term v0.0.0-20201216013528-df9cb8a40635 h1:rzf0wL0CHVc8CEsgyygG0Mn9CNCCPZqOPaz8RiiHYQk=
|
github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y=
|
||||||
github.com/moby/term v0.0.0-20201216013528-df9cb8a40635/go.mod h1:FBS0z0QWA44HXygs7VXDUOGoN/1TV3RuWkLO04am3wc=
|
|
||||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
|
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
|
||||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||||
|
@ -537,7 +526,6 @@ github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9G
|
||||||
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||||
github.com/mojocn/base64Captcha v1.3.5 h1:Qeilr7Ta6eDtG4S+tQuZ5+hO+QHbiGAJdi4PfoagaA0=
|
github.com/mojocn/base64Captcha v1.3.5 h1:Qeilr7Ta6eDtG4S+tQuZ5+hO+QHbiGAJdi4PfoagaA0=
|
||||||
github.com/mojocn/base64Captcha v1.3.5/go.mod h1:/tTTXn4WTpX9CfrmipqRytCpJ27Uw3G6I7NcP2WwcmY=
|
github.com/mojocn/base64Captcha v1.3.5/go.mod h1:/tTTXn4WTpX9CfrmipqRytCpJ27Uw3G6I7NcP2WwcmY=
|
||||||
github.com/mrunalp/fileutils v0.5.0/go.mod h1:M1WthSahJixYnrXQl/DFQuteStB1weuxD2QJNHXfbSQ=
|
|
||||||
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||||
github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg=
|
github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg=
|
||||||
github.com/nats-io/jwt v0.3.2/go.mod h1:/euKqTS1ZD+zzjYrY7pseZrTtWQSjujC7xjPc8wL6eU=
|
github.com/nats-io/jwt v0.3.2/go.mod h1:/euKqTS1ZD+zzjYrY7pseZrTtWQSjujC7xjPc8wL6eU=
|
||||||
|
@ -560,10 +548,8 @@ github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8
|
||||||
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
|
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
|
||||||
github.com/opencontainers/image-spec v1.0.2 h1:9yCKha/T5XdGtO0q9Q9a6T5NUCsTn/DrBg0D7ufOcFM=
|
github.com/opencontainers/image-spec v1.0.2 h1:9yCKha/T5XdGtO0q9Q9a6T5NUCsTn/DrBg0D7ufOcFM=
|
||||||
github.com/opencontainers/image-spec v1.0.2/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
|
github.com/opencontainers/image-spec v1.0.2/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
|
||||||
github.com/opencontainers/runc v1.1.2 h1:2VSZwLx5k/BfsBxMMipG/LYUnmqOD/BPkIVgQUcTlLw=
|
github.com/opencontainers/runc v1.1.9 h1:XR0VIHTGce5eWPkaPesqTBrhW2yAcaraWfsEalNwQLM=
|
||||||
github.com/opencontainers/runc v1.1.2/go.mod h1:Tj1hFw6eFWp/o33uxGf5yF2BX5yz2Z6iptFpuvbbKqc=
|
github.com/opencontainers/runc v1.1.9/go.mod h1:CbUumNnWCuTGFukNXahoo/RFBZvDAgRh/smNYNOhA50=
|
||||||
github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
|
|
||||||
github.com/opencontainers/selinux v1.10.0/go.mod h1:2i0OySw99QjzBBQByd1Gr9gSjvuho1lHsJxIJ3gGbJI=
|
|
||||||
github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis=
|
github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis=
|
||||||
github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74=
|
github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74=
|
||||||
github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
|
github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
|
||||||
|
@ -572,8 +558,8 @@ github.com/openzipkin-contrib/zipkin-go-opentracing v0.4.5/go.mod h1:/wsWhb9smxS
|
||||||
github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw=
|
github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw=
|
||||||
github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4=
|
github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4=
|
||||||
github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4=
|
github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4=
|
||||||
github.com/ory/dockertest/v3 v3.9.1 h1:v4dkG+dlu76goxMiTT2j8zV7s4oPPEppKT8K8p2f1kY=
|
github.com/ory/dockertest/v3 v3.10.0 h1:4K3z2VMe8Woe++invjaTB7VRyQXQy5UY+loujO4aNE4=
|
||||||
github.com/ory/dockertest/v3 v3.9.1/go.mod h1:42Ir9hmvaAPm0Mgibk6mBPi7SFvTXxEcnztDYOJ//uM=
|
github.com/ory/dockertest/v3 v3.10.0/go.mod h1:nr57ZbRWMqfsdGdFNLHz5jjNdDb7VVFnzAeW1n5N1Lg=
|
||||||
github.com/otiai10/copy v1.7.0/go.mod h1:rmRl6QPdJj6EiUqXQ/4Nn2lLXoNQjFCQbbNrxgc/t3U=
|
github.com/otiai10/copy v1.7.0/go.mod h1:rmRl6QPdJj6EiUqXQ/4Nn2lLXoNQjFCQbbNrxgc/t3U=
|
||||||
github.com/otiai10/curr v0.0.0-20150429015615-9b4961190c95/go.mod h1:9qAhocn7zKJG+0mI8eUu6xqkFDYS2kb2saOteoSB3cE=
|
github.com/otiai10/curr v0.0.0-20150429015615-9b4961190c95/go.mod h1:9qAhocn7zKJG+0mI8eUu6xqkFDYS2kb2saOteoSB3cE=
|
||||||
github.com/otiai10/curr v1.0.0/go.mod h1:LskTG5wDwr8Rs+nNQ+1LlxRjAtTZZjtJW4rMXl6j4vs=
|
github.com/otiai10/curr v1.0.0/go.mod h1:LskTG5wDwr8Rs+nNQ+1LlxRjAtTZZjtJW4rMXl6j4vs=
|
||||||
|
@ -640,13 +626,8 @@ github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdh
|
||||||
github.com/scottleedavis/go-exif-remove v0.0.0-20230314195146-7e059d593405 h1:2ieGkj4z/YPXVyQ2ayZUg3GwE1pYWd5f1RB6DzAOXKM=
|
github.com/scottleedavis/go-exif-remove v0.0.0-20230314195146-7e059d593405 h1:2ieGkj4z/YPXVyQ2ayZUg3GwE1pYWd5f1RB6DzAOXKM=
|
||||||
github.com/scottleedavis/go-exif-remove v0.0.0-20230314195146-7e059d593405/go.mod h1:rIxVzVLKlBwLxO+lC+k/I4HJfRQcemg/f/76Xmmzsec=
|
github.com/scottleedavis/go-exif-remove v0.0.0-20230314195146-7e059d593405/go.mod h1:rIxVzVLKlBwLxO+lC+k/I4HJfRQcemg/f/76Xmmzsec=
|
||||||
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
|
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
|
||||||
github.com/seccomp/libseccomp-golang v0.9.2-0.20210429002308-3879420cc921/go.mod h1:JA8cRccbGaA1s33RQf7Y1+q9gHmZX1yB/z9WDN1C6fg=
|
|
||||||
github.com/segmentfault/pacman v1.0.5-0.20230822075009-309985fb8700 h1:VqxiuNGQg86GEKxnzmJegZR2Ufr7EVXo68mdKaf+/MQ=
|
|
||||||
github.com/segmentfault/pacman v1.0.5-0.20230822075009-309985fb8700/go.mod h1:5lNp5REd8QMThmBUvR3Fi9Y3AsOB4GRq7soCB4QLqOs=
|
|
||||||
github.com/segmentfault/pacman v1.0.5-0.20230822083413-c0075a2d401f h1:9f2Bjf6bdMvNyUop32wAGJCdp+Jdm/d6nKBYvFvkRo0=
|
github.com/segmentfault/pacman v1.0.5-0.20230822083413-c0075a2d401f h1:9f2Bjf6bdMvNyUop32wAGJCdp+Jdm/d6nKBYvFvkRo0=
|
||||||
github.com/segmentfault/pacman v1.0.5-0.20230822083413-c0075a2d401f/go.mod h1:5lNp5REd8QMThmBUvR3Fi9Y3AsOB4GRq7soCB4QLqOs=
|
github.com/segmentfault/pacman v1.0.5-0.20230822083413-c0075a2d401f/go.mod h1:5lNp5REd8QMThmBUvR3Fi9Y3AsOB4GRq7soCB4QLqOs=
|
||||||
github.com/segmentfault/pacman/contrib/cache/memory v0.0.0-20230822075009-309985fb8700 h1:VZpexPTcr7sOxxYUGa/9cneyCESfisAhCNbaEuTpcwI=
|
|
||||||
github.com/segmentfault/pacman/contrib/cache/memory v0.0.0-20230822075009-309985fb8700/go.mod h1:rmf1TCwz67dyM+AmTwSd1BxTo2AOYHj262lP93bOZbs=
|
|
||||||
github.com/segmentfault/pacman/contrib/cache/memory v0.0.0-20230822083413-c0075a2d401f h1:1KHe0uN6p798E7XJZPhZkgm/hXk5CTjisCvFMqaZSKI=
|
github.com/segmentfault/pacman/contrib/cache/memory v0.0.0-20230822083413-c0075a2d401f h1:1KHe0uN6p798E7XJZPhZkgm/hXk5CTjisCvFMqaZSKI=
|
||||||
github.com/segmentfault/pacman/contrib/cache/memory v0.0.0-20230822083413-c0075a2d401f/go.mod h1:rmf1TCwz67dyM+AmTwSd1BxTo2AOYHj262lP93bOZbs=
|
github.com/segmentfault/pacman/contrib/cache/memory v0.0.0-20230822083413-c0075a2d401f/go.mod h1:rmf1TCwz67dyM+AmTwSd1BxTo2AOYHj262lP93bOZbs=
|
||||||
github.com/segmentfault/pacman/contrib/conf/viper v0.0.0-20221018072427-a15dd1434e05 h1:BlqTgc3/MYKG6vMI2MI+6o+7P4Gy5PXlawu185wPXAk=
|
github.com/segmentfault/pacman/contrib/conf/viper v0.0.0-20221018072427-a15dd1434e05 h1:BlqTgc3/MYKG6vMI2MI+6o+7P4Gy5PXlawu185wPXAk=
|
||||||
|
@ -664,9 +645,8 @@ github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeV
|
||||||
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||||
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
|
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
|
||||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||||
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
|
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
|
||||||
github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE=
|
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
||||||
github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
|
|
||||||
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
||||||
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
|
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
|
||||||
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
|
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
|
||||||
|
@ -681,7 +661,6 @@ github.com/spf13/cobra v1.6.1/go.mod h1:IOw/AERYS7UzyrGinqmz6HLUo219MORXGxhbaJUq
|
||||||
github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk=
|
github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk=
|
||||||
github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo=
|
github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo=
|
||||||
github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||||
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
|
||||||
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
||||||
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||||
github.com/spf13/viper v1.13.0 h1:BWSJ/M+f+3nmdz9bxB+bWX28kkALN2ok11D0rSo8EJU=
|
github.com/spf13/viper v1.13.0 h1:BWSJ/M+f+3nmdz9bxB+bWX28kkALN2ok11D0rSo8EJU=
|
||||||
|
@ -717,7 +696,6 @@ github.com/swaggo/gin-swagger v1.5.3/go.mod h1:3XJKSfHjDMB5dBo/0rrTXidPmgLeqsX89
|
||||||
github.com/swaggo/swag v1.8.1/go.mod h1:ugemnJsPZm/kRwFUnzBlbHRd0JY9zE1M4F+uy2pAaPQ=
|
github.com/swaggo/swag v1.8.1/go.mod h1:ugemnJsPZm/kRwFUnzBlbHRd0JY9zE1M4F+uy2pAaPQ=
|
||||||
github.com/swaggo/swag v1.16.1 h1:fTNRhKstPKxcnoKsytm4sahr8FaYzUcT7i1/3nd/fBg=
|
github.com/swaggo/swag v1.16.1 h1:fTNRhKstPKxcnoKsytm4sahr8FaYzUcT7i1/3nd/fBg=
|
||||||
github.com/swaggo/swag v1.16.1/go.mod h1:9/LMvHycG3NFHfR6LwvikHv5iFvmPADQ359cKikGxto=
|
github.com/swaggo/swag v1.16.1/go.mod h1:9/LMvHycG3NFHfR6LwvikHv5iFvmPADQ359cKikGxto=
|
||||||
github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
|
|
||||||
github.com/syndtr/goleveldb v1.0.0 h1:fBdIW9lB4Iz0n9khmH8w27SJ3QEJ7+IgjPEwGSZiFdE=
|
github.com/syndtr/goleveldb v1.0.0 h1:fBdIW9lB4Iz0n9khmH8w27SJ3QEJ7+IgjPEwGSZiFdE=
|
||||||
github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ=
|
github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ=
|
||||||
github.com/tidwall/gjson v1.14.4 h1:uo0p8EbA09J7RQaflQ1aBRffTR7xedD2bcIVSYxLnkM=
|
github.com/tidwall/gjson v1.14.4 h1:uo0p8EbA09J7RQaflQ1aBRffTR7xedD2bcIVSYxLnkM=
|
||||||
|
@ -738,10 +716,9 @@ github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZ
|
||||||
github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
|
github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
|
||||||
github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
|
github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
|
||||||
github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI=
|
github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI=
|
||||||
github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE=
|
|
||||||
github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17pCcGlemwknint6hfoeCVQrEMVwxRLRjXpq+BU=
|
|
||||||
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f h1:J9EGpcZtP0E/raorCMxlFGSTBrsSlaDGf3jU/qvAE2c=
|
|
||||||
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
|
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
|
||||||
|
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb h1:zGWFAtiMcyryUHoUjUJX0/lt1H2+i2Ka2n+D3DImSNo=
|
||||||
|
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
|
||||||
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0=
|
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0=
|
||||||
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
|
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
|
||||||
github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74=
|
github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74=
|
||||||
|
@ -777,7 +754,6 @@ go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
||||||
go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ=
|
go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ=
|
||||||
go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
|
go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
|
||||||
go.uber.org/goleak v1.1.11 h1:wy28qYRKZgnJTxGxvye5/wgWr1EKjmUDGYox5mGlRlI=
|
go.uber.org/goleak v1.1.11 h1:wy28qYRKZgnJTxGxvye5/wgWr1EKjmUDGYox5mGlRlI=
|
||||||
go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ=
|
|
||||||
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
|
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
|
||||||
go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4=
|
go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4=
|
||||||
go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU=
|
go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU=
|
||||||
|
@ -812,8 +788,8 @@ golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5y
|
||||||
golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||||
golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||||
golang.org/x/crypto v0.11.0 h1:6Ewdq3tDic1mg5xRO4milcWCfMVQhI4NkqWWvqejpuA=
|
golang.org/x/crypto v0.13.0 h1:mvySKfSWJ+UKUii46M40LOvyWfN0s2U+46/jDd0e6Ck=
|
||||||
golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio=
|
golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc=
|
||||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||||
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||||
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
||||||
|
@ -901,8 +877,8 @@ golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su
|
||||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||||
golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=
|
golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=
|
||||||
golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||||
golang.org/x/net v0.12.0 h1:cfawfvKITfUsFCeJIHJrbSxpeu/E81khclypR0GVT50=
|
golang.org/x/net v0.15.0 h1:ugBLEUaxABaB5AJqW9enI0ACdci2RUd4eP51NTBvuJ8=
|
||||||
golang.org/x/net v0.12.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA=
|
golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk=
|
||||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||||
|
@ -942,14 +918,12 @@ golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||||
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190606203320-7fc4e5ec1444/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20191115151921-52ab43148777/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
@ -967,7 +941,6 @@ golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||||
golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200831180312-196b9ba8737a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
@ -975,7 +948,6 @@ golang.org/x/sys v0.0.0-20201126233918-771906719818/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||||
golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210420072515-93ed5bcd2bfe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20210420072515-93ed5bcd2bfe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
@ -983,24 +955,23 @@ golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||||
golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20210902050250-f475640dd07b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20210902050250-f475640dd07b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20210906170528-6f6e22806c34/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|
||||||
golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|
||||||
golang.org/x/sys v0.0.0-20211116061358-0a5406a5449c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|
||||||
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA=
|
golang.org/x/sys v0.12.0 h1:CM0HF96J0hcLAwsHPJZjfdNzs0gftsLfgKt57wWHJ0o=
|
||||||
golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
||||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||||
|
@ -1016,8 +987,8 @@ golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||||
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||||
golang.org/x/text v0.11.0 h1:LAntKIrcmeSKERyiOh0XMV39LXS8IE9UL2yP7+f5ij4=
|
golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k=
|
||||||
golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||||
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
|
@ -1038,7 +1009,6 @@ golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBn
|
||||||
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||||
golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||||
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||||
golang.org/x/tools v0.0.0-20190624222133-a101b041ded4/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
|
||||||
golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||||
golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
golang.org/x/tools v0.0.0-20190823170909-c4a336ef6a2f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
golang.org/x/tools v0.0.0-20190823170909-c4a336ef6a2f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
|
@ -1085,8 +1055,8 @@ golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
|
||||||
golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||||
golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo=
|
golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo=
|
||||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||||
golang.org/x/tools v0.11.0 h1:EMCa6U9S2LtZXLAMoWiR/R8dAQFRqbAitmbJ2UKhoi8=
|
golang.org/x/tools v0.13.0 h1:Iey4qkscZuv0VvIt8E0neZjtPVQFSc870HQ448QgEmQ=
|
||||||
golang.org/x/tools v0.11.0/go.mod h1:anzJrxPjNtfgiYQYirP2CPGzGLxrH2u2QBhn6Bf3qY8=
|
golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58=
|
||||||
golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
|
@ -1190,7 +1160,6 @@ google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpAD
|
||||||
google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
|
google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
|
||||||
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
|
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
|
||||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||||
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
|
||||||
google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||||
google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng=
|
google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng=
|
||||||
google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||||
|
@ -1230,8 +1199,7 @@ gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C
|
||||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk=
|
gotest.tools/v3 v3.3.0 h1:MfDY1b1/0xN1CyMlQDac0ziEy9zJQd9CXBRRDHw2jJo=
|
||||||
gotest.tools/v3 v3.2.0 h1:I0DwBVMGAx26dttAj1BtJLAkVGncrkkUXfJLC4Flt/I=
|
|
||||||
honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||||
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||||
|
|
|
@ -1292,16 +1292,16 @@ ui:
|
||||||
page_title: CSS and HTML
|
page_title: CSS and HTML
|
||||||
custom_css:
|
custom_css:
|
||||||
label: Custom CSS
|
label: Custom CSS
|
||||||
text: This will insert as <link>
|
text: This will insert as <link>
|
||||||
head:
|
head:
|
||||||
label: Head
|
label: Head
|
||||||
text: This will insert before </head>
|
text: This will insert before </head>
|
||||||
header:
|
header:
|
||||||
label: Header
|
label: Header
|
||||||
text: This will insert after <body>
|
text: This will insert after <body>
|
||||||
footer:
|
footer:
|
||||||
label: Footer
|
label: Footer
|
||||||
text: This will insert before </html>.
|
text: This will insert before </body>.
|
||||||
login:
|
login:
|
||||||
page_title: Login
|
page_title: Login
|
||||||
membership:
|
membership:
|
||||||
|
|
|
@ -1263,12 +1263,14 @@ ui:
|
||||||
site_name:
|
site_name:
|
||||||
label: Site name
|
label: Site name
|
||||||
msg: Site name cannot be empty.
|
msg: Site name cannot be empty.
|
||||||
|
msg_max_length: Site name must be at maximum 30 characters in length.
|
||||||
site_url:
|
site_url:
|
||||||
label: Site URL
|
label: Site URL
|
||||||
text: The address of your site.
|
text: The address of your site.
|
||||||
msg:
|
msg:
|
||||||
empty: Site URL cannot be empty.
|
empty: Site URL cannot be empty.
|
||||||
incorrect: Site URL incorrect format.
|
incorrect: Site URL incorrect format.
|
||||||
|
max_length: Site URL must be at maximum 512 characters in length.
|
||||||
contact_email:
|
contact_email:
|
||||||
label: Contact email
|
label: Contact email
|
||||||
text: Email address of key contact responsible for this site.
|
text: Email address of key contact responsible for this site.
|
||||||
|
@ -1283,12 +1285,15 @@ ui:
|
||||||
label: Name
|
label: Name
|
||||||
msg: Name cannot be empty.
|
msg: Name cannot be empty.
|
||||||
character: 'Must use the character set "a-z", "0-9", " - . _"'
|
character: 'Must use the character set "a-z", "0-9", " - . _"'
|
||||||
|
msg_max_length: Name must be at maximum 30 characters in length.
|
||||||
admin_password:
|
admin_password:
|
||||||
label: Password
|
label: Password
|
||||||
text: >-
|
text: >-
|
||||||
You will need this password to log in. Please store it in a secure
|
You will need this password to log in. Please store it in a secure
|
||||||
location.
|
location.
|
||||||
msg: Password cannot be empty.
|
msg: Password cannot be empty.
|
||||||
|
msg_min_length: Password must be at least 8 characters in length.
|
||||||
|
msg_max_length: Password must be at maximum 32 characters in length.
|
||||||
admin_email:
|
admin_email:
|
||||||
label: Email
|
label: Email
|
||||||
text: You will need this email to log in.
|
text: You will need this email to log in.
|
||||||
|
@ -1652,16 +1657,16 @@ ui:
|
||||||
page_title: CSS and HTML
|
page_title: CSS and HTML
|
||||||
custom_css:
|
custom_css:
|
||||||
label: Custom CSS
|
label: Custom CSS
|
||||||
text: This will insert as <link>
|
text: This will insert as <link>
|
||||||
head:
|
head:
|
||||||
label: Head
|
label: Head
|
||||||
text: This will insert before </head>
|
text: This will insert before </head>
|
||||||
header:
|
header:
|
||||||
label: Header
|
label: Header
|
||||||
text: This will insert after <body>
|
text: This will insert after <body>
|
||||||
footer:
|
footer:
|
||||||
label: Footer
|
label: Footer
|
||||||
text: This will insert before </body>.
|
text: This will insert before </body>.
|
||||||
sidebar:
|
sidebar:
|
||||||
label: Sidebar
|
label: Sidebar
|
||||||
text: This will insert in sidebar.
|
text: This will insert in sidebar.
|
||||||
|
|
|
@ -1607,16 +1607,16 @@ ui:
|
||||||
page_title: CSS 与 HTML
|
page_title: CSS 与 HTML
|
||||||
custom_css:
|
custom_css:
|
||||||
label: 自定义 CSS
|
label: 自定义 CSS
|
||||||
text: 这将以 <link> 方式插入
|
text: 这将以 <link> 方式插入
|
||||||
head:
|
head:
|
||||||
label: 头部
|
label: 头部
|
||||||
text: 这将在 </head> 之前插入
|
text: 这将在 </head> 之前插入
|
||||||
header:
|
header:
|
||||||
label: 页眉
|
label: 页眉
|
||||||
text: 这将在 <body> 之后插入
|
text: 这将在 <body> 之后插入
|
||||||
footer:
|
footer:
|
||||||
label: 页脚
|
label: 页脚
|
||||||
text: 这将在 </body> 之前插入.
|
text: 这将在 </body> 之前插入.
|
||||||
sidebar:
|
sidebar:
|
||||||
label: 侧边栏
|
label: 侧边栏
|
||||||
text: 这将插入侧边栏中。
|
text: 这将插入侧边栏中。
|
||||||
|
|
|
@ -14,6 +14,7 @@ const (
|
||||||
SiteInfoCacheTime = 1 * time.Hour
|
SiteInfoCacheTime = 1 * time.Hour
|
||||||
ConfigID2KEYCacheKeyPrefix = "answer:config:id:"
|
ConfigID2KEYCacheKeyPrefix = "answer:config:id:"
|
||||||
ConfigKEY2ContentCacheKeyPrefix = "answer:config:key:"
|
ConfigKEY2ContentCacheKeyPrefix = "answer:config:key:"
|
||||||
|
ConfigCacheTime = 1 * time.Hour
|
||||||
ConnectorUserExternalInfoCacheKey = "answer:connector:"
|
ConnectorUserExternalInfoCacheKey = "answer:connector:"
|
||||||
ConnectorUserExternalInfoCacheTime = 10 * time.Minute
|
ConnectorUserExternalInfoCacheTime = 10 * time.Minute
|
||||||
SiteMapQuestionCacheKeyPrefix = "answer:sitemap:question:%d"
|
SiteMapQuestionCacheKeyPrefix = "answer:sitemap:question:%d"
|
||||||
|
|
|
@ -2,15 +2,13 @@ package handler
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"net/http"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/answerdev/answer/internal/base/constant"
|
"github.com/answerdev/answer/internal/base/constant"
|
||||||
"github.com/answerdev/answer/internal/base/reason"
|
"github.com/answerdev/answer/internal/base/reason"
|
||||||
"github.com/answerdev/answer/internal/base/validator"
|
"github.com/answerdev/answer/internal/base/validator"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
myErrors "github.com/segmentfault/pacman/errors"
|
myErrors "github.com/segmentfault/pacman/errors"
|
||||||
"github.com/segmentfault/pacman/log"
|
"github.com/segmentfault/pacman/log"
|
||||||
|
"net/http"
|
||||||
)
|
)
|
||||||
|
|
||||||
// HandleResponse Handle response body
|
// HandleResponse Handle response body
|
||||||
|
@ -74,10 +72,3 @@ func BindAndCheckReturnErr(ctx *gin.Context, data interface{}) (errFields []*val
|
||||||
errFields, _ = validator.GetValidatorByLang(lang).Check(data)
|
errFields, _ = validator.GetValidatorByLang(lang).Check(data)
|
||||||
return errFields
|
return errFields
|
||||||
}
|
}
|
||||||
|
|
||||||
func MsgWithParameter(msg string, list map[string]string) string {
|
|
||||||
for k, v := range list {
|
|
||||||
msg = strings.Replace(msg, "{{ "+k+" }}", v, -1)
|
|
||||||
}
|
|
||||||
return msg
|
|
||||||
}
|
|
||||||
|
|
|
@ -319,11 +319,11 @@ func (ac *AnswerController) AnswerList(ctx *gin.Context) {
|
||||||
// @Accept json
|
// @Accept json
|
||||||
// @Produce json
|
// @Produce json
|
||||||
// @Security ApiKeyAuth
|
// @Security ApiKeyAuth
|
||||||
// @Param data body schema.AnswerAcceptedReq true "AnswerAcceptedReq"
|
// @Param data body schema.AcceptAnswerReq true "AcceptAnswerReq"
|
||||||
// @Success 200 {string} string ""
|
// @Success 200 {string} string ""
|
||||||
// @Router /answer/api/v1/answer/acceptance [post]
|
// @Router /answer/api/v1/answer/acceptance [post]
|
||||||
func (ac *AnswerController) Accepted(ctx *gin.Context) {
|
func (ac *AnswerController) Accepted(ctx *gin.Context) {
|
||||||
req := &schema.AnswerAcceptedReq{}
|
req := &schema.AcceptAnswerReq{}
|
||||||
if handler.BindAndCheck(ctx, req) {
|
if handler.BindAndCheck(ctx, req) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -341,7 +341,7 @@ func (ac *AnswerController) Accepted(ctx *gin.Context) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
err = ac.answerService.UpdateAccepted(ctx, req)
|
err = ac.answerService.AcceptAnswer(ctx, req)
|
||||||
handler.HandleResponse(ctx, err, nil)
|
handler.HandleResponse(ctx, err, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -157,20 +157,23 @@ func (cc *CommentController) UpdateComment(ctx *gin.Context) {
|
||||||
}
|
}
|
||||||
|
|
||||||
req.UserID = middleware.GetLoginUserIDFromContext(ctx)
|
req.UserID = middleware.GetLoginUserIDFromContext(ctx)
|
||||||
|
req.IsAdmin = middleware.GetIsAdminFromContext(ctx)
|
||||||
canList, err := cc.rankService.CheckOperationPermissions(ctx, req.UserID, []string{
|
canList, err := cc.rankService.CheckOperationPermissions(ctx, req.UserID, []string{
|
||||||
permission.CommentAdd,
|
|
||||||
permission.CommentEdit,
|
permission.CommentEdit,
|
||||||
permission.CommentDelete,
|
|
||||||
permission.LinkUrlLimit,
|
permission.LinkUrlLimit,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
handler.HandleResponse(ctx, err, nil)
|
handler.HandleResponse(ctx, err, nil)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
linkUrlLimitUser := canList[3]
|
req.CanEdit = canList[0] || cc.rankService.CheckOperationObjectOwner(ctx, req.UserID, req.CommentID)
|
||||||
req.IsAdmin = middleware.GetIsAdminFromContext(ctx)
|
linkUrlLimitUser := canList[1]
|
||||||
isAdmin := middleware.GetUserIsAdminModerator(ctx)
|
if !req.CanEdit {
|
||||||
if !isAdmin || !linkUrlLimitUser {
|
handler.HandleResponse(ctx, errors.Forbidden(reason.RankFailToMeetTheCondition), nil)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if !req.IsAdmin || !linkUrlLimitUser {
|
||||||
captchaPass := cc.actionService.ActionRecordVerifyCaptcha(ctx, entity.CaptchaActionEdit, req.UserID, req.CaptchaID, req.CaptchaCode)
|
captchaPass := cc.actionService.ActionRecordVerifyCaptcha(ctx, entity.CaptchaActionEdit, req.UserID, req.CaptchaID, req.CaptchaCode)
|
||||||
if !captchaPass {
|
if !captchaPass {
|
||||||
errFields := append([]*validator.FormErrorField{}, &validator.FormErrorField{
|
errFields := append([]*validator.FormErrorField{}, &validator.FormErrorField{
|
||||||
|
@ -182,21 +185,8 @@ func (cc *CommentController) UpdateComment(ctx *gin.Context) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
req.CanAdd = canList[0]
|
|
||||||
req.CanEdit = canList[1]
|
|
||||||
req.CanDelete = canList[2]
|
|
||||||
can, err := cc.rankService.CheckOperationPermission(ctx, req.UserID, permission.CommentEdit, req.CommentID)
|
|
||||||
if err != nil {
|
|
||||||
handler.HandleResponse(ctx, err, nil)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if !can {
|
|
||||||
handler.HandleResponse(ctx, errors.Forbidden(reason.RankFailToMeetTheCondition), nil)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
resp, err := cc.commentService.UpdateComment(ctx, req)
|
resp, err := cc.commentService.UpdateComment(ctx, req)
|
||||||
if !isAdmin || !linkUrlLimitUser {
|
if !req.IsAdmin || !linkUrlLimitUser {
|
||||||
cc.actionService.ActionRecordAdd(ctx, entity.CaptchaActionEdit, req.UserID)
|
cc.actionService.ActionRecordAdd(ctx, entity.CaptchaActionEdit, req.UserID)
|
||||||
}
|
}
|
||||||
handler.HandleResponse(ctx, err, resp)
|
handler.HandleResponse(ctx, err, resp)
|
||||||
|
|
|
@ -686,9 +686,9 @@ func (qc *QuestionController) UpdateQuestionInviteUser(ctx *gin.Context) {
|
||||||
handler.HandleResponse(ctx, nil, nil)
|
handler.HandleResponse(ctx, nil, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
// SearchByTitleLike add question title like
|
// GetSimilarQuestions fuzzy query similar questions based on title
|
||||||
// @Summary add question title like
|
// @Summary fuzzy query similar questions based on title
|
||||||
// @Description add question title like
|
// @Description fuzzy query similar questions based on title
|
||||||
// @Tags Question
|
// @Tags Question
|
||||||
// @Accept json
|
// @Accept json
|
||||||
// @Produce json
|
// @Produce json
|
||||||
|
@ -696,10 +696,9 @@ func (qc *QuestionController) UpdateQuestionInviteUser(ctx *gin.Context) {
|
||||||
// @Param title query string true "title" default(string)
|
// @Param title query string true "title" default(string)
|
||||||
// @Success 200 {object} handler.RespBody
|
// @Success 200 {object} handler.RespBody
|
||||||
// @Router /answer/api/v1/question/similar [get]
|
// @Router /answer/api/v1/question/similar [get]
|
||||||
func (qc *QuestionController) SearchByTitleLike(ctx *gin.Context) {
|
func (qc *QuestionController) GetSimilarQuestions(ctx *gin.Context) {
|
||||||
title := ctx.Query("title")
|
title := ctx.Query("title")
|
||||||
userID := middleware.GetLoginUserIDFromContext(ctx)
|
resp, err := qc.questionService.GetQuestionsByTitle(ctx, title)
|
||||||
resp, err := qc.questionService.SearchByTitleLike(ctx, title, userID)
|
|
||||||
handler.HandleResponse(ctx, err, resp)
|
handler.HandleResponse(ctx, err, resp)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -45,7 +45,6 @@ func (tc *TagController) SearchTagLike(ctx *gin.Context) {
|
||||||
if handler.BindAndCheck(ctx, req) {
|
if handler.BindAndCheck(ctx, req) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
req.IsAdmin = middleware.GetIsAdminFromContext(ctx)
|
|
||||||
resp, err := tc.tagCommonService.SearchTagLike(ctx, req)
|
resp, err := tc.tagCommonService.SearchTagLike(ctx, req)
|
||||||
handler.HandleResponse(ctx, err, resp)
|
handler.HandleResponse(ctx, err, resp)
|
||||||
}
|
}
|
||||||
|
|
|
@ -161,35 +161,41 @@ func (tc *TemplateController) QuestionList(ctx *gin.Context) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tc *TemplateController) QuestionInfoeRdirect(ctx *gin.Context, siteInfo *schema.TemplateSiteInfoResp, correctTitle bool) (jump bool, url string) {
|
func (tc *TemplateController) QuestionInfoeRdirect(ctx *gin.Context, siteInfo *schema.TemplateSiteInfoResp, correctTitle bool) (jump bool, url string) {
|
||||||
id := ctx.Param("id")
|
questionID := ctx.Param("id")
|
||||||
title := ctx.Param("title")
|
title := ctx.Param("title")
|
||||||
|
answerID := uid.DeShortID(title)
|
||||||
titleIsAnswerID := false
|
titleIsAnswerID := false
|
||||||
needChangeShortID := false
|
needChangeShortID := false
|
||||||
|
|
||||||
|
objectType, err := obj.GetObjectTypeStrByObjectID(answerID)
|
||||||
|
if err == nil && objectType == constant.AnswerObjectType {
|
||||||
|
titleIsAnswerID = true
|
||||||
|
}
|
||||||
|
|
||||||
siteSeo, err := tc.siteInfoService.GetSiteSeo(ctx)
|
siteSeo, err := tc.siteInfoService.GetSiteSeo(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, ""
|
return false, ""
|
||||||
}
|
}
|
||||||
isShortID := uid.IsShortID(id)
|
isShortID := uid.IsShortID(questionID)
|
||||||
if siteSeo.IsShortLink() {
|
if siteSeo.IsShortLink() {
|
||||||
if !isShortID {
|
if !isShortID {
|
||||||
id = uid.EnShortID(id)
|
questionID = uid.EnShortID(questionID)
|
||||||
needChangeShortID = true
|
needChangeShortID = true
|
||||||
}
|
}
|
||||||
|
if titleIsAnswerID {
|
||||||
|
answerID = uid.EnShortID(answerID)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if isShortID {
|
if isShortID {
|
||||||
needChangeShortID = true
|
needChangeShortID = true
|
||||||
id = uid.DeShortID(id)
|
questionID = uid.DeShortID(questionID)
|
||||||
|
}
|
||||||
|
if titleIsAnswerID {
|
||||||
|
answerID = uid.DeShortID(answerID)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
objectType, objectTypeerr := obj.GetObjectTypeStrByObjectID(uid.DeShortID(title))
|
url = fmt.Sprintf("%s/questions/%s", siteInfo.General.SiteUrl, questionID)
|
||||||
if objectTypeerr == nil {
|
|
||||||
if objectType == constant.AnswerObjectType {
|
|
||||||
titleIsAnswerID = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
url = fmt.Sprintf("%s/questions/%s", siteInfo.General.SiteUrl, id)
|
|
||||||
if siteInfo.SiteSeo.PermaLink == constant.PermaLinkQuestionID || siteInfo.SiteSeo.PermaLink == constant.PermaLinkQuestionIDByShortID {
|
if siteInfo.SiteSeo.PermaLink == constant.PermaLinkQuestionID || siteInfo.SiteSeo.PermaLink == constant.PermaLinkQuestionIDByShortID {
|
||||||
if len(ctx.Request.URL.Query()) > 0 {
|
if len(ctx.Request.URL.Query()) > 0 {
|
||||||
url = fmt.Sprintf("%s?%s", url, ctx.Request.URL.RawQuery)
|
url = fmt.Sprintf("%s?%s", url, ctx.Request.URL.RawQuery)
|
||||||
|
@ -205,14 +211,14 @@ func (tc *TemplateController) QuestionInfoeRdirect(ctx *gin.Context, siteInfo *s
|
||||||
return true, url
|
return true, url
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
detail, err := tc.templateRenderController.QuestionDetail(ctx, id)
|
detail, err := tc.templateRenderController.QuestionDetail(ctx, questionID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
tc.Page404(ctx)
|
tc.Page404(ctx)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
url = fmt.Sprintf("%s/%s", url, htmltext.UrlTitle(detail.Title))
|
url = fmt.Sprintf("%s/%s", url, htmltext.UrlTitle(detail.Title))
|
||||||
if titleIsAnswerID {
|
if titleIsAnswerID {
|
||||||
url = fmt.Sprintf("%s/%s", url, title)
|
url = fmt.Sprintf("%s/%s", url, answerID)
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(ctx.Request.URL.Query()) > 0 {
|
if len(ctx.Request.URL.Query()) > 0 {
|
||||||
|
|
|
@ -2,6 +2,7 @@ package entity
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"github.com/segmentfault/pacman/log"
|
||||||
|
|
||||||
"github.com/answerdev/answer/pkg/converter"
|
"github.com/answerdev/answer/pkg/converter"
|
||||||
)
|
)
|
||||||
|
@ -33,6 +34,9 @@ func (c *Config) JsonString() string {
|
||||||
|
|
||||||
// GetIntValue get int value
|
// GetIntValue get int value
|
||||||
func (c *Config) GetIntValue() int {
|
func (c *Config) GetIntValue() int {
|
||||||
|
if len(c.Value) == 0 {
|
||||||
|
log.Warnf("config value is empty, key: %s, value: %s", c.Key, c.Value)
|
||||||
|
}
|
||||||
return converter.StringToInt(c.Value)
|
return converter.StringToInt(c.Value)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -72,6 +72,7 @@ var migrations = []Migration{
|
||||||
NewMigration("v1.1.0", "add gravatar base url", updateCount, true),
|
NewMigration("v1.1.0", "add gravatar base url", updateCount, true),
|
||||||
NewMigration("v1.1.1", "update the length of revision content", updateTheLengthOfRevisionContent, false),
|
NewMigration("v1.1.1", "update the length of revision content", updateTheLengthOfRevisionContent, false),
|
||||||
NewMigration("v1.1.2", "add notification config", addNoticeConfig, true),
|
NewMigration("v1.1.2", "add notification config", addNoticeConfig, true),
|
||||||
|
NewMigration("v1.1.3", "set default user notification config", setDefaultUserNotificationConfig, false),
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetMigrations() []Migration {
|
func GetMigrations() []Migration {
|
||||||
|
|
|
@ -0,0 +1,38 @@
|
||||||
|
package migrations
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"github.com/answerdev/answer/internal/base/constant"
|
||||||
|
"github.com/answerdev/answer/internal/entity"
|
||||||
|
"github.com/segmentfault/pacman/log"
|
||||||
|
"xorm.io/xorm"
|
||||||
|
)
|
||||||
|
|
||||||
|
func setDefaultUserNotificationConfig(ctx context.Context, x *xorm.Engine) error {
|
||||||
|
userIDs := make([]string, 0)
|
||||||
|
err := x.Context(ctx).Table("user").Select("id").Find(&userIDs)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, id := range userIDs {
|
||||||
|
bean := entity.UserNotificationConfig{UserID: id, Source: string(constant.InboxSource)}
|
||||||
|
exist, err := x.Context(ctx).Get(&bean)
|
||||||
|
if err != nil {
|
||||||
|
log.Error(err)
|
||||||
|
}
|
||||||
|
if exist {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
_, err = x.Context(ctx).Insert(&entity.UserNotificationConfig{
|
||||||
|
UserID: id,
|
||||||
|
Source: string(constant.InboxSource),
|
||||||
|
Channels: `[{"key":"email","enable":true}]`,
|
||||||
|
Enabled: true,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
log.Error(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
|
@ -46,15 +46,6 @@ func NewAnswerActivityRepo(
|
||||||
|
|
||||||
func (ar *AnswerActivityRepo) SaveAcceptAnswerActivity(ctx context.Context, op *schema.AcceptAnswerOperationInfo) (
|
func (ar *AnswerActivityRepo) SaveAcceptAnswerActivity(ctx context.Context, op *schema.AcceptAnswerOperationInfo) (
|
||||||
err error) {
|
err error) {
|
||||||
// pre check
|
|
||||||
noNeedToDo, err := ar.activityPreCheck(ctx, op)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if noNeedToDo {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// save activity
|
// save activity
|
||||||
_, err = ar.data.DB.Transaction(func(session *xorm.Session) (result any, err error) {
|
_, err = ar.data.DB.Transaction(func(session *xorm.Session) (result any, err error) {
|
||||||
session = session.Context(ctx)
|
session = session.Context(ctx)
|
||||||
|
@ -131,21 +122,6 @@ func (ar *AnswerActivityRepo) SaveCancelAcceptAnswerActivity(ctx context.Context
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ar *AnswerActivityRepo) activityPreCheck(ctx context.Context, op *schema.AcceptAnswerOperationInfo) (
|
|
||||||
noNeedToDo bool, err error) {
|
|
||||||
activities, err := ar.getExistActivity(ctx, op)
|
|
||||||
if err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
done := 0
|
|
||||||
for _, act := range activities {
|
|
||||||
if act.Cancelled == entity.ActivityAvailable {
|
|
||||||
done++
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return done == len(op.Activities), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ar *AnswerActivityRepo) acquireUserInfo(session *xorm.Session, userIDs []string) (map[string]*entity.User, error) {
|
func (ar *AnswerActivityRepo) acquireUserInfo(session *xorm.Session, userIDs []string) (map[string]*entity.User, error) {
|
||||||
us := make([]*entity.User, 0)
|
us := make([]*entity.User, 0)
|
||||||
err := session.In("id", userIDs).ForUpdate().Find(&us)
|
err := session.In("id", userIDs).ForUpdate().Find(&us)
|
||||||
|
@ -286,18 +262,17 @@ func (ar *AnswerActivityRepo) rollbackUserRank(ctx context.Context, session *xor
|
||||||
func (ar *AnswerActivityRepo) getExistActivity(ctx context.Context, op *schema.AcceptAnswerOperationInfo) ([]*entity.Activity, error) {
|
func (ar *AnswerActivityRepo) getExistActivity(ctx context.Context, op *schema.AcceptAnswerOperationInfo) ([]*entity.Activity, error) {
|
||||||
var activities []*entity.Activity
|
var activities []*entity.Activity
|
||||||
for _, action := range op.Activities {
|
for _, action := range op.Activities {
|
||||||
t := &entity.Activity{}
|
var t []*entity.Activity
|
||||||
exist, err := ar.data.DB.Context(ctx).
|
err := ar.data.DB.Context(ctx).
|
||||||
Where(builder.Eq{"user_id": action.ActivityUserID}).
|
Where(builder.Eq{"user_id": action.ActivityUserID}).
|
||||||
And(builder.Eq{"trigger_user_id": action.TriggerUserID}).
|
|
||||||
And(builder.Eq{"activity_type": action.ActivityType}).
|
And(builder.Eq{"activity_type": action.ActivityType}).
|
||||||
And(builder.Eq{"object_id": op.AnswerObjectID}).
|
And(builder.Eq{"object_id": op.AnswerObjectID}).
|
||||||
Get(t)
|
Find(&t)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
|
return nil, errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
|
||||||
}
|
}
|
||||||
if exist {
|
if len(t) > 0 {
|
||||||
activities = append(activities, t)
|
activities = append(activities, t...)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return activities, nil
|
return activities, nil
|
||||||
|
|
|
@ -166,30 +166,29 @@ func (ar *answerRepo) GetAnswerPage(ctx context.Context, page, pageSize int, ans
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdateAccepted
|
// UpdateAcceptedStatus update all accepted status of this question's answers
|
||||||
// If no answer is selected, the answer id can be 0
|
func (ar *answerRepo) UpdateAcceptedStatus(ctx context.Context, acceptedAnswerID string, questionID string) error {
|
||||||
func (ar *answerRepo) UpdateAccepted(ctx context.Context, id string, questionID string) error {
|
acceptedAnswerID = uid.DeShortID(acceptedAnswerID)
|
||||||
if questionID == "" {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
id = uid.DeShortID(id)
|
|
||||||
questionID = uid.DeShortID(questionID)
|
questionID = uid.DeShortID(questionID)
|
||||||
var data entity.Answer
|
|
||||||
data.ID = id
|
|
||||||
|
|
||||||
data.Accepted = schema.AnswerAcceptedFailed
|
// update all this question's answer accepted status to false
|
||||||
_, err := ar.data.DB.Context(ctx).Where("question_id =?", questionID).Cols("adopted").Update(&data)
|
_, err := ar.data.DB.Context(ctx).Where("question_id = ?", questionID).Cols("adopted").Update(&entity.Answer{
|
||||||
|
Accepted: schema.AnswerAcceptedFailed,
|
||||||
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
|
||||||
}
|
}
|
||||||
if id != "0" {
|
|
||||||
data.Accepted = schema.AnswerAcceptedEnable
|
// if acceptedAnswerID is not empty, update accepted status to true
|
||||||
_, err = ar.data.DB.Context(ctx).Where("id = ?", id).Cols("adopted").Update(&data)
|
if len(acceptedAnswerID) > 0 && acceptedAnswerID != "0" {
|
||||||
|
_, err = ar.data.DB.Context(ctx).Where("id = ?", acceptedAnswerID).Cols("adopted").Update(&entity.Answer{
|
||||||
|
Accepted: schema.AnswerAcceptedEnable,
|
||||||
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
|
return errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ = ar.updateSearch(ctx, id)
|
_ = ar.updateSearch(ctx, acceptedAnswerID)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -259,7 +258,7 @@ func (ar *answerRepo) SearchList(ctx context.Context, search *entity.AnswerSearc
|
||||||
search.PageSize = constant.DefaultPageSize
|
search.PageSize = constant.DefaultPageSize
|
||||||
}
|
}
|
||||||
offset := search.Page * search.PageSize
|
offset := search.Page * search.PageSize
|
||||||
session := ar.data.DB.Context(ctx).Where("")
|
session := ar.data.DB.Context(ctx)
|
||||||
|
|
||||||
if search.QuestionID != "" {
|
if search.QuestionID != "" {
|
||||||
session = session.And("question_id = ?", search.QuestionID)
|
session = session.And("question_id = ?", search.QuestionID)
|
||||||
|
|
|
@ -2,9 +2,9 @@ package collection
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
"github.com/answerdev/answer/internal/base/constant"
|
"github.com/answerdev/answer/internal/base/constant"
|
||||||
"github.com/answerdev/answer/internal/base/data"
|
"github.com/answerdev/answer/internal/base/data"
|
||||||
|
"github.com/answerdev/answer/internal/base/handler"
|
||||||
"github.com/answerdev/answer/internal/base/pager"
|
"github.com/answerdev/answer/internal/base/pager"
|
||||||
"github.com/answerdev/answer/internal/base/reason"
|
"github.com/answerdev/answer/internal/base/reason"
|
||||||
"github.com/answerdev/answer/internal/entity"
|
"github.com/answerdev/answer/internal/entity"
|
||||||
|
@ -142,25 +142,32 @@ func (cr *collectionRepo) GetCollectionPage(ctx context.Context, page, pageSize
|
||||||
session = session.OrderBy("update_time desc")
|
session = session.OrderBy("update_time desc")
|
||||||
|
|
||||||
total, err = pager.Help(page, pageSize, collectionList, collection, session)
|
total, err = pager.Help(page, pageSize, collectionList, collection, session)
|
||||||
|
if err != nil {
|
||||||
err = errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
|
err = errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// SearchObjectCollected check object is collected or not
|
// SearchObjectCollected check object is collected or not
|
||||||
func (cr *collectionRepo) SearchObjectCollected(ctx context.Context, userID string, objectIds []string) (map[string]bool, error) {
|
func (cr *collectionRepo) SearchObjectCollected(ctx context.Context, userID string, objectIds []string) (map[string]bool, error) {
|
||||||
collectedMap := make(map[string]bool)
|
for i := 0; i < len(objectIds); i++ {
|
||||||
for k, object_id := range objectIds {
|
objectIds[i] = uid.DeShortID(objectIds[i])
|
||||||
objectIds[k] = uid.DeShortID(object_id)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
list, err := cr.SearchByObjectIDsAndUser(ctx, userID, objectIds)
|
list, err := cr.SearchByObjectIDsAndUser(ctx, userID, objectIds)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
err = errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
|
return nil, errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
|
||||||
return collectedMap, err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
collectedMap := make(map[string]bool)
|
||||||
|
short := handler.GetEnableShortID(ctx)
|
||||||
for _, item := range list {
|
for _, item := range list {
|
||||||
|
if short {
|
||||||
|
item.ObjectID = uid.EnShortID(item.ObjectID)
|
||||||
|
}
|
||||||
collectedMap[item.ObjectID] = true
|
collectedMap[item.ObjectID] = true
|
||||||
}
|
}
|
||||||
return collectedMap, err
|
return collectedMap, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// SearchList
|
// SearchList
|
||||||
|
|
|
@ -58,9 +58,13 @@ func (cr *commentRepo) RemoveComment(ctx context.Context, commentID string) (err
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdateComment update comment
|
// UpdateCommentContent update comment
|
||||||
func (cr *commentRepo) UpdateComment(ctx context.Context, comment *entity.Comment) (err error) {
|
func (cr *commentRepo) UpdateCommentContent(
|
||||||
_, err = cr.data.DB.Context(ctx).ID(comment.ID).Where("user_id = ?", comment.UserID).Update(comment)
|
ctx context.Context, commentID string, originalText string, parsedText string) (err error) {
|
||||||
|
_, err = cr.data.DB.Context(ctx).ID(commentID).Update(&entity.Comment{
|
||||||
|
OriginalText: originalText,
|
||||||
|
ParsedText: parsedText,
|
||||||
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
err = errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
|
err = errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
|
||||||
}
|
}
|
||||||
|
@ -69,8 +73,7 @@ func (cr *commentRepo) UpdateComment(ctx context.Context, comment *entity.Commen
|
||||||
|
|
||||||
// GetComment get comment one
|
// GetComment get comment one
|
||||||
func (cr *commentRepo) GetComment(ctx context.Context, commentID string) (
|
func (cr *commentRepo) GetComment(ctx context.Context, commentID string) (
|
||||||
comment *entity.Comment, exist bool, err error,
|
comment *entity.Comment, exist bool, err error) {
|
||||||
) {
|
|
||||||
comment = &entity.Comment{}
|
comment = &entity.Comment{}
|
||||||
exist, err = cr.data.DB.Context(ctx).ID(commentID).Get(comment)
|
exist, err = cr.data.DB.Context(ctx).ID(commentID).Get(comment)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -28,7 +28,8 @@ func NewConfigRepo(data *data.Data) config.ConfigRepo {
|
||||||
|
|
||||||
func (cr configRepo) GetConfigByID(ctx context.Context, id int) (c *entity.Config, err error) {
|
func (cr configRepo) GetConfigByID(ctx context.Context, id int) (c *entity.Config, err error) {
|
||||||
cacheKey := fmt.Sprintf("%s%d", constant.ConfigID2KEYCacheKeyPrefix, id)
|
cacheKey := fmt.Sprintf("%s%d", constant.ConfigID2KEYCacheKeyPrefix, id)
|
||||||
if cacheData, exist, err := cr.data.Cache.GetString(ctx, cacheKey); err == nil && exist {
|
cacheData, exist, err := cr.data.Cache.GetString(ctx, cacheKey)
|
||||||
|
if err == nil && exist && len(cacheData) > 0 {
|
||||||
c = &entity.Config{}
|
c = &entity.Config{}
|
||||||
c.BuildByJSON([]byte(cacheData))
|
c.BuildByJSON([]byte(cacheData))
|
||||||
if c.ID > 0 {
|
if c.ID > 0 {
|
||||||
|
@ -37,7 +38,7 @@ func (cr configRepo) GetConfigByID(ctx context.Context, id int) (c *entity.Confi
|
||||||
}
|
}
|
||||||
|
|
||||||
c = &entity.Config{}
|
c = &entity.Config{}
|
||||||
exist, err := cr.data.DB.Context(ctx).ID(id).Get(c)
|
exist, err = cr.data.DB.Context(ctx).ID(id).Get(c)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
|
return nil, errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
|
||||||
}
|
}
|
||||||
|
@ -46,7 +47,7 @@ func (cr configRepo) GetConfigByID(ctx context.Context, id int) (c *entity.Confi
|
||||||
}
|
}
|
||||||
|
|
||||||
// update cache
|
// update cache
|
||||||
if err := cr.data.Cache.SetString(ctx, cacheKey, c.JsonString(), -1); err != nil {
|
if err := cr.data.Cache.SetString(ctx, cacheKey, c.JsonString(), constant.ConfigCacheTime); err != nil {
|
||||||
log.Error(err)
|
log.Error(err)
|
||||||
}
|
}
|
||||||
return c, nil
|
return c, nil
|
||||||
|
@ -54,7 +55,8 @@ func (cr configRepo) GetConfigByID(ctx context.Context, id int) (c *entity.Confi
|
||||||
|
|
||||||
func (cr configRepo) GetConfigByKey(ctx context.Context, key string) (c *entity.Config, err error) {
|
func (cr configRepo) GetConfigByKey(ctx context.Context, key string) (c *entity.Config, err error) {
|
||||||
cacheKey := constant.ConfigKEY2ContentCacheKeyPrefix + key
|
cacheKey := constant.ConfigKEY2ContentCacheKeyPrefix + key
|
||||||
if cacheData, exist, err := cr.data.Cache.GetString(ctx, cacheKey); err == nil && exist {
|
cacheData, exist, err := cr.data.Cache.GetString(ctx, cacheKey)
|
||||||
|
if err == nil && exist && len(cacheData) > 0 {
|
||||||
c = &entity.Config{}
|
c = &entity.Config{}
|
||||||
c.BuildByJSON([]byte(cacheData))
|
c.BuildByJSON([]byte(cacheData))
|
||||||
if c.ID > 0 {
|
if c.ID > 0 {
|
||||||
|
@ -63,7 +65,7 @@ func (cr configRepo) GetConfigByKey(ctx context.Context, key string) (c *entity.
|
||||||
}
|
}
|
||||||
|
|
||||||
c = &entity.Config{Key: key}
|
c = &entity.Config{Key: key}
|
||||||
exist, err := cr.data.DB.Context(ctx).Get(c)
|
exist, err = cr.data.DB.Context(ctx).Get(c)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
|
return nil, errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
|
||||||
}
|
}
|
||||||
|
@ -72,7 +74,7 @@ func (cr configRepo) GetConfigByKey(ctx context.Context, key string) (c *entity.
|
||||||
}
|
}
|
||||||
|
|
||||||
// update cache
|
// update cache
|
||||||
if err := cr.data.Cache.SetString(ctx, cacheKey, c.JsonString(), -1); err != nil {
|
if err := cr.data.Cache.SetString(ctx, cacheKey, c.JsonString(), constant.ConfigCacheTime); err != nil {
|
||||||
log.Error(err)
|
log.Error(err)
|
||||||
}
|
}
|
||||||
return c, nil
|
return c, nil
|
||||||
|
@ -99,11 +101,11 @@ func (cr configRepo) UpdateConfig(ctx context.Context, key string, value string)
|
||||||
cacheVal := oldConfig.JsonString()
|
cacheVal := oldConfig.JsonString()
|
||||||
// update cache
|
// update cache
|
||||||
if err := cr.data.Cache.SetString(ctx,
|
if err := cr.data.Cache.SetString(ctx,
|
||||||
constant.ConfigKEY2ContentCacheKeyPrefix+key, cacheVal, -1); err != nil {
|
constant.ConfigKEY2ContentCacheKeyPrefix+key, cacheVal, constant.ConfigCacheTime); err != nil {
|
||||||
log.Error(err)
|
log.Error(err)
|
||||||
}
|
}
|
||||||
if err := cr.data.Cache.SetString(ctx,
|
if err := cr.data.Cache.SetString(ctx,
|
||||||
fmt.Sprintf("%s%d", constant.ConfigID2KEYCacheKeyPrefix, oldConfig.ID), cacheVal, -1); err != nil {
|
fmt.Sprintf("%s%d", constant.ConfigID2KEYCacheKeyPrefix, oldConfig.ID), cacheVal, constant.ConfigCacheTime); err != nil {
|
||||||
log.Error(err)
|
log.Error(err)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
|
|
|
@ -186,10 +186,15 @@ func (qr *questionRepo) GetQuestion(ctx context.Context, id string) (
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetTagBySlugName get tag by slug name
|
// GetQuestionsByTitle get question list by title
|
||||||
func (qr *questionRepo) SearchByTitleLike(ctx context.Context, title string) (questionList []*entity.Question, err error) {
|
func (qr *questionRepo) GetQuestionsByTitle(ctx context.Context, title string, pageSize int) (
|
||||||
|
questionList []*entity.Question, err error) {
|
||||||
questionList = make([]*entity.Question, 0)
|
questionList = make([]*entity.Question, 0)
|
||||||
err = qr.data.DB.Context(ctx).Table("question").Where("title like ?", "%"+title+"%").Limit(10, 0).Find(&questionList)
|
session := qr.data.DB.Context(ctx)
|
||||||
|
session.Where("status != ?", entity.QuestionStatusDeleted)
|
||||||
|
session.Where("title like ?", "%"+title+"%")
|
||||||
|
session.Limit(pageSize)
|
||||||
|
err = session.Find(&questionList)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
|
return nil, errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,7 +65,7 @@ func Test_commentRepo_UpdateComment(t *testing.T) {
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
testCommentEntity.ParsedText = "test"
|
testCommentEntity.ParsedText = "test"
|
||||||
err = commentRepo.UpdateComment(context.TODO(), testCommentEntity)
|
err = commentRepo.UpdateCommentContent(context.TODO(), testCommentEntity, "", "")
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
newComment, exist, err := commonCommentRepo.GetComment(context.TODO(), testCommentEntity.ID)
|
newComment, exist, err := commonCommentRepo.GetComment(context.TODO(), testCommentEntity.ID)
|
||||||
|
|
|
@ -3,6 +3,7 @@ package search_common
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
tagcommon "github.com/answerdev/answer/internal/service/tag_common"
|
||||||
"github.com/answerdev/answer/plugin"
|
"github.com/answerdev/answer/plugin"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
@ -19,7 +20,6 @@ import (
|
||||||
usercommon "github.com/answerdev/answer/internal/service/user_common"
|
usercommon "github.com/answerdev/answer/internal/service/user_common"
|
||||||
"github.com/answerdev/answer/pkg/converter"
|
"github.com/answerdev/answer/pkg/converter"
|
||||||
"github.com/answerdev/answer/pkg/obj"
|
"github.com/answerdev/answer/pkg/obj"
|
||||||
"github.com/jinzhu/copier"
|
|
||||||
"github.com/segmentfault/pacman/errors"
|
"github.com/segmentfault/pacman/errors"
|
||||||
"xorm.io/builder"
|
"xorm.io/builder"
|
||||||
)
|
)
|
||||||
|
@ -58,19 +58,26 @@ type searchRepo struct {
|
||||||
data *data.Data
|
data *data.Data
|
||||||
userCommon *usercommon.UserCommon
|
userCommon *usercommon.UserCommon
|
||||||
uniqueIDRepo unique.UniqueIDRepo
|
uniqueIDRepo unique.UniqueIDRepo
|
||||||
|
tagCommon *tagcommon.TagCommonService
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewSearchRepo new repository
|
// NewSearchRepo new repository
|
||||||
func NewSearchRepo(data *data.Data, uniqueIDRepo unique.UniqueIDRepo, userCommon *usercommon.UserCommon) search_common.SearchRepo {
|
func NewSearchRepo(
|
||||||
|
data *data.Data,
|
||||||
|
uniqueIDRepo unique.UniqueIDRepo,
|
||||||
|
userCommon *usercommon.UserCommon,
|
||||||
|
tagCommon *tagcommon.TagCommonService,
|
||||||
|
) search_common.SearchRepo {
|
||||||
return &searchRepo{
|
return &searchRepo{
|
||||||
data: data,
|
data: data,
|
||||||
uniqueIDRepo: uniqueIDRepo,
|
uniqueIDRepo: uniqueIDRepo,
|
||||||
userCommon: userCommon,
|
userCommon: userCommon,
|
||||||
|
tagCommon: tagCommon,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// SearchContents search question and answer data
|
// SearchContents search question and answer data
|
||||||
func (sr *searchRepo) SearchContents(ctx context.Context, words []string, tagIDs []string, userID string, votes int, page, size int, order string) (resp []schema.SearchResult, total int64, err error) {
|
func (sr *searchRepo) SearchContents(ctx context.Context, words []string, tagIDs []string, userID string, votes int, page, size int, order string) (resp []*schema.SearchResult, total int64, err error) {
|
||||||
words = filterWords(words)
|
words = filterWords(words)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -210,7 +217,7 @@ func (sr *searchRepo) SearchContents(ctx context.Context, words []string, tagIDs
|
||||||
}
|
}
|
||||||
|
|
||||||
// SearchQuestions search question data
|
// SearchQuestions search question data
|
||||||
func (sr *searchRepo) SearchQuestions(ctx context.Context, words []string, tagIDs []string, notAccepted bool, views, answers int, page, size int, order string) (resp []schema.SearchResult, total int64, err error) {
|
func (sr *searchRepo) SearchQuestions(ctx context.Context, words []string, tagIDs []string, notAccepted bool, views, answers int, page, size int, order string) (resp []*schema.SearchResult, total int64, err error) {
|
||||||
words = filterWords(words)
|
words = filterWords(words)
|
||||||
var (
|
var (
|
||||||
qfs = qFields
|
qfs = qFields
|
||||||
|
@ -319,7 +326,7 @@ func (sr *searchRepo) SearchQuestions(ctx context.Context, words []string, tagID
|
||||||
}
|
}
|
||||||
|
|
||||||
// SearchAnswers search answer data
|
// SearchAnswers search answer data
|
||||||
func (sr *searchRepo) SearchAnswers(ctx context.Context, words []string, tagIDs []string, accepted bool, questionID string, page, size int, order string) (resp []schema.SearchResult, total int64, err error) {
|
func (sr *searchRepo) SearchAnswers(ctx context.Context, words []string, tagIDs []string, accepted bool, questionID string, page, size int, order string) (resp []*schema.SearchResult, total int64, err error) {
|
||||||
words = filterWords(words)
|
words = filterWords(words)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -428,7 +435,7 @@ func (sr *searchRepo) parseOrder(ctx context.Context, order string) (res string)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ParseSearchPluginResult parse search plugin result
|
// ParseSearchPluginResult parse search plugin result
|
||||||
func (sr *searchRepo) ParseSearchPluginResult(ctx context.Context, sres []plugin.SearchResult) (resp []schema.SearchResult, err error) {
|
func (sr *searchRepo) ParseSearchPluginResult(ctx context.Context, sres []plugin.SearchResult) (resp []*schema.SearchResult, err error) {
|
||||||
var (
|
var (
|
||||||
qres []map[string][]byte
|
qres []map[string][]byte
|
||||||
res = make([]map[string][]byte, 0)
|
res = make([]map[string][]byte, 0)
|
||||||
|
@ -455,82 +462,79 @@ func (sr *searchRepo) ParseSearchPluginResult(ctx context.Context, sres []plugin
|
||||||
}
|
}
|
||||||
|
|
||||||
// parseResult parse search result, return the data structure
|
// parseResult parse search result, return the data structure
|
||||||
func (sr *searchRepo) parseResult(ctx context.Context, res []map[string][]byte) (resp []schema.SearchResult, err error) {
|
func (sr *searchRepo) parseResult(ctx context.Context, res []map[string][]byte) (resp []*schema.SearchResult, err error) {
|
||||||
|
questionIDs := make([]string, 0)
|
||||||
|
userIDs := make([]string, 0)
|
||||||
|
resultList := make([]*schema.SearchResult, 0)
|
||||||
for _, r := range res {
|
for _, r := range res {
|
||||||
var (
|
questionIDs = append(questionIDs, string(r["question_id"]))
|
||||||
objectKey,
|
userIDs = append(userIDs, string(r["user_id"]))
|
||||||
status string
|
tp, _ := time.ParseInLocation("2006-01-02 15:04:05", string(r["created_at"]), time.Local)
|
||||||
|
object := &schema.SearchObject{
|
||||||
|
ID: string(r["id"]),
|
||||||
|
QuestionID: string(r["question_id"]),
|
||||||
|
Title: string(r["title"]),
|
||||||
|
Excerpt: htmltext.FetchExcerpt(string(r["parsed_text"]), "...", 240),
|
||||||
|
CreatedAtParsed: tp.Unix(),
|
||||||
|
UserInfo: &schema.SearchObjectUser{
|
||||||
|
ID: string(r["user_id"]),
|
||||||
|
},
|
||||||
|
Tags: make([]*schema.TagResp, 0),
|
||||||
|
VoteCount: converter.StringToInt(string(r["vote_count"])),
|
||||||
|
Accepted: string(r["accepted"]) == "2",
|
||||||
|
AnswerCount: converter.StringToInt(string(r["answer_count"])),
|
||||||
|
}
|
||||||
|
|
||||||
tags []schema.TagResp
|
objectKey, err := obj.GetObjectTypeStrByObjectID(string(r["id"]))
|
||||||
tagsEntity []entity.Tag
|
|
||||||
object schema.SearchObject
|
|
||||||
)
|
|
||||||
objectKey, err = obj.GetObjectTypeStrByObjectID(string(r["id"]))
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
tp, _ := time.ParseInLocation("2006-01-02 15:04:05", string(r["created_at"]), time.Local)
|
|
||||||
|
|
||||||
// get user info
|
|
||||||
userInfo, _, e := sr.userCommon.GetUserBasicInfoByID(ctx, string(r["user_id"]))
|
|
||||||
if e != nil {
|
|
||||||
err = errors.InternalServer(reason.DatabaseError).WithError(e).WithStack()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// get tags
|
|
||||||
err = sr.data.DB.Context(ctx).
|
|
||||||
Select("`display_name`,`slug_name`,`main_tag_slug_name`,`recommend`,`reserved`").
|
|
||||||
Table("tag").
|
|
||||||
Join("INNER", "tag_rel", "tag.id = tag_rel.tag_id").
|
|
||||||
Where(builder.Eq{"tag_rel.object_id": r["question_id"]}).
|
|
||||||
And(builder.Eq{"tag_rel.status": entity.TagRelStatusAvailable}).
|
|
||||||
UseBool("recommend", "reserved").
|
|
||||||
OrderBy("tag.recommend DESC, tag.reserved DESC, tag.id DESC").
|
|
||||||
Find(&tagsEntity)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
err = errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
_ = copier.Copy(&tags, tagsEntity)
|
|
||||||
switch objectKey {
|
switch objectKey {
|
||||||
case "question":
|
case "question":
|
||||||
for k, v := range entity.AdminQuestionSearchStatus {
|
for k, v := range entity.AdminQuestionSearchStatus {
|
||||||
if v == converter.StringToInt(string(r["status"])) {
|
if v == converter.StringToInt(string(r["status"])) {
|
||||||
status = k
|
object.StatusStr = k
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case "answer":
|
case "answer":
|
||||||
for k, v := range entity.AdminAnswerSearchStatus {
|
for k, v := range entity.AdminAnswerSearchStatus {
|
||||||
if v == converter.StringToInt(string(r["status"])) {
|
if v == converter.StringToInt(string(r["status"])) {
|
||||||
status = k
|
object.StatusStr = k
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
object = schema.SearchObject{
|
resultList = append(resultList, &schema.SearchResult{
|
||||||
ID: string(r["id"]),
|
|
||||||
QuestionID: string(r["question_id"]),
|
|
||||||
Title: string(r["title"]),
|
|
||||||
Excerpt: htmltext.FetchExcerpt(string(r["parsed_text"]), "...", 240),
|
|
||||||
CreatedAtParsed: tp.Unix(),
|
|
||||||
UserInfo: userInfo,
|
|
||||||
Tags: tags,
|
|
||||||
VoteCount: converter.StringToInt(string(r["vote_count"])),
|
|
||||||
Accepted: string(r["accepted"]) == "2",
|
|
||||||
AnswerCount: converter.StringToInt(string(r["answer_count"])),
|
|
||||||
StatusStr: status,
|
|
||||||
}
|
|
||||||
resp = append(resp, schema.SearchResult{
|
|
||||||
ObjectType: objectKey,
|
ObjectType: objectKey,
|
||||||
Object: object,
|
Object: object,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
return
|
|
||||||
|
tagsMap, err := sr.tagCommon.BatchGetObjectTag(ctx, questionIDs)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
userInfoMap, err := sr.userCommon.BatchUserBasicInfoByID(ctx, userIDs)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, item := range resultList {
|
||||||
|
tags, ok := tagsMap[item.Object.QuestionID]
|
||||||
|
if ok {
|
||||||
|
item.Object.Tags = tags
|
||||||
|
}
|
||||||
|
if userInfo := userInfoMap[item.Object.UserInfo.ID]; userInfo != nil {
|
||||||
|
item.Object.UserInfo.Username = userInfo.Username
|
||||||
|
item.Object.UserInfo.DisplayName = userInfo.DisplayName
|
||||||
|
item.Object.UserInfo.Rank = userInfo.Rank
|
||||||
|
item.Object.UserInfo.Status = userInfo.Status
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return resultList, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func addRelevanceField(searchFields, words, fields []string) (res []string, args []interface{}) {
|
func addRelevanceField(searchFields, words, fields []string) (res []string, args []interface{}) {
|
||||||
|
|
|
@ -3,6 +3,7 @@ package tag_common
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/answerdev/answer/internal/base/data"
|
"github.com/answerdev/answer/internal/base/data"
|
||||||
"github.com/answerdev/answer/internal/base/pager"
|
"github.com/answerdev/answer/internal/base/pager"
|
||||||
|
@ -56,19 +57,28 @@ func (tr *tagCommonRepo) GetTagBySlugName(ctx context.Context, slugName string)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetTagListByName get tag list all like name
|
// GetTagListByName get tag list all like name
|
||||||
func (tr *tagCommonRepo) GetTagListByName(ctx context.Context, name string, hasReserved bool) (tagList []*entity.Tag, err error) {
|
func (tr *tagCommonRepo) GetTagListByName(ctx context.Context, name string, recommend, reserved bool) (tagList []*entity.Tag, err error) {
|
||||||
tagList = make([]*entity.Tag, 0)
|
|
||||||
cond := &entity.Tag{}
|
cond := &entity.Tag{}
|
||||||
session := tr.data.DB.Context(ctx).Where("")
|
session := tr.data.DB.Context(ctx)
|
||||||
if name != "" {
|
if len(name) > 0 {
|
||||||
session.Where("slug_name LIKE LOWER(?) or display_name LIKE ?", name+"%", name+"%")
|
session.Where("slug_name LIKE ? OR display_name LIKE ?", strings.ToLower(name)+"%", name+"%")
|
||||||
} else {
|
}
|
||||||
session.UseBool("recommend")
|
var columns []string
|
||||||
|
if recommend {
|
||||||
|
columns = append(columns, "recommend")
|
||||||
cond.Recommend = true
|
cond.Recommend = true
|
||||||
}
|
}
|
||||||
|
if reserved {
|
||||||
|
columns = append(columns, "reserved")
|
||||||
|
cond.Reserved = true
|
||||||
|
}
|
||||||
|
if len(columns) > 0 {
|
||||||
|
session.UseBool(columns...)
|
||||||
|
}
|
||||||
session.Where(builder.Eq{"status": entity.TagStatusAvailable})
|
session.Where(builder.Eq{"status": entity.TagStatusAvailable})
|
||||||
session.Asc("slug_name")
|
|
||||||
err = session.OrderBy("recommend desc,reserved desc,id desc").Find(&tagList, cond)
|
tagList = make([]*entity.Tag, 0)
|
||||||
|
err = session.OrderBy("recommend DESC,reserved DESC,slug_name ASC").Find(&tagList, cond)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
err = errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
|
err = errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
|
||||||
}
|
}
|
||||||
|
|
|
@ -131,21 +131,21 @@ func (ur *userAdminRepo) GetUserPage(ctx context.Context, page, pageSize int, us
|
||||||
session := ur.data.DB.Context(ctx)
|
session := ur.data.DB.Context(ctx)
|
||||||
switch user.Status {
|
switch user.Status {
|
||||||
case entity.UserStatusDeleted:
|
case entity.UserStatusDeleted:
|
||||||
session.Desc("user.deleted_at")
|
session.Desc("`user`.deleted_at")
|
||||||
case entity.UserStatusSuspended:
|
case entity.UserStatusSuspended:
|
||||||
session.Desc("user.suspended_at")
|
session.Desc("`user`.suspended_at")
|
||||||
default:
|
default:
|
||||||
session.Desc("user.created_at")
|
session.Desc("`user`.created_at")
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(usernameOrDisplayName) > 0 {
|
if len(usernameOrDisplayName) > 0 {
|
||||||
session.And(builder.Or(
|
session.And(builder.Or(
|
||||||
builder.Like{"user.username", usernameOrDisplayName},
|
builder.Like{"`user`.username", usernameOrDisplayName},
|
||||||
builder.Like{"user.display_name", usernameOrDisplayName},
|
builder.Like{"`user`.display_name", usernameOrDisplayName},
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
if isStaff {
|
if isStaff {
|
||||||
session.Join("INNER", "user_role_rel", "user.id = user_role_rel.user_id AND user_role_rel.role_id > 1")
|
session.Join("INNER", "user_role_rel", "`user`.id = `user_role_rel`.user_id AND `user_role_rel`.role_id > 1")
|
||||||
}
|
}
|
||||||
|
|
||||||
total, err = pager.Help(page, pageSize, &users, user, session)
|
total, err = pager.Help(page, pageSize, &users, user, session)
|
||||||
|
|
|
@ -22,6 +22,24 @@ func NewUserNotificationConfigRepo(data *data.Data) user_notification_config.Use
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add add notification config
|
||||||
|
func (ur *userNotificationConfigRepo) Add(ctx context.Context, userIDs []string, source, channels string) (err error) {
|
||||||
|
var configs []*entity.UserNotificationConfig
|
||||||
|
for _, userID := range userIDs {
|
||||||
|
configs = append(configs, &entity.UserNotificationConfig{
|
||||||
|
UserID: userID,
|
||||||
|
Source: source,
|
||||||
|
Channels: channels,
|
||||||
|
Enabled: true,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
_, err = ur.data.DB.Context(ctx).Insert(configs)
|
||||||
|
if err != nil {
|
||||||
|
return errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// Save save notification config, if existed, update, if not exist, insert
|
// Save save notification config, if existed, update, if not exist, insert
|
||||||
func (ur *userNotificationConfigRepo) Save(ctx context.Context, uc *entity.UserNotificationConfig) (err error) {
|
func (ur *userNotificationConfigRepo) Save(ctx context.Context, uc *entity.UserNotificationConfig) (err error) {
|
||||||
old := &entity.UserNotificationConfig{UserID: uc.UserID, Source: uc.Source}
|
old := &entity.UserNotificationConfig{UserID: uc.UserID, Source: uc.Source}
|
||||||
|
|
|
@ -203,7 +203,7 @@ func (a *AnswerAPIRouter) RegisterAnswerAPIRouter(r *gin.RouterGroup) {
|
||||||
r.PUT("/question/status", a.questionController.CloseQuestion)
|
r.PUT("/question/status", a.questionController.CloseQuestion)
|
||||||
r.PUT("/question/operation", a.questionController.OperationQuestion)
|
r.PUT("/question/operation", a.questionController.OperationQuestion)
|
||||||
r.PUT("/question/reopen", a.questionController.ReopenQuestion)
|
r.PUT("/question/reopen", a.questionController.ReopenQuestion)
|
||||||
r.GET("/question/similar", a.questionController.SearchByTitleLike)
|
r.GET("/question/similar", a.questionController.GetSimilarQuestions)
|
||||||
|
|
||||||
// answer
|
// answer
|
||||||
r.POST("/answer", a.answerController.Add)
|
r.POST("/answer", a.answerController.Add)
|
||||||
|
|
|
@ -108,12 +108,19 @@ type AdminAnswerInfo struct {
|
||||||
} `json:"question_info"`
|
} `json:"question_info"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type AnswerAcceptedReq struct {
|
type AcceptAnswerReq struct {
|
||||||
QuestionID string `json:"question_id"`
|
QuestionID string `validate:"required,gt=0,lte=30" json:"question_id"`
|
||||||
AnswerID string `json:"answer_id"`
|
AnswerID string `validate:"omitempty" json:"answer_id"`
|
||||||
UserID string `json:"-"`
|
UserID string `json:"-"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (req *AcceptAnswerReq) Check() (errFields []*validator.FormErrorField, err error) {
|
||||||
|
if len(req.AnswerID) == 0 {
|
||||||
|
req.AnswerID = "0"
|
||||||
|
}
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
type AdminSetAnswerStatusRequest struct {
|
type AdminSetAnswerStatusRequest struct {
|
||||||
StatusStr string `json:"status"`
|
StatusStr string `json:"status"`
|
||||||
AnswerID string `json:"answer_id"`
|
AnswerID string `json:"answer_id"`
|
||||||
|
|
|
@ -58,11 +58,10 @@ type UpdateCommentReq struct {
|
||||||
UserID string `json:"-"`
|
UserID string `json:"-"`
|
||||||
IsAdmin bool `json:"-"`
|
IsAdmin bool `json:"-"`
|
||||||
|
|
||||||
CanAdd bool `json:"-"`
|
|
||||||
// whether user can edit it
|
// whether user can edit it
|
||||||
CanEdit bool `json:"-"`
|
CanEdit bool `json:"-"`
|
||||||
|
|
||||||
// whether user can delete it
|
// whether user can delete it
|
||||||
CanDelete bool `json:"-"`
|
|
||||||
CaptchaID string `json:"captcha_id"` // captcha_id
|
CaptchaID string `json:"captcha_id"` // captcha_id
|
||||||
CaptchaCode string `json:"captcha_code"`
|
CaptchaCode string `json:"captcha_code"`
|
||||||
}
|
}
|
||||||
|
@ -72,6 +71,15 @@ func (req *UpdateCommentReq) Check() (errFields []*validator.FormErrorField, err
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type UpdateCommentResp struct {
|
||||||
|
// comment id
|
||||||
|
CommentID string `json:"comment_id"`
|
||||||
|
// original comment content
|
||||||
|
OriginalText string `json:"original_text"`
|
||||||
|
// parsed comment content
|
||||||
|
ParsedText string `json:"parsed_text"`
|
||||||
|
}
|
||||||
|
|
||||||
// GetCommentListReq get comment list all request
|
// GetCommentListReq get comment list all request
|
||||||
type GetCommentListReq struct {
|
type GetCommentListReq struct {
|
||||||
// user id
|
// user id
|
||||||
|
|
|
@ -90,13 +90,21 @@ type SearchObject struct {
|
||||||
Accepted bool `json:"accepted"`
|
Accepted bool `json:"accepted"`
|
||||||
AnswerCount int `json:"answer_count"`
|
AnswerCount int `json:"answer_count"`
|
||||||
// user info
|
// user info
|
||||||
UserInfo *UserBasicInfo `json:"user_info"`
|
UserInfo *SearchObjectUser `json:"user_info"`
|
||||||
// tags
|
// tags
|
||||||
Tags []TagResp `json:"tags"`
|
Tags []*TagResp `json:"tags"`
|
||||||
// Status
|
// Status
|
||||||
StatusStr string `json:"status"`
|
StatusStr string `json:"status"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type SearchObjectUser struct {
|
||||||
|
ID string `json:"id"`
|
||||||
|
Username string `json:"username"`
|
||||||
|
DisplayName string `json:"display_name"`
|
||||||
|
Rank int `json:"rank"`
|
||||||
|
Status string `json:"status"`
|
||||||
|
}
|
||||||
|
|
||||||
type TagResp struct {
|
type TagResp struct {
|
||||||
ID string `json:"-"`
|
ID string `json:"-"`
|
||||||
SlugName string `json:"slug_name"`
|
SlugName string `json:"slug_name"`
|
||||||
|
@ -111,13 +119,13 @@ type SearchResult struct {
|
||||||
// object_type
|
// object_type
|
||||||
ObjectType string `json:"object_type"`
|
ObjectType string `json:"object_type"`
|
||||||
// this object
|
// this object
|
||||||
Object SearchObject `json:"object"`
|
Object *SearchObject `json:"object"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type SearchResp struct {
|
type SearchResp struct {
|
||||||
Total int64 `json:"count"`
|
Total int64 `json:"count"`
|
||||||
// search response
|
// search response
|
||||||
SearchResults []SearchResult `json:"list"`
|
SearchResults []*SearchResult `json:"list"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type SearchDescResp struct {
|
type SearchDescResp struct {
|
||||||
|
|
|
@ -34,6 +34,9 @@ func NewAnswerActivityService(
|
||||||
// AcceptAnswer accept answer change activity
|
// AcceptAnswer accept answer change activity
|
||||||
func (as *AnswerActivityService) AcceptAnswer(ctx context.Context,
|
func (as *AnswerActivityService) AcceptAnswer(ctx context.Context,
|
||||||
loginUserID, answerObjID, questionObjID, questionUserID, answerUserID string, isSelf bool) (err error) {
|
loginUserID, answerObjID, questionObjID, questionUserID, answerUserID string, isSelf bool) (err error) {
|
||||||
|
log.Debugf("user %s want to accept answer %s[%s] for question %s[%s]", loginUserID,
|
||||||
|
answerObjID, answerUserID,
|
||||||
|
questionObjID, questionUserID)
|
||||||
operationInfo := as.createAcceptAnswerOperationInfo(ctx, loginUserID,
|
operationInfo := as.createAcceptAnswerOperationInfo(ctx, loginUserID,
|
||||||
answerObjID, questionObjID, questionUserID, answerUserID, isSelf)
|
answerObjID, questionObjID, questionUserID, answerUserID, isSelf)
|
||||||
return as.answerActivityRepo.SaveAcceptAnswerActivity(ctx, operationInfo)
|
return as.answerActivityRepo.SaveAcceptAnswerActivity(ctx, operationInfo)
|
||||||
|
|
|
@ -17,7 +17,7 @@ type AnswerRepo interface {
|
||||||
GetAnswer(ctx context.Context, id string) (answer *entity.Answer, exist bool, err error)
|
GetAnswer(ctx context.Context, id string) (answer *entity.Answer, exist bool, err error)
|
||||||
GetAnswerList(ctx context.Context, answer *entity.Answer) (answerList []*entity.Answer, err error)
|
GetAnswerList(ctx context.Context, answer *entity.Answer) (answerList []*entity.Answer, err error)
|
||||||
GetAnswerPage(ctx context.Context, page, pageSize int, answer *entity.Answer) (answerList []*entity.Answer, total int64, err error)
|
GetAnswerPage(ctx context.Context, page, pageSize int, answer *entity.Answer) (answerList []*entity.Answer, total int64, err error)
|
||||||
UpdateAccepted(ctx context.Context, id string, questionID string) error
|
UpdateAcceptedStatus(ctx context.Context, acceptedAnswerID string, questionID string) error
|
||||||
GetByID(ctx context.Context, id string) (*entity.Answer, bool, error)
|
GetByID(ctx context.Context, id string) (*entity.Answer, bool, error)
|
||||||
GetCountByQuestionID(ctx context.Context, questionID string) (int64, error)
|
GetCountByQuestionID(ctx context.Context, questionID string) (int64, error)
|
||||||
GetCountByUserID(ctx context.Context, userID string) (int64, error)
|
GetCountByUserID(ctx context.Context, userID string) (int64, error)
|
||||||
|
@ -83,6 +83,7 @@ func (as *AnswerCommon) ShowFormat(ctx context.Context, data *entity.Answer) *sc
|
||||||
info.UserID = data.UserID
|
info.UserID = data.UserID
|
||||||
info.UpdateUserID = data.LastEditUserID
|
info.UpdateUserID = data.LastEditUserID
|
||||||
info.Status = data.Status
|
info.Status = data.Status
|
||||||
|
info.MemberActions = make([]*schema.PermissionMemberAction, 0)
|
||||||
return &info
|
return &info
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -230,15 +230,13 @@ func (as *AnswerService) Insert(ctx context.Context, req *schema.AnswerAddReq) (
|
||||||
}
|
}
|
||||||
|
|
||||||
func (as *AnswerService) Update(ctx context.Context, req *schema.AnswerUpdateReq) (string, error) {
|
func (as *AnswerService) Update(ctx context.Context, req *schema.AnswerUpdateReq) (string, error) {
|
||||||
//req.NoNeedReview //true 不需要审核
|
|
||||||
var canUpdate bool
|
var canUpdate bool
|
||||||
_, existUnreviewed, err := as.revisionService.ExistUnreviewedByObjectID(ctx, req.ID)
|
_, existUnreviewed, err := as.revisionService.ExistUnreviewedByObjectID(ctx, req.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
if existUnreviewed {
|
if existUnreviewed {
|
||||||
err = errors.BadRequest(reason.AnswerCannotUpdate)
|
return "", errors.BadRequest(reason.AnswerCannotUpdate)
|
||||||
return "", err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
questionInfo, exist, err := as.questionRepo.GetQuestion(ctx, req.QuestionID)
|
questionInfo, exist, err := as.questionRepo.GetQuestion(ctx, req.QuestionID)
|
||||||
|
@ -254,12 +252,11 @@ func (as *AnswerService) Update(ctx context.Context, req *schema.AnswerUpdateReq
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
if !exist {
|
if !exist {
|
||||||
return "", nil
|
return "", errors.BadRequest(reason.AnswerNotFound)
|
||||||
}
|
}
|
||||||
|
|
||||||
if answerInfo.Status == entity.AnswerStatusDeleted {
|
if answerInfo.Status == entity.AnswerStatusDeleted {
|
||||||
err = errors.BadRequest(reason.AnswerCannotUpdate)
|
return "", errors.BadRequest(reason.AnswerCannotUpdate)
|
||||||
return "", err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//If the content is the same, ignore it
|
//If the content is the same, ignore it
|
||||||
|
@ -267,15 +264,13 @@ func (as *AnswerService) Update(ctx context.Context, req *schema.AnswerUpdateReq
|
||||||
return "", nil
|
return "", nil
|
||||||
}
|
}
|
||||||
|
|
||||||
now := time.Now()
|
insertData := &entity.Answer{}
|
||||||
insertData := new(entity.Answer)
|
|
||||||
insertData.ID = req.ID
|
insertData.ID = req.ID
|
||||||
insertData.UserID = answerInfo.UserID
|
insertData.UserID = answerInfo.UserID
|
||||||
insertData.QuestionID = req.QuestionID
|
insertData.QuestionID = req.QuestionID
|
||||||
insertData.OriginalText = req.Content
|
insertData.OriginalText = req.Content
|
||||||
insertData.ParsedText = req.HTML
|
insertData.ParsedText = req.HTML
|
||||||
insertData.UpdatedAt = now
|
insertData.UpdatedAt = time.Now()
|
||||||
|
|
||||||
insertData.LastEditUserID = "0"
|
insertData.LastEditUserID = "0"
|
||||||
if answerInfo.UserID != req.UserID {
|
if answerInfo.UserID != req.UserID {
|
||||||
insertData.LastEditUserID = req.UserID
|
insertData.LastEditUserID = req.UserID
|
||||||
|
@ -284,7 +279,6 @@ func (as *AnswerService) Update(ctx context.Context, req *schema.AnswerUpdateReq
|
||||||
revisionDTO := &schema.AddRevisionDTO{
|
revisionDTO := &schema.AddRevisionDTO{
|
||||||
UserID: req.UserID,
|
UserID: req.UserID,
|
||||||
ObjectID: req.ID,
|
ObjectID: req.ID,
|
||||||
Title: "",
|
|
||||||
Log: req.EditSummary,
|
Log: req.EditSummary,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -314,7 +308,7 @@ func (as *AnswerService) Update(ctx context.Context, req *schema.AnswerUpdateReq
|
||||||
}
|
}
|
||||||
if canUpdate {
|
if canUpdate {
|
||||||
as.activityQueueService.Send(ctx, &schema.ActivityMsg{
|
as.activityQueueService.Send(ctx, &schema.ActivityMsg{
|
||||||
UserID: insertData.UserID,
|
UserID: req.UserID,
|
||||||
ObjectID: insertData.ID,
|
ObjectID: insertData.ID,
|
||||||
OriginalObjectID: insertData.ID,
|
OriginalObjectID: insertData.ID,
|
||||||
ActivityTypeKey: constant.ActAnswerEdited,
|
ActivityTypeKey: constant.ActAnswerEdited,
|
||||||
|
@ -325,47 +319,47 @@ func (as *AnswerService) Update(ctx context.Context, req *schema.AnswerUpdateReq
|
||||||
return insertData.ID, nil
|
return insertData.ID, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdateAccepted
|
// AcceptAnswer accept answer
|
||||||
func (as *AnswerService) UpdateAccepted(ctx context.Context, req *schema.AnswerAcceptedReq) error {
|
func (as *AnswerService) AcceptAnswer(ctx context.Context, req *schema.AcceptAnswerReq) (err error) {
|
||||||
if req.AnswerID == "" {
|
// find question
|
||||||
req.AnswerID = "0"
|
|
||||||
}
|
|
||||||
if req.UserID == "" {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
newAnswerInfo := &entity.Answer{}
|
|
||||||
newAnswerInfoexist := false
|
|
||||||
var err error
|
|
||||||
|
|
||||||
if req.AnswerID != "0" {
|
|
||||||
newAnswerInfo, newAnswerInfoexist, err = as.answerRepo.GetByID(ctx, req.AnswerID)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
newAnswerInfo.ID = uid.DeShortID(newAnswerInfo.ID)
|
|
||||||
if !newAnswerInfoexist {
|
|
||||||
return errors.BadRequest(reason.AnswerNotFound)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
questionInfo, exist, err := as.questionRepo.GetQuestion(ctx, req.QuestionID)
|
questionInfo, exist, err := as.questionRepo.GetQuestion(ctx, req.QuestionID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
questionInfo.ID = uid.DeShortID(questionInfo.ID)
|
|
||||||
if !exist {
|
if !exist {
|
||||||
return errors.BadRequest(reason.QuestionNotFound)
|
return errors.BadRequest(reason.QuestionNotFound)
|
||||||
}
|
}
|
||||||
// if questionInfo.UserID != req.UserID {
|
questionInfo.ID = uid.DeShortID(questionInfo.ID)
|
||||||
// return fmt.Errorf("no permission to set answer")
|
|
||||||
// }
|
|
||||||
if questionInfo.AcceptedAnswerID == req.AnswerID {
|
if questionInfo.AcceptedAnswerID == req.AnswerID {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// find answer
|
||||||
|
var acceptedAnswerInfo *entity.Answer
|
||||||
|
if len(req.AnswerID) > 1 {
|
||||||
|
acceptedAnswerInfo, exist, err = as.answerRepo.GetByID(ctx, req.AnswerID)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if !exist {
|
||||||
|
return errors.BadRequest(reason.AnswerNotFound)
|
||||||
|
}
|
||||||
|
acceptedAnswerInfo.ID = uid.DeShortID(acceptedAnswerInfo.ID)
|
||||||
|
}
|
||||||
|
|
||||||
|
// update answers status
|
||||||
|
if err = as.answerRepo.UpdateAcceptedStatus(ctx, req.AnswerID, req.QuestionID); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// update question status
|
||||||
|
err = as.questionCommon.UpdateAccepted(ctx, req.QuestionID, req.AnswerID)
|
||||||
|
if err != nil {
|
||||||
|
log.Error("UpdateLastAnswer error", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
var oldAnswerInfo *entity.Answer
|
var oldAnswerInfo *entity.Answer
|
||||||
if len(questionInfo.AcceptedAnswerID) > 0 && questionInfo.AcceptedAnswerID != "0" {
|
if len(questionInfo.AcceptedAnswerID) > 1 {
|
||||||
oldAnswerInfo, _, err = as.answerRepo.GetByID(ctx, questionInfo.AcceptedAnswerID)
|
oldAnswerInfo, _, err = as.answerRepo.GetByID(ctx, questionInfo.AcceptedAnswerID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -373,17 +367,7 @@ func (as *AnswerService) UpdateAccepted(ctx context.Context, req *schema.AnswerA
|
||||||
oldAnswerInfo.ID = uid.DeShortID(oldAnswerInfo.ID)
|
oldAnswerInfo.ID = uid.DeShortID(oldAnswerInfo.ID)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = as.answerRepo.UpdateAccepted(ctx, req.AnswerID, req.QuestionID)
|
as.updateAnswerRank(ctx, req.UserID, questionInfo, acceptedAnswerInfo, oldAnswerInfo)
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
err = as.questionCommon.UpdateAccepted(ctx, req.QuestionID, req.AnswerID)
|
|
||||||
if err != nil {
|
|
||||||
log.Error("UpdateLastAnswer error", err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
as.updateAnswerRank(ctx, req.UserID, questionInfo, newAnswerInfo, oldAnswerInfo)
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -398,9 +382,9 @@ func (as *AnswerService) updateAnswerRank(ctx context.Context, userID string,
|
||||||
log.Error(err)
|
log.Error(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if newAnswerInfo.ID != "" {
|
if newAnswerInfo != nil {
|
||||||
err := as.answerActivityService.AcceptAnswer(ctx, userID, newAnswerInfo.ID,
|
err := as.answerActivityService.AcceptAnswer(ctx, userID, newAnswerInfo.ID,
|
||||||
questionInfo.ID, questionInfo.UserID, newAnswerInfo.UserID, newAnswerInfo.UserID == userID)
|
questionInfo.ID, questionInfo.UserID, newAnswerInfo.UserID, newAnswerInfo.UserID == questionInfo.UserID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error(err)
|
log.Error(err)
|
||||||
}
|
}
|
||||||
|
@ -443,12 +427,11 @@ func (as *AnswerService) Get(ctx context.Context, answerID, loginUserID string)
|
||||||
|
|
||||||
info.VoteStatus = as.voteRepo.GetVoteStatus(ctx, answerID, loginUserID)
|
info.VoteStatus = as.voteRepo.GetVoteStatus(ctx, answerID, loginUserID)
|
||||||
|
|
||||||
CollectedMap, err := as.collectionCommon.SearchObjectCollected(ctx, loginUserID, []string{answerInfo.ID})
|
collectedMap, err := as.collectionCommon.SearchObjectCollected(ctx, loginUserID, []string{answerInfo.ID})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("CollectionFunc.SearchObjectCollected error", err)
|
return nil, nil, has, err
|
||||||
}
|
}
|
||||||
_, ok = CollectedMap[answerInfo.ID]
|
if len(collectedMap) > 0 {
|
||||||
if ok {
|
|
||||||
info.Collected = true
|
info.Collected = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -529,46 +512,28 @@ func (as *AnswerService) SearchFormatInfo(ctx context.Context, answers []*entity
|
||||||
item := as.ShowFormat(ctx, info)
|
item := as.ShowFormat(ctx, info)
|
||||||
list = append(list, item)
|
list = append(list, item)
|
||||||
objectIDs = append(objectIDs, info.ID)
|
objectIDs = append(objectIDs, info.ID)
|
||||||
userIDs = append(userIDs, info.UserID)
|
userIDs = append(userIDs, info.UserID, info.LastEditUserID)
|
||||||
userIDs = append(userIDs, info.LastEditUserID)
|
|
||||||
if req.UserID != "" {
|
|
||||||
item.ID = uid.DeShortID(item.ID)
|
|
||||||
item.VoteStatus = as.voteRepo.GetVoteStatus(ctx, item.ID, req.UserID)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
userInfoMap, err := as.userCommon.BatchUserBasicInfoByID(ctx, userIDs)
|
userInfoMap, err := as.userCommon.BatchUserBasicInfoByID(ctx, userIDs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return list, err
|
return list, err
|
||||||
}
|
}
|
||||||
for _, item := range list {
|
for _, item := range list {
|
||||||
_, ok := userInfoMap[item.UserID]
|
|
||||||
if ok {
|
|
||||||
item.UserInfo = userInfoMap[item.UserID]
|
item.UserInfo = userInfoMap[item.UserID]
|
||||||
}
|
|
||||||
_, ok = userInfoMap[item.UpdateUserID]
|
|
||||||
if ok {
|
|
||||||
item.UpdateUserInfo = userInfoMap[item.UpdateUserID]
|
item.UpdateUserInfo = userInfoMap[item.UpdateUserID]
|
||||||
}
|
}
|
||||||
}
|
if len(req.UserID) == 0 {
|
||||||
|
|
||||||
if req.UserID == "" {
|
|
||||||
return list, nil
|
return list, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
searchObjectCollected, err := as.collectionCommon.SearchObjectCollected(ctx, req.UserID, objectIDs)
|
collectedMap, err := as.collectionCommon.SearchObjectCollected(ctx, req.UserID, objectIDs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, item := range list {
|
for _, item := range list {
|
||||||
_, ok := searchObjectCollected[item.ID]
|
item.VoteStatus = as.voteRepo.GetVoteStatus(ctx, item.ID, req.UserID)
|
||||||
if ok {
|
item.Collected = collectedMap[item.ID]
|
||||||
item.Collected = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, item := range list {
|
|
||||||
item.ID = uid.EnShortID(item.ID)
|
|
||||||
item.MemberActions = permission.GetAnswerPermission(ctx, req.UserID, item.UserID, req.CanEdit, req.CanDelete)
|
item.MemberActions = permission.GetAnswerPermission(ctx, req.UserID, item.UserID, req.CanEdit, req.CanDelete)
|
||||||
}
|
}
|
||||||
return list, nil
|
return list, nil
|
||||||
|
|
|
@ -29,7 +29,7 @@ import (
|
||||||
type CommentRepo interface {
|
type CommentRepo interface {
|
||||||
AddComment(ctx context.Context, comment *entity.Comment) (err error)
|
AddComment(ctx context.Context, comment *entity.Comment) (err error)
|
||||||
RemoveComment(ctx context.Context, commentID string) (err error)
|
RemoveComment(ctx context.Context, commentID string) (err error)
|
||||||
UpdateComment(ctx context.Context, comment *entity.Comment) (err error)
|
UpdateCommentContent(ctx context.Context, commentID string, original string, parsedText string) (err error)
|
||||||
GetComment(ctx context.Context, commentID string) (comment *entity.Comment, exist bool, err error)
|
GetComment(ctx context.Context, commentID string) (comment *entity.Comment, exist bool, err error)
|
||||||
GetCommentPage(ctx context.Context, commentQuery *CommentQuery) (
|
GetCommentPage(ctx context.Context, commentQuery *CommentQuery) (
|
||||||
comments []*entity.Comment, total int64, err error)
|
comments []*entity.Comment, total int64, err error)
|
||||||
|
@ -224,39 +224,34 @@ func (cs *CommentService) RemoveComment(ctx context.Context, req *schema.RemoveC
|
||||||
|
|
||||||
// UpdateComment update comment
|
// UpdateComment update comment
|
||||||
func (cs *CommentService) UpdateComment(ctx context.Context, req *schema.UpdateCommentReq) (
|
func (cs *CommentService) UpdateComment(ctx context.Context, req *schema.UpdateCommentReq) (
|
||||||
resp *schema.GetCommentResp, err error) {
|
resp *schema.UpdateCommentResp, err error) {
|
||||||
resp = &schema.GetCommentResp{}
|
|
||||||
|
|
||||||
old, exist, err := cs.commentCommonRepo.GetComment(ctx, req.CommentID)
|
old, exist, err := cs.commentCommonRepo.GetComment(ctx, req.CommentID)
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if !exist {
|
|
||||||
return resp, errors.BadRequest(reason.CommentNotFound)
|
|
||||||
}
|
|
||||||
|
|
||||||
// user can edit the comment that was posted by himself before deadline.
|
|
||||||
if !req.IsAdmin && (time.Now().After(old.CreatedAt.Add(constant.CommentEditDeadline))) {
|
|
||||||
return resp, errors.BadRequest(reason.CommentCannotEditAfterDeadline)
|
|
||||||
}
|
|
||||||
|
|
||||||
comment := &entity.Comment{}
|
|
||||||
_ = copier.Copy(comment, req)
|
|
||||||
comment.ID = req.CommentID
|
|
||||||
resp.SetFromComment(comment)
|
|
||||||
resp.MemberActions = permission.GetCommentPermission(ctx, req.UserID, resp.UserID,
|
|
||||||
time.Now(), req.CanEdit, req.CanDelete)
|
|
||||||
userInfo, exist, err := cs.userCommon.GetUserBasicInfoByID(ctx, resp.UserID)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if exist {
|
if !exist {
|
||||||
resp.Username = userInfo.Username
|
return nil, errors.BadRequest(reason.CommentNotFound)
|
||||||
resp.UserDisplayName = userInfo.DisplayName
|
|
||||||
resp.UserAvatar = userInfo.Avatar
|
|
||||||
resp.UserStatus = userInfo.Status
|
|
||||||
}
|
}
|
||||||
return resp, cs.commentRepo.UpdateComment(ctx, comment)
|
// user can't edit the comment that was posted by others except admin
|
||||||
|
if !req.IsAdmin && req.UserID != old.UserID {
|
||||||
|
return nil, errors.BadRequest(reason.CommentNotFound)
|
||||||
|
}
|
||||||
|
|
||||||
|
// user can edit the comment that was posted by himself before deadline.
|
||||||
|
// admin can edit it at any time
|
||||||
|
if !req.IsAdmin && (time.Now().After(old.CreatedAt.Add(constant.CommentEditDeadline))) {
|
||||||
|
return nil, errors.BadRequest(reason.CommentCannotEditAfterDeadline)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = cs.commentRepo.UpdateCommentContent(ctx, old.ID, req.OriginalText, req.ParsedText); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
resp = &schema.UpdateCommentResp{
|
||||||
|
CommentID: old.ID,
|
||||||
|
OriginalText: req.OriginalText,
|
||||||
|
ParsedText: req.ParsedText,
|
||||||
|
}
|
||||||
|
return resp, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetComment get comment one
|
// GetComment get comment one
|
||||||
|
|
|
@ -40,7 +40,7 @@ type QuestionRepo interface {
|
||||||
UpdateQuestionStatus(ctx context.Context, question *entity.Question) (err error)
|
UpdateQuestionStatus(ctx context.Context, question *entity.Question) (err error)
|
||||||
UpdateQuestionStatusWithOutUpdateTime(ctx context.Context, question *entity.Question) (err error)
|
UpdateQuestionStatusWithOutUpdateTime(ctx context.Context, question *entity.Question) (err error)
|
||||||
UpdateQuestionOperation(ctx context.Context, question *entity.Question) (err error)
|
UpdateQuestionOperation(ctx context.Context, question *entity.Question) (err error)
|
||||||
SearchByTitleLike(ctx context.Context, title string) (questionList []*entity.Question, err error)
|
GetQuestionsByTitle(ctx context.Context, title string, pageSize int) (questionList []*entity.Question, err error)
|
||||||
UpdatePvCount(ctx context.Context, questionID string) (err error)
|
UpdatePvCount(ctx context.Context, questionID string) (err error)
|
||||||
UpdateAnswerCount(ctx context.Context, questionID string, num int) (err error)
|
UpdateAnswerCount(ctx context.Context, questionID string, num int) (err error)
|
||||||
UpdateCollectionCount(ctx context.Context, questionID string, num int) (err error)
|
UpdateCollectionCount(ctx context.Context, questionID string, num int) (err error)
|
||||||
|
@ -282,17 +282,13 @@ func (qs *QuestionCommon) Info(ctx context.Context, questionID string, loginUser
|
||||||
}
|
}
|
||||||
showinfo.Answered = has
|
showinfo.Answered = has
|
||||||
|
|
||||||
// login user Collected information
|
collectedMap, err := qs.collectionCommon.SearchObjectCollected(ctx, loginUserID, []string{dbinfo.ID})
|
||||||
|
|
||||||
CollectedMap, err := qs.collectionCommon.SearchObjectCollected(ctx, loginUserID, []string{dbinfo.ID})
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("CollectionFunc.SearchObjectCollected", err)
|
return nil, err
|
||||||
}
|
}
|
||||||
_, ok = CollectedMap[dbinfo.ID]
|
if len(collectedMap) > 0 {
|
||||||
if ok {
|
|
||||||
showinfo.Collected = true
|
showinfo.Collected = true
|
||||||
}
|
}
|
||||||
|
|
||||||
return showinfo, nil
|
return showinfo, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -406,9 +402,7 @@ func (qs *QuestionCommon) FormatQuestions(ctx context.Context, questionList []*e
|
||||||
item := qs.ShowFormat(ctx, questionInfo)
|
item := qs.ShowFormat(ctx, questionInfo)
|
||||||
list = append(list, item)
|
list = append(list, item)
|
||||||
objectIds = append(objectIds, item.ID)
|
objectIds = append(objectIds, item.ID)
|
||||||
userIds = append(userIds, item.UserID)
|
userIds = append(userIds, item.UserID, item.LastEditUserID, item.LastAnsweredUserID)
|
||||||
userIds = append(userIds, item.LastEditUserID)
|
|
||||||
userIds = append(userIds, item.LastAnsweredUserID)
|
|
||||||
}
|
}
|
||||||
tagsMap, err := qs.tagCommon.BatchGetObjectTag(ctx, objectIds)
|
tagsMap, err := qs.tagCommon.BatchGetObjectTag(ctx, objectIds)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -421,38 +415,21 @@ func (qs *QuestionCommon) FormatQuestions(ctx context.Context, questionList []*e
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, item := range list {
|
for _, item := range list {
|
||||||
_, ok := tagsMap[item.ID]
|
|
||||||
if ok {
|
|
||||||
item.Tags = tagsMap[item.ID]
|
item.Tags = tagsMap[item.ID]
|
||||||
}
|
|
||||||
_, ok = userInfoMap[item.UserID]
|
|
||||||
if ok {
|
|
||||||
item.UserInfo = userInfoMap[item.UserID]
|
item.UserInfo = userInfoMap[item.UserID]
|
||||||
}
|
|
||||||
_, ok = userInfoMap[item.LastEditUserID]
|
|
||||||
if ok {
|
|
||||||
item.UpdateUserInfo = userInfoMap[item.LastEditUserID]
|
item.UpdateUserInfo = userInfoMap[item.LastEditUserID]
|
||||||
}
|
|
||||||
_, ok = userInfoMap[item.LastAnsweredUserID]
|
|
||||||
if ok {
|
|
||||||
item.LastAnsweredUserInfo = userInfoMap[item.LastAnsweredUserID]
|
item.LastAnsweredUserInfo = userInfoMap[item.LastAnsweredUserID]
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if loginUserID == "" {
|
if loginUserID == "" {
|
||||||
return list, nil
|
return list, nil
|
||||||
}
|
}
|
||||||
// //login user Collected information
|
|
||||||
CollectedMap, err := qs.collectionCommon.SearchObjectCollected(ctx, loginUserID, objectIds)
|
|
||||||
if err != nil {
|
|
||||||
log.Error("CollectionFunc.SearchObjectCollected", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, item := range list {
|
collectedMap, err := qs.collectionCommon.SearchObjectCollected(ctx, loginUserID, objectIds)
|
||||||
_, ok := CollectedMap[item.ID]
|
if err != nil {
|
||||||
if ok {
|
return nil, err
|
||||||
item.Collected = true
|
|
||||||
}
|
}
|
||||||
|
for _, item := range list {
|
||||||
|
item.Collected = collectedMap[item.ID]
|
||||||
}
|
}
|
||||||
return list, nil
|
return list, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -1103,14 +1103,18 @@ func (qs *QuestionService) SearchUserTopList(ctx context.Context, userName strin
|
||||||
return userQuestionlist, userAnswerlist, nil
|
return userQuestionlist, userAnswerlist, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// SearchByTitleLike
|
// GetQuestionsByTitle get questions by title
|
||||||
func (qs *QuestionService) SearchByTitleLike(ctx context.Context, title string, loginUserID string) ([]*schema.QuestionBaseInfo, error) {
|
func (qs *QuestionService) GetQuestionsByTitle(ctx context.Context, title string) (
|
||||||
list := make([]*schema.QuestionBaseInfo, 0)
|
resp []*schema.QuestionBaseInfo, err error) {
|
||||||
dblist, err := qs.questionRepo.SearchByTitleLike(ctx, title)
|
resp = make([]*schema.QuestionBaseInfo, 0)
|
||||||
if err != nil {
|
if len(title) == 0 {
|
||||||
return list, err
|
return resp, nil
|
||||||
}
|
}
|
||||||
for _, question := range dblist {
|
questions, err := qs.questionRepo.GetQuestionsByTitle(ctx, title, 10)
|
||||||
|
if err != nil {
|
||||||
|
return resp, err
|
||||||
|
}
|
||||||
|
for _, question := range questions {
|
||||||
item := &schema.QuestionBaseInfo{}
|
item := &schema.QuestionBaseInfo{}
|
||||||
item.ID = question.ID
|
item.ID = question.ID
|
||||||
item.Title = question.Title
|
item.Title = question.Title
|
||||||
|
@ -1125,10 +1129,9 @@ func (qs *QuestionService) SearchByTitleLike(ctx context.Context, title string,
|
||||||
if question.AcceptedAnswerID != "0" {
|
if question.AcceptedAnswerID != "0" {
|
||||||
item.AcceptedAnswer = true
|
item.AcceptedAnswer = true
|
||||||
}
|
}
|
||||||
list = append(list, item)
|
resp = append(resp, item)
|
||||||
}
|
}
|
||||||
|
return resp, nil
|
||||||
return list, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// SimilarQuestion
|
// SimilarQuestion
|
||||||
|
|
|
@ -7,8 +7,8 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
type SearchRepo interface {
|
type SearchRepo interface {
|
||||||
SearchContents(ctx context.Context, words []string, tagIDs []string, userID string, votes, page, size int, order string) (resp []schema.SearchResult, total int64, err error)
|
SearchContents(ctx context.Context, words []string, tagIDs []string, userID string, votes, page, size int, order string) (resp []*schema.SearchResult, total int64, err error)
|
||||||
SearchQuestions(ctx context.Context, words []string, tagIDs []string, notAccepted bool, views, answers int, page, size int, order string) (resp []schema.SearchResult, total int64, err error)
|
SearchQuestions(ctx context.Context, words []string, tagIDs []string, notAccepted bool, views, answers int, page, size int, order string) (resp []*schema.SearchResult, total int64, err error)
|
||||||
SearchAnswers(ctx context.Context, words []string, tagIDs []string, accepted bool, questionID string, page, size int, order string) (resp []schema.SearchResult, total int64, err error)
|
SearchAnswers(ctx context.Context, words []string, tagIDs []string, accepted bool, questionID string, page, size int, order string) (resp []*schema.SearchResult, total int64, err error)
|
||||||
ParseSearchPluginResult(ctx context.Context, sres []plugin.SearchResult) (resp []schema.SearchResult, err error)
|
ParseSearchPluginResult(ctx context.Context, sres []plugin.SearchResult) (resp []*schema.SearchResult, err error)
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@ package search_parser
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"fmt"
|
||||||
"github.com/answerdev/answer/internal/base/constant"
|
"github.com/answerdev/answer/internal/base/constant"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
|
@ -105,8 +106,12 @@ func (sp *SearchParser) parseTags(ctx context.Context, query *string) (tags []st
|
||||||
if err != nil || !exists {
|
if err != nil || !exists {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
if tag.MainTagID > 0 {
|
||||||
|
tags = append(tags, fmt.Sprintf("%d", tag.MainTagID))
|
||||||
|
} else {
|
||||||
tags = append(tags, tag.ID)
|
tags = append(tags, tag.ID)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// limit maximum 5 tags
|
// limit maximum 5 tags
|
||||||
if len(tags) > limit {
|
if len(tags) > limit {
|
||||||
|
|
|
@ -24,7 +24,7 @@ type TagCommonRepo interface {
|
||||||
AddTagList(ctx context.Context, tagList []*entity.Tag) (err error)
|
AddTagList(ctx context.Context, tagList []*entity.Tag) (err error)
|
||||||
GetTagListByIDs(ctx context.Context, ids []string) (tagList []*entity.Tag, err error)
|
GetTagListByIDs(ctx context.Context, ids []string) (tagList []*entity.Tag, err error)
|
||||||
GetTagBySlugName(ctx context.Context, slugName string) (tagInfo *entity.Tag, exist bool, err error)
|
GetTagBySlugName(ctx context.Context, slugName string) (tagInfo *entity.Tag, exist bool, err error)
|
||||||
GetTagListByName(ctx context.Context, name string, hasReserved bool) (tagList []*entity.Tag, err error)
|
GetTagListByName(ctx context.Context, name string, recommend, reserved bool) (tagList []*entity.Tag, err error)
|
||||||
GetTagListByNames(ctx context.Context, names []string) (tagList []*entity.Tag, err error)
|
GetTagListByNames(ctx context.Context, names []string) (tagList []*entity.Tag, err error)
|
||||||
GetTagByID(ctx context.Context, tagID string, includeDeleted bool) (tag *entity.Tag, exist bool, err error)
|
GetTagByID(ctx context.Context, tagID string, includeDeleted bool) (tag *entity.Tag, exist bool, err error)
|
||||||
GetTagPage(ctx context.Context, page, pageSize int, tag *entity.Tag, queryCond string) (tagList []*entity.Tag, total int64, err error)
|
GetTagPage(ctx context.Context, page, pageSize int, tag *entity.Tag, queryCond string) (tagList []*entity.Tag, total int64, err error)
|
||||||
|
@ -86,7 +86,7 @@ func NewTagCommonService(
|
||||||
|
|
||||||
// SearchTagLike get tag list all
|
// SearchTagLike get tag list all
|
||||||
func (ts *TagCommonService) SearchTagLike(ctx context.Context, req *schema.SearchTagLikeReq) (resp []schema.SearchTagLikeResp, err error) {
|
func (ts *TagCommonService) SearchTagLike(ctx context.Context, req *schema.SearchTagLikeReq) (resp []schema.SearchTagLikeResp, err error) {
|
||||||
tags, err := ts.tagCommonRepo.GetTagListByName(ctx, req.Tag, req.IsAdmin)
|
tags, err := ts.tagCommonRepo.GetTagListByName(ctx, req.Tag, len(req.Tag) == 0, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -97,35 +97,39 @@ func (ts *TagCommonService) SearchTagLike(ctx context.Context, req *schema.Searc
|
||||||
mainTagId = append(mainTagId, converter.IntToString(tag.MainTagID))
|
mainTagId = append(mainTagId, converter.IntToString(tag.MainTagID))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
mainTagMap := make(map[string]*entity.Tag)
|
||||||
|
if len(mainTagId) > 0 {
|
||||||
mainTagList, err := ts.tagCommonRepo.GetTagListByIDs(ctx, mainTagId)
|
mainTagList, err := ts.tagCommonRepo.GetTagListByIDs(ctx, mainTagId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return nil, err
|
||||||
}
|
}
|
||||||
mainTagMap := make(map[string]*entity.Tag)
|
|
||||||
for _, tag := range mainTagList {
|
for _, tag := range mainTagList {
|
||||||
mainTagMap[tag.ID] = tag
|
mainTagMap[tag.ID] = tag
|
||||||
}
|
}
|
||||||
|
}
|
||||||
for _, tag := range tags {
|
for _, tag := range tags {
|
||||||
if tag.MainTagID != 0 {
|
if tag.MainTagID == 0 {
|
||||||
_, ok := mainTagMap[converter.IntToString(tag.MainTagID)]
|
continue
|
||||||
if ok {
|
}
|
||||||
tag.SlugName = mainTagMap[converter.IntToString(tag.MainTagID)].SlugName
|
mainTagID := converter.IntToString(tag.MainTagID)
|
||||||
tag.DisplayName = mainTagMap[converter.IntToString(tag.MainTagID)].DisplayName
|
if _, ok := mainTagMap[mainTagID]; ok {
|
||||||
tag.Reserved = mainTagMap[converter.IntToString(tag.MainTagID)].Reserved
|
tag.SlugName = mainTagMap[mainTagID].SlugName
|
||||||
tag.Recommend = mainTagMap[converter.IntToString(tag.MainTagID)].Recommend
|
tag.DisplayName = mainTagMap[mainTagID].DisplayName
|
||||||
|
tag.Reserved = mainTagMap[mainTagID].Reserved
|
||||||
|
tag.Recommend = mainTagMap[mainTagID].Recommend
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
resp = make([]schema.SearchTagLikeResp, 0)
|
||||||
RepetitiveTag := make(map[string]bool)
|
repetitiveTag := make(map[string]bool)
|
||||||
for _, tag := range tags {
|
for _, tag := range tags {
|
||||||
if _, ok := RepetitiveTag[tag.SlugName]; !ok {
|
if _, ok := repetitiveTag[tag.SlugName]; !ok {
|
||||||
item := schema.SearchTagLikeResp{}
|
item := schema.SearchTagLikeResp{}
|
||||||
item.SlugName = tag.SlugName
|
item.SlugName = tag.SlugName
|
||||||
item.DisplayName = tag.DisplayName
|
item.DisplayName = tag.DisplayName
|
||||||
item.Recommend = tag.Recommend
|
item.Recommend = tag.Recommend
|
||||||
item.Reserved = tag.Reserved
|
item.Reserved = tag.Reserved
|
||||||
resp = append(resp, item)
|
resp = append(resp, item)
|
||||||
RepetitiveTag[tag.SlugName] = true
|
repetitiveTag[tag.SlugName] = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return resp, nil
|
return resp, nil
|
||||||
|
@ -432,6 +436,9 @@ func (ts *TagCommonService) tagFormatRecommendAndReserved(ctx context.Context, t
|
||||||
// BatchGetObjectTag batch get object tag
|
// BatchGetObjectTag batch get object tag
|
||||||
func (ts *TagCommonService) BatchGetObjectTag(ctx context.Context, objectIds []string) (map[string][]*schema.TagResp, error) {
|
func (ts *TagCommonService) BatchGetObjectTag(ctx context.Context, objectIds []string) (map[string][]*schema.TagResp, error) {
|
||||||
objectIDTagMap := make(map[string][]*schema.TagResp)
|
objectIDTagMap := make(map[string][]*schema.TagResp)
|
||||||
|
if len(objectIds) == 0 {
|
||||||
|
return objectIDTagMap, nil
|
||||||
|
}
|
||||||
objectTagRelList, err := ts.tagRelRepo.BatchGetObjectTagRelList(ctx, objectIds)
|
objectTagRelList, err := ts.tagRelRepo.BatchGetObjectTagRelList(ctx, objectIds)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return objectIDTagMap, err
|
return objectIDTagMap, err
|
||||||
|
|
|
@ -106,9 +106,12 @@ func (us *UserCommon) UpdateQuestionCount(ctx context.Context, userID string, nu
|
||||||
return us.userRepo.UpdateQuestionCount(ctx, userID, num)
|
return us.userRepo.UpdateQuestionCount(ctx, userID, num)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (us *UserCommon) BatchUserBasicInfoByID(ctx context.Context, IDs []string) (map[string]*schema.UserBasicInfo, error) {
|
func (us *UserCommon) BatchUserBasicInfoByID(ctx context.Context, userIDs []string) (map[string]*schema.UserBasicInfo, error) {
|
||||||
userMap := make(map[string]*schema.UserBasicInfo)
|
userMap := make(map[string]*schema.UserBasicInfo)
|
||||||
userList, err := us.userRepo.BatchGetByID(ctx, IDs)
|
if len(userIDs) == 0 {
|
||||||
|
return userMap, nil
|
||||||
|
}
|
||||||
|
userList, err := us.userRepo.BatchGetByID(ctx, userIDs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return userMap, err
|
return userMap, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
type UserNotificationConfigRepo interface {
|
type UserNotificationConfigRepo interface {
|
||||||
|
Add(ctx context.Context, userIDs []string, source, channels string) (err error)
|
||||||
Save(ctx context.Context, uc *entity.UserNotificationConfig) (err error)
|
Save(ctx context.Context, uc *entity.UserNotificationConfig) (err error)
|
||||||
GetByUserID(ctx context.Context, userID string) ([]*entity.UserNotificationConfig, error)
|
GetByUserID(ctx context.Context, userID string) ([]*entity.UserNotificationConfig, error)
|
||||||
GetBySource(ctx context.Context, source constant.NotificationSource) ([]*entity.UserNotificationConfig, error)
|
GetBySource(ctx context.Context, source constant.NotificationSource) ([]*entity.UserNotificationConfig, error)
|
||||||
|
@ -68,6 +69,13 @@ func (us *UserNotificationConfigService) UpdateUserNotificationConfig(
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetDefaultUserNotificationConfig set default user notification config for user register
|
||||||
|
func (us *UserNotificationConfigService) SetDefaultUserNotificationConfig(ctx context.Context, userIDs []string) (
|
||||||
|
err error) {
|
||||||
|
return us.userNotificationConfigRepo.Add(ctx, userIDs,
|
||||||
|
string(constant.InboxSource), `[{"key":"email","enable":true}]`)
|
||||||
|
}
|
||||||
|
|
||||||
func (us *UserNotificationConfigService) convertToEntity(ctx context.Context, userID string,
|
func (us *UserNotificationConfigService) convertToEntity(ctx context.Context, userID string,
|
||||||
source constant.NotificationSource, channels schema.NotificationChannels) (c *entity.UserNotificationConfig) {
|
source constant.NotificationSource, channels schema.NotificationChannels) (c *entity.UserNotificationConfig) {
|
||||||
c = &entity.UserNotificationConfig{
|
c = &entity.UserNotificationConfig{
|
||||||
|
|
|
@ -42,6 +42,7 @@ type UserService struct {
|
||||||
userRoleService *role.UserRoleRelService
|
userRoleService *role.UserRoleRelService
|
||||||
userExternalLoginService *user_external_login.UserExternalLoginService
|
userExternalLoginService *user_external_login.UserExternalLoginService
|
||||||
userNotificationConfigRepo user_notification_config.UserNotificationConfigRepo
|
userNotificationConfigRepo user_notification_config.UserNotificationConfigRepo
|
||||||
|
userNotificationConfigService *user_notification_config.UserNotificationConfigService
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewUserService(userRepo usercommon.UserRepo,
|
func NewUserService(userRepo usercommon.UserRepo,
|
||||||
|
@ -54,6 +55,7 @@ func NewUserService(userRepo usercommon.UserRepo,
|
||||||
userCommonService *usercommon.UserCommon,
|
userCommonService *usercommon.UserCommon,
|
||||||
userExternalLoginService *user_external_login.UserExternalLoginService,
|
userExternalLoginService *user_external_login.UserExternalLoginService,
|
||||||
userNotificationConfigRepo user_notification_config.UserNotificationConfigRepo,
|
userNotificationConfigRepo user_notification_config.UserNotificationConfigRepo,
|
||||||
|
userNotificationConfigService *user_notification_config.UserNotificationConfigService,
|
||||||
) *UserService {
|
) *UserService {
|
||||||
return &UserService{
|
return &UserService{
|
||||||
userCommonService: userCommonService,
|
userCommonService: userCommonService,
|
||||||
|
@ -66,6 +68,7 @@ func NewUserService(userRepo usercommon.UserRepo,
|
||||||
userRoleService: userRoleService,
|
userRoleService: userRoleService,
|
||||||
userExternalLoginService: userExternalLoginService,
|
userExternalLoginService: userExternalLoginService,
|
||||||
userNotificationConfigRepo: userNotificationConfigRepo,
|
userNotificationConfigRepo: userNotificationConfigRepo,
|
||||||
|
userNotificationConfigService: userNotificationConfigService,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -398,6 +401,9 @@ func (us *UserService) UserRegisterByEmail(ctx context.Context, registerUserInfo
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
if err := us.userNotificationConfigService.SetDefaultUserNotificationConfig(ctx, []string{userInfo.ID}); err != nil {
|
||||||
|
log.Errorf("set default user notification config failed, err: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
// send email
|
// send email
|
||||||
data := &schema.EmailCodeContent{
|
data := &schema.EmailCodeContent{
|
||||||
|
|
|
@ -12,6 +12,7 @@ interface Props {
|
||||||
avatarSearchStr?: string;
|
avatarSearchStr?: string;
|
||||||
className?: string;
|
className?: string;
|
||||||
avatarClass?: string;
|
avatarClass?: string;
|
||||||
|
nameMaxWidth?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Index: FC<Props> = ({
|
const Index: FC<Props> = ({
|
||||||
|
@ -22,11 +23,14 @@ const Index: FC<Props> = ({
|
||||||
className = 'small',
|
className = 'small',
|
||||||
avatarSearchStr = 's=48',
|
avatarSearchStr = 's=48',
|
||||||
showReputation = true,
|
showReputation = true,
|
||||||
|
nameMaxWidth = '300px',
|
||||||
}) => {
|
}) => {
|
||||||
return (
|
return (
|
||||||
<div className={`d-flex align-items-center text-secondary ${className}`}>
|
<div className={`d-flex align-items-center text-secondary ${className}`}>
|
||||||
{data?.status !== 'deleted' ? (
|
{data?.status !== 'deleted' ? (
|
||||||
<Link to={`/users/${data?.username}`}>
|
<Link
|
||||||
|
to={`/users/${data?.username}`}
|
||||||
|
className="d-flex align-items-center">
|
||||||
{showAvatar && (
|
{showAvatar && (
|
||||||
<Avatar
|
<Avatar
|
||||||
avatar={data?.avatar}
|
avatar={data?.avatar}
|
||||||
|
@ -36,7 +40,9 @@ const Index: FC<Props> = ({
|
||||||
alt={data?.display_name}
|
alt={data?.display_name}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
<span className="me-1 text-truncate-1" style={{ maxWidth: '300px' }}>
|
<span
|
||||||
|
className="me-1 name-ellipsis"
|
||||||
|
style={{ maxWidth: nameMaxWidth }}>
|
||||||
{data?.display_name}
|
{data?.display_name}
|
||||||
</span>
|
</span>
|
||||||
</Link>
|
</Link>
|
||||||
|
@ -51,9 +57,7 @@ const Index: FC<Props> = ({
|
||||||
alt={data?.display_name}
|
alt={data?.display_name}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
<span className="me-1 text-truncate-1" style={{ maxWidth: '300px' }}>
|
<span className="me-1 name-ellipsis">{data?.display_name}</span>
|
||||||
{data?.display_name}
|
|
||||||
</span>
|
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { FC, useContext, useEffect } from 'react';
|
import { FC, useContext, useEffect } from 'react';
|
||||||
import { Dropdown, OverlayTrigger, Tooltip, Button } from 'react-bootstrap';
|
import { Dropdown, Button } from 'react-bootstrap';
|
||||||
|
|
||||||
import { EditorContext } from './EditorContext';
|
import { EditorContext } from './EditorContext';
|
||||||
|
|
||||||
|
@ -49,9 +49,9 @@ const ToolItem: FC<IProps> = (props) => {
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const btnRender = () => (
|
const btnRender = () => (
|
||||||
<OverlayTrigger placement="bottom" overlay={<Tooltip>{tip}</Tooltip>}>
|
|
||||||
<Button
|
<Button
|
||||||
variant="link"
|
variant="link"
|
||||||
|
title={tip}
|
||||||
className={`p-0 b-0 btn-no-border toolbar icon-${label} ${
|
className={`p-0 b-0 btn-no-border toolbar icon-${label} ${
|
||||||
disable ? 'disabled' : ''
|
disable ? 'disabled' : ''
|
||||||
} `}
|
} `}
|
||||||
|
@ -70,7 +70,6 @@ const ToolItem: FC<IProps> = (props) => {
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</OverlayTrigger>
|
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!context) {
|
if (!context) {
|
||||||
|
|
|
@ -141,6 +141,13 @@ img[src=""] {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.name-ellipsis {
|
||||||
|
display: inline-block;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
.text-truncate-1,
|
.text-truncate-1,
|
||||||
.text-truncate-2,
|
.text-truncate-2,
|
||||||
.text-truncate-3,
|
.text-truncate-3,
|
||||||
|
|
|
@ -155,7 +155,7 @@ const Answers: FC = () => {
|
||||||
<td>{li.vote_count}</td>
|
<td>{li.vote_count}</td>
|
||||||
<td>
|
<td>
|
||||||
<Stack>
|
<Stack>
|
||||||
<BaseUserCard data={li.user_info} />
|
<BaseUserCard data={li.user_info} nameMaxWidth="200px" />
|
||||||
|
|
||||||
<FormatTime
|
<FormatTime
|
||||||
className="small text-secondary"
|
className="small text-secondary"
|
||||||
|
|
|
@ -160,7 +160,7 @@ const Questions: FC = () => {
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<Stack>
|
<Stack>
|
||||||
<BaseUserCard data={li.user_info} />
|
<BaseUserCard data={li.user_info} nameMaxWidth="130px" />
|
||||||
<FormatTime
|
<FormatTime
|
||||||
className="small text-secondary"
|
className="small text-secondary"
|
||||||
time={li.create_time}
|
time={li.create_time}
|
||||||
|
|
|
@ -6,6 +6,7 @@ import { getSeoSetting, putSeoSetting } from '@/services';
|
||||||
import { SchemaForm, JSONSchema, initFormData, UISchema } from '@/components';
|
import { SchemaForm, JSONSchema, initFormData, UISchema } from '@/components';
|
||||||
import { useToast } from '@/hooks';
|
import { useToast } from '@/hooks';
|
||||||
import { handleFormError } from '@/utils';
|
import { handleFormError } from '@/utils';
|
||||||
|
import { seoSettingStore } from '@/stores';
|
||||||
|
|
||||||
const Index: FC = () => {
|
const Index: FC = () => {
|
||||||
const { t } = useTranslation('translation', {
|
const { t } = useTranslation('translation', {
|
||||||
|
@ -64,6 +65,7 @@ const Index: FC = () => {
|
||||||
msg: t('update', { keyPrefix: 'toast' }),
|
msg: t('update', { keyPrefix: 'toast' }),
|
||||||
variant: 'success',
|
variant: 'success',
|
||||||
});
|
});
|
||||||
|
seoSettingStore.getState().update(reqParams);
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
if (err.isError) {
|
if (err.isError) {
|
||||||
|
|
|
@ -254,6 +254,7 @@ const Users: FC = () => {
|
||||||
avatarSearchStr="s=48"
|
avatarSearchStr="s=48"
|
||||||
avatarClass="me-2"
|
avatarClass="me-2"
|
||||||
showReputation={false}
|
showReputation={false}
|
||||||
|
nameMaxWidth="160px"
|
||||||
/>
|
/>
|
||||||
</td>
|
</td>
|
||||||
<td>{formatCount(user.rank)}</td>
|
<td>{formatCount(user.rank)}</td>
|
||||||
|
|
|
@ -28,6 +28,15 @@ const Index: FC<Props> = ({ visible, data, changeCallback, nextCallback }) => {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (site_name.value && site_name.value.length > 30) {
|
||||||
|
bol = false;
|
||||||
|
data.site_url = {
|
||||||
|
value: site_name.value,
|
||||||
|
isInvalid: true,
|
||||||
|
errorMsg: t('site_name.msg_max_length'),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
if (!site_url.value) {
|
if (!site_url.value) {
|
||||||
bol = false;
|
bol = false;
|
||||||
data.site_url = {
|
data.site_url = {
|
||||||
|
@ -36,6 +45,7 @@ const Index: FC<Props> = ({ visible, data, changeCallback, nextCallback }) => {
|
||||||
errorMsg: t('site_name.msg.empty'),
|
errorMsg: t('site_name.msg.empty'),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const reg = /^(http|https):\/\//g;
|
const reg = /^(http|https):\/\//g;
|
||||||
if (site_url.value && !site_url.value.match(reg)) {
|
if (site_url.value && !site_url.value.match(reg)) {
|
||||||
bol = false;
|
bol = false;
|
||||||
|
@ -44,6 +54,13 @@ const Index: FC<Props> = ({ visible, data, changeCallback, nextCallback }) => {
|
||||||
isInvalid: true,
|
isInvalid: true,
|
||||||
errorMsg: t('site_url.msg.incorrect'),
|
errorMsg: t('site_url.msg.incorrect'),
|
||||||
};
|
};
|
||||||
|
} else if (site_url.value.length > 512) {
|
||||||
|
bol = false;
|
||||||
|
data.site_url = {
|
||||||
|
value: site_url.value,
|
||||||
|
isInvalid: true,
|
||||||
|
errorMsg: t('site_url.msg.max_length'),
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!contact_email.value) {
|
if (!contact_email.value) {
|
||||||
|
@ -78,6 +95,13 @@ const Index: FC<Props> = ({ visible, data, changeCallback, nextCallback }) => {
|
||||||
isInvalid: true,
|
isInvalid: true,
|
||||||
errorMsg: t('admin_name.character'),
|
errorMsg: t('admin_name.character'),
|
||||||
};
|
};
|
||||||
|
} else if (data.name.value.length > 30) {
|
||||||
|
bol = false;
|
||||||
|
data.name = {
|
||||||
|
value: data.name.value,
|
||||||
|
isInvalid: true,
|
||||||
|
errorMsg: t('admin_name.msg_max_length'),
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!password.value) {
|
if (!password.value) {
|
||||||
|
@ -89,6 +113,24 @@ const Index: FC<Props> = ({ visible, data, changeCallback, nextCallback }) => {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (password.value && password.value.length < 4) {
|
||||||
|
bol = false;
|
||||||
|
data.password = {
|
||||||
|
value: data.password.value,
|
||||||
|
isInvalid: true,
|
||||||
|
errorMsg: t('admin_password.msg_min_length'),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (password.value && password.value.length > 32) {
|
||||||
|
bol = false;
|
||||||
|
data.password = {
|
||||||
|
value: data.password.value,
|
||||||
|
isInvalid: true,
|
||||||
|
errorMsg: t('admin_password.msg_max_length'),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
if (!email.value) {
|
if (!email.value) {
|
||||||
bol = false;
|
bol = false;
|
||||||
data.email = {
|
data.email = {
|
||||||
|
@ -132,7 +174,6 @@ const Index: FC<Props> = ({ visible, data, changeCallback, nextCallback }) => {
|
||||||
required
|
required
|
||||||
value={data.site_name.value}
|
value={data.site_name.value}
|
||||||
isInvalid={data.site_name.isInvalid}
|
isInvalid={data.site_name.isInvalid}
|
||||||
maxLength={30}
|
|
||||||
onChange={(e) => {
|
onChange={(e) => {
|
||||||
changeCallback({
|
changeCallback({
|
||||||
site_name: {
|
site_name: {
|
||||||
|
@ -153,7 +194,6 @@ const Index: FC<Props> = ({ visible, data, changeCallback, nextCallback }) => {
|
||||||
required
|
required
|
||||||
value={data.site_url.value}
|
value={data.site_url.value}
|
||||||
isInvalid={data.site_url.isInvalid}
|
isInvalid={data.site_url.isInvalid}
|
||||||
maxLength={512}
|
|
||||||
onChange={(e) => {
|
onChange={(e) => {
|
||||||
changeCallback({
|
changeCallback({
|
||||||
site_url: {
|
site_url: {
|
||||||
|
@ -220,7 +260,6 @@ const Index: FC<Props> = ({ visible, data, changeCallback, nextCallback }) => {
|
||||||
required
|
required
|
||||||
value={data.name.value}
|
value={data.name.value}
|
||||||
isInvalid={data.name.isInvalid}
|
isInvalid={data.name.isInvalid}
|
||||||
maxLength={30}
|
|
||||||
onChange={(e) => {
|
onChange={(e) => {
|
||||||
changeCallback({
|
changeCallback({
|
||||||
name: {
|
name: {
|
||||||
|
@ -241,7 +280,6 @@ const Index: FC<Props> = ({ visible, data, changeCallback, nextCallback }) => {
|
||||||
<Form.Control
|
<Form.Control
|
||||||
required
|
required
|
||||||
type="password"
|
type="password"
|
||||||
maxLength={32}
|
|
||||||
value={data.password.value}
|
value={data.password.value}
|
||||||
isInvalid={data.password.isInvalid}
|
isInvalid={data.password.isInvalid}
|
||||||
onChange={(e) => {
|
onChange={(e) => {
|
||||||
|
|
|
@ -23,7 +23,7 @@ import {
|
||||||
|
|
||||||
const Index: FC = () => {
|
const Index: FC = () => {
|
||||||
const { t } = useTranslation('translation', { keyPrefix: 'install' });
|
const { t } = useTranslation('translation', { keyPrefix: 'install' });
|
||||||
const [step, setStep] = useState(1);
|
const [step, setStep] = useState(4);
|
||||||
const [loading, setLoading] = useState(true);
|
const [loading, setLoading] = useState(true);
|
||||||
const [errorData, setErrorData] = useState<{ [propName: string]: any }>({
|
const [errorData, setErrorData] = useState<{ [propName: string]: any }>({
|
||||||
msg: '',
|
msg: '',
|
||||||
|
|
|
@ -27,7 +27,7 @@ const SearchQuestion = ({ similarQuestions }) => {
|
||||||
<ListGroup.Item
|
<ListGroup.Item
|
||||||
action
|
action
|
||||||
as="a"
|
as="a"
|
||||||
className="link-dark"
|
className="d-flex align-items-center link-dark"
|
||||||
key={item.id}
|
key={item.id}
|
||||||
href={pathFactory.questionLanding(item.id, item.url_title)}
|
href={pathFactory.questionLanding(item.id, item.url_title)}
|
||||||
target="_blank">
|
target="_blank">
|
||||||
|
@ -38,20 +38,24 @@ const SearchQuestion = ({ similarQuestions }) => {
|
||||||
: null}
|
: null}
|
||||||
</span>
|
</span>
|
||||||
{item.accepted_answer ? (
|
{item.accepted_answer ? (
|
||||||
<span className="ms-3 text-success">
|
<span className="small ms-3 text-success">
|
||||||
<Icon type="bi" name="check-circle-fill" />
|
<Icon type="bi" name="check-circle-fill" />
|
||||||
<span className="ms-1">{item.answer_count}</span>
|
<span className="ms-1">
|
||||||
|
{t('x_answers', {
|
||||||
|
keyPrefix: 'question',
|
||||||
|
count: item.answer_count,
|
||||||
|
})}
|
||||||
|
</span>
|
||||||
</span>
|
</span>
|
||||||
) : (
|
) : (
|
||||||
item.answer_count > 0 && (
|
item.answer_count > 0 && (
|
||||||
<span className="ms-3">
|
<span className="small ms-3 text-secondary">
|
||||||
<Icon
|
<Icon type="bi" name="chat-square-text-fill" />
|
||||||
type="bi"
|
<span className="ms-1">
|
||||||
name="chat-square-text-fill"
|
{t('x_answers', {
|
||||||
className="text-secondary"
|
keyPrefix: 'question',
|
||||||
/>
|
count: item.answer_count,
|
||||||
<span className="ms-1 text-primary">
|
})}
|
||||||
{item.answer_count}
|
|
||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
)
|
)
|
||||||
|
|
|
@ -108,7 +108,7 @@ const Index: FC = () => {
|
||||||
return (
|
return (
|
||||||
<Row className="pt-4 mb-5">
|
<Row className="pt-4 mb-5">
|
||||||
<Col className="page-main flex-auto">
|
<Col className="page-main flex-auto">
|
||||||
{isLoading || listLoading ? (
|
{isLoading ? (
|
||||||
<div className="tag-box mb-5 placeholder-glow">
|
<div className="tag-box mb-5 placeholder-glow">
|
||||||
<div className="mb-3 h3 placeholder" style={{ width: '120px' }} />
|
<div className="mb-3 h3 placeholder" style={{ width: '120px' }} />
|
||||||
<p
|
<p
|
||||||
|
|
|
@ -187,7 +187,6 @@ const Index: React.FC = () => {
|
||||||
tabIndex={1}
|
tabIndex={1}
|
||||||
type="password"
|
type="password"
|
||||||
// value={formData.pass.value}
|
// value={formData.pass.value}
|
||||||
maxLength={32}
|
|
||||||
isInvalid={formData.pass.isInvalid}
|
isInvalid={formData.pass.isInvalid}
|
||||||
onChange={(e) =>
|
onChange={(e) =>
|
||||||
handleChange({
|
handleChange({
|
||||||
|
|
|
@ -127,7 +127,6 @@ const Index: React.FC = () => {
|
||||||
autoComplete="off"
|
autoComplete="off"
|
||||||
required
|
required
|
||||||
type="password"
|
type="password"
|
||||||
maxLength={32}
|
|
||||||
isInvalid={formData.pass.isInvalid}
|
isInvalid={formData.pass.isInvalid}
|
||||||
onChange={(e) => {
|
onChange={(e) => {
|
||||||
handleChange({
|
handleChange({
|
||||||
|
@ -150,7 +149,6 @@ const Index: React.FC = () => {
|
||||||
autoComplete="off"
|
autoComplete="off"
|
||||||
required
|
required
|
||||||
type="password"
|
type="password"
|
||||||
maxLength={32}
|
|
||||||
isInvalid={formData.passSecond.isInvalid}
|
isInvalid={formData.passSecond.isInvalid}
|
||||||
onChange={(e) => {
|
onChange={(e) => {
|
||||||
handleChange({
|
handleChange({
|
||||||
|
|
|
@ -184,7 +184,6 @@ const Index: React.FC<Props> = ({ callback }) => {
|
||||||
autoComplete="off"
|
autoComplete="off"
|
||||||
required
|
required
|
||||||
type="password"
|
type="password"
|
||||||
maxLength={32}
|
|
||||||
isInvalid={formData.pass.isInvalid}
|
isInvalid={formData.pass.isInvalid}
|
||||||
value={formData.pass.value}
|
value={formData.pass.value}
|
||||||
onChange={(e) =>
|
onChange={(e) =>
|
||||||
|
|
|
@ -158,7 +158,6 @@ const Index: FC = () => {
|
||||||
autoComplete="new-password"
|
autoComplete="new-password"
|
||||||
required
|
required
|
||||||
type="password"
|
type="password"
|
||||||
maxLength={32}
|
|
||||||
isInvalid={formData.pass.isInvalid}
|
isInvalid={formData.pass.isInvalid}
|
||||||
onChange={(e) =>
|
onChange={(e) =>
|
||||||
handleChange({
|
handleChange({
|
||||||
|
|
|
@ -185,7 +185,6 @@ const Index: FC = () => {
|
||||||
autoComplete="off"
|
autoComplete="off"
|
||||||
required
|
required
|
||||||
type="password"
|
type="password"
|
||||||
maxLength={32}
|
|
||||||
isInvalid={formData.pass.isInvalid}
|
isInvalid={formData.pass.isInvalid}
|
||||||
onChange={(e) =>
|
onChange={(e) =>
|
||||||
handleChange({
|
handleChange({
|
||||||
|
@ -208,7 +207,6 @@ const Index: FC = () => {
|
||||||
autoComplete="off"
|
autoComplete="off"
|
||||||
required
|
required
|
||||||
type="password"
|
type="password"
|
||||||
maxLength={32}
|
|
||||||
isInvalid={formData.pass2.isInvalid}
|
isInvalid={formData.pass2.isInvalid}
|
||||||
onChange={(e) =>
|
onChange={(e) =>
|
||||||
handleChange({
|
handleChange({
|
||||||
|
|
|
@ -72,7 +72,9 @@ export const addComment = (params) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
export const queryTags = (tag: string) => {
|
export const queryTags = (tag: string) => {
|
||||||
return request.get(`/answer/api/v1/question/tags?tag=${tag}`);
|
return request.get(
|
||||||
|
`/answer/api/v1/question/tags?tag=${encodeURIComponent(tag)}`,
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const useQueryAnswerInfo = (id: string) => {
|
export const useQueryAnswerInfo = (id: string) => {
|
||||||
|
|
Loading…
Reference in New Issue