mirror of https://gitee.com/answerdev/answer.git
Merge branch 'main' into 'fix/typo'
# Conflicts: # ui/src/i18n/locales/en.json
This commit is contained in:
commit
e8a5677b26
|
@ -21,4 +21,5 @@ Thumbs*.db
|
|||
tmp
|
||||
vendor/
|
||||
.husky
|
||||
answer-data/
|
||||
/answer-data/
|
||||
/answer
|
||||
|
|
|
@ -1,4 +1,8 @@
|
|||
# Contributing to answer
|
||||
## Coding and documentation Style
|
||||
|
||||
To be developed.
|
||||
|
||||
## Submitting Modifications
|
||||
|
||||
To be developed.
|
||||
|
|
54
Dockerfile
54
Dockerfile
|
@ -6,40 +6,54 @@ COPY . /answer
|
|||
WORKDIR /answer
|
||||
RUN make install-ui-packages ui && mv ui/build /tmp
|
||||
|
||||
FROM golang:1.18 AS golang-builder
|
||||
LABEL maintainer="aichy"
|
||||
# stage2 build the main binary within static resource
|
||||
FROM golang:1.19-alpine AS golang-builder
|
||||
LABEL maintainer="aichy@sf.com"
|
||||
|
||||
ARG GOPROXY
|
||||
ENV GOPROXY ${GOPROXY:-direct}
|
||||
|
||||
ENV GOPATH /go
|
||||
ENV GOROOT /usr/local/go
|
||||
ENV PACKAGE github.com/answerdev/answer
|
||||
ENV GOPROXY https://goproxy.cn,direct
|
||||
ENV BUILD_DIR ${GOPATH}/src/${PACKAGE}
|
||||
# Build
|
||||
|
||||
ARG TAGS="sqlite sqlite_unlock_notify"
|
||||
ENV TAGS "bindata timetzdata $TAGS"
|
||||
ARG CGO_EXTRA_CFLAGS
|
||||
|
||||
COPY . ${BUILD_DIR}
|
||||
WORKDIR ${BUILD_DIR}
|
||||
COPY --from=node-builder /tmp/build ${BUILD_DIR}/ui/build
|
||||
RUN make clean build && \
|
||||
cp answer /usr/bin/answer && \
|
||||
mkdir -p /data/upfiles && chmod 777 /data/upfiles && \
|
||||
mkdir -p /data/i18n && chmod 777 /data/i18n && cp -r i18n/*.yaml /data/i18n
|
||||
RUN apk --no-cache add build-base git \
|
||||
&& make clean build \
|
||||
&& cp answer /usr/bin/answer
|
||||
|
||||
RUN mkdir -p /data/upfiles && chmod 777 /data/upfiles \
|
||||
&& mkdir -p /data/i18n && cp -r i18n/*.yaml /data/i18n
|
||||
|
||||
# stage3 copy the binary and resource files into fresh container
|
||||
FROM alpine
|
||||
LABEL maintainer="maintainers@sf.com"
|
||||
|
||||
FROM debian:bullseye
|
||||
ENV TZ "Asia/Shanghai"
|
||||
RUN sed -i 's/deb.debian.org/mirrors.tuna.tsinghua.edu.cn/g' /etc/apt/sources.list \
|
||||
&& sed -i 's/security.debian.org/mirrors.tuna.tsinghua.edu.cn/g' /etc/apt/sources.list \
|
||||
&& echo "Asia/Shanghai" > /etc/timezone \
|
||||
&& apt -y update \
|
||||
&& apt -y upgrade \
|
||||
&& apt -y install ca-certificates openssl tzdata curl netcat dumb-init \
|
||||
&& apt -y autoremove \
|
||||
&& mkdir -p /tmp/cache
|
||||
|
||||
COPY --from=golang-builder /data /data
|
||||
VOLUME /data
|
||||
RUN apk update \
|
||||
&& apk --no-cache add \
|
||||
bash \
|
||||
ca-certificates \
|
||||
curl \
|
||||
dumb-init \
|
||||
gettext \
|
||||
openssh \
|
||||
sqlite \
|
||||
gnupg \
|
||||
&& echo "Asia/Shanghai" > /etc/timezone
|
||||
|
||||
COPY --from=golang-builder /usr/bin/answer /usr/bin/answer
|
||||
COPY --from=golang-builder /data /data
|
||||
COPY /script/entrypoint.sh /entrypoint.sh
|
||||
RUN chmod 755 /entrypoint.sh
|
||||
|
||||
VOLUME /data
|
||||
EXPOSE 80
|
||||
ENTRYPOINT ["/entrypoint.sh"]
|
||||
|
|
54
INSTALL.md
54
INSTALL.md
|
@ -6,9 +6,9 @@ Before installing Answer, you need to install the base environment first.
|
|||
|
||||
You can then install Answer in several ways:
|
||||
|
||||
- Deploy with Docker
|
||||
- binary installation
|
||||
- Source installation
|
||||
- [Deploy with Docker](#Docker-compose-for-Answer)
|
||||
- [Binary installation](#Install-Answer-using-binary)
|
||||
- [Source installation](#Compile-the-image)
|
||||
|
||||
## Docker-compose for Answer
|
||||
```bash
|
||||
|
@ -17,15 +17,15 @@ $ wget https://raw.githubusercontent.com/answerdev/answer/main/docker-compose.ya
|
|||
$ docker-compose up
|
||||
```
|
||||
|
||||
browser open URL [http://127.0.0.1:9080/](http://127.0.0.1:9080/).
|
||||
In browser, open URL [http://127.0.0.1:9080/](http://127.0.0.1:9080/).
|
||||
|
||||
You can log in with the default administrator username( **`admin@admin.com`** ) and password( **`admin`** ).
|
||||
You can log in with the default administrator username (**`admin@admin.com`**) and password (**`admin`**).
|
||||
|
||||
## Docker for Answer
|
||||
Visit Docker Hub or GitHub Container registry to see all available images and tags.
|
||||
Visit [Docker Hub](https://hub.docker.com/r/answerdev/answer) or GitHub Container registry to see all available images and tags.
|
||||
|
||||
### Usage
|
||||
To keep your data out of Docker container, we do a volume (/var/data -> /data) here, and you can change it based on your situation.
|
||||
To persist data beyond the life of a Docker container, use a volume (/var/data -> /data). You can modify this based on your situation.
|
||||
|
||||
```
|
||||
# Pull image from Docker Hub.
|
||||
|
@ -35,9 +35,9 @@ $ docker pull answerdev/answer:latest
|
|||
$ mkdir -p /var/data
|
||||
|
||||
# Run the image first
|
||||
$ docker run --name=answer -p 9080:80 -v /var/data:/data answer/answer
|
||||
$ docker run --name=answer -p 9080:80 -v /var/data:/data answerdev/answer
|
||||
|
||||
# After the first startup, a configuration file will be generated in the /var/data directory
|
||||
# After successful first startup, a configuration file will be generated in the /var/data directory
|
||||
# /var/data/conf/config.yaml
|
||||
# Need to modify the Mysql database address in the configuration file
|
||||
vim /var/data/conf/config.yaml
|
||||
|
@ -46,34 +46,32 @@ vim /var/data/conf/config.yaml
|
|||
# connection: [username]:[password]@tcp([host]:[port])/[DbName]
|
||||
...
|
||||
|
||||
# After configuring the configuration file, you can start the mirror again to start the service
|
||||
# After configuring the configuration file, you can start the container again to start the service
|
||||
$ docker start answer
|
||||
```
|
||||
|
||||
## Binary for Answer
|
||||
## Install Answer using binary
|
||||
|
||||
1. Unzip the compressed package
|
||||
2. Use the command cd to enter the directory you just created
|
||||
3. Execute the command ./answer init
|
||||
4. Answer will generate a ./data directory in the current directory
|
||||
5. Enter the data directory and modify the config.yaml file
|
||||
6. Modify the database connection address to your database connection address
|
||||
|
||||
connection: [username]:[password]@tcp([host]:[port])/[DbName]
|
||||
7. Exit the data directory and execute ./answer run -c ./data/conf/config.yaml
|
||||
2. Use the command `cd` to enter the directory you just created
|
||||
3. Execute the command `./answer init`
|
||||
4. Answer will generate a `./data` directory in the current directory
|
||||
5. Enter the `data` directory and modify the `config.yaml` file
|
||||
6. Modify the database connection identify your database connection information
|
||||
`connection: [username]:[password]@tcp([host]:[port])/[DbName]`
|
||||
7. Use `cd ..` to return the directory from step 2, and execute `./answer run -c ./data/conf/config.yaml`
|
||||
|
||||
## Available Commands
|
||||
Usage: answer [command]
|
||||
Usage: `answer [command]`
|
||||
|
||||
- help: Help about any command
|
||||
- init: Init answer application
|
||||
- run: Run answer application
|
||||
- check: Check answer required environment
|
||||
- dump: Backup answer data
|
||||
- `help`: Help about any command
|
||||
- `init`: Init answer application
|
||||
- `run`: Run answer application
|
||||
- `check`: Check answer required environment
|
||||
- `dump`: Backup answer data
|
||||
|
||||
## config.yaml Description
|
||||
|
||||
Here is a sample/default config.yaml file, as would be created from `answer init`.
|
||||
```
|
||||
server:
|
||||
http:
|
||||
|
@ -97,9 +95,9 @@ service_config:
|
|||
```
|
||||
|
||||
## Compile the image
|
||||
If you have modified the source files and want to repackage the image, you can use the following statement to repackage the image
|
||||
If you have modified the source files and want to repackage the image, you can use the following to repackage the image
|
||||
```
|
||||
docker build -t answer:v1.0.0 .
|
||||
```
|
||||
## common problem
|
||||
1. The project cannot be started, answer the main program startup depends on the configuration file config.yaml, the internationalization translation directory/i18n, the upload file storage directory/upfiles, you need to ensure that the configuration file is loaded when the project starts, answer run -c config.yaml and the correct config.yaml The configuration items that specify the i18n and upfiles directories
|
||||
1. The project cannot be started: the main program startup depends on proper configuraiton of the configuration file, `config.yaml`, as well as the internationalization translation directory (`i18n`), and the upload file storage directory (`upfiles`). Ensure that the configuration file is loaded when the project starts, such as when using `answer run -c config.yaml` and that the `config.yaml` correctly specifies the i18n and upfiles directories.
|
||||
|
|
|
@ -35,7 +35,7 @@ $ docker pull answerdev/answer:latest
|
|||
$ mkdir -p /var/data
|
||||
|
||||
# 先运行一遍镜像
|
||||
$ docker run --name=answer -p 9080:80 -v /var/data:/data answer/answer
|
||||
$ docker run --name=answer -p 9080:80 -v /var/data:/data answerdev/answer
|
||||
|
||||
# 第一次启动后会在/var/data 目录下生成配置文件
|
||||
# /var/data/conf/config.yaml
|
||||
|
|
10
Makefile
10
Makefile
|
@ -7,12 +7,19 @@ DOCKER_CMD=docker
|
|||
|
||||
#GO_ENV=CGO_ENABLED=0
|
||||
Revision=$(shell git rev-parse --short HEAD)
|
||||
GO_FLAGS=-ldflags="-X main.Version=$(VERSION) -X main.Revision=$(Revision) -X 'main.Time=`date`' -extldflags -static"
|
||||
GO_FLAGS=-ldflags="-X main.Version=$(VERSION) -X 'main.Revision=$(Revision)' -X 'main.Time=`date`' -extldflags -static"
|
||||
GO=$(GO_ENV) $(shell which go)
|
||||
|
||||
build:
|
||||
@$(GO_ENV) $(GO) build $(GO_FLAGS) -o $(BIN) $(DIR_SRC)
|
||||
|
||||
# https://dev.to/thewraven/universal-macos-binaries-with-go-1-16-3mm3
|
||||
universal:
|
||||
@GOOS=darwin GOARCH=amd64 $(GO_ENV) $(GO) build $(GO_FLAGS) -o ${BIN}_amd64 $(DIR_SRC)
|
||||
@GOOS=darwin GOARCH=arm64 $(GO_ENV) $(GO) build $(GO_FLAGS) -o ${BIN}_arm64 $(DIR_SRC)
|
||||
@lipo -create -output ${BIN} ${BIN}_amd64 ${BIN}_arm64
|
||||
@rm -f ${BIN}_amd64 ${BIN}_arm64
|
||||
|
||||
generate:
|
||||
go get github.com/google/wire/cmd/wire@latest
|
||||
go generate ./...
|
||||
|
@ -23,6 +30,7 @@ test:
|
|||
|
||||
# clean all build result
|
||||
clean:
|
||||
|
||||
@$(GO) clean ./...
|
||||
@rm -f $(BIN)
|
||||
|
||||
|
|
13
README.md
13
README.md
|
@ -4,13 +4,14 @@
|
|||
|
||||
# Answer - Build Q&A community
|
||||
|
||||
An open-source knowledge based community software. You can use it to quickly build your Q&A community for product technical support, customer support, user communication, and more.
|
||||
An open-source knowledge-based community software. You can use it to quickly build your Q&A community for product technical support, customer support, user communication, and more.
|
||||
|
||||
To learn more about the project, visit [answer.dev](https://answer.dev).
|
||||
|
||||
[![LICENSE](https://img.shields.io/badge/License-Apache-green)](https://github.com/answerdev/answer/blob/main/LICENSE)
|
||||
[![Language](https://img.shields.io/badge/Language-Go-blue.svg)](https://golang.org/)
|
||||
[![Language](https://img.shields.io/badge/Language-React-blue.svg)](https://reactjs.org/)
|
||||
[![Go Report Card](https://goreportcard.com/badge/github.com/answerdev/answer)](https://goreportcard.com/report/github.com/answerdev/answer)
|
||||
|
||||
## Screenshots
|
||||
|
||||
|
@ -18,15 +19,13 @@ To learn more about the project, visit [answer.dev](https://answer.dev).
|
|||
|
||||
## Quick start
|
||||
|
||||
### Running with docker-compose
|
||||
### Running with docker
|
||||
|
||||
```bash
|
||||
mkdir answer && cd answer
|
||||
wget https://raw.githubusercontent.com/answerdev/answer/main/docker-compose.yaml
|
||||
docker-compose up
|
||||
docker run -d -p 9080:80 -v $PWD/answer-data:/data --name answer answerdev/answer:latest
|
||||
```
|
||||
|
||||
For more information you can see [INSTALL.md](./INSTALL.md)
|
||||
For more information, see [INSTALL.md](./INSTALL.md)
|
||||
|
||||
## Contributing
|
||||
|
||||
|
@ -36,4 +35,4 @@ See [CONTRIBUTING.md](CONTRIBUTING.md) for ways to get started.
|
|||
|
||||
## License
|
||||
|
||||
[Apache](https://github.com/answerdev/answer/blob/main/LICENSE)
|
||||
[Apache License 2.0](https://github.com/answerdev/answer/blob/main/LICENSE)
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
[![LICENSE](https://img.shields.io/badge/License-Apache-green)](https://github.com/answerdev/answer/blob/main/LICENSE)
|
||||
[![Language](https://img.shields.io/badge/Language-Go-blue.svg)](https://golang.org/)
|
||||
[![Language](https://img.shields.io/badge/Language-React-blue.svg)](https://reactjs.org/)
|
||||
[![Go Report Card](https://goreportcard.com/badge/github.com/answerdev/answer)](https://goreportcard.com/report/github.com/answerdev/answer)
|
||||
|
||||
## 截图
|
||||
|
||||
|
@ -18,12 +19,10 @@
|
|||
|
||||
## 快速开始
|
||||
|
||||
### 使用 docker-compose 快速搭建
|
||||
### 使用 docker 快速搭建
|
||||
|
||||
```bash
|
||||
mkdir answer && cd answer
|
||||
wget https://raw.githubusercontent.com/answerdev/answer/main/docker-compose.yaml
|
||||
docker-compose up
|
||||
docker run -d -p 9080:80 -v $PWD/answer-data:/data --name answer answerdev/answer:latest
|
||||
```
|
||||
|
||||
其他安装配置细节请参考 [INSTALL.md](./INSTALL.md)
|
||||
|
@ -36,4 +35,4 @@ docker-compose up
|
|||
|
||||
## License
|
||||
|
||||
[Apache](https://github.com/answerdev/answer/blob/main/LICENSE)
|
||||
[Apache License 2.0](https://github.com/answerdev/answer/blob/main/LICENSE)
|
||||
|
|
|
@ -48,7 +48,7 @@ To run answer, use:
|
|||
Use: "run",
|
||||
Short: "Run the application",
|
||||
Long: `Run the application`,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
Run: func(_ *cobra.Command, _ []string) {
|
||||
runApp()
|
||||
},
|
||||
}
|
||||
|
@ -58,7 +58,7 @@ To run answer, use:
|
|||
Use: "init",
|
||||
Short: "init answer application",
|
||||
Long: `init answer application`,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
Run: func(_ *cobra.Command, _ []string) {
|
||||
cli.InstallAllInitialEnvironment(dataDirPath)
|
||||
c, err := readConfig()
|
||||
if err != nil {
|
||||
|
@ -79,7 +79,7 @@ To run answer, use:
|
|||
Use: "upgrade",
|
||||
Short: "upgrade Answer version",
|
||||
Long: `upgrade Answer version`,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
Run: func(_ *cobra.Command, _ []string) {
|
||||
c, err := readConfig()
|
||||
if err != nil {
|
||||
fmt.Println("read config failed: ", err.Error())
|
||||
|
@ -98,7 +98,7 @@ To run answer, use:
|
|||
Use: "dump",
|
||||
Short: "back up data",
|
||||
Long: `back up data`,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
Run: func(_ *cobra.Command, _ []string) {
|
||||
fmt.Println("Answer is backing up data")
|
||||
c, err := readConfig()
|
||||
if err != nil {
|
||||
|
@ -119,7 +119,7 @@ To run answer, use:
|
|||
Use: "check",
|
||||
Short: "checking the required environment",
|
||||
Long: `Check if the current environment meets the startup requirements`,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
Run: func(_ *cobra.Command, _ []string) {
|
||||
fmt.Println("Start checking the required environment...")
|
||||
if cli.CheckConfigFile(configFilePath) {
|
||||
fmt.Println("config file exists [✔]")
|
||||
|
|
|
@ -14,9 +14,9 @@ import (
|
|||
"github.com/answerdev/answer/internal/base/translator"
|
||||
"github.com/answerdev/answer/internal/controller"
|
||||
"github.com/answerdev/answer/internal/controller_backyard"
|
||||
"github.com/answerdev/answer/internal/repo"
|
||||
"github.com/answerdev/answer/internal/repo/activity"
|
||||
"github.com/answerdev/answer/internal/repo/activity_common"
|
||||
"github.com/answerdev/answer/internal/repo/answer"
|
||||
"github.com/answerdev/answer/internal/repo/auth"
|
||||
"github.com/answerdev/answer/internal/repo/captcha"
|
||||
"github.com/answerdev/answer/internal/repo/collection"
|
||||
|
@ -26,10 +26,13 @@ import (
|
|||
"github.com/answerdev/answer/internal/repo/export"
|
||||
"github.com/answerdev/answer/internal/repo/meta"
|
||||
"github.com/answerdev/answer/internal/repo/notification"
|
||||
"github.com/answerdev/answer/internal/repo/question"
|
||||
"github.com/answerdev/answer/internal/repo/rank"
|
||||
"github.com/answerdev/answer/internal/repo/reason"
|
||||
"github.com/answerdev/answer/internal/repo/report"
|
||||
"github.com/answerdev/answer/internal/repo/revision"
|
||||
"github.com/answerdev/answer/internal/repo/search_common"
|
||||
"github.com/answerdev/answer/internal/repo/site_info"
|
||||
"github.com/answerdev/answer/internal/repo/tag"
|
||||
"github.com/answerdev/answer/internal/repo/unique"
|
||||
"github.com/answerdev/answer/internal/repo/user"
|
||||
|
@ -92,11 +95,11 @@ func initApplication(debug bool, serverConf *conf.Server, dbConf *data.Database,
|
|||
configRepo := config.NewConfigRepo(dataData)
|
||||
userRepo := user.NewUserRepo(dataData, configRepo)
|
||||
uniqueIDRepo := unique.NewUniqueIDRepo(dataData)
|
||||
activityRepo := repo.NewActivityRepo(dataData, uniqueIDRepo, configRepo)
|
||||
activityRepo := activity_common.NewActivityRepo(dataData, uniqueIDRepo, configRepo)
|
||||
userRankRepo := rank.NewUserRankRepo(dataData, configRepo)
|
||||
userActiveActivityRepo := activity.NewUserActiveActivityRepo(dataData, activityRepo, userRankRepo, configRepo)
|
||||
emailRepo := export.NewEmailRepo(dataData)
|
||||
siteInfoRepo := repo.NewSiteInfo(dataData)
|
||||
siteInfoRepo := site_info.NewSiteInfo(dataData)
|
||||
emailService := export2.NewEmailService(configRepo, emailRepo, siteInfoRepo)
|
||||
userService := service.NewUserService(userRepo, userActiveActivityRepo, emailService, authService, serviceConf)
|
||||
captchaRepo := captcha.NewCaptchaRepo(dataData)
|
||||
|
@ -106,8 +109,8 @@ func initApplication(debug bool, serverConf *conf.Server, dbConf *data.Database,
|
|||
commentRepo := comment.NewCommentRepo(dataData, uniqueIDRepo)
|
||||
commentCommonRepo := comment.NewCommentCommonRepo(dataData, uniqueIDRepo)
|
||||
userCommon := usercommon.NewUserCommon(userRepo)
|
||||
answerRepo := repo.NewAnswerRepo(dataData, uniqueIDRepo, userRankRepo, activityRepo)
|
||||
questionRepo := repo.NewQuestionRepo(dataData, uniqueIDRepo)
|
||||
answerRepo := answer.NewAnswerRepo(dataData, uniqueIDRepo, userRankRepo, activityRepo)
|
||||
questionRepo := question.NewQuestionRepo(dataData, uniqueIDRepo)
|
||||
tagRepo := tag.NewTagRepo(dataData, uniqueIDRepo)
|
||||
objService := object_info.NewObjService(answerRepo, questionRepo, commentCommonRepo, tagRepo)
|
||||
voteRepo := activity_common.NewVoteRepo(dataData, activityRepo)
|
||||
|
@ -130,7 +133,7 @@ func initApplication(debug bool, serverConf *conf.Server, dbConf *data.Database,
|
|||
followController := controller.NewFollowController(followService)
|
||||
collectionRepo := collection.NewCollectionRepo(dataData, uniqueIDRepo)
|
||||
collectionGroupRepo := collection.NewCollectionGroupRepo(dataData)
|
||||
tagRelRepo := tag.NewTagListRepo(dataData)
|
||||
tagRelRepo := tag.NewTagRelRepo(dataData)
|
||||
tagCommonService := tagcommon.NewTagCommonService(tagRepo, tagRelRepo, revisionService)
|
||||
collectionCommon := collectioncommon.NewCollectionCommon(collectionRepo)
|
||||
answerCommon := answercommon.NewAnswerCommon(answerRepo)
|
||||
|
@ -146,7 +149,7 @@ func initApplication(debug bool, serverConf *conf.Server, dbConf *data.Database,
|
|||
questionController := controller.NewQuestionController(questionService, rankService)
|
||||
answerService := service.NewAnswerService(answerRepo, questionRepo, questionCommon, userCommon, collectionCommon, userRepo, revisionService, answerActivityService, answerCommon, voteRepo)
|
||||
answerController := controller.NewAnswerController(answerService, rankService)
|
||||
searchRepo := repo.NewSearchRepo(dataData, uniqueIDRepo, userCommon)
|
||||
searchRepo := search_common.NewSearchRepo(dataData, uniqueIDRepo, userCommon)
|
||||
searchService := service.NewSearchService(searchRepo, tagRepo, userCommon, followRepo)
|
||||
searchController := controller.NewSearchController(searchService)
|
||||
serviceRevisionService := service.NewRevisionService(revisionRepo, userCommon, questionCommon, answerService)
|
||||
|
@ -156,7 +159,7 @@ func initApplication(debug bool, serverConf *conf.Server, dbConf *data.Database,
|
|||
reportHandle := report_handle_backyard.NewReportHandle(questionCommon, commentRepo, configRepo)
|
||||
reportBackyardService := report_backyard.NewReportBackyardService(reportRepo, userCommon, commonRepo, answerRepo, questionRepo, commentCommonRepo, reportHandle, configRepo)
|
||||
controller_backyardReportController := controller_backyard.NewReportController(reportBackyardService)
|
||||
userBackyardRepo := user.NewUserBackyardRepo(dataData)
|
||||
userBackyardRepo := user.NewUserBackyardRepo(dataData, authRepo)
|
||||
userBackyardService := user_backyard.NewUserBackyardService(userBackyardRepo)
|
||||
userBackyardController := controller_backyard.NewUserBackyardController(userBackyardService)
|
||||
reasonRepo := reason.NewReasonRepo(configRepo)
|
||||
|
|
|
@ -3,10 +3,10 @@ server:
|
|||
addr: 0.0.0.0:80
|
||||
data:
|
||||
database:
|
||||
driver: "mysql"
|
||||
connection: root:root@tcp(db:3306)/answer
|
||||
driver: "sqlite3"
|
||||
connection: "/data/sqlite3/answer.db"
|
||||
cache:
|
||||
file_path: "/tmp/cache/cache.db"
|
||||
file_path: "/data/cache/cache.db"
|
||||
i18n:
|
||||
bundle_dir: "/data/i18n"
|
||||
swaggerui:
|
||||
|
|
|
@ -1,29 +1,12 @@
|
|||
version: "3.9"
|
||||
version: "3"
|
||||
services:
|
||||
answer:
|
||||
image: answerdev/answer:latest
|
||||
image: answerdev/answer
|
||||
ports:
|
||||
- '9080:80'
|
||||
restart: on-failure
|
||||
depends_on:
|
||||
db:
|
||||
condition: service_healthy
|
||||
links:
|
||||
- db
|
||||
volumes:
|
||||
- ./answer-data/data:/data
|
||||
db:
|
||||
image: mariadb:10.4.7
|
||||
ports:
|
||||
- '13306:3306'
|
||||
restart: on-failure
|
||||
environment:
|
||||
MYSQL_DATABASE: answer
|
||||
MYSQL_ROOT_PASSWORD: root
|
||||
healthcheck:
|
||||
test: [ "CMD", "mysqladmin" ,"ping", "-uroot", "-proot"]
|
||||
timeout: 20s
|
||||
retries: 10
|
||||
command: ['mysqld', '--character-set-server=utf8mb4', '--collation-server=utf8mb4_unicode_ci', '--skip-character-set-client-handshake']
|
||||
volumes:
|
||||
- ./answer-data/mysql:/var/lib/mysql
|
||||
- answer-data:/data
|
||||
|
||||
volumes:
|
||||
answer-data:
|
||||
|
|
159
docs/docs.go
159
docs/docs.go
|
@ -56,6 +56,18 @@ const docTemplate = `{
|
|||
"description": "user status",
|
||||
"name": "status",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "answer id or question title",
|
||||
"name": "query",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "question id",
|
||||
"name": "question_id",
|
||||
"in": "query"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
|
@ -173,6 +185,12 @@ const docTemplate = `{
|
|||
"description": "user status",
|
||||
"name": "status",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "question id or title",
|
||||
"name": "query",
|
||||
"in": "query"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
|
@ -709,19 +727,12 @@ const docTemplate = `{
|
|||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "username",
|
||||
"name": "username",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "email",
|
||||
"name": "e_mail",
|
||||
"description": "search query: email, username or id:[id]",
|
||||
"name": "query",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"enum": [
|
||||
"normal",
|
||||
"suspended",
|
||||
"deleted",
|
||||
"inactive"
|
||||
|
@ -3303,7 +3314,7 @@ const docTemplate = `{
|
|||
"ApiKeyAuth": []
|
||||
}
|
||||
],
|
||||
"description": "GetUserInfoByUserID",
|
||||
"description": "get user info, if user no login response http code is 200, but user info is null",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
|
@ -3326,7 +3337,7 @@ const docTemplate = `{
|
|||
"type": "object",
|
||||
"properties": {
|
||||
"data": {
|
||||
"$ref": "#/definitions/schema.GetUserResp"
|
||||
"$ref": "#/definitions/schema.GetUserToSetShowResp"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4108,6 +4119,23 @@ const docTemplate = `{
|
|||
}
|
||||
}
|
||||
},
|
||||
"schema.AvatarInfo": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"custom": {
|
||||
"type": "string",
|
||||
"maxLength": 200
|
||||
},
|
||||
"gravatar": {
|
||||
"type": "string",
|
||||
"maxLength": 200
|
||||
},
|
||||
"type": {
|
||||
"type": "string",
|
||||
"maxLength": 100
|
||||
}
|
||||
}
|
||||
},
|
||||
"schema.CloseQuestionReq": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
|
@ -4836,6 +4864,102 @@ const docTemplate = `{
|
|||
}
|
||||
}
|
||||
},
|
||||
"schema.GetUserToSetShowResp": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"access_token": {
|
||||
"description": "access token",
|
||||
"type": "string"
|
||||
},
|
||||
"answer_count": {
|
||||
"description": "answer count",
|
||||
"type": "integer"
|
||||
},
|
||||
"authority_group": {
|
||||
"description": "authority group",
|
||||
"type": "integer"
|
||||
},
|
||||
"avatar": {
|
||||
"$ref": "#/definitions/schema.AvatarInfo"
|
||||
},
|
||||
"bio": {
|
||||
"description": "bio markdown",
|
||||
"type": "string"
|
||||
},
|
||||
"bio_html": {
|
||||
"description": "bio html",
|
||||
"type": "string"
|
||||
},
|
||||
"created_at": {
|
||||
"description": "create time",
|
||||
"type": "integer"
|
||||
},
|
||||
"display_name": {
|
||||
"description": "display name",
|
||||
"type": "string"
|
||||
},
|
||||
"e_mail": {
|
||||
"description": "email",
|
||||
"type": "string"
|
||||
},
|
||||
"follow_count": {
|
||||
"description": "follow count",
|
||||
"type": "integer"
|
||||
},
|
||||
"id": {
|
||||
"description": "user id",
|
||||
"type": "string"
|
||||
},
|
||||
"ip_info": {
|
||||
"description": "ip info",
|
||||
"type": "string"
|
||||
},
|
||||
"is_admin": {
|
||||
"description": "is admin",
|
||||
"type": "boolean"
|
||||
},
|
||||
"last_login_date": {
|
||||
"description": "last login date",
|
||||
"type": "integer"
|
||||
},
|
||||
"location": {
|
||||
"description": "location",
|
||||
"type": "string"
|
||||
},
|
||||
"mail_status": {
|
||||
"description": "mail status(1 pass 2 to be verified)",
|
||||
"type": "integer"
|
||||
},
|
||||
"mobile": {
|
||||
"description": "mobile",
|
||||
"type": "string"
|
||||
},
|
||||
"notice_status": {
|
||||
"description": "notice status(1 on 2off)",
|
||||
"type": "integer"
|
||||
},
|
||||
"question_count": {
|
||||
"description": "question count",
|
||||
"type": "integer"
|
||||
},
|
||||
"rank": {
|
||||
"description": "rank",
|
||||
"type": "integer"
|
||||
},
|
||||
"status": {
|
||||
"description": "user status",
|
||||
"type": "string"
|
||||
},
|
||||
"username": {
|
||||
"description": "username",
|
||||
"type": "string"
|
||||
},
|
||||
"website": {
|
||||
"description": "website",
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"schema.GetVoteWithPageResp": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
|
@ -4962,7 +5086,7 @@ const docTemplate = `{
|
|||
"type": "integer"
|
||||
},
|
||||
"tag": {
|
||||
"description": "Tags []string ` + "`" + `json:\"tags\" form:\"tags\"` + "`" + ` //Search tag",
|
||||
"description": "Tags []string ` + "`" + `json:\"tags\" form:\"tags\"` + "`" + ` // Search tag",
|
||||
"type": "string"
|
||||
},
|
||||
"username": {
|
||||
|
@ -5318,8 +5442,7 @@ const docTemplate = `{
|
|||
"properties": {
|
||||
"avatar": {
|
||||
"description": "avatar",
|
||||
"type": "string",
|
||||
"maxLength": 500
|
||||
"$ref": "#/definitions/schema.AvatarInfo"
|
||||
},
|
||||
"bio": {
|
||||
"description": "bio",
|
||||
|
@ -5516,6 +5639,14 @@ const docTemplate = `{
|
|||
"e_mail"
|
||||
],
|
||||
"properties": {
|
||||
"captcha_code": {
|
||||
"type": "string",
|
||||
"maxLength": 500
|
||||
},
|
||||
"captcha_id": {
|
||||
"type": "string",
|
||||
"maxLength": 500
|
||||
},
|
||||
"e_mail": {
|
||||
"type": "string",
|
||||
"maxLength": 500
|
||||
|
|
|
@ -44,6 +44,18 @@
|
|||
"description": "user status",
|
||||
"name": "status",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "answer id or question title",
|
||||
"name": "query",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "question id",
|
||||
"name": "question_id",
|
||||
"in": "query"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
|
@ -161,6 +173,12 @@
|
|||
"description": "user status",
|
||||
"name": "status",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "question id or title",
|
||||
"name": "query",
|
||||
"in": "query"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
|
@ -697,19 +715,12 @@
|
|||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "username",
|
||||
"name": "username",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "email",
|
||||
"name": "e_mail",
|
||||
"description": "search query: email, username or id:[id]",
|
||||
"name": "query",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"enum": [
|
||||
"normal",
|
||||
"suspended",
|
||||
"deleted",
|
||||
"inactive"
|
||||
|
@ -3291,7 +3302,7 @@
|
|||
"ApiKeyAuth": []
|
||||
}
|
||||
],
|
||||
"description": "GetUserInfoByUserID",
|
||||
"description": "get user info, if user no login response http code is 200, but user info is null",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
|
@ -3314,7 +3325,7 @@
|
|||
"type": "object",
|
||||
"properties": {
|
||||
"data": {
|
||||
"$ref": "#/definitions/schema.GetUserResp"
|
||||
"$ref": "#/definitions/schema.GetUserToSetShowResp"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4096,6 +4107,23 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"schema.AvatarInfo": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"custom": {
|
||||
"type": "string",
|
||||
"maxLength": 200
|
||||
},
|
||||
"gravatar": {
|
||||
"type": "string",
|
||||
"maxLength": 200
|
||||
},
|
||||
"type": {
|
||||
"type": "string",
|
||||
"maxLength": 100
|
||||
}
|
||||
}
|
||||
},
|
||||
"schema.CloseQuestionReq": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
|
@ -4824,6 +4852,102 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"schema.GetUserToSetShowResp": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"access_token": {
|
||||
"description": "access token",
|
||||
"type": "string"
|
||||
},
|
||||
"answer_count": {
|
||||
"description": "answer count",
|
||||
"type": "integer"
|
||||
},
|
||||
"authority_group": {
|
||||
"description": "authority group",
|
||||
"type": "integer"
|
||||
},
|
||||
"avatar": {
|
||||
"$ref": "#/definitions/schema.AvatarInfo"
|
||||
},
|
||||
"bio": {
|
||||
"description": "bio markdown",
|
||||
"type": "string"
|
||||
},
|
||||
"bio_html": {
|
||||
"description": "bio html",
|
||||
"type": "string"
|
||||
},
|
||||
"created_at": {
|
||||
"description": "create time",
|
||||
"type": "integer"
|
||||
},
|
||||
"display_name": {
|
||||
"description": "display name",
|
||||
"type": "string"
|
||||
},
|
||||
"e_mail": {
|
||||
"description": "email",
|
||||
"type": "string"
|
||||
},
|
||||
"follow_count": {
|
||||
"description": "follow count",
|
||||
"type": "integer"
|
||||
},
|
||||
"id": {
|
||||
"description": "user id",
|
||||
"type": "string"
|
||||
},
|
||||
"ip_info": {
|
||||
"description": "ip info",
|
||||
"type": "string"
|
||||
},
|
||||
"is_admin": {
|
||||
"description": "is admin",
|
||||
"type": "boolean"
|
||||
},
|
||||
"last_login_date": {
|
||||
"description": "last login date",
|
||||
"type": "integer"
|
||||
},
|
||||
"location": {
|
||||
"description": "location",
|
||||
"type": "string"
|
||||
},
|
||||
"mail_status": {
|
||||
"description": "mail status(1 pass 2 to be verified)",
|
||||
"type": "integer"
|
||||
},
|
||||
"mobile": {
|
||||
"description": "mobile",
|
||||
"type": "string"
|
||||
},
|
||||
"notice_status": {
|
||||
"description": "notice status(1 on 2off)",
|
||||
"type": "integer"
|
||||
},
|
||||
"question_count": {
|
||||
"description": "question count",
|
||||
"type": "integer"
|
||||
},
|
||||
"rank": {
|
||||
"description": "rank",
|
||||
"type": "integer"
|
||||
},
|
||||
"status": {
|
||||
"description": "user status",
|
||||
"type": "string"
|
||||
},
|
||||
"username": {
|
||||
"description": "username",
|
||||
"type": "string"
|
||||
},
|
||||
"website": {
|
||||
"description": "website",
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"schema.GetVoteWithPageResp": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
|
@ -4950,7 +5074,7 @@
|
|||
"type": "integer"
|
||||
},
|
||||
"tag": {
|
||||
"description": "Tags []string `json:\"tags\" form:\"tags\"` //Search tag",
|
||||
"description": "Tags []string `json:\"tags\" form:\"tags\"` // Search tag",
|
||||
"type": "string"
|
||||
},
|
||||
"username": {
|
||||
|
@ -5306,8 +5430,7 @@
|
|||
"properties": {
|
||||
"avatar": {
|
||||
"description": "avatar",
|
||||
"type": "string",
|
||||
"maxLength": 500
|
||||
"$ref": "#/definitions/schema.AvatarInfo"
|
||||
},
|
||||
"bio": {
|
||||
"description": "bio",
|
||||
|
@ -5504,6 +5627,14 @@
|
|||
"e_mail"
|
||||
],
|
||||
"properties": {
|
||||
"captcha_code": {
|
||||
"type": "string",
|
||||
"maxLength": 500
|
||||
},
|
||||
"captcha_id": {
|
||||
"type": "string",
|
||||
"maxLength": 500
|
||||
},
|
||||
"e_mail": {
|
||||
"type": "string",
|
||||
"maxLength": 500
|
||||
|
|
|
@ -139,6 +139,18 @@ definitions:
|
|||
description: title
|
||||
type: string
|
||||
type: object
|
||||
schema.AvatarInfo:
|
||||
properties:
|
||||
custom:
|
||||
maxLength: 200
|
||||
type: string
|
||||
gravatar:
|
||||
maxLength: 200
|
||||
type: string
|
||||
type:
|
||||
maxLength: 100
|
||||
type: string
|
||||
type: object
|
||||
schema.CloseQuestionReq:
|
||||
properties:
|
||||
close_msg:
|
||||
|
@ -671,6 +683,77 @@ definitions:
|
|||
description: website
|
||||
type: string
|
||||
type: object
|
||||
schema.GetUserToSetShowResp:
|
||||
properties:
|
||||
access_token:
|
||||
description: access token
|
||||
type: string
|
||||
answer_count:
|
||||
description: answer count
|
||||
type: integer
|
||||
authority_group:
|
||||
description: authority group
|
||||
type: integer
|
||||
avatar:
|
||||
$ref: '#/definitions/schema.AvatarInfo'
|
||||
bio:
|
||||
description: bio markdown
|
||||
type: string
|
||||
bio_html:
|
||||
description: bio html
|
||||
type: string
|
||||
created_at:
|
||||
description: create time
|
||||
type: integer
|
||||
display_name:
|
||||
description: display name
|
||||
type: string
|
||||
e_mail:
|
||||
description: email
|
||||
type: string
|
||||
follow_count:
|
||||
description: follow count
|
||||
type: integer
|
||||
id:
|
||||
description: user id
|
||||
type: string
|
||||
ip_info:
|
||||
description: ip info
|
||||
type: string
|
||||
is_admin:
|
||||
description: is admin
|
||||
type: boolean
|
||||
last_login_date:
|
||||
description: last login date
|
||||
type: integer
|
||||
location:
|
||||
description: location
|
||||
type: string
|
||||
mail_status:
|
||||
description: mail status(1 pass 2 to be verified)
|
||||
type: integer
|
||||
mobile:
|
||||
description: mobile
|
||||
type: string
|
||||
notice_status:
|
||||
description: notice status(1 on 2off)
|
||||
type: integer
|
||||
question_count:
|
||||
description: question count
|
||||
type: integer
|
||||
rank:
|
||||
description: rank
|
||||
type: integer
|
||||
status:
|
||||
description: user status
|
||||
type: string
|
||||
username:
|
||||
description: username
|
||||
type: string
|
||||
website:
|
||||
description: website
|
||||
type: string
|
||||
type: object
|
||||
schema.GetVoteWithPageResp:
|
||||
properties:
|
||||
answer_id:
|
||||
|
@ -763,7 +846,7 @@ definitions:
|
|||
description: Search page size
|
||||
type: integer
|
||||
tag:
|
||||
description: Tags []string `json:"tags" form:"tags"` //Search
|
||||
description: Tags []string `json:"tags" form:"tags"` // Search
|
||||
tag
|
||||
type: string
|
||||
username:
|
||||
|
@ -1013,9 +1096,8 @@ definitions:
|
|||
schema.UpdateInfoRequest:
|
||||
properties:
|
||||
avatar:
|
||||
$ref: '#/definitions/schema.AvatarInfo'
|
||||
description: avatar
|
||||
maxLength: 500
|
||||
type: string
|
||||
bio:
|
||||
description: bio
|
||||
maxLength: 4096
|
||||
|
@ -1159,6 +1241,12 @@ definitions:
|
|||
type: object
|
||||
schema.UserChangeEmailSendCodeReq:
|
||||
properties:
|
||||
captcha_code:
|
||||
maxLength: 500
|
||||
type: string
|
||||
captcha_id:
|
||||
maxLength: 500
|
||||
type: string
|
||||
e_mail:
|
||||
maxLength: 500
|
||||
type: string
|
||||
|
@ -1302,6 +1390,14 @@ paths:
|
|||
in: query
|
||||
name: status
|
||||
type: string
|
||||
- description: answer id or question title
|
||||
in: query
|
||||
name: query
|
||||
type: string
|
||||
- description: question id
|
||||
in: query
|
||||
name: question_id
|
||||
type: string
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
|
@ -1375,6 +1471,10 @@ paths:
|
|||
in: query
|
||||
name: status
|
||||
type: string
|
||||
- description: question id or title
|
||||
in: query
|
||||
name: query
|
||||
type: string
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
|
@ -1700,17 +1800,12 @@ paths:
|
|||
in: query
|
||||
name: page_size
|
||||
type: integer
|
||||
- description: username
|
||||
- description: 'search query: email, username or id:[id]'
|
||||
in: query
|
||||
name: username
|
||||
type: string
|
||||
- description: email
|
||||
in: query
|
||||
name: e_mail
|
||||
name: query
|
||||
type: string
|
||||
- description: user status
|
||||
enum:
|
||||
- normal
|
||||
- suspended
|
||||
- deleted
|
||||
- inactive
|
||||
|
@ -3283,7 +3378,8 @@ paths:
|
|||
get:
|
||||
consumes:
|
||||
- application/json
|
||||
description: GetUserInfoByUserID
|
||||
description: get user info, if user no login response http code is 200, but
|
||||
user info is null
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
|
@ -3294,7 +3390,7 @@ paths:
|
|||
- $ref: '#/definitions/handler.RespBody'
|
||||
- properties:
|
||||
data:
|
||||
$ref: '#/definitions/schema.GetUserResp'
|
||||
$ref: '#/definitions/schema.GetUserToSetShowResp'
|
||||
type: object
|
||||
security:
|
||||
- ApiKeyAuth: []
|
||||
|
|
59
go.mod
59
go.mod
|
@ -17,22 +17,23 @@ require (
|
|||
github.com/google/wire v0.5.0
|
||||
github.com/jinzhu/copier v0.3.5
|
||||
github.com/jinzhu/now v1.1.5
|
||||
github.com/lib/pq v1.10.2
|
||||
github.com/mattn/go-sqlite3 v2.0.3+incompatible
|
||||
github.com/lib/pq v1.10.7
|
||||
github.com/mattn/go-sqlite3 v1.14.16
|
||||
github.com/mojocn/base64Captcha v1.3.5
|
||||
github.com/ory/dockertest/v3 v3.9.1
|
||||
github.com/segmentfault/pacman v1.0.1
|
||||
github.com/segmentfault/pacman/contrib/cache/memory v0.0.0-20220929065758-260b3093a347
|
||||
github.com/segmentfault/pacman/contrib/conf/viper v0.0.0-20220929065758-260b3093a347
|
||||
github.com/segmentfault/pacman/contrib/i18n v0.0.0-20220929065758-260b3093a347
|
||||
github.com/segmentfault/pacman/contrib/log/zap v0.0.0-20220929065758-260b3093a347
|
||||
github.com/segmentfault/pacman/contrib/server/http v0.0.0-20220929065758-260b3093a347
|
||||
github.com/spf13/cobra v1.5.0
|
||||
github.com/stretchr/testify v1.8.0
|
||||
github.com/segmentfault/pacman/contrib/cache/memory v0.0.0-20221018072427-a15dd1434e05
|
||||
github.com/segmentfault/pacman/contrib/conf/viper v0.0.0-20221018072427-a15dd1434e05
|
||||
github.com/segmentfault/pacman/contrib/i18n v0.0.0-20221018072427-a15dd1434e05
|
||||
github.com/segmentfault/pacman/contrib/log/zap v0.0.0-20221018072427-a15dd1434e05
|
||||
github.com/segmentfault/pacman/contrib/server/http v0.0.0-20221018072427-a15dd1434e05
|
||||
github.com/spf13/cobra v1.6.1
|
||||
github.com/stretchr/testify v1.8.1
|
||||
github.com/swaggo/files v0.0.0-20220728132757-551d4a08d97a
|
||||
github.com/swaggo/gin-swagger v1.5.3
|
||||
github.com/swaggo/swag v1.8.6
|
||||
golang.org/x/crypto v0.0.0-20220926161630-eccd6366d1be
|
||||
golang.org/x/net v0.0.0-20220927171203-f486391704dc
|
||||
github.com/swaggo/swag v1.8.7
|
||||
golang.org/x/crypto v0.1.0
|
||||
golang.org/x/net v0.1.0
|
||||
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df
|
||||
xorm.io/builder v0.3.12
|
||||
xorm.io/core v0.7.3
|
||||
|
@ -40,19 +41,31 @@ require (
|
|||
)
|
||||
|
||||
require (
|
||||
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78 // indirect
|
||||
github.com/KyleBanks/depth v1.2.1 // indirect
|
||||
github.com/andybalholm/brotli v1.0.1 // indirect
|
||||
github.com/Microsoft/go-winio v0.5.2 // indirect
|
||||
github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 // indirect
|
||||
github.com/andybalholm/brotli v1.0.4 // indirect
|
||||
github.com/cenkalti/backoff/v4 v4.1.3 // indirect
|
||||
github.com/containerd/continuity v0.3.0 // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/fsnotify/fsnotify v1.5.4 // indirect
|
||||
github.com/docker/cli v20.10.14+incompatible // indirect
|
||||
github.com/docker/docker v20.10.7+incompatible // indirect
|
||||
github.com/docker/go-connections v0.4.0 // indirect
|
||||
github.com/docker/go-units v0.4.0 // indirect
|
||||
github.com/fsnotify/fsnotify v1.6.0 // indirect
|
||||
github.com/gin-contrib/sse v0.1.0 // indirect
|
||||
github.com/go-openapi/jsonpointer v0.19.5 // indirect
|
||||
github.com/go-openapi/jsonreference v0.20.0 // indirect
|
||||
github.com/go-openapi/spec v0.20.7 // indirect
|
||||
github.com/go-openapi/swag v0.22.3 // indirect
|
||||
github.com/gogo/protobuf v1.3.2 // indirect
|
||||
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect
|
||||
github.com/golang/snappy v0.0.4 // indirect
|
||||
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect
|
||||
github.com/hashicorp/hcl v1.0.0 // indirect
|
||||
github.com/inconshreveable/mousetrap v1.0.0 // indirect
|
||||
github.com/imdario/mergo v0.3.12 // indirect
|
||||
github.com/inconshreveable/mousetrap v1.0.1 // indirect
|
||||
github.com/josharian/intern v1.0.0 // indirect
|
||||
github.com/json-iterator/go v1.1.12 // indirect
|
||||
github.com/leodido/go-urn v1.2.1 // indirect
|
||||
|
@ -62,14 +75,19 @@ require (
|
|||
github.com/mailru/easyjson v0.7.7 // indirect
|
||||
github.com/mattn/go-isatty v0.0.16 // indirect
|
||||
github.com/mitchellh/mapstructure v1.5.0 // indirect
|
||||
github.com/moby/term v0.0.0-20201216013528-df9cb8a40635 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||
github.com/nicksnyder/go-i18n/v2 v2.2.0 // indirect
|
||||
github.com/opencontainers/go-digest v1.0.0 // indirect
|
||||
github.com/opencontainers/image-spec v1.0.2 // indirect
|
||||
github.com/opencontainers/runc v1.1.2 // 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/v2 v2.0.5 // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/sirupsen/logrus v1.8.1 // indirect
|
||||
github.com/spf13/afero v1.9.2 // indirect
|
||||
github.com/spf13/cast v1.5.0 // indirect
|
||||
github.com/spf13/jwalterweatherman v1.1.0 // indirect
|
||||
|
@ -78,13 +96,16 @@ require (
|
|||
github.com/subosito/gotenv v1.4.1 // indirect
|
||||
github.com/syndtr/goleveldb v1.0.0 // indirect
|
||||
github.com/ugorji/go/codec v1.2.7 // indirect
|
||||
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f // indirect
|
||||
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
|
||||
github.com/xeipuuv/gojsonschema v1.2.0 // indirect
|
||||
go.uber.org/atomic v1.10.0 // indirect
|
||||
go.uber.org/multierr v1.8.0 // indirect
|
||||
go.uber.org/zap v1.23.0 // indirect
|
||||
golang.org/x/image v0.0.0-20220902085622-e7cb96979f69 // indirect
|
||||
golang.org/x/sys v0.0.0-20220928140112-f11e5e49a4ec // indirect
|
||||
golang.org/x/text v0.3.7 // indirect
|
||||
golang.org/x/tools v0.1.12 // indirect
|
||||
golang.org/x/image v0.1.0 // indirect
|
||||
golang.org/x/sys v0.1.0 // indirect
|
||||
golang.org/x/text v0.4.0 // indirect
|
||||
golang.org/x/tools v0.2.0 // indirect
|
||||
google.golang.org/protobuf v1.28.1 // indirect
|
||||
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect
|
||||
gopkg.in/ini.v1 v1.67.0 // indirect
|
||||
|
|
158
go.sum
158
go.sum
|
@ -39,6 +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/go.mod h1:EXuID2Zs0pAQhH8yz+DNjUbjppKQzKFAn28TMYPB6IU=
|
||||
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-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8=
|
||||
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/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
|
||||
|
@ -49,6 +51,10 @@ github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go
|
|||
github.com/KyleBanks/depth v1.2.1 h1:5h8fQADFrWtarTdtDudMmGsC7GPbOAu6RVB3ffsVFHc=
|
||||
github.com/KyleBanks/depth v1.2.1/go.mod h1:jzSb9d0L43HxTQfT+oSA1EEp2q+ne2uh6XgeJcm8brE=
|
||||
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.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY=
|
||||
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/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
|
||||
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
|
||||
github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo=
|
||||
|
@ -62,8 +68,9 @@ github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRF
|
|||
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||
github.com/anargu/gin-brotli v0.0.0-20220116052358-12bf532d5267 h1:vDHsaEcs/Q0dwetADENtwus6W1ccaZ9h3KBTm0d2X0g=
|
||||
github.com/anargu/gin-brotli v0.0.0-20220116052358-12bf532d5267/go.mod h1:Yj3yPP/vi87JjwylUTCMyd6FrOfGqP1AHk0305hDm2o=
|
||||
github.com/andybalholm/brotli v1.0.1 h1:KqhlKozYbRtJvsPrrEeXcO+N2l6NYT5A2QAFmSULpEc=
|
||||
github.com/andybalholm/brotli v1.0.1/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y=
|
||||
github.com/andybalholm/brotli v1.0.4 h1:V7DdXeJtZscaqfNuAdSRuRFzuiKlHSC/Zh3zl9qY3JY=
|
||||
github.com/andybalholm/brotli v1.0.4/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
|
||||
github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
|
||||
github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
|
||||
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
|
||||
|
@ -82,11 +89,15 @@ github.com/bwmarrin/snowflake v0.3.0 h1:xm67bEhkKh6ij1790JB83OujPR5CzNe8QuQqAgIS
|
|||
github.com/bwmarrin/snowflake v0.3.0/go.mod h1:NdZxfVWX+oR6y2K0o6qAYv6gIOP9rjG0/E9WsDpxqwE=
|
||||
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/v4 v4.1.3 h1:cFAlzYUlVYDysBEH2T5hyJZMh3+5+WCBvSnK6Q8UtC4=
|
||||
github.com/cenkalti/backoff/v4 v4.1.3/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw=
|
||||
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/checkpoint-restore/go-criu/v5 v5.3.0/go.mod h1:E/eQpaFtUKGOOSEBZgmKAcn+zUUwWxqcaKZlF54wK8E=
|
||||
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/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/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=
|
||||
|
@ -95,15 +106,22 @@ 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/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/containerd/console v1.0.3/go.mod h1:7LqA/THxQ86k76b8c/EMSiaJ3h1eZkMkXar0TQ1gf3U=
|
||||
github.com/containerd/continuity v0.3.0 h1:nisirsYROK15TAMVukJOUyGJjz4BNQJBVsNvAXZJ/eg=
|
||||
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-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-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/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/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.11 h1:07n33Z8lZxZ2qwegKbObQohDhXDQxiMMz1NOUGYlesw=
|
||||
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.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
|
@ -111,6 +129,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/disintegration/imaging v1.6.2 h1:w1LecBlG2Lnp8B3jk5zSuNqd7b4DXhcjwek1ei82L+c=
|
||||
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 v20.10.14+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
|
||||
github.com/docker/docker v20.10.7+incompatible h1:Z6O9Nhsjv+ayUEeI1IojKbYcsGdgYSNqxe1s2MYzUhQ=
|
||||
github.com/docker/docker v20.10.7+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/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec=
|
||||
github.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw=
|
||||
github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
|
||||
github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
||||
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
||||
github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs=
|
||||
|
@ -127,10 +153,11 @@ 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/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/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k=
|
||||
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.5.4 h1:jRbGcIw6P2Meqdwuo0H1p6JVLbL5DHKAKlYndzMwVZI=
|
||||
github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU=
|
||||
github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY=
|
||||
github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw=
|
||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
github.com/gin-contrib/gzip v0.0.6 h1:NjcunTcGAj5CO1gn4N8jHOSIeRFHIbn51z6K+xaN4d4=
|
||||
github.com/gin-contrib/gzip v0.0.6/go.mod h1:QOJlmV2xmayAjkNS2Y8NQsMneuRShOU/kjovCXNuzzk=
|
||||
|
@ -182,12 +209,16 @@ 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.11 h1:/pAaQDLHEoCq/5FFmSKBswWmK6H0e8g4159Kc/X/nqk=
|
||||
github.com/goccy/go-json v0.9.11/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 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/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||
github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
|
||||
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
|
||||
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
||||
github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0=
|
||||
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 h1:DACJavvAHhabrF08vX0COfcOBJRhZ8lUbR+ZWIs0Y5g=
|
||||
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k=
|
||||
|
@ -251,6 +282,8 @@ github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLe
|
|||
github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||
github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
||||
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4=
|
||||
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ=
|
||||
github.com/google/subcommands v1.0.1/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk=
|
||||
github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
|
@ -296,8 +329,11 @@ 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/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/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
|
||||
github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU=
|
||||
github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
|
||||
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/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
|
||||
github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo=
|
||||
github.com/jackc/chunkreader v1.0.0/go.mod h1:RT6O25fNZIuasFJRyZ4R/Y2BbhasbmZXF9QQ7T3kePo=
|
||||
github.com/jackc/chunkreader/v2 v2.0.0/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk=
|
||||
|
@ -368,6 +404,7 @@ github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7V
|
|||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs=
|
||||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8=
|
||||
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
|
||||
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
|
@ -395,8 +432,9 @@ github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
|||
github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
github.com/lib/pq v1.3.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
github.com/lib/pq v1.10.2 h1:AqzbZs4ZoCBp+GtejcpCpcxM3zlSMx29dXbUSeVtJb8=
|
||||
github.com/lib/pq v1.10.2/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||
github.com/lib/pq v1.10.7 h1:p7ZhMD+KsSRozJr34udlUrhboJwWAgCg34+/ZZNvZZw=
|
||||
github.com/lib/pq v1.10.7/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||
github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM=
|
||||
github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4=
|
||||
github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ=
|
||||
|
@ -424,8 +462,8 @@ github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/
|
|||
github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
|
||||
github.com/mattn/go-sqlite3 v1.10.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
||||
github.com/mattn/go-sqlite3 v1.14.9/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
|
||||
github.com/mattn/go-sqlite3 v2.0.3+incompatible h1:gXHsfypPkaMZrKbD5209QV9jbUTJKjyR5WD3HYQSd+U=
|
||||
github.com/mattn/go-sqlite3 v2.0.3+incompatible/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
||||
github.com/mattn/go-sqlite3 v1.14.16 h1:yOQRA0RpS5PFz/oikGwBEqvAWhWg5ufRz4ETLjwpU1Y=
|
||||
github.com/mattn/go-sqlite3 v1.14.16/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
|
||||
github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
|
||||
|
@ -437,6 +475,9 @@ 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.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
|
||||
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.0.0-20201216013528-df9cb8a40635 h1:rzf0wL0CHVc8CEsgyygG0Mn9CNCCPZqOPaz8RiiHYQk=
|
||||
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-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
|
@ -446,6 +487,7 @@ 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/mojocn/base64Captcha v1.3.5 h1:Qeilr7Ta6eDtG4S+tQuZ5+hO+QHbiGAJdi4PfoagaA0=
|
||||
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/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg=
|
||||
github.com/nats-io/jwt v0.3.2/go.mod h1:/euKqTS1ZD+zzjYrY7pseZrTtWQSjujC7xjPc8wL6eU=
|
||||
|
@ -466,6 +508,14 @@ github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+W
|
|||
github.com/onsi/gomega v1.4.3 h1:RE1xgDvH7imwFD45h+u2SgIfERHlS2yNG4DObb5BSKU=
|
||||
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk=
|
||||
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
|
||||
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/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
|
||||
github.com/opencontainers/runc v1.1.2 h1:2VSZwLx5k/BfsBxMMipG/LYUnmqOD/BPkIVgQUcTlLw=
|
||||
github.com/opencontainers/runc v1.1.2/go.mod h1:Tj1hFw6eFWp/o33uxGf5yF2BX5yz2Z6iptFpuvbbKqc=
|
||||
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/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74=
|
||||
github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
|
||||
|
@ -474,6 +524,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.2.1/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.9.1/go.mod h1:42Ir9hmvaAPm0Mgibk6mBPi7SFvTXxEcnztDYOJ//uM=
|
||||
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 v1.0.0/go.mod h1:LskTG5wDwr8Rs+nNQ+1LlxRjAtTZZjtJW4rMXl6j4vs=
|
||||
|
@ -535,18 +587,19 @@ github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb
|
|||
github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E=
|
||||
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
|
||||
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.1 h1:GFdvPtNxvVVjnDM4ty02D/+4unHwG9PmjcOZSc2wRXE=
|
||||
github.com/segmentfault/pacman v1.0.1/go.mod h1:5lNp5REd8QMThmBUvR3Fi9Y3AsOB4GRq7soCB4QLqOs=
|
||||
github.com/segmentfault/pacman/contrib/cache/memory v0.0.0-20220929065758-260b3093a347 h1:0xWBBXHHuemzMY61KYJXh7F5FW/4K8g98RYKNXodTCc=
|
||||
github.com/segmentfault/pacman/contrib/cache/memory v0.0.0-20220929065758-260b3093a347/go.mod h1:rmf1TCwz67dyM+AmTwSd1BxTo2AOYHj262lP93bOZbs=
|
||||
github.com/segmentfault/pacman/contrib/conf/viper v0.0.0-20220929065758-260b3093a347 h1:WpnEbmZFE8FYIgvseX+NJtDgGJlM1KSaKJhoxJywUgo=
|
||||
github.com/segmentfault/pacman/contrib/conf/viper v0.0.0-20220929065758-260b3093a347/go.mod h1:prPjFam7MyZ5b3S9dcDOt2tMPz6kf7C9c243s9zSwPY=
|
||||
github.com/segmentfault/pacman/contrib/i18n v0.0.0-20220929065758-260b3093a347 h1:Q29Ky9ZUGhdLIygfX6jwPYeEa7Wqn8o3f1NJWb8LvvE=
|
||||
github.com/segmentfault/pacman/contrib/i18n v0.0.0-20220929065758-260b3093a347/go.mod h1:5Afm+OQdau/HQqSOp/ALlSUp0vZsMMMbv//kJhxuoi8=
|
||||
github.com/segmentfault/pacman/contrib/log/zap v0.0.0-20220929065758-260b3093a347 h1:7Adjc296AKv32dg88S0T8t9K3+N+PFYLSCctpPnCUr0=
|
||||
github.com/segmentfault/pacman/contrib/log/zap v0.0.0-20220929065758-260b3093a347/go.mod h1:L4GqtXLoR73obTYqUQIzfkm8NG8pvZafxFb6KZFSSHk=
|
||||
github.com/segmentfault/pacman/contrib/server/http v0.0.0-20220929065758-260b3093a347 h1:CfuRhTPK2CBQIZruq5ceuTVthspe8U1FDjWXXI2RWdo=
|
||||
github.com/segmentfault/pacman/contrib/server/http v0.0.0-20220929065758-260b3093a347/go.mod h1:UjNiOFYv1uGCq1ZCcONaKq4eE7MW3nbgpLqgl8f9N40=
|
||||
github.com/segmentfault/pacman/contrib/cache/memory v0.0.0-20221018072427-a15dd1434e05 h1:rXsXgC/HR7m4V425l9pDBW/qxJv6zCh6pEvvO1ZCNsI=
|
||||
github.com/segmentfault/pacman/contrib/cache/memory v0.0.0-20221018072427-a15dd1434e05/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/go.mod h1:prPjFam7MyZ5b3S9dcDOt2tMPz6kf7C9c243s9zSwPY=
|
||||
github.com/segmentfault/pacman/contrib/i18n v0.0.0-20221018072427-a15dd1434e05 h1:gFCY9KUxhYg+/MXNcDYl4ILK+R1SG78FtaSR3JqZNYY=
|
||||
github.com/segmentfault/pacman/contrib/i18n v0.0.0-20221018072427-a15dd1434e05/go.mod h1:5Afm+OQdau/HQqSOp/ALlSUp0vZsMMMbv//kJhxuoi8=
|
||||
github.com/segmentfault/pacman/contrib/log/zap v0.0.0-20221018072427-a15dd1434e05 h1:jcGZU2juv0L3eFEkuZYV14ESLUlWfGMWnP0mjOfrSZc=
|
||||
github.com/segmentfault/pacman/contrib/log/zap v0.0.0-20221018072427-a15dd1434e05/go.mod h1:L4GqtXLoR73obTYqUQIzfkm8NG8pvZafxFb6KZFSSHk=
|
||||
github.com/segmentfault/pacman/contrib/server/http v0.0.0-20221018072427-a15dd1434e05 h1:91is1nKNbfTOl8CvMYiFgg4c5Vmol+5mVmMV/jDXD+A=
|
||||
github.com/segmentfault/pacman/contrib/server/http v0.0.0-20221018072427-a15dd1434e05/go.mod h1:UjNiOFYv1uGCq1ZCcONaKq4eE7MW3nbgpLqgl8f9N40=
|
||||
github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4=
|
||||
github.com/shopspring/decimal v0.0.0-20200227202807-02e2044944cc/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
|
||||
github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
|
||||
|
@ -554,6 +607,9 @@ 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.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
|
||||
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.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE=
|
||||
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/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
|
||||
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
|
||||
|
@ -563,11 +619,12 @@ github.com/spf13/afero v1.9.2/go.mod h1:iUV7ddyEEZPO5gA3zD4fJt6iStLlL+Lg4m2cihcD
|
|||
github.com/spf13/cast v1.5.0 h1:rj3WzYc11XZaIZMPKmwP96zkFEnnAmV8s6XbB2aY32w=
|
||||
github.com/spf13/cast v1.5.0/go.mod h1:SpXXQ5YoyJw6s3/6cMTQuxvgRl3PCJiyaX9p6b155UU=
|
||||
github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
|
||||
github.com/spf13/cobra v1.5.0 h1:X+jTBEBqF0bHN+9cSMgmfuvv2VHJ9ezmFNf9Y/XstYU=
|
||||
github.com/spf13/cobra v1.5.0/go.mod h1:dWXEIy2H428czQCjInthrTRUg7yKbok+2Qi/yBIJoUM=
|
||||
github.com/spf13/cobra v1.6.1 h1:o94oiPyS4KD1mPy2fmcYYHHfCxLqYjJOhGsCHFZtEzA=
|
||||
github.com/spf13/cobra v1.6.1/go.mod h1:IOw/AERYS7UzyrGinqmz6HLUo219MORXGxhbaJUqzrY=
|
||||
github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk=
|
||||
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.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/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/spf13/viper v1.13.0 h1:BWSJ/M+f+3nmdz9bxB+bWX28kkALN2ok11D0rSo8EJU=
|
||||
|
@ -579,6 +636,7 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+
|
|||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
|
@ -586,8 +644,9 @@ github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5
|
|||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
|
||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/subosito/gotenv v1.4.1 h1:jyEFiXpy21Wm81FBN71l9VoMMV8H8jG+qIK3GCpY6Qs=
|
||||
github.com/subosito/gotenv v1.4.1/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0=
|
||||
github.com/swaggo/files v0.0.0-20220728132757-551d4a08d97a h1:kAe4YSu0O0UFn1DowNo2MY5p6xzqtJ/wQ7LZynSvGaY=
|
||||
|
@ -595,8 +654,9 @@ github.com/swaggo/files v0.0.0-20220728132757-551d4a08d97a/go.mod h1:lKJPbtWzJ9J
|
|||
github.com/swaggo/gin-swagger v1.5.3 h1:8mWmHLolIbrhJJTflsaFoZzRBYVmEE7JZGIq08EiC0Q=
|
||||
github.com/swaggo/gin-swagger v1.5.3/go.mod h1:3XJKSfHjDMB5dBo/0rrTXidPmgLeqsX89Yp4uA50HpI=
|
||||
github.com/swaggo/swag v1.8.1/go.mod h1:ugemnJsPZm/kRwFUnzBlbHRd0JY9zE1M4F+uy2pAaPQ=
|
||||
github.com/swaggo/swag v1.8.6 h1:2rgOaLbonWu1PLP6G+/rYjSvPg0jQE0HtrEKuE380eg=
|
||||
github.com/swaggo/swag v1.8.6/go.mod h1:jMLeXOOmYyjk8PvHTsXBdrubsNd9gUJTTCzL5iBnseg=
|
||||
github.com/swaggo/swag v1.8.7 h1:2K9ivTD3teEO+2fXV6zrZKDqk5IuU2aJtBDo8U7omWU=
|
||||
github.com/swaggo/swag v1.8.7/go.mod h1:ezQVUUhly8dludpVk+/PuwJWvLLanB13ygV5Pr9enSk=
|
||||
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/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ=
|
||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
||||
|
@ -608,12 +668,21 @@ github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95
|
|||
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/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/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/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74=
|
||||
github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y=
|
||||
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
|
||||
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||
github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q=
|
||||
github.com/ziutek/mymysql v1.5.4/go.mod h1:LMSpPZ6DbqWFxNCHW77HeMg9I646SAhApZ/wKdgO/C0=
|
||||
go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
|
||||
|
@ -663,10 +732,11 @@ golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm
|
|||
golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
|
||||
golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/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-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.0.0-20220926161630-eccd6366d1be h1:fmw3UbQh+nxngCAHrDCCztao/kbYFnWjoqop8dHx05A=
|
||||
golang.org/x/crypto v0.0.0-20220926161630-eccd6366d1be/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.1.0 h1:MDRAIl0xIo9Io2xV565hzXHw3zVseKrJKodhohM5CjU=
|
||||
golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw=
|
||||
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-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
||||
|
@ -681,8 +751,8 @@ golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMx
|
|||
golang.org/x/image v0.0.0-20190501045829-6d32002ffd75/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
|
||||
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||
golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||
golang.org/x/image v0.0.0-20220902085622-e7cb96979f69 h1:Lj6HJGCSn5AjxRAH2+r35Mir4icalbqku+CLUtjnvXY=
|
||||
golang.org/x/image v0.0.0-20220902085622-e7cb96979f69/go.mod h1:doUCurBvlfPMKfmIpRIywoHmhN3VyhnoFDbvIEWF4hY=
|
||||
golang.org/x/image v0.1.0 h1:r8Oj8ZA2Xy12/b5KZYj3tuv7NG/fBz3TwQVvpJ9l8Rk=
|
||||
golang.org/x/image v0.1.0/go.mod h1:iyPr49SD/G/TBxYVB/9RRtGUT5eNbo2u4NamWeQcD5c=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
|
@ -705,7 +775,8 @@ golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
|||
golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 h1:6zppjxzCulZykYSLyVDYbneBfbaBIQPYMevg0bEwv2s=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||
golang.org/x/mod v0.6.0 h1:b9gGHsz9/HhJ3HF5DHQytPpuwocVTChQJK3AvoLRD5I=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
|
@ -749,8 +820,9 @@ golang.org/x/net v0.0.0-20210421230115-4e50805a0758/go.mod h1:72T/g9IO56b78aLF+1
|
|||
golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
|
||||
golang.org/x/net v0.0.0-20220927171203-f486391704dc h1:FxpXZdoBqT8RjqTy6i1E8nXHhW21wK7ptQ/EPIGxzPQ=
|
||||
golang.org/x/net v0.0.0-20220927171203-f486391704dc/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/net v0.1.0 h1:hZ/3BUoy5aId7sCpA/Tc5lt8DkFgdVS2onTpJsZ/fl0=
|
||||
golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco=
|
||||
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-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
|
@ -771,6 +843,7 @@ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJ
|
|||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
|
@ -788,12 +861,14 @@ 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-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-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-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-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-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-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
|
@ -811,6 +886,7 @@ 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-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-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-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
|
@ -818,6 +894,7 @@ 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-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-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-20210420072515-93ed5bcd2bfe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
|
@ -827,12 +904,17 @@ golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBc
|
|||
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-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-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-20220412211240-33da011f77ad/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-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220928140112-f11e5e49a4ec h1:BkDtF2Ih9xZ7le9ndzTA7KJow28VbQW3odyk/8drmuI=
|
||||
golang.org/x/sys v0.0.0-20220928140112-f11e5e49a4ec/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.1.0 h1:kunALQeHf1/185U1i0GOB/fy1IPRDDpuoOOqRReG57U=
|
||||
golang.org/x/sys v0.1.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-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
|
@ -843,8 +925,9 @@ golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
|||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/text v0.4.0 h1:BrVqGRd7+k1DiOgtnFvAkoQEWQvBc25ouMJM6429SFg=
|
||||
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
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-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
|
@ -865,6 +948,7 @@ 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-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-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-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20190823170909-c4a336ef6a2f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
|
@ -895,6 +979,7 @@ golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roY
|
|||
golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
||||
golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
||||
golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
||||
|
@ -904,11 +989,13 @@ golang.org/x/tools v0.0.0-20201124115921-2c860bdd6e78/go.mod h1:emZCQorbCU4vsT4f
|
|||
golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
|
||||
golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo=
|
||||
golang.org/x/tools v0.1.12 h1:VveCTK38A2rkS8ZqFY25HIDFscX5X9OoEhJd3quQmXU=
|
||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||
golang.org/x/tools v0.2.0 h1:G6AHpWxTMGY1KyEYoAQ5WTtIekUUvDNjan3ugu60JvE=
|
||||
golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA=
|
||||
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-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
|
@ -1013,6 +1100,7 @@ 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.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.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.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w=
|
||||
google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||
|
@ -1051,6 +1139,8 @@ 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.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
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.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-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
|
|
|
@ -1,91 +1,93 @@
|
|||
base:
|
||||
success:
|
||||
other: "success"
|
||||
other: "Success."
|
||||
unknown:
|
||||
other: "unknown error"
|
||||
other: "Unknown error."
|
||||
request_format_error:
|
||||
other: "request format is not valid"
|
||||
other: "Request format is not valid."
|
||||
unauthorized_error:
|
||||
other: "unauthorized"
|
||||
other: "Unauthorized."
|
||||
database_error:
|
||||
other: "data server error"
|
||||
other: "Data server error."
|
||||
|
||||
email:
|
||||
other: "email"
|
||||
other: "Email"
|
||||
password:
|
||||
other: "password"
|
||||
other: "Password"
|
||||
|
||||
email_or_password_wrong_error: &email_or_password_wrong
|
||||
other: "email or password wrong"
|
||||
other: "Email and password do not match."
|
||||
|
||||
error:
|
||||
admin:
|
||||
email_or_password_wrong: *email_or_password_wrong
|
||||
answer:
|
||||
not_found:
|
||||
other: "answer not found"
|
||||
other: "Answer do not found."
|
||||
comment:
|
||||
edit_without_permission:
|
||||
other: "comment not allowed to edit"
|
||||
other: "Comment are not allowed to edit."
|
||||
not_found:
|
||||
other: "comment not found"
|
||||
other: "Comment not found."
|
||||
email:
|
||||
duplicate:
|
||||
other: "email already exists"
|
||||
other: "Email already exists."
|
||||
need_to_be_verified:
|
||||
other: "email should be verified"
|
||||
other: "Email should be verified."
|
||||
verify_url_expired:
|
||||
other: "email verified url is expired, please resend the email"
|
||||
other: "Email verified URL has expired, please resend the email."
|
||||
lang:
|
||||
not_found:
|
||||
other: "language not found"
|
||||
other: "Language file not found."
|
||||
object:
|
||||
captcha_verification_failed:
|
||||
other: "captcha wrong"
|
||||
other: "Captcha wrong."
|
||||
disallow_follow:
|
||||
other: "You are not allowed to follow"
|
||||
other: "You are not allowed to follow."
|
||||
disallow_vote:
|
||||
other: "You are not allowed to vote"
|
||||
other: "You are not allowed to vote."
|
||||
disallow_vote_your_self:
|
||||
other: "You can't vote for your own post!"
|
||||
other: "You can't vote for your own post."
|
||||
not_found:
|
||||
other: "object not found"
|
||||
other: "Object not found."
|
||||
verification_failed:
|
||||
other: "verification failed"
|
||||
other: "Verification failed."
|
||||
email_or_password_incorrect:
|
||||
other: "email or password incorrect"
|
||||
other: "Email and password do not match."
|
||||
old_password_verification_failed:
|
||||
other: "the old password verification failed"
|
||||
other: "The old password verification failed"
|
||||
new_password_same_as_previous_setting:
|
||||
other: "The new password is the same as the previous setting"
|
||||
other: "The new password is the same as the previous one."
|
||||
question:
|
||||
not_found:
|
||||
other: "question not found"
|
||||
other: "Question not found."
|
||||
rank:
|
||||
fail_to_meet_the_condition:
|
||||
other: "rank fail to meet the condition"
|
||||
other: "Rank fail to meet the condition."
|
||||
report:
|
||||
handle_failed:
|
||||
other: "report handle failed"
|
||||
other: "Report handle failed."
|
||||
not_found:
|
||||
other: "report not found"
|
||||
other: "Report not found."
|
||||
tag:
|
||||
not_found:
|
||||
other: "tag not found"
|
||||
other: "Tag not found."
|
||||
theme:
|
||||
not_found:
|
||||
other: "theme not found"
|
||||
other: "Theme not found."
|
||||
user:
|
||||
email_or_password_wrong:
|
||||
other: *email_or_password_wrong
|
||||
not_found:
|
||||
other: "user not found"
|
||||
other: "User not found."
|
||||
suspended:
|
||||
other: "user is suspended"
|
||||
other: "User has been suspended."
|
||||
username_invalid:
|
||||
other: "username is invalid"
|
||||
other: "Username is invalid."
|
||||
username_duplicate:
|
||||
other: "username is already in use"
|
||||
other: "Username is already in use."
|
||||
set_avatar:
|
||||
other: "Avatar set failed."
|
||||
|
||||
report:
|
||||
spam:
|
||||
|
@ -161,10 +163,10 @@ notification:
|
|||
mention_you:
|
||||
other: "mentioned you"
|
||||
your_question_is_closed:
|
||||
other: "your question has been closed"
|
||||
other: "Your question has been closed"
|
||||
your_question_was_deleted:
|
||||
other: "your question has been deleted"
|
||||
other: "Your question has been deleted"
|
||||
your_answer_was_deleted:
|
||||
other: "your answer has been deleted"
|
||||
other: "Your answer has been deleted"
|
||||
your_comment_was_deleted:
|
||||
other: "your comment has been deleted"
|
||||
other: "Your comment has been deleted"
|
||||
|
|
|
@ -0,0 +1,170 @@
|
|||
base:
|
||||
success:
|
||||
other: "Successo"
|
||||
unknown:
|
||||
other: "Errore sconosciuto"
|
||||
request_format_error:
|
||||
other: "Il formato della richiesta non è valido"
|
||||
unauthorized_error:
|
||||
other: "Non autorizzato"
|
||||
database_error:
|
||||
other: "Errore server dati"
|
||||
|
||||
email:
|
||||
other: "email"
|
||||
password:
|
||||
other: "password"
|
||||
|
||||
email_or_password_wrong_error: &email_or_password_wrong
|
||||
other: "Email o password errati"
|
||||
|
||||
error:
|
||||
admin:
|
||||
email_or_password_wrong: *email_or_password_wrong
|
||||
answer:
|
||||
not_found:
|
||||
other: "Risposta non trovata"
|
||||
comment:
|
||||
edit_without_permission:
|
||||
other: "Non si hanno di privilegi sufficienti per modificare il commento"
|
||||
not_found:
|
||||
other: "Commento non trovato"
|
||||
email:
|
||||
duplicate:
|
||||
other: "email già esistente"
|
||||
need_to_be_verified:
|
||||
other: "email deve essere verificata"
|
||||
verify_url_expired:
|
||||
other: "l'url di verifica email è scaduto, si prega di reinviare la email"
|
||||
lang:
|
||||
not_found:
|
||||
other: "lingua non trovata"
|
||||
object:
|
||||
captcha_verification_failed:
|
||||
other: "captcha errato"
|
||||
disallow_follow:
|
||||
other: "Non sei autorizzato a seguire"
|
||||
disallow_vote:
|
||||
other: "non sei autorizzato a votare"
|
||||
disallow_vote_your_self:
|
||||
other: "Non puoi votare un tuo post!"
|
||||
not_found:
|
||||
other: "oggetto non trovato"
|
||||
verification_failed:
|
||||
other: "verifica fallita"
|
||||
email_or_password_incorrect:
|
||||
other: "email o password incorretti"
|
||||
old_password_verification_failed:
|
||||
other: "la verifica della vecchia password è fallita"
|
||||
new_password_same_as_previous_setting:
|
||||
other: "La nuova password è identica alla precedente"
|
||||
question:
|
||||
not_found:
|
||||
other: "domanda non trovata"
|
||||
rank:
|
||||
fail_to_meet_the_condition:
|
||||
other: "Condizioni non valide per il grado"
|
||||
report:
|
||||
handle_failed:
|
||||
other: "Gestione del report fallita"
|
||||
not_found:
|
||||
other: "Report non trovato"
|
||||
tag:
|
||||
not_found:
|
||||
other: "Etichetta non trovata"
|
||||
theme:
|
||||
not_found:
|
||||
other: "tema non trovato"
|
||||
user:
|
||||
email_or_password_wrong:
|
||||
other: *email_or_password_wrong
|
||||
not_found:
|
||||
other: "utente non trovato"
|
||||
suspended:
|
||||
other: "utente sospeso"
|
||||
username_invalid:
|
||||
other: "utente non valido"
|
||||
username_duplicate:
|
||||
other: "utente già in uso"
|
||||
|
||||
report:
|
||||
spam:
|
||||
name:
|
||||
other: "spam"
|
||||
description:
|
||||
other: "Questo articolo è una pubblicità o vandalismo. Non è utile o rilevante all'argomento corrente"
|
||||
rude:
|
||||
name:
|
||||
other: "scortese o violento"
|
||||
description:
|
||||
other: "Una persona ragionevole trova questo contenuto inappropriato a un discorso rispettoso"
|
||||
duplicate:
|
||||
name:
|
||||
other: "duplicato"
|
||||
description:
|
||||
other: "Questa domanda è già stata posta e ha già una risposta."
|
||||
not_answer:
|
||||
name:
|
||||
other: "non è una risposta"
|
||||
description:
|
||||
other: "Questo è stato postato come una risposta, ma non sta cercando di rispondere alla domanda. Dovrebbe essere una modifica, un commento, un'altra domanda o cancellato del tutto."
|
||||
not_need:
|
||||
name:
|
||||
other: "non più necessario"
|
||||
description:
|
||||
other: "Questo commento è datato, conversazionale o non rilevante a questo articolo."
|
||||
other:
|
||||
name:
|
||||
other: "altro"
|
||||
description:
|
||||
other: "Questo articolo richiede una supervisione dello staff per altre ragioni non listate sopra."
|
||||
|
||||
question:
|
||||
close:
|
||||
duplicate:
|
||||
name:
|
||||
other: "spam"
|
||||
description:
|
||||
other: "Questa domanda è già stata chiesta o ha già una risposta."
|
||||
guideline:
|
||||
name:
|
||||
other: "motivo legato alla community"
|
||||
description:
|
||||
other: "Questa domanda non soddisfa le linee guida della comunità."
|
||||
multiple:
|
||||
name:
|
||||
other: "richiede maggiori dettagli o chiarezza"
|
||||
description:
|
||||
other: "Questa domanda attualmente contiene più domande. Deve concentrarsi solamente su un unico problema."
|
||||
other:
|
||||
name:
|
||||
other: "altro"
|
||||
description:
|
||||
other: "Questo articolo richiede un'altro motivo non listato sopra."
|
||||
|
||||
notification:
|
||||
action:
|
||||
update_question:
|
||||
other: "domanda aggiornata"
|
||||
answer_the_question:
|
||||
other: "domanda risposta"
|
||||
update_answer:
|
||||
other: "risposta aggiornata"
|
||||
adopt_answer:
|
||||
other: "risposta accettata"
|
||||
comment_question:
|
||||
other: "domanda commentata"
|
||||
comment_answer:
|
||||
other: "risposta commentata"
|
||||
reply_to_you:
|
||||
other: "hai ricevuto risposta"
|
||||
mention_you:
|
||||
other: "sei stato menzionato"
|
||||
your_question_is_closed:
|
||||
other: "la tua domanda è stata chiusa"
|
||||
your_question_was_deleted:
|
||||
other: "la tua domanda è stata rimossa"
|
||||
your_answer_was_deleted:
|
||||
other: "la tua risposta è stata rimossa"
|
||||
your_comment_was_deleted:
|
||||
other: "il tuo commento è stato rimosso"
|
|
@ -86,6 +86,8 @@ error:
|
|||
other: "用户名无效"
|
||||
username_duplicate:
|
||||
other: "用户名已被使用"
|
||||
set_avatar:
|
||||
other: "头像设置错误"
|
||||
|
||||
report:
|
||||
spam:
|
||||
|
|
|
@ -3,7 +3,7 @@ package constant
|
|||
import "time"
|
||||
|
||||
const (
|
||||
Default_PageSize = 20 //Default number of pages
|
||||
DefaultPageSize = 20 // Default number of pages
|
||||
UserStatusChangedCacheKey = "answer:user:status:"
|
||||
UserStatusChangedCacheTime = 7 * 24 * time.Hour
|
||||
UserTokenCacheKey = "answer:user:token:"
|
||||
|
|
|
@ -13,7 +13,7 @@ const (
|
|||
ReportNotAnswerDescription = "report.not_answer.description"
|
||||
ReportNotNeedName = "report.not_need.name"
|
||||
ReportNotNeedDescription = "report.not_need.description"
|
||||
//question close
|
||||
// question close
|
||||
QuestionCloseDuplicateName = "question.close.duplicate.name"
|
||||
QuestionCloseDuplicateDescription = "question.close.duplicate.description"
|
||||
QuestionCloseGuidelineName = "question.close.guideline.name"
|
||||
|
@ -27,8 +27,8 @@ const (
|
|||
const (
|
||||
// TODO put this in database
|
||||
// TODO need reason controller to resolve
|
||||
QuestionCloseJson = `[{"name":"question.close.duplicate.name","description":"question.close.duplicate.description","source":"question","type":1,"have_content":false,"content_type":""},{"name":"question.close.guideline.name","description":"question.close.guideline.description","source":"question","type":2,"have_content":false,"content_type":""},{"name":"question.close.multiple.name","description":"question.close.multiple.description","source":"question","type":3,"have_content":true,"content_type":"text"},{"name":"question.close.other.name","description":"question.close.other.description","source":"question","type":4,"have_content":true,"content_type":"textarea"}]`
|
||||
QuestionReportJson = `[{"name":"report.spam.name","description":"report.spam.description","source":"question","type":1,"have_content":false,"content_type":""},{"name":"report.rude.name","description":"report.rude.description","source":"question","type":2,"have_content":false,"content_type":""},{"name":"report.duplicate.name","description":"report.duplicate.description","source":"question","type":3,"have_content":true,"content_type":"text"},{"name":"report.other.name","description":"report.other.description","source":"question","type":4,"have_content":true,"content_type":"textarea"}]`
|
||||
AnswerReportJson = `[{"name":"report.spam.name","description":"report.spam.description","source":"answer","type":1,"have_content":false,"content_type":""},{"name":"report.rude.name","description":"report.rude.description","source":"answer","type":2,"have_content":false,"content_type":""},{"name":"report.not_answer.name","description":"report.not_answer.description","source":"answer","type":3,"have_content":false,"content_type":""},{"name":"report.other.name","description":"report.other.description","source":"answer","type":4,"have_content":true,"content_type":"textarea"}]`
|
||||
CommentReportJson = `[{"name":"report.spam.name","description":"report.spam.description","source":"comment","type":1,"have_content":false,"content_type":""},{"name":"report.rude.name","description":"report.rude.description","source":"comment","type":2,"have_content":false,"content_type":""},{"name":"report.not_need.name","description":"report.not_need.description","source":"comment","type":3,"have_content":true,"content_type":"text"},{"name":"report.other.name","description":"report.other.description","source":"comment","type":4,"have_content":true,"content_type":"textarea"}]`
|
||||
QuestionCloseJSON = `[{"name":"question.close.duplicate.name","description":"question.close.duplicate.description","source":"question","type":1,"have_content":false,"content_type":""},{"name":"question.close.guideline.name","description":"question.close.guideline.description","source":"question","type":2,"have_content":false,"content_type":""},{"name":"question.close.multiple.name","description":"question.close.multiple.description","source":"question","type":3,"have_content":true,"content_type":"text"},{"name":"question.close.other.name","description":"question.close.other.description","source":"question","type":4,"have_content":true,"content_type":"textarea"}]`
|
||||
QuestionReportJSON = `[{"name":"report.spam.name","description":"report.spam.description","source":"question","type":1,"have_content":false,"content_type":""},{"name":"report.rude.name","description":"report.rude.description","source":"question","type":2,"have_content":false,"content_type":""},{"name":"report.duplicate.name","description":"report.duplicate.description","source":"question","type":3,"have_content":true,"content_type":"text"},{"name":"report.other.name","description":"report.other.description","source":"question","type":4,"have_content":true,"content_type":"textarea"}]`
|
||||
AnswerReportJSON = `[{"name":"report.spam.name","description":"report.spam.description","source":"answer","type":1,"have_content":false,"content_type":""},{"name":"report.rude.name","description":"report.rude.description","source":"answer","type":2,"have_content":false,"content_type":""},{"name":"report.not_answer.name","description":"report.not_answer.description","source":"answer","type":3,"have_content":false,"content_type":""},{"name":"report.other.name","description":"report.other.description","source":"answer","type":4,"have_content":true,"content_type":"textarea"}]`
|
||||
CommentReportJSON = `[{"name":"report.spam.name","description":"report.spam.description","source":"comment","type":1,"have_content":false,"content_type":""},{"name":"report.rude.name","description":"report.rude.description","source":"comment","type":2,"have_content":false,"content_type":""},{"name":"report.not_need.name","description":"report.not_need.description","source":"comment","type":3,"have_content":true,"content_type":"text"},{"name":"report.other.name","description":"report.other.description","source":"comment","type":4,"have_content":true,"content_type":"textarea"}]`
|
||||
)
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
package data
|
||||
|
||||
import (
|
||||
"path/filepath"
|
||||
"time"
|
||||
|
||||
"github.com/answerdev/answer/pkg/dir"
|
||||
_ "github.com/go-sql-driver/mysql"
|
||||
_ "github.com/lib/pq"
|
||||
_ "github.com/mattn/go-sqlite3"
|
||||
|
@ -35,6 +37,13 @@ func NewDB(debug bool, dataConf *Database) (*xorm.Engine, error) {
|
|||
if dataConf.Driver == "" {
|
||||
dataConf.Driver = string(schemas.MYSQL)
|
||||
}
|
||||
if dataConf.Driver == string(schemas.SQLITE) {
|
||||
dbFileDir := filepath.Dir(dataConf.Connection)
|
||||
log.Debugf("try to create database directory %s", dbFileDir)
|
||||
if err := dir.CreateDirIfNotExist(dbFileDir); err != nil {
|
||||
log.Errorf("create database dir failed: %s", err)
|
||||
}
|
||||
}
|
||||
engine, err := xorm.NewEngine(dataConf.Driver, dataConf.Connection)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -69,6 +78,12 @@ func NewCache(c *CacheConf) (cache.Cache, func(), error) {
|
|||
memCache := memory.NewCache()
|
||||
|
||||
if len(c.FilePath) > 0 {
|
||||
cacheFileDir := filepath.Dir(c.FilePath)
|
||||
log.Debugf("try to create cache directory %s", cacheFileDir)
|
||||
err := dir.CreateDirIfNotExist(cacheFileDir)
|
||||
if err != nil {
|
||||
log.Errorf("create cache dir failed: %s", err)
|
||||
}
|
||||
log.Infof("try to load cache file from %s", c.FilePath)
|
||||
if err := memory.Load(memCache, c.FilePath); err != nil {
|
||||
log.Warn(err)
|
||||
|
|
|
@ -40,7 +40,6 @@ func HandleResponse(ctx *gin.Context, err error, data interface{}) {
|
|||
respBody.Data = data
|
||||
}
|
||||
ctx.JSON(myErr.Code, respBody)
|
||||
return
|
||||
}
|
||||
|
||||
// BindAndCheck bind request and check
|
||||
|
|
|
@ -14,9 +14,7 @@ import (
|
|||
"github.com/segmentfault/pacman/errors"
|
||||
)
|
||||
|
||||
var (
|
||||
ctxUuidKey = "ctxUuidKey"
|
||||
)
|
||||
var ctxUUIDKey = "ctxUuidKey"
|
||||
|
||||
// AuthUserMiddleware auth user middleware
|
||||
type AuthUserMiddleware struct {
|
||||
|
@ -44,7 +42,7 @@ func (am *AuthUserMiddleware) Auth() gin.HandlerFunc {
|
|||
return
|
||||
}
|
||||
if userInfo != nil {
|
||||
ctx.Set(ctxUuidKey, userInfo)
|
||||
ctx.Set(ctxUUIDKey, userInfo)
|
||||
}
|
||||
ctx.Next()
|
||||
}
|
||||
|
@ -82,7 +80,7 @@ func (am *AuthUserMiddleware) MustAuth() gin.HandlerFunc {
|
|||
ctx.Abort()
|
||||
return
|
||||
}
|
||||
ctx.Set(ctxUuidKey, userInfo)
|
||||
ctx.Set(ctxUUIDKey, userInfo)
|
||||
ctx.Next()
|
||||
}
|
||||
}
|
||||
|
@ -107,7 +105,7 @@ func (am *AuthUserMiddleware) CmsAuth() gin.HandlerFunc {
|
|||
ctx.Abort()
|
||||
return
|
||||
}
|
||||
ctx.Set(ctxUuidKey, userInfo)
|
||||
ctx.Set(ctxUUIDKey, userInfo)
|
||||
}
|
||||
ctx.Next()
|
||||
}
|
||||
|
@ -115,7 +113,7 @@ func (am *AuthUserMiddleware) CmsAuth() gin.HandlerFunc {
|
|||
|
||||
// GetLoginUserIDFromContext get user id from context
|
||||
func GetLoginUserIDFromContext(ctx *gin.Context) (userID string) {
|
||||
userInfo, exist := ctx.Get(ctxUuidKey)
|
||||
userInfo, exist := ctx.Get(ctxUUIDKey)
|
||||
if !exist {
|
||||
return ""
|
||||
}
|
||||
|
@ -128,7 +126,7 @@ func GetLoginUserIDFromContext(ctx *gin.Context) (userID string) {
|
|||
|
||||
// GetUserInfoFromContext get user info from context
|
||||
func GetUserInfoFromContext(ctx *gin.Context) (u *entity.UserCacheInfo) {
|
||||
userInfo, exist := ctx.Get(ctxUuidKey)
|
||||
userInfo, exist := ctx.Get(ctxUUIDKey)
|
||||
if !exist {
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -26,8 +26,9 @@ const (
|
|||
UserNotFound = "error.user.not_found"
|
||||
UsernameInvalid = "error.user.username_invalid"
|
||||
UsernameDuplicate = "error.user.username_duplicate"
|
||||
UserSetAvatar = "error.user.set_avatar"
|
||||
EmailDuplicate = "error.email.duplicate"
|
||||
EmailVerifyUrlExpired = "error.email.verify_url_expired"
|
||||
EmailVerifyURLExpired = "error.email.verify_url_expired"
|
||||
EmailNeedToBeVerified = "error.email.need_to_be_verified"
|
||||
UserSuspended = "error.user.suspended"
|
||||
ObjectNotFound = "error.object.not_found"
|
||||
|
|
|
@ -9,7 +9,7 @@ import (
|
|||
"github.com/go-playground/locales"
|
||||
english "github.com/go-playground/locales/en"
|
||||
zhongwen "github.com/go-playground/locales/zh"
|
||||
"github.com/go-playground/universal-translator"
|
||||
ut "github.com/go-playground/universal-translator"
|
||||
"github.com/go-playground/validator/v10"
|
||||
"github.com/go-playground/validator/v10/translations/en"
|
||||
"github.com/go-playground/validator/v10/translations/zh"
|
||||
|
@ -31,10 +31,8 @@ type ErrorField struct {
|
|||
Value string `json:"value"`
|
||||
}
|
||||
|
||||
var (
|
||||
// GlobalValidatorMapping is a mapping from validator to translator used
|
||||
GlobalValidatorMapping = make(map[string]*MyValidator, 0)
|
||||
)
|
||||
// GlobalValidatorMapping is a mapping from validator to translator used
|
||||
var GlobalValidatorMapping = make(map[string]*MyValidator, 0)
|
||||
|
||||
func init() {
|
||||
zhTran, zhVal := getTran(zhongwen.New(), i18n.LanguageChinese.Abbr()), createDefaultValidator(i18n.LanguageChinese)
|
||||
|
|
|
@ -31,7 +31,6 @@ func InstallAllInitialEnvironment(dataDirPath string) {
|
|||
installUploadDir()
|
||||
installI18nBundle()
|
||||
fmt.Println("install all initial environment done")
|
||||
return
|
||||
}
|
||||
|
||||
func installConfigFile() {
|
||||
|
@ -96,7 +95,7 @@ func installI18nBundle() {
|
|||
}
|
||||
|
||||
func writerFile(filePath, content string) error {
|
||||
file, err := os.OpenFile(filePath, os.O_WRONLY|os.O_CREATE, 0666)
|
||||
file, err := os.OpenFile(filePath, os.O_WRONLY|os.O_CREATE, 0o666)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -62,9 +62,9 @@ func (ac *AnswerController) RemoveAnswer(ctx *gin.Context) {
|
|||
// @Success 200 {string} string ""
|
||||
func (ac *AnswerController) Get(ctx *gin.Context) {
|
||||
id := ctx.Query("id")
|
||||
userId := middleware.GetLoginUserIDFromContext(ctx)
|
||||
userID := middleware.GetLoginUserIDFromContext(ctx)
|
||||
|
||||
info, questionInfo, has, err := ac.answerService.Get(ctx, id, userId)
|
||||
info, questionInfo, has, err := ac.answerService.Get(ctx, id, userID)
|
||||
if err != nil {
|
||||
handler.HandleResponse(ctx, err, gin.H{})
|
||||
return
|
||||
|
@ -101,18 +101,18 @@ func (ac *AnswerController) Add(ctx *gin.Context) {
|
|||
return
|
||||
}
|
||||
|
||||
answerId, err := ac.answerService.Insert(ctx, req)
|
||||
answerID, err := ac.answerService.Insert(ctx, req)
|
||||
if err != nil {
|
||||
handler.HandleResponse(ctx, err, nil)
|
||||
return
|
||||
}
|
||||
info, questionInfo, has, err := ac.answerService.Get(ctx, answerId, req.UserID)
|
||||
info, questionInfo, has, err := ac.answerService.Get(ctx, answerID, req.UserID)
|
||||
if err != nil {
|
||||
handler.HandleResponse(ctx, err, nil)
|
||||
return
|
||||
}
|
||||
if !has {
|
||||
//todo !has
|
||||
// todo !has
|
||||
handler.HandleResponse(ctx, nil, nil)
|
||||
return
|
||||
}
|
||||
|
@ -120,7 +120,6 @@ func (ac *AnswerController) Add(ctx *gin.Context) {
|
|||
"info": info,
|
||||
"question": questionInfo,
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
// Update godoc
|
||||
|
@ -156,7 +155,7 @@ func (ac *AnswerController) Update(ctx *gin.Context) {
|
|||
return
|
||||
}
|
||||
if !has {
|
||||
//todo !has
|
||||
// todo !has
|
||||
handler.HandleResponse(ctx, nil, nil)
|
||||
return
|
||||
}
|
||||
|
|
|
@ -111,6 +111,6 @@ func (nc *NotificationController) GetList(ctx *gin.Context) {
|
|||
return
|
||||
}
|
||||
req.UserID = middleware.GetLoginUserIDFromContext(ctx)
|
||||
resp, err := nc.notificationService.GetList(ctx, req)
|
||||
resp, err := nc.notificationService.GetNotificationPage(ctx, req)
|
||||
handler.HandleResponse(ctx, err, resp)
|
||||
}
|
||||
|
|
|
@ -66,7 +66,7 @@ func (qc *QuestionController) CloseQuestion(ctx *gin.Context) {
|
|||
if handler.BindAndCheck(ctx, req) {
|
||||
return
|
||||
}
|
||||
req.UserId = middleware.GetLoginUserIDFromContext(ctx)
|
||||
req.UserID = middleware.GetLoginUserIDFromContext(ctx)
|
||||
err := qc.questionService.CloseQuestion(ctx, req)
|
||||
handler.HandleResponse(ctx, err, nil)
|
||||
}
|
||||
|
@ -114,7 +114,6 @@ func (qc *QuestionController) SimilarQuestion(ctx *gin.Context) {
|
|||
"list": list,
|
||||
"count": count,
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
// Index godoc
|
||||
|
@ -365,6 +364,7 @@ func (qc *QuestionController) UserCollectionList(ctx *gin.Context) {
|
|||
// @Param page query int false "page size"
|
||||
// @Param page_size query int false "page size"
|
||||
// @Param status query string false "user status" Enums(available, closed, deleted)
|
||||
// @Param query query string false "question id or title"
|
||||
// @Success 200 {object} handler.RespBody
|
||||
// @Router /answer/admin/api/question/page [get]
|
||||
func (qc *QuestionController) CmsSearchList(ctx *gin.Context) {
|
||||
|
@ -390,6 +390,8 @@ func (qc *QuestionController) CmsSearchList(ctx *gin.Context) {
|
|||
// @Param page query int false "page size"
|
||||
// @Param page_size query int false "page size"
|
||||
// @Param status query string false "user status" Enums(available,deleted)
|
||||
// @Param query query string false "answer id or question title"
|
||||
// @Param question_id query string false "question id"
|
||||
// @Success 200 {object} handler.RespBody
|
||||
// @Router /answer/admin/api/answer/page [get]
|
||||
func (qc *QuestionController) CmsSearchAnswerList(ctx *gin.Context) {
|
||||
|
|
|
@ -35,7 +35,8 @@ func NewUserController(
|
|||
userService *service.UserService,
|
||||
actionService *action.CaptchaService,
|
||||
emailService *export.EmailService,
|
||||
uploaderService *uploader.UploaderService) *UserController {
|
||||
uploaderService *uploader.UploaderService,
|
||||
) *UserController {
|
||||
return &UserController{
|
||||
authService: authService,
|
||||
userService: userService,
|
||||
|
@ -45,18 +46,25 @@ func NewUserController(
|
|||
}
|
||||
}
|
||||
|
||||
// GetUserInfoByUserID godoc
|
||||
// GetUserInfoByUserID get user info, if user no login response http code is 200, but user info is null
|
||||
// @Summary GetUserInfoByUserID
|
||||
// @Description GetUserInfoByUserID
|
||||
// @Description get user info, if user no login response http code is 200, but user info is null
|
||||
// @Tags User
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Security ApiKeyAuth
|
||||
// @Success 200 {object} handler.RespBody{data=schema.GetUserResp}
|
||||
// @Success 200 {object} handler.RespBody{data=schema.GetUserToSetShowResp}
|
||||
// @Router /answer/api/v1/user/info [get]
|
||||
func (uc *UserController) GetUserInfoByUserID(ctx *gin.Context) {
|
||||
userID := middleware.GetLoginUserIDFromContext(ctx)
|
||||
token := middleware.ExtractToken(ctx)
|
||||
|
||||
// if user is no login return null in data
|
||||
if len(token) == 0 || len(userID) == 0 {
|
||||
handler.HandleResponse(ctx, nil, nil)
|
||||
return
|
||||
}
|
||||
|
||||
resp, err := uc.userService.GetUserInfoByUserID(ctx, token, userID)
|
||||
handler.HandleResponse(ctx, err, resp)
|
||||
}
|
||||
|
@ -112,7 +120,7 @@ func (uc *UserController) UserEmailLogin(ctx *gin.Context) {
|
|||
return
|
||||
}
|
||||
|
||||
captchaPass := uc.actionService.ActionRecordVerifyCaptcha(ctx, schema.ActionRecord_Type_Login, ctx.ClientIP(), req.CaptchaID, req.CaptchaCode)
|
||||
captchaPass := uc.actionService.ActionRecordVerifyCaptcha(ctx, schema.ActionRecordTypeLogin, ctx.ClientIP(), req.CaptchaID, req.CaptchaCode)
|
||||
if !captchaPass {
|
||||
resp := schema.UserVerifyEmailErrorResponse{
|
||||
Key: "captcha_code",
|
||||
|
@ -125,7 +133,7 @@ func (uc *UserController) UserEmailLogin(ctx *gin.Context) {
|
|||
|
||||
resp, err := uc.userService.EmailLogin(ctx, req)
|
||||
if err != nil {
|
||||
_, _ = uc.actionService.ActionRecordAdd(ctx, schema.ActionRecord_Type_Login, ctx.ClientIP())
|
||||
_, _ = uc.actionService.ActionRecordAdd(ctx, schema.ActionRecordTypeLogin, ctx.ClientIP())
|
||||
resp := schema.UserVerifyEmailErrorResponse{
|
||||
Key: "e_mail",
|
||||
Value: "error.object.email_or_password_incorrect",
|
||||
|
@ -134,7 +142,7 @@ func (uc *UserController) UserEmailLogin(ctx *gin.Context) {
|
|||
handler.HandleResponse(ctx, errors.BadRequest(reason.CaptchaVerificationFailed), resp)
|
||||
return
|
||||
}
|
||||
uc.actionService.ActionRecordDel(ctx, schema.ActionRecord_Type_Login, ctx.ClientIP())
|
||||
uc.actionService.ActionRecordDel(ctx, schema.ActionRecordTypeLogin, ctx.ClientIP())
|
||||
handler.HandleResponse(ctx, nil, resp)
|
||||
}
|
||||
|
||||
|
@ -152,7 +160,7 @@ func (uc *UserController) RetrievePassWord(ctx *gin.Context) {
|
|||
if handler.BindAndCheck(ctx, req) {
|
||||
return
|
||||
}
|
||||
captchaPass := uc.actionService.ActionRecordVerifyCaptcha(ctx, schema.ActionRecord_Type_Find_Pass, ctx.ClientIP(), req.CaptchaID, req.CaptchaCode)
|
||||
captchaPass := uc.actionService.ActionRecordVerifyCaptcha(ctx, schema.ActionRecordTypeFindPass, ctx.ClientIP(), req.CaptchaID, req.CaptchaCode)
|
||||
if !captchaPass {
|
||||
resp := schema.UserVerifyEmailErrorResponse{
|
||||
Key: "captcha_code",
|
||||
|
@ -162,7 +170,7 @@ func (uc *UserController) RetrievePassWord(ctx *gin.Context) {
|
|||
handler.HandleResponse(ctx, errors.BadRequest(reason.CaptchaVerificationFailed), resp)
|
||||
return
|
||||
}
|
||||
_, _ = uc.actionService.ActionRecordAdd(ctx, schema.ActionRecord_Type_Find_Pass, ctx.ClientIP())
|
||||
_, _ = uc.actionService.ActionRecordAdd(ctx, schema.ActionRecordTypeFindPass, ctx.ClientIP())
|
||||
code, err := uc.userService.RetrievePassWord(ctx, req)
|
||||
handler.HandleResponse(ctx, err, code)
|
||||
}
|
||||
|
@ -184,13 +192,13 @@ func (uc *UserController) UseRePassWord(ctx *gin.Context) {
|
|||
|
||||
req.Content = uc.emailService.VerifyUrlExpired(ctx, req.Code)
|
||||
if len(req.Content) == 0 {
|
||||
handler.HandleResponse(ctx, errors.Forbidden(reason.EmailVerifyUrlExpired),
|
||||
&schema.ForbiddenResp{Type: schema.ForbiddenReasonTypeUrlExpired})
|
||||
handler.HandleResponse(ctx, errors.Forbidden(reason.EmailVerifyURLExpired),
|
||||
&schema.ForbiddenResp{Type: schema.ForbiddenReasonTypeURLExpired})
|
||||
return
|
||||
}
|
||||
|
||||
resp, err := uc.userService.UseRePassWord(ctx, req)
|
||||
uc.actionService.ActionRecordDel(ctx, schema.ActionRecord_Type_Find_Pass, ctx.ClientIP())
|
||||
resp, err := uc.userService.UseRePassword(ctx, req)
|
||||
uc.actionService.ActionRecordDel(ctx, schema.ActionRecordTypeFindPass, ctx.ClientIP())
|
||||
handler.HandleResponse(ctx, err, resp)
|
||||
}
|
||||
|
||||
|
@ -245,8 +253,8 @@ func (uc *UserController) UserVerifyEmail(ctx *gin.Context) {
|
|||
|
||||
req.Content = uc.emailService.VerifyUrlExpired(ctx, req.Code)
|
||||
if len(req.Content) == 0 {
|
||||
handler.HandleResponse(ctx, errors.Forbidden(reason.EmailVerifyUrlExpired),
|
||||
&schema.ForbiddenResp{Type: schema.ForbiddenReasonTypeUrlExpired})
|
||||
handler.HandleResponse(ctx, errors.Forbidden(reason.EmailVerifyURLExpired),
|
||||
&schema.ForbiddenResp{Type: schema.ForbiddenReasonTypeURLExpired})
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -256,7 +264,7 @@ func (uc *UserController) UserVerifyEmail(ctx *gin.Context) {
|
|||
return
|
||||
}
|
||||
|
||||
uc.actionService.ActionRecordDel(ctx, schema.ActionRecord_Type_Email, ctx.ClientIP())
|
||||
uc.actionService.ActionRecordDel(ctx, schema.ActionRecordTypeEmail, ctx.ClientIP())
|
||||
handler.HandleResponse(ctx, err, resp)
|
||||
}
|
||||
|
||||
|
@ -282,7 +290,7 @@ func (uc *UserController) UserVerifyEmailSend(ctx *gin.Context) {
|
|||
return
|
||||
}
|
||||
|
||||
captchaPass := uc.actionService.ActionRecordVerifyCaptcha(ctx, schema.ActionRecord_Type_Email, ctx.ClientIP(),
|
||||
captchaPass := uc.actionService.ActionRecordVerifyCaptcha(ctx, schema.ActionRecordTypeEmail, ctx.ClientIP(),
|
||||
req.CaptchaID, req.CaptchaCode)
|
||||
if !captchaPass {
|
||||
resp := schema.UserVerifyEmailErrorResponse{
|
||||
|
@ -294,7 +302,7 @@ func (uc *UserController) UserVerifyEmailSend(ctx *gin.Context) {
|
|||
|
||||
return
|
||||
}
|
||||
uc.actionService.ActionRecordAdd(ctx, schema.ActionRecord_Type_Email, ctx.ClientIP())
|
||||
uc.actionService.ActionRecordAdd(ctx, schema.ActionRecordTypeEmail, ctx.ClientIP())
|
||||
err := uc.userService.UserVerifyEmailSend(ctx, userInfo.UserID)
|
||||
handler.HandleResponse(ctx, err, nil)
|
||||
}
|
||||
|
@ -314,7 +322,7 @@ func (uc *UserController) UserModifyPassWord(ctx *gin.Context) {
|
|||
if handler.BindAndCheck(ctx, req) {
|
||||
return
|
||||
}
|
||||
req.UserId = middleware.GetLoginUserIDFromContext(ctx)
|
||||
req.UserID = middleware.GetLoginUserIDFromContext(ctx)
|
||||
|
||||
oldPassVerification, err := uc.userService.UserModifyPassWordVerification(ctx, req)
|
||||
if err != nil {
|
||||
|
@ -340,7 +348,7 @@ func (uc *UserController) UserModifyPassWord(ctx *gin.Context) {
|
|||
handler.HandleResponse(ctx, errors.BadRequest(reason.CaptchaVerificationFailed), resp)
|
||||
return
|
||||
}
|
||||
err = uc.userService.UserModifyPassWord(ctx, req)
|
||||
err = uc.userService.UserModifyPassword(ctx, req)
|
||||
handler.HandleResponse(ctx, err, nil)
|
||||
}
|
||||
|
||||
|
@ -360,7 +368,7 @@ func (uc *UserController) UserUpdateInfo(ctx *gin.Context) {
|
|||
if handler.BindAndCheck(ctx, req) {
|
||||
return
|
||||
}
|
||||
req.UserId = middleware.GetLoginUserIDFromContext(ctx)
|
||||
req.UserID = middleware.GetLoginUserIDFromContext(ctx)
|
||||
err := uc.userService.UpdateInfo(ctx, req)
|
||||
handler.HandleResponse(ctx, err, nil)
|
||||
}
|
||||
|
@ -438,7 +446,7 @@ func (uc *UserController) ActionRecord(ctx *gin.Context) {
|
|||
if handler.BindAndCheck(ctx, req) {
|
||||
return
|
||||
}
|
||||
req.Ip = ctx.ClientIP()
|
||||
req.IP = ctx.ClientIP()
|
||||
|
||||
resp, err := uc.actionService.ActionRecord(ctx, req)
|
||||
handler.HandleResponse(ctx, err, resp)
|
||||
|
@ -460,8 +468,8 @@ func (uc *UserController) UserNoticeSet(ctx *gin.Context) {
|
|||
return
|
||||
}
|
||||
|
||||
req.UserId = middleware.GetLoginUserIDFromContext(ctx)
|
||||
resp, err := uc.userService.UserNoticeSet(ctx, req.UserId, req.NoticeSwitch)
|
||||
req.UserID = middleware.GetLoginUserIDFromContext(ctx)
|
||||
resp, err := uc.userService.UserNoticeSet(ctx, req.UserID, req.NoticeSwitch)
|
||||
handler.HandleResponse(ctx, err, resp)
|
||||
}
|
||||
|
||||
|
@ -483,7 +491,7 @@ func (uc *UserController) UserChangeEmailSendCode(ctx *gin.Context) {
|
|||
// If the user is not logged in, the api cannot be used.
|
||||
// If the user email is not verified, that also can use this api to modify the email.
|
||||
|
||||
captchaPass := uc.actionService.ActionRecordVerifyCaptcha(ctx, schema.ActionRecord_Type_Email, ctx.ClientIP(), req.CaptchaID, req.CaptchaCode)
|
||||
captchaPass := uc.actionService.ActionRecordVerifyCaptcha(ctx, schema.ActionRecordTypeEmail, ctx.ClientIP(), req.CaptchaID, req.CaptchaCode)
|
||||
if !captchaPass {
|
||||
resp := schema.UserVerifyEmailErrorResponse{
|
||||
Key: "captcha_code",
|
||||
|
@ -498,7 +506,7 @@ func (uc *UserController) UserChangeEmailSendCode(ctx *gin.Context) {
|
|||
handler.HandleResponse(ctx, errors.Unauthorized(reason.UnauthorizedError), nil)
|
||||
return
|
||||
}
|
||||
_, _ = uc.actionService.ActionRecordAdd(ctx, schema.ActionRecord_Type_Email, ctx.ClientIP())
|
||||
_, _ = uc.actionService.ActionRecordAdd(ctx, schema.ActionRecordTypeEmail, ctx.ClientIP())
|
||||
err := uc.userService.UserChangeEmailSendCode(ctx, req)
|
||||
handler.HandleResponse(ctx, err, nil)
|
||||
}
|
||||
|
@ -520,12 +528,12 @@ func (uc *UserController) UserChangeEmailVerify(ctx *gin.Context) {
|
|||
}
|
||||
req.Content = uc.emailService.VerifyUrlExpired(ctx, req.Code)
|
||||
if len(req.Content) == 0 {
|
||||
handler.HandleResponse(ctx, errors.Forbidden(reason.EmailVerifyUrlExpired),
|
||||
&schema.ForbiddenResp{Type: schema.ForbiddenReasonTypeUrlExpired})
|
||||
handler.HandleResponse(ctx, errors.Forbidden(reason.EmailVerifyURLExpired),
|
||||
&schema.ForbiddenResp{Type: schema.ForbiddenReasonTypeURLExpired})
|
||||
return
|
||||
}
|
||||
|
||||
err := uc.userService.UserChangeEmailVerify(ctx, req.Content)
|
||||
uc.actionService.ActionRecordDel(ctx, schema.ActionRecord_Type_Email, ctx.ClientIP())
|
||||
uc.actionService.ActionRecordDel(ctx, schema.ActionRecordTypeEmail, ctx.ClientIP())
|
||||
handler.HandleResponse(ctx, err, nil)
|
||||
}
|
||||
|
|
|
@ -45,9 +45,8 @@ func (uc *UserBackyardController) UpdateUserStatus(ctx *gin.Context) {
|
|||
// @Produce json
|
||||
// @Param page query int false "page size"
|
||||
// @Param page_size query int false "page size"
|
||||
// @Param username query string false "username"
|
||||
// @Param e_mail query string false "email"
|
||||
// @Param status query string false "user status" Enums(normal, suspended, deleted, inactive)
|
||||
// @Param query query string false "search query: email, username or id:[id]"
|
||||
// @Param status query string false "user status" Enums(suspended, deleted, inactive)
|
||||
// @Success 200 {object} handler.RespBody{data=pager.PageModel{records=[]schema.GetUserPageResp}}
|
||||
// @Router /answer/admin/api/users/page [get]
|
||||
func (uc *UserBackyardController) GetUserPage(ctx *gin.Context) {
|
||||
|
|
|
@ -3,9 +3,9 @@ package entity
|
|||
import "time"
|
||||
|
||||
const (
|
||||
Answer_Search_OrderBy_Default = "default"
|
||||
Answer_Search_OrderBy_Time = "updated"
|
||||
Answer_Search_OrderBy_Vote = "vote"
|
||||
AnswerSearchOrderByDefault = "default"
|
||||
AnswerSearchOrderByTime = "updated"
|
||||
AnswerSearchOrderByVote = "vote"
|
||||
|
||||
AnswerStatusAvailable = 1
|
||||
AnswerStatusDeleted = 10
|
||||
|
@ -35,15 +35,17 @@ type Answer struct {
|
|||
type AnswerSearch struct {
|
||||
Answer
|
||||
Order string `json:"order_by" ` // default or updated
|
||||
Page int `json:"page" form:"page"` //Query number of pages
|
||||
PageSize int `json:"page_size" form:"page_size"` //Search page size
|
||||
Page int `json:"page" form:"page"` // Query number of pages
|
||||
PageSize int `json:"page_size" form:"page_size"` // Search page size
|
||||
}
|
||||
|
||||
type CmsAnswerSearch struct {
|
||||
Page int `json:"page" form:"page"` //Query number of pages
|
||||
PageSize int `json:"page_size" form:"page_size"` //Search page size
|
||||
Status int `json:"-" form:"-"`
|
||||
StatusStr string `json:"status" form:"status"` //Status 1 Available 2 closed 10 Deleted
|
||||
Page int `json:"page" form:"page"` // Query number of pages
|
||||
PageSize int `json:"page_size" form:"page_size"` // Search page size
|
||||
Status int `json:"-" form:"-"`
|
||||
StatusStr string `json:"status" form:"status"` // Status 1 Available 2 closed 10 Deleted
|
||||
Query string `validate:"omitempty,gt=0,lte=100" json:"query" form:"query" ` //Query string
|
||||
QuestionID string `validate:"omitempty,gt=0,lte=24" json:"question_id" form:"question_id" ` //Query string
|
||||
}
|
||||
|
||||
type AdminSetAnswerStatusRequest struct {
|
||||
|
|
|
@ -13,7 +13,8 @@ type Revision struct {
|
|||
Title string `xorm:"not null default '' VARCHAR(255) title"`
|
||||
Content string `xorm:"not null TEXT content"`
|
||||
Log string `xorm:"VARCHAR(255) log"`
|
||||
Status int `xorm:"not null default 1 INT(11) status"`
|
||||
// Status todo: this field is not used, will be removed in the future
|
||||
Status int `xorm:"not null default 1 INT(11) status"`
|
||||
}
|
||||
|
||||
// TableName revision table name
|
||||
|
|
|
@ -40,7 +40,7 @@ type User struct {
|
|||
Avatar string `xorm:"not null default '' VARCHAR(255) avatar"`
|
||||
Mobile string `xorm:"not null VARCHAR(20) mobile"`
|
||||
Bio string `xorm:"not null TEXT bio"`
|
||||
BioHtml string `xorm:"not null TEXT bio_html"`
|
||||
BioHTML string `xorm:"not null TEXT bio_html"`
|
||||
Website string `xorm:"not null default '' VARCHAR(255) website"`
|
||||
Location string `xorm:"not null default '' VARCHAR(100) location"`
|
||||
IPInfo string `xorm:"not null default '' VARCHAR(255) ip_info"`
|
||||
|
@ -54,6 +54,6 @@ func (User) TableName() string {
|
|||
|
||||
type UserSearch struct {
|
||||
User
|
||||
Page int `json:"page" form:"page"` //Query number of pages
|
||||
PageSize int `json:"page_size" form:"page_size"` //Search page size
|
||||
Page int `json:"page" form:"page"` // Query number of pages
|
||||
PageSize int `json:"page_size" form:"page_size"` // Search page size
|
||||
}
|
||||
|
|
|
@ -8,27 +8,25 @@ import (
|
|||
"xorm.io/xorm"
|
||||
)
|
||||
|
||||
var (
|
||||
tables = []interface{}{
|
||||
&entity.Activity{},
|
||||
&entity.Answer{},
|
||||
&entity.Collection{},
|
||||
&entity.CollectionGroup{},
|
||||
&entity.Comment{},
|
||||
&entity.Config{},
|
||||
&entity.Meta{},
|
||||
&entity.Notification{},
|
||||
&entity.Question{},
|
||||
&entity.Report{},
|
||||
&entity.Revision{},
|
||||
&entity.SiteInfo{},
|
||||
&entity.Tag{},
|
||||
&entity.TagRel{},
|
||||
&entity.Uniqid{},
|
||||
&entity.User{},
|
||||
&entity.Version{},
|
||||
}
|
||||
)
|
||||
var tables = []interface{}{
|
||||
&entity.Activity{},
|
||||
&entity.Answer{},
|
||||
&entity.Collection{},
|
||||
&entity.CollectionGroup{},
|
||||
&entity.Comment{},
|
||||
&entity.Config{},
|
||||
&entity.Meta{},
|
||||
&entity.Notification{},
|
||||
&entity.Question{},
|
||||
&entity.Report{},
|
||||
&entity.Revision{},
|
||||
&entity.SiteInfo{},
|
||||
&entity.Tag{},
|
||||
&entity.TagRel{},
|
||||
&entity.Uniqid{},
|
||||
&entity.User{},
|
||||
&entity.Version{},
|
||||
}
|
||||
|
||||
// InitDB init db
|
||||
func InitDB(dataConf *data.Database) (err error) {
|
||||
|
@ -95,91 +93,91 @@ func initSiteInfo(engine *xorm.Engine) error {
|
|||
|
||||
func initConfigTable(engine *xorm.Engine) error {
|
||||
defaultConfigTable := []*entity.Config{
|
||||
{1, "answer.accepted", `15`},
|
||||
{2, "answer.voted_up", `10`},
|
||||
{3, "question.voted_up", `10`},
|
||||
{4, "tag.edit_accepted", `2`},
|
||||
{5, "answer.accept", `2`},
|
||||
{6, "answer.voted_down_cancel", `2`},
|
||||
{7, "question.voted_down_cancel", `2`},
|
||||
{8, "answer.vote_down_cancel", `1`},
|
||||
{9, "question.vote_down_cancel", `1`},
|
||||
{10, "user.activated", `1`},
|
||||
{11, "edit.accepted", `2`},
|
||||
{12, "answer.vote_down", `-1`},
|
||||
{13, "question.voted_down", `-2`},
|
||||
{14, "answer.voted_down", `-2`},
|
||||
{15, "answer.accept_cancel", `-2`},
|
||||
{16, "answer.deleted", `-5`},
|
||||
{17, "question.voted_up_cancel", `-10`},
|
||||
{18, "answer.voted_up_cancel", `-10`},
|
||||
{19, "answer.accepted_cancel", `-15`},
|
||||
{20, "object.reported", `-100`},
|
||||
{21, "edit.rejected", `-2`},
|
||||
{22, "daily_rank_limit", `200`},
|
||||
{23, "daily_rank_limit.exclude", `["answer.accepted"]`},
|
||||
{24, "user.follow", `0`},
|
||||
{25, "comment.vote_up", `0`},
|
||||
{26, "comment.vote_up_cancel", `0`},
|
||||
{27, "question.vote_down", `0`},
|
||||
{28, "question.vote_up", `0`},
|
||||
{29, "question.vote_up_cancel", `0`},
|
||||
{30, "answer.vote_up", `0`},
|
||||
{31, "answer.vote_up_cancel", `0`},
|
||||
{32, "question.follow", `0`},
|
||||
{33, "email.config", `{"from_name":"answer","from_email":"answer@answer.com","smtp_host":"smtp.answer.org","smtp_port":465,"smtp_password":"answer","smtp_username":"answer@answer.com","smtp_authentication":true,"encryption":"","register_title":"[{{.SiteName}}] Confirm your new account","register_body":"Welcome to {{.SiteName}}<br><br>\n\nClick the following link to confirm and activate your new account:<br>\n<a href='{{.RegisterUrl}}' target='_blank'>{{.RegisterUrl}}</a><br><br>\n\nIf the above link is not clickable, try copying and pasting it into the address bar of your web browser.\n","pass_reset_title":"[{{.SiteName }}] Password reset","pass_reset_body":"Somebody asked to reset your password on [{{.SiteName}}].<br><br>\n\nIf it was not you, you can safely ignore this email.<br><br>\n\nClick the following link to choose a new password:<br>\n<a href='{{.PassResetUrl}}' target='_blank'>{{.PassResetUrl}}</a>\n","change_title":"[{{.SiteName}}] Confirm your new email address","change_body":"Confirm your new email address for {{.SiteName}} by clicking on the following link:<br><br>\n\n<a href='{{.ChangeEmailUrl}}' target='_blank'>{{.ChangeEmailUrl}}</a><br><br>\n\nIf you did not request this change, please ignore this email.\n","test_title":"[{{.SiteName}}] Test Email","test_body":"This is a test email."}`},
|
||||
{35, "tag.follow", `0`},
|
||||
{36, "rank.question.add", `0`},
|
||||
{37, "rank.question.edit", `0`},
|
||||
{38, "rank.question.delete", `0`},
|
||||
{39, "rank.question.vote_up", `0`},
|
||||
{40, "rank.question.vote_down", `0`},
|
||||
{41, "rank.answer.add", `0`},
|
||||
{42, "rank.answer.edit", `0`},
|
||||
{43, "rank.answer.delete", `0`},
|
||||
{44, "rank.answer.accept", `0`},
|
||||
{45, "rank.answer.vote_up", `0`},
|
||||
{46, "rank.answer.vote_down", `0`},
|
||||
{47, "rank.comment.add", `0`},
|
||||
{48, "rank.comment.edit", `0`},
|
||||
{49, "rank.comment.delete", `0`},
|
||||
{50, "rank.report.add", `0`},
|
||||
{51, "rank.tag.add", `0`},
|
||||
{52, "rank.tag.edit", `0`},
|
||||
{53, "rank.tag.delete", `0`},
|
||||
{54, "rank.tag.synonym", `0`},
|
||||
{55, "rank.link.url_limit", `0`},
|
||||
{56, "rank.vote.detail", `0`},
|
||||
{57, "reason.spam", `{"name":"spam","description":"This post is an advertisement, or vandalism. It is not useful or relevant to the current topic."}`},
|
||||
{58, "reason.rude_or_abusive", `{"name":"rude or abusive","description":"A reasonable person would find this content inappropriate for respectful discourse."}`},
|
||||
{59, "reason.something", `{"name":"something else","description":"This post requires staff attention for another reason not listed above.","content_type":"textarea"}`},
|
||||
{60, "reason.a_duplicate", `{"name":"a duplicate","description":"This question has been asked before and already has an answer.","content_type":"text"}`},
|
||||
{61, "reason.not_a_answer", `{"name":"not a answer","description":"This was posted as an answer, but it does not attempt to answer the question. It should possibly be an edit, a comment, another question, or deleted altogether.","content_type":""}`},
|
||||
{62, "reason.no_longer_needed", `{"name":"no longer needed","description":"This comment is outdated, conversational or not relevant to this post."}`},
|
||||
{63, "reason.community_specific", `{"name":"a community-specific reason","description":"This question doesn’t meet a community guideline."}`},
|
||||
{64, "reason.not_clarity", `{"name":"needs details or clarity","description":"This question currently includes multiple questions in one. It should focus on one problem only.","content_type":"text"}`},
|
||||
{65, "reason.normal", `{"name":"normal","description":"A normal post available to everyone."}`},
|
||||
{66, "reason.normal.user", `{"name":"normal","description":"A normal user can ask and answer questions."}`},
|
||||
{67, "reason.closed", `{"name":"closed","description":"A closed question can’t answer, but still can edit, vote and comment."}`},
|
||||
{68, "reason.deleted", `{"name":"deleted","description":"All reputation gained and lost will be restored."}`},
|
||||
{69, "reason.deleted.user", `{"name":"deleted","description":"Delete profile, authentication associations."}`},
|
||||
{70, "reason.suspended", `{"name":"suspended","description":"A suspended user can’t log in."}`},
|
||||
{71, "reason.inactive", `{"name":"inactive","description":"An inactive user must re-validate their email."}`},
|
||||
{72, "reason.looks_ok", `{"name":"looks ok","description":"This post is good as-is and not low quality."}`},
|
||||
{73, "reason.needs_edit", `{"name":"needs edit, and I did it","description":"Improve and correct problems with this post yourself."}`},
|
||||
{74, "reason.needs_close", `{"name":"needs close","description":"A closed question can’t answer, but still can edit, vote and comment."}`},
|
||||
{75, "reason.needs_delete", `{"name":"needs delete","description":"All reputation gained and lost will be restored."}`},
|
||||
{76, "question.flag.reasons", `["reason.spam","reason.rude_or_abusive","reason.something","reason.a_duplicate"]`},
|
||||
{77, "answer.flag.reasons", `["reason.spam","reason.rude_or_abusive","reason.something","reason.not_a_answer"]`},
|
||||
{78, "comment.flag.reasons", `["reason.spam","reason.rude_or_abusive","reason.something","reason.no_longer_needed"]`},
|
||||
{79, "question.close.reasons", `["reason.a_duplicate","reason.community_specific","reason.not_clarity","reason.something"]`},
|
||||
{80, "question.status.reasons", `["reason.normal","reason.closed","reason.deleted"]`},
|
||||
{81, "answer.status.reasons", `["reason.normal","reason.deleted"]`},
|
||||
{82, "comment.status.reasons", `["reason.normal","reason.deleted"]`},
|
||||
{83, "user.status.reasons", `["reason.normal.user","reason.suspended","reason.deleted.user","reason.inactive"]`},
|
||||
{84, "question.review.reasons", `["reason.looks_ok","reason.needs_edit","reason.needs_close","reason.needs_delete"]`},
|
||||
{85, "answer.review.reasons", `["reason.looks_ok","reason.needs_edit","reason.needs_delete"]`},
|
||||
{86, "comment.review.reasons", `["reason.looks_ok","reason.needs_edit","reason.needs_delete"]`},
|
||||
{ID: 1, Key: "answer.accepted", Value: `15`},
|
||||
{ID: 2, Key: "answer.voted_up", Value: `10`},
|
||||
{ID: 3, Key: "question.voted_up", Value: `10`},
|
||||
{ID: 4, Key: "tag.edit_accepted", Value: `2`},
|
||||
{ID: 5, Key: "answer.accept", Value: `2`},
|
||||
{ID: 6, Key: "answer.voted_down_cancel", Value: `2`},
|
||||
{ID: 7, Key: "question.voted_down_cancel", Value: `2`},
|
||||
{ID: 8, Key: "answer.vote_down_cancel", Value: `1`},
|
||||
{ID: 9, Key: "question.vote_down_cancel", Value: `1`},
|
||||
{ID: 10, Key: "user.activated", Value: `1`},
|
||||
{ID: 11, Key: "edit.accepted", Value: `2`},
|
||||
{ID: 12, Key: "answer.vote_down", Value: `-1`},
|
||||
{ID: 13, Key: "question.voted_down", Value: `-2`},
|
||||
{ID: 14, Key: "answer.voted_down", Value: `-2`},
|
||||
{ID: 15, Key: "answer.accept_cancel", Value: `-2`},
|
||||
{ID: 16, Key: "answer.deleted", Value: `-5`},
|
||||
{ID: 17, Key: "question.voted_up_cancel", Value: `-10`},
|
||||
{ID: 18, Key: "answer.voted_up_cancel", Value: `-10`},
|
||||
{ID: 19, Key: "answer.accepted_cancel", Value: `-15`},
|
||||
{ID: 20, Key: "object.reported", Value: `-100`},
|
||||
{ID: 21, Key: "edit.rejected", Value: `-2`},
|
||||
{ID: 22, Key: "daily_rank_limit", Value: `200`},
|
||||
{ID: 23, Key: "daily_rank_limit.exclude", Value: `["answer.accepted"]`},
|
||||
{ID: 24, Key: "user.follow", Value: `0`},
|
||||
{ID: 25, Key: "comment.vote_up", Value: `0`},
|
||||
{ID: 26, Key: "comment.vote_up_cancel", Value: `0`},
|
||||
{ID: 27, Key: "question.vote_down", Value: `0`},
|
||||
{ID: 28, Key: "question.vote_up", Value: `0`},
|
||||
{ID: 29, Key: "question.vote_up_cancel", Value: `0`},
|
||||
{ID: 30, Key: "answer.vote_up", Value: `0`},
|
||||
{ID: 31, Key: "answer.vote_up_cancel", Value: `0`},
|
||||
{ID: 32, Key: "question.follow", Value: `0`},
|
||||
{ID: 33, Key: "email.config", Value: `{"from_name":"answer","from_email":"answer@answer.com","smtp_host":"smtp.answer.org","smtp_port":465,"smtp_password":"answer","smtp_username":"answer@answer.com","smtp_authentication":true,"encryption":"","register_title":"[{{.SiteName}}] Confirm your new account","register_body":"Welcome to {{.SiteName}}<br><br>\n\nClick the following link to confirm and activate your new account:<br>\n<a href='{{.RegisterUrl}}' target='_blank'>{{.RegisterUrl}}</a><br><br>\n\nIf the above link is not clickable, try copying and pasting it into the address bar of your web browser.\n","pass_reset_title":"[{{.SiteName }}] Password reset","pass_reset_body":"Somebody asked to reset your password on [{{.SiteName}}].<br><br>\n\nIf it was not you, you can safely ignore this email.<br><br>\n\nClick the following link to choose a new password:<br>\n<a href='{{.PassResetUrl}}' target='_blank'>{{.PassResetUrl}}</a>\n","change_title":"[{{.SiteName}}] Confirm your new email address","change_body":"Confirm your new email address for {{.SiteName}} by clicking on the following link:<br><br>\n\n<a href='{{.ChangeEmailUrl}}' target='_blank'>{{.ChangeEmailUrl}}</a><br><br>\n\nIf you did not request this change, please ignore this email.\n","test_title":"[{{.SiteName}}] Test Email","test_body":"This is a test email."}`},
|
||||
{ID: 35, Key: "tag.follow", Value: `0`},
|
||||
{ID: 36, Key: "rank.question.add", Value: `0`},
|
||||
{ID: 37, Key: "rank.question.edit", Value: `0`},
|
||||
{ID: 38, Key: "rank.question.delete", Value: `0`},
|
||||
{ID: 39, Key: "rank.question.vote_up", Value: `0`},
|
||||
{ID: 40, Key: "rank.question.vote_down", Value: `0`},
|
||||
{ID: 41, Key: "rank.answer.add", Value: `0`},
|
||||
{ID: 42, Key: "rank.answer.edit", Value: `0`},
|
||||
{ID: 43, Key: "rank.answer.delete", Value: `0`},
|
||||
{ID: 44, Key: "rank.answer.accept", Value: `0`},
|
||||
{ID: 45, Key: "rank.answer.vote_up", Value: `0`},
|
||||
{ID: 46, Key: "rank.answer.vote_down", Value: `0`},
|
||||
{ID: 47, Key: "rank.comment.add", Value: `0`},
|
||||
{ID: 48, Key: "rank.comment.edit", Value: `0`},
|
||||
{ID: 49, Key: "rank.comment.delete", Value: `0`},
|
||||
{ID: 50, Key: "rank.report.add", Value: `0`},
|
||||
{ID: 51, Key: "rank.tag.add", Value: `0`},
|
||||
{ID: 52, Key: "rank.tag.edit", Value: `0`},
|
||||
{ID: 53, Key: "rank.tag.delete", Value: `0`},
|
||||
{ID: 54, Key: "rank.tag.synonym", Value: `0`},
|
||||
{ID: 55, Key: "rank.link.url_limit", Value: `0`},
|
||||
{ID: 56, Key: "rank.vote.detail", Value: `0`},
|
||||
{ID: 57, Key: "reason.spam", Value: `{"name":"spam","description":"This post is an advertisement, or vandalism. It is not useful or relevant to the current topic."}`},
|
||||
{ID: 58, Key: "reason.rude_or_abusive", Value: `{"name":"rude or abusive","description":"A reasonable person would find this content inappropriate for respectful discourse."}`},
|
||||
{ID: 59, Key: "reason.something", Value: `{"name":"something else","description":"This post requires staff attention for another reason not listed above.","content_type":"textarea"}`},
|
||||
{ID: 60, Key: "reason.a_duplicate", Value: `{"name":"a duplicate","description":"This question has been asked before and already has an answer.","content_type":"text"}`},
|
||||
{ID: 61, Key: "reason.not_a_answer", Value: `{"name":"not a answer","description":"This was posted as an answer, but it does not attempt to answer the question. It should possibly be an edit, a comment, another question, or deleted altogether.","content_type":""}`},
|
||||
{ID: 62, Key: "reason.no_longer_needed", Value: `{"name":"no longer needed","description":"This comment is outdated, conversational or not relevant to this post."}`},
|
||||
{ID: 63, Key: "reason.community_specific", Value: `{"name":"a community-specific reason","description":"This question doesn’t meet a community guideline."}`},
|
||||
{ID: 64, Key: "reason.not_clarity", Value: `{"name":"needs details or clarity","description":"This question currently includes multiple questions in one. It should focus on one problem only.","content_type":"text"}`},
|
||||
{ID: 65, Key: "reason.normal", Value: `{"name":"normal","description":"A normal post available to everyone."}`},
|
||||
{ID: 66, Key: "reason.normal.user", Value: `{"name":"normal","description":"A normal user can ask and answer questions."}`},
|
||||
{ID: 67, Key: "reason.closed", Value: `{"name":"closed","description":"A closed question can’t answer, but still can edit, vote and comment."}`},
|
||||
{ID: 68, Key: "reason.deleted", Value: `{"name":"deleted","description":"All reputation gained and lost will be restored."}`},
|
||||
{ID: 69, Key: "reason.deleted.user", Value: `{"name":"deleted","description":"Delete profile, authentication associations."}`},
|
||||
{ID: 70, Key: "reason.suspended", Value: `{"name":"suspended","description":"A suspended user can’t log in."}`},
|
||||
{ID: 71, Key: "reason.inactive", Value: `{"name":"inactive","description":"An inactive user must re-validate their email."}`},
|
||||
{ID: 72, Key: "reason.looks_ok", Value: `{"name":"looks ok","description":"This post is good as-is and not low quality."}`},
|
||||
{ID: 73, Key: "reason.needs_edit", Value: `{"name":"needs edit, and I did it","description":"Improve and correct problems with this post yourself."}`},
|
||||
{ID: 74, Key: "reason.needs_close", Value: `{"name":"needs close","description":"A closed question can’t answer, but still can edit, vote and comment."}`},
|
||||
{ID: 75, Key: "reason.needs_delete", Value: `{"name":"needs delete","description":"All reputation gained and lost will be restored."}`},
|
||||
{ID: 76, Key: "question.flag.reasons", Value: `["reason.spam","reason.rude_or_abusive","reason.something","reason.a_duplicate"]`},
|
||||
{ID: 77, Key: "answer.flag.reasons", Value: `["reason.spam","reason.rude_or_abusive","reason.something","reason.not_a_answer"]`},
|
||||
{ID: 78, Key: "comment.flag.reasons", Value: `["reason.spam","reason.rude_or_abusive","reason.something","reason.no_longer_needed"]`},
|
||||
{ID: 79, Key: "question.close.reasons", Value: `["reason.a_duplicate","reason.community_specific","reason.not_clarity","reason.something"]`},
|
||||
{ID: 80, Key: "question.status.reasons", Value: `["reason.normal","reason.closed","reason.deleted"]`},
|
||||
{ID: 81, Key: "answer.status.reasons", Value: `["reason.normal","reason.deleted"]`},
|
||||
{ID: 82, Key: "comment.status.reasons", Value: `["reason.normal","reason.deleted"]`},
|
||||
{ID: 83, Key: "user.status.reasons", Value: `["reason.normal.user","reason.suspended","reason.deleted.user","reason.inactive"]`},
|
||||
{ID: 84, Key: "question.review.reasons", Value: `["reason.looks_ok","reason.needs_edit","reason.needs_close","reason.needs_delete"]`},
|
||||
{ID: 85, Key: "answer.review.reasons", Value: `["reason.looks_ok","reason.needs_edit","reason.needs_delete"]`},
|
||||
{ID: 86, Key: "comment.review.reasons", Value: `["reason.looks_ok","reason.needs_edit","reason.needs_delete"]`},
|
||||
}
|
||||
_, err := engine.Insert(defaultConfigTable)
|
||||
return err
|
||||
|
|
|
@ -44,7 +44,6 @@ func NewAnswerActivityRepo(
|
|||
userRankRepo rank.UserRankRepo,
|
||||
) activity.AnswerActivityRepo {
|
||||
return &AnswerActivityRepo{
|
||||
|
||||
data: data,
|
||||
activityRepo: activityRepo,
|
||||
userRankRepo: userRankRepo,
|
||||
|
@ -125,7 +124,8 @@ func (ar *AnswerActivityRepo) DeleteQuestion(ctx context.Context, questionID str
|
|||
|
||||
// AcceptAnswer accept other answer
|
||||
func (ar *AnswerActivityRepo) AcceptAnswer(ctx context.Context,
|
||||
answerObjID, questionUserID, answerUserID string, isSelf bool) (err error) {
|
||||
answerObjID, questionUserID, answerUserID string, isSelf bool,
|
||||
) (err error) {
|
||||
addActivityList := make([]*entity.Activity, 0)
|
||||
for _, action := range acceptActionList {
|
||||
// get accept answer need add rank amount
|
||||
|
@ -173,7 +173,7 @@ func (ar *AnswerActivityRepo) AcceptAnswer(ctx context.Context,
|
|||
}
|
||||
|
||||
if exists {
|
||||
if _, e := session.Where("id = ?", existsActivity.ID).Cols("`cancelled`").
|
||||
if _, e = session.Where("id = ?", existsActivity.ID).Cols("`cancelled`").
|
||||
Update(&entity.Activity{Cancelled: entity.ActivityAvailable}); e != nil {
|
||||
return nil, errors.InternalServer(reason.DatabaseError).WithError(e).WithStack()
|
||||
}
|
||||
|
@ -222,7 +222,8 @@ func (ar *AnswerActivityRepo) AcceptAnswer(ctx context.Context,
|
|||
|
||||
// CancelAcceptAnswer accept other answer
|
||||
func (ar *AnswerActivityRepo) CancelAcceptAnswer(ctx context.Context,
|
||||
answerObjID, questionUserID, answerUserID string) (err error) {
|
||||
answerObjID, questionUserID, answerUserID string,
|
||||
) (err error) {
|
||||
addActivityList := make([]*entity.Activity, 0)
|
||||
for _, action := range acceptActionList {
|
||||
// get accept answer need add rank amount
|
||||
|
|
|
@ -37,8 +37,8 @@ func NewFollowRepo(
|
|||
}
|
||||
}
|
||||
|
||||
func (ar *FollowRepo) Follow(ctx context.Context, objectId, userId string) error {
|
||||
activityType, _, _, err := ar.activityRepo.GetActivityTypeByObjID(ctx, objectId, "follow")
|
||||
func (ar *FollowRepo) Follow(ctx context.Context, objectID, userID string) error {
|
||||
activityType, _, _, err := ar.activityRepo.GetActivityTypeByObjID(ctx, objectID, "follow")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -51,8 +51,8 @@ func (ar *FollowRepo) Follow(ctx context.Context, objectId, userId string) error
|
|||
result = nil
|
||||
|
||||
has, err = session.Where(builder.Eq{"activity_type": activityType}).
|
||||
And(builder.Eq{"user_id": userId}).
|
||||
And(builder.Eq{"object_id": objectId}).
|
||||
And(builder.Eq{"user_id": userID}).
|
||||
And(builder.Eq{"object_id": objectID}).
|
||||
Get(&existsActivity)
|
||||
|
||||
if err != nil {
|
||||
|
@ -72,8 +72,8 @@ func (ar *FollowRepo) Follow(ctx context.Context, objectId, userId string) error
|
|||
} else {
|
||||
// update existing activity with new user id and u object id
|
||||
_, err = session.Insert(&entity.Activity{
|
||||
UserID: userId,
|
||||
ObjectID: objectId,
|
||||
UserID: userID,
|
||||
ObjectID: objectID,
|
||||
ActivityType: activityType,
|
||||
Cancelled: 0,
|
||||
Rank: 0,
|
||||
|
@ -87,7 +87,7 @@ func (ar *FollowRepo) Follow(ctx context.Context, objectId, userId string) error
|
|||
}
|
||||
|
||||
// start update followers when everything is fine
|
||||
err = ar.updateFollows(ctx, session, objectId, 1)
|
||||
err = ar.updateFollows(ctx, session, objectID, 1)
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
}
|
||||
|
@ -98,8 +98,8 @@ func (ar *FollowRepo) Follow(ctx context.Context, objectId, userId string) error
|
|||
return err
|
||||
}
|
||||
|
||||
func (ar *FollowRepo) FollowCancel(ctx context.Context, objectId, userId string) error {
|
||||
activityType, _, _, err := ar.activityRepo.GetActivityTypeByObjID(ctx, objectId, "follow")
|
||||
func (ar *FollowRepo) FollowCancel(ctx context.Context, objectID, userID string) error {
|
||||
activityType, _, _, err := ar.activityRepo.GetActivityTypeByObjID(ctx, objectID, "follow")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -112,8 +112,8 @@ func (ar *FollowRepo) FollowCancel(ctx context.Context, objectId, userId string)
|
|||
result = nil
|
||||
|
||||
has, err = session.Where(builder.Eq{"activity_type": activityType}).
|
||||
And(builder.Eq{"user_id": userId}).
|
||||
And(builder.Eq{"object_id": objectId}).
|
||||
And(builder.Eq{"user_id": userID}).
|
||||
And(builder.Eq{"object_id": objectID}).
|
||||
Get(&existsActivity)
|
||||
|
||||
if err != nil || !has {
|
||||
|
@ -130,24 +130,24 @@ func (ar *FollowRepo) FollowCancel(ctx context.Context, objectId, userId string)
|
|||
}); err != nil {
|
||||
return
|
||||
}
|
||||
err = ar.updateFollows(ctx, session, objectId, -1)
|
||||
err = ar.updateFollows(ctx, session, objectID, -1)
|
||||
return
|
||||
})
|
||||
return err
|
||||
}
|
||||
|
||||
func (ar *FollowRepo) updateFollows(ctx context.Context, session *xorm.Session, objectId string, follows int) error {
|
||||
objectType, err := obj.GetObjectTypeStrByObjectID(objectId)
|
||||
func (ar *FollowRepo) updateFollows(ctx context.Context, session *xorm.Session, objectID string, follows int) error {
|
||||
objectType, err := obj.GetObjectTypeStrByObjectID(objectID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
switch objectType {
|
||||
case "question":
|
||||
_, err = session.Where("id = ?", objectId).Incr("follow_count", follows).Update(&entity.Question{})
|
||||
_, err = session.Where("id = ?", objectID).Incr("follow_count", follows).Update(&entity.Question{})
|
||||
case "user":
|
||||
_, err = session.Where("id = ?", objectId).Incr("follow_count", follows).Update(&entity.User{})
|
||||
_, err = session.Where("id = ?", objectID).Incr("follow_count", follows).Update(&entity.User{})
|
||||
case "tag":
|
||||
_, err = session.Where("id = ?", objectId).Incr("follow_count", follows).Update(&entity.Tag{})
|
||||
_, err = session.Where("id = ?", objectID).Incr("follow_count", follows).Update(&entity.Tag{})
|
||||
default:
|
||||
err = errors.InternalServer(reason.DisallowFollow).WithMsg("this object can't be followed")
|
||||
}
|
||||
|
|
|
@ -2,9 +2,10 @@ package activity
|
|||
|
||||
import (
|
||||
"context"
|
||||
"github.com/answerdev/answer/pkg/converter"
|
||||
"strings"
|
||||
|
||||
"github.com/answerdev/answer/pkg/converter"
|
||||
|
||||
"github.com/answerdev/answer/internal/base/pager"
|
||||
"github.com/answerdev/answer/internal/service/config"
|
||||
"github.com/answerdev/answer/internal/service/notice_queue"
|
||||
|
@ -42,7 +43,8 @@ func NewVoteRepo(
|
|||
configRepo config.ConfigRepo,
|
||||
activityRepo activity_common.ActivityRepo,
|
||||
userRankRepo rank.UserRankRepo,
|
||||
voteCommon activity_common.VoteRepo) service.VoteRepo {
|
||||
voteCommon activity_common.VoteRepo,
|
||||
) service.VoteRepo {
|
||||
return &VoteRepo{
|
||||
data: data,
|
||||
uniqueIDRepo: uniqueIDRepo,
|
||||
|
@ -65,7 +67,7 @@ var LimitDownActions = map[string][]string{
|
|||
"comment": {"vote_down"},
|
||||
}
|
||||
|
||||
func (vr *VoteRepo) vote(ctx context.Context, objectID string, userID, objectUserId string, actions []string) (resp *schema.VoteResp, err error) {
|
||||
func (vr *VoteRepo) vote(ctx context.Context, objectID string, userID, objectUserID string, actions []string) (resp *schema.VoteResp, err error) {
|
||||
resp = &schema.VoteResp{}
|
||||
_, err = vr.data.DB.Transaction(func(session *xorm.Session) (result any, err error) {
|
||||
result = nil
|
||||
|
@ -75,24 +77,24 @@ func (vr *VoteRepo) vote(ctx context.Context, objectID string, userID, objectUse
|
|||
insertActivity entity.Activity
|
||||
has bool
|
||||
triggerUserID,
|
||||
activityUserId string
|
||||
activityUserID string
|
||||
activityType, deltaRank, hasRank int
|
||||
)
|
||||
|
||||
activityUserId, activityType, deltaRank, hasRank, err = vr.CheckRank(ctx, objectID, objectUserId, userID, action)
|
||||
activityUserID, activityType, deltaRank, hasRank, err = vr.CheckRank(ctx, objectID, objectUserID, userID, action)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
triggerUserID = userID
|
||||
if userID == activityUserId {
|
||||
if userID == activityUserID {
|
||||
triggerUserID = "0"
|
||||
}
|
||||
|
||||
// check is voted up
|
||||
has, _ = session.
|
||||
Where(builder.Eq{"object_id": objectID}).
|
||||
And(builder.Eq{"user_id": activityUserId}).
|
||||
And(builder.Eq{"user_id": activityUserID}).
|
||||
And(builder.Eq{"trigger_user_id": triggerUserID}).
|
||||
And(builder.Eq{"activity_type": activityType}).
|
||||
Get(&existsActivity)
|
||||
|
@ -104,7 +106,7 @@ func (vr *VoteRepo) vote(ctx context.Context, objectID string, userID, objectUse
|
|||
|
||||
insertActivity = entity.Activity{
|
||||
ObjectID: objectID,
|
||||
UserID: activityUserId,
|
||||
UserID: activityUserID,
|
||||
TriggerUserID: converter.StringToInt64(triggerUserID),
|
||||
ActivityType: activityType,
|
||||
Rank: deltaRank,
|
||||
|
@ -114,7 +116,8 @@ func (vr *VoteRepo) vote(ctx context.Context, objectID string, userID, objectUse
|
|||
|
||||
// trigger user rank and send notification
|
||||
if hasRank != 0 {
|
||||
isReachStandard, err := vr.userRankRepo.TriggerUserRank(ctx, session, activityUserId, deltaRank, activityType)
|
||||
var isReachStandard bool
|
||||
isReachStandard, err = vr.userRankRepo.TriggerUserRank(ctx, session, activityUserID, deltaRank, activityType)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -122,7 +125,7 @@ func (vr *VoteRepo) vote(ctx context.Context, objectID string, userID, objectUse
|
|||
insertActivity.Rank = 0
|
||||
}
|
||||
|
||||
vr.sendNotification(ctx, activityUserId, objectUserId, objectID)
|
||||
vr.sendNotification(ctx, activityUserID, objectUserID, objectID)
|
||||
}
|
||||
|
||||
if has {
|
||||
|
@ -163,7 +166,7 @@ func (vr *VoteRepo) vote(ctx context.Context, objectID string, userID, objectUse
|
|||
return
|
||||
}
|
||||
|
||||
func (vr *VoteRepo) voteCancel(ctx context.Context, objectID string, userID, objectUserId string, actions []string) (resp *schema.VoteResp, err error) {
|
||||
func (vr *VoteRepo) voteCancel(ctx context.Context, objectID string, userID, objectUserID string, actions []string) (resp *schema.VoteResp, err error) {
|
||||
resp = &schema.VoteResp{}
|
||||
_, err = vr.data.DB.Transaction(func(session *xorm.Session) (result any, err error) {
|
||||
for _, action := range actions {
|
||||
|
@ -171,24 +174,24 @@ func (vr *VoteRepo) voteCancel(ctx context.Context, objectID string, userID, obj
|
|||
existsActivity entity.Activity
|
||||
has bool
|
||||
triggerUserID,
|
||||
activityUserId string
|
||||
activityUserID string
|
||||
activityType,
|
||||
deltaRank, hasRank int
|
||||
)
|
||||
result = nil
|
||||
|
||||
activityUserId, activityType, deltaRank, hasRank, err = vr.CheckRank(ctx, objectID, objectUserId, userID, action)
|
||||
activityUserID, activityType, deltaRank, hasRank, err = vr.CheckRank(ctx, objectID, objectUserID, userID, action)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
triggerUserID = userID
|
||||
if userID == activityUserId {
|
||||
if userID == activityUserID {
|
||||
triggerUserID = "0"
|
||||
}
|
||||
|
||||
has, err = session.
|
||||
Where(builder.Eq{"user_id": activityUserId}).
|
||||
Where(builder.Eq{"user_id": activityUserID}).
|
||||
And(builder.Eq{"trigger_user_id": triggerUserID}).
|
||||
And(builder.Eq{"activity_type": activityType}).
|
||||
And(builder.Eq{"object_id": objectID}).
|
||||
|
@ -211,12 +214,12 @@ func (vr *VoteRepo) voteCancel(ctx context.Context, objectID string, userID, obj
|
|||
|
||||
// trigger user rank and send notification
|
||||
if hasRank != 0 {
|
||||
_, err = vr.userRankRepo.TriggerUserRank(ctx, session, activityUserId, -deltaRank, activityType)
|
||||
_, err = vr.userRankRepo.TriggerUserRank(ctx, session, activityUserID, -deltaRank, activityType)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
vr.sendNotification(ctx, activityUserId, objectUserId, objectID)
|
||||
vr.sendNotification(ctx, activityUserID, objectUserID, objectID)
|
||||
}
|
||||
|
||||
// update votes
|
||||
|
@ -242,7 +245,7 @@ func (vr *VoteRepo) voteCancel(ctx context.Context, objectID string, userID, obj
|
|||
return
|
||||
}
|
||||
|
||||
func (vr *VoteRepo) VoteUp(ctx context.Context, objectID string, userID, objectUserId string) (resp *schema.VoteResp, err error) {
|
||||
func (vr *VoteRepo) VoteUp(ctx context.Context, objectID string, userID, objectUserID string) (resp *schema.VoteResp, err error) {
|
||||
resp = &schema.VoteResp{}
|
||||
objectType, err := obj.GetObjectTypeStrByObjectID(objectID)
|
||||
if err != nil {
|
||||
|
@ -256,11 +259,11 @@ func (vr *VoteRepo) VoteUp(ctx context.Context, objectID string, userID, objectU
|
|||
return
|
||||
}
|
||||
|
||||
_, _ = vr.VoteDownCancel(ctx, objectID, userID, objectUserId)
|
||||
return vr.vote(ctx, objectID, userID, objectUserId, actions)
|
||||
_, _ = vr.VoteDownCancel(ctx, objectID, userID, objectUserID)
|
||||
return vr.vote(ctx, objectID, userID, objectUserID, actions)
|
||||
}
|
||||
|
||||
func (vr *VoteRepo) VoteDown(ctx context.Context, objectID string, userID, objectUserId string) (resp *schema.VoteResp, err error) {
|
||||
func (vr *VoteRepo) VoteDown(ctx context.Context, objectID string, userID, objectUserID string) (resp *schema.VoteResp, err error) {
|
||||
resp = &schema.VoteResp{}
|
||||
objectType, err := obj.GetObjectTypeStrByObjectID(objectID)
|
||||
if err != nil {
|
||||
|
@ -273,14 +276,12 @@ func (vr *VoteRepo) VoteDown(ctx context.Context, objectID string, userID, objec
|
|||
return
|
||||
}
|
||||
|
||||
_, _ = vr.VoteUpCancel(ctx, objectID, userID, objectUserId)
|
||||
return vr.vote(ctx, objectID, userID, objectUserId, actions)
|
||||
_, _ = vr.VoteUpCancel(ctx, objectID, userID, objectUserID)
|
||||
return vr.vote(ctx, objectID, userID, objectUserID, actions)
|
||||
}
|
||||
|
||||
func (vr *VoteRepo) VoteUpCancel(ctx context.Context, objectID string, userID, objectUserId string) (resp *schema.VoteResp, err error) {
|
||||
var (
|
||||
objectType string
|
||||
)
|
||||
func (vr *VoteRepo) VoteUpCancel(ctx context.Context, objectID string, userID, objectUserID string) (resp *schema.VoteResp, err error) {
|
||||
var objectType string
|
||||
resp = &schema.VoteResp{}
|
||||
|
||||
objectType, err = obj.GetObjectTypeStrByObjectID(objectID)
|
||||
|
@ -294,13 +295,11 @@ func (vr *VoteRepo) VoteUpCancel(ctx context.Context, objectID string, userID, o
|
|||
return
|
||||
}
|
||||
|
||||
return vr.voteCancel(ctx, objectID, userID, objectUserId, actions)
|
||||
return vr.voteCancel(ctx, objectID, userID, objectUserID, actions)
|
||||
}
|
||||
|
||||
func (vr *VoteRepo) VoteDownCancel(ctx context.Context, objectID string, userID, objectUserId string) (resp *schema.VoteResp, err error) {
|
||||
var (
|
||||
objectType string
|
||||
)
|
||||
func (vr *VoteRepo) VoteDownCancel(ctx context.Context, objectID string, userID, objectUserID string) (resp *schema.VoteResp, err error) {
|
||||
var objectType string
|
||||
resp = &schema.VoteResp{}
|
||||
|
||||
objectType, err = obj.GetObjectTypeStrByObjectID(objectID)
|
||||
|
@ -314,22 +313,22 @@ func (vr *VoteRepo) VoteDownCancel(ctx context.Context, objectID string, userID,
|
|||
return
|
||||
}
|
||||
|
||||
return vr.voteCancel(ctx, objectID, userID, objectUserId, actions)
|
||||
return vr.voteCancel(ctx, objectID, userID, objectUserID, actions)
|
||||
}
|
||||
|
||||
func (vr *VoteRepo) CheckRank(ctx context.Context, objectID, objectUserId, userID string, action string) (activityUserId string, activityType, rank, hasRank int, err error) {
|
||||
func (vr *VoteRepo) CheckRank(ctx context.Context, objectID, objectUserID, userID string, action string) (activityUserID string, activityType, rank, hasRank int, err error) {
|
||||
activityType, rank, hasRank, err = vr.activityRepo.GetActivityTypeByObjID(ctx, objectID, action)
|
||||
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
activityUserId = userID
|
||||
activityUserID = userID
|
||||
if strings.Contains(action, "voted") {
|
||||
activityUserId = objectUserId
|
||||
activityUserID = objectUserID
|
||||
}
|
||||
|
||||
return activityUserId, activityType, rank, hasRank, nil
|
||||
return activityUserID, activityType, rank, hasRank, nil
|
||||
}
|
||||
|
||||
func (vr *VoteRepo) GetVoteResultByObjectId(ctx context.Context, objectID string) (resp *schema.VoteResp, err error) {
|
||||
|
@ -341,7 +340,7 @@ func (vr *VoteRepo) GetVoteResultByObjectId(ctx context.Context, objectID string
|
|||
activityType int
|
||||
)
|
||||
|
||||
activityType, _, _, err = vr.activityRepo.GetActivityTypeByObjID(ctx, objectID, action)
|
||||
activityType, _, _, _ = vr.activityRepo.GetActivityTypeByObjID(ctx, objectID, action)
|
||||
|
||||
votes, err = vr.data.DB.Where(builder.Eq{"object_id": objectID}).
|
||||
And(builder.Eq{"activity_type": activityType}).
|
||||
|
@ -417,15 +416,15 @@ func (vr *VoteRepo) updateVotes(ctx context.Context, session *xorm.Session, obje
|
|||
}
|
||||
|
||||
// sendNotification send rank triggered notification
|
||||
func (vr *VoteRepo) sendNotification(ctx context.Context, activityUserId, objectUserId, objectID string) {
|
||||
func (vr *VoteRepo) sendNotification(ctx context.Context, activityUserID, objectUserID, objectID string) {
|
||||
objectType, err := obj.GetObjectTypeStrByObjectID(objectID)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
msg := &schema.NotificationMsg{
|
||||
ReceiverUserID: activityUserId,
|
||||
TriggerUserID: objectUserId,
|
||||
ReceiverUserID: activityUserID,
|
||||
TriggerUserID: objectUserID,
|
||||
Type: schema.NotificationTypeAchievement,
|
||||
ObjectID: objectID,
|
||||
ObjectType: objectType,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
package repo
|
||||
package activity_common
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
@ -37,14 +37,14 @@ func NewActivityRepo(
|
|||
}
|
||||
}
|
||||
|
||||
func (ar *ActivityRepo) GetActivityTypeByObjID(ctx context.Context, objectId string, action string) (activityType, rank, hasRank int, err error) {
|
||||
objectKey, err := obj.GetObjectTypeStrByObjectID(objectId)
|
||||
func (ar *ActivityRepo) GetActivityTypeByObjID(ctx context.Context, objectID string, action string) (activityType, rank, hasRank int, err error) {
|
||||
objectKey, err := obj.GetObjectTypeStrByObjectID(objectID)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
confKey := fmt.Sprintf("%s.%s", objectKey, action)
|
||||
activityType, err = ar.configRepo.GetConfigType(confKey)
|
||||
activityType, _ = ar.configRepo.GetConfigType(confKey)
|
||||
|
||||
rank, err = ar.configRepo.GetInt(confKey)
|
||||
hasRank = 0
|
||||
|
@ -64,7 +64,8 @@ func (ar *ActivityRepo) GetActivityTypeByObjKey(ctx context.Context, objectKey,
|
|||
}
|
||||
|
||||
func (ar *ActivityRepo) GetActivity(ctx context.Context, session *xorm.Session,
|
||||
objectID, userID string, activityType int) (existsActivity *entity.Activity, exist bool, err error) {
|
||||
objectID, userID string, activityType int,
|
||||
) (existsActivity *entity.Activity, exist bool, err error) {
|
||||
existsActivity = &entity.Activity{}
|
||||
exist, err = session.
|
||||
Where(builder.Eq{"object_id": objectID}).
|
|
@ -33,27 +33,27 @@ func NewFollowRepo(
|
|||
}
|
||||
|
||||
// GetFollowAmount get object id's follows
|
||||
func (ar *FollowRepo) GetFollowAmount(ctx context.Context, objectId string) (follows int, err error) {
|
||||
objectType, err := obj.GetObjectTypeStrByObjectID(objectId)
|
||||
func (ar *FollowRepo) GetFollowAmount(ctx context.Context, objectID string) (follows int, err error) {
|
||||
objectType, err := obj.GetObjectTypeStrByObjectID(objectID)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
switch objectType {
|
||||
case "question":
|
||||
model := &entity.Question{}
|
||||
_, err = ar.data.DB.Where("id = ?", objectId).Cols("`follow_count`").Get(model)
|
||||
_, err = ar.data.DB.Where("id = ?", objectID).Cols("`follow_count`").Get(model)
|
||||
if err == nil {
|
||||
follows = int(model.FollowCount)
|
||||
}
|
||||
case "user":
|
||||
model := &entity.User{}
|
||||
_, err = ar.data.DB.Where("id = ?", objectId).Cols("`follow_count`").Get(model)
|
||||
_, err = ar.data.DB.Where("id = ?", objectID).Cols("`follow_count`").Get(model)
|
||||
if err == nil {
|
||||
follows = int(model.FollowCount)
|
||||
}
|
||||
case "tag":
|
||||
model := &entity.Tag{}
|
||||
_, err = ar.data.DB.Where("id = ?", objectId).Cols("`follow_count`").Get(model)
|
||||
_, err = ar.data.DB.Where("id = ?", objectID).Cols("`follow_count`").Get(model)
|
||||
if err == nil {
|
||||
follows = int(model.FollowCount)
|
||||
}
|
||||
|
@ -95,6 +95,9 @@ func (ar *FollowRepo) GetFollowUserIDs(ctx context.Context, objectID string) (us
|
|||
func (ar *FollowRepo) GetFollowIDs(ctx context.Context, userID, objectKey string) (followIDs []string, err error) {
|
||||
followIDs = make([]string, 0)
|
||||
activityType, err := ar.activityRepo.GetActivityTypeByObjKey(ctx, objectKey, "follow")
|
||||
if err != nil {
|
||||
return nil, errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
|
||||
}
|
||||
session := ar.data.DB.Select("object_id")
|
||||
session.Table(entity.Activity{}.TableName())
|
||||
session.Where("user_id = ? AND activity_type = ?", userID, activityType)
|
||||
|
@ -107,14 +110,14 @@ func (ar *FollowRepo) GetFollowIDs(ctx context.Context, userID, objectKey string
|
|||
}
|
||||
|
||||
// IsFollowed check user if follow object or not
|
||||
func (ar *FollowRepo) IsFollowed(userId, objectId string) (bool, error) {
|
||||
activityType, _, _, err := ar.activityRepo.GetActivityTypeByObjID(nil, objectId, "follow")
|
||||
func (ar *FollowRepo) IsFollowed(userID, objectID string) (bool, error) {
|
||||
activityType, _, _, err := ar.activityRepo.GetActivityTypeByObjID(context.TODO(), objectID, "follow")
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
at := &entity.Activity{}
|
||||
has, err := ar.data.DB.Where("user_id = ? AND object_id = ? AND activity_type = ?", userId, objectId, activityType).Get(at)
|
||||
has, err := ar.data.DB.Where("user_id = ? AND object_id = ? AND activity_type = ?", userID, objectID, activityType).Get(at)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
|
|
@ -6,13 +6,11 @@ import (
|
|||
"github.com/answerdev/answer/internal/base/data"
|
||||
"github.com/answerdev/answer/internal/entity"
|
||||
"github.com/answerdev/answer/internal/service/activity_common"
|
||||
"github.com/answerdev/answer/internal/service/unique"
|
||||
)
|
||||
|
||||
// VoteRepo activity repository
|
||||
type VoteRepo struct {
|
||||
data *data.Data
|
||||
uniqueIDRepo unique.UniqueIDRepo
|
||||
activityRepo activity_common.ActivityRepo
|
||||
}
|
||||
|
||||
|
@ -24,11 +22,14 @@ func NewVoteRepo(data *data.Data, activityRepo activity_common.ActivityRepo) act
|
|||
}
|
||||
}
|
||||
|
||||
func (vr *VoteRepo) GetVoteStatus(ctx context.Context, objectId, userId string) (status string) {
|
||||
func (vr *VoteRepo) GetVoteStatus(ctx context.Context, objectID, userID string) (status string) {
|
||||
for _, action := range []string{"vote_up", "vote_down"} {
|
||||
at := &entity.Activity{}
|
||||
activityType, _, _, err := vr.activityRepo.GetActivityTypeByObjID(ctx, objectId, action)
|
||||
has, err := vr.data.DB.Where("object_id =? AND cancelled=0 AND activity_type=? AND user_id=?", objectId, activityType, userId).Get(at)
|
||||
activityType, _, _, err := vr.activityRepo.GetActivityTypeByObjID(ctx, objectID, action)
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
has, err := vr.data.DB.Where("object_id =? AND cancelled=0 AND activity_type=? AND user_id=?", objectID, activityType, userID).Get(at)
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
|
|
|
@ -1,8 +1,11 @@
|
|||
package repo
|
||||
package answer
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strings"
|
||||
"time"
|
||||
"unicode"
|
||||
"xorm.io/builder"
|
||||
|
||||
"github.com/answerdev/answer/internal/base/constant"
|
||||
"github.com/answerdev/answer/internal/base/data"
|
||||
|
@ -89,7 +92,8 @@ func (ar *answerRepo) UpdateAnswerStatus(ctx context.Context, answer *entity.Ans
|
|||
|
||||
// GetAnswer get answer one
|
||||
func (ar *answerRepo) GetAnswer(ctx context.Context, id string) (
|
||||
answer *entity.Answer, exist bool, err error) {
|
||||
answer *entity.Answer, exist bool, err error,
|
||||
) {
|
||||
answer = &entity.Answer{}
|
||||
exist, err = ar.data.DB.ID(id).Get(answer)
|
||||
if err != nil {
|
||||
|
@ -120,20 +124,20 @@ func (ar *answerRepo) GetAnswerPage(ctx context.Context, page, pageSize int, ans
|
|||
|
||||
// UpdateAdopted
|
||||
// If no answer is selected, the answer id can be 0
|
||||
func (ar *answerRepo) UpdateAdopted(ctx context.Context, id string, questionId string) error {
|
||||
if questionId == "" {
|
||||
func (ar *answerRepo) UpdateAdopted(ctx context.Context, id string, questionID string) error {
|
||||
if questionID == "" {
|
||||
return nil
|
||||
}
|
||||
var data entity.Answer
|
||||
data.ID = id
|
||||
|
||||
data.Adopted = schema.Answer_Adopted_Failed
|
||||
_, err := ar.data.DB.Where("question_id =?", questionId).Cols("adopted").Update(&data)
|
||||
data.Adopted = schema.AnswerAdoptedFailed
|
||||
_, err := ar.data.DB.Where("question_id =?", questionID).Cols("adopted").Update(&data)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if id != "0" {
|
||||
data.Adopted = schema.Answer_Adopted_Enable
|
||||
data.Adopted = schema.AnswerAdoptedEnable
|
||||
_, err = ar.data.DB.Where("id = ?", id).Cols("adopted").Update(&data)
|
||||
if err != nil {
|
||||
return errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
|
||||
|
@ -152,9 +156,9 @@ func (ar *answerRepo) GetByID(ctx context.Context, id string) (*entity.Answer, b
|
|||
return &resp, has, nil
|
||||
}
|
||||
|
||||
func (ar *answerRepo) GetByUserIdQuestionId(ctx context.Context, userId string, questionId string) (*entity.Answer, bool, error) {
|
||||
func (ar *answerRepo) GetByUserIDQuestionID(ctx context.Context, userID string, questionID string) (*entity.Answer, bool, error) {
|
||||
var resp entity.Answer
|
||||
has, err := ar.data.DB.Where("question_id =? and user_id = ?", questionId, userId).Get(&resp)
|
||||
has, err := ar.data.DB.Where("question_id =? and user_id = ?", questionID, userID).Get(&resp)
|
||||
if err != nil {
|
||||
return &resp, false, errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
|
||||
}
|
||||
|
@ -172,7 +176,7 @@ func (ar *answerRepo) SearchList(ctx context.Context, search *entity.AnswerSearc
|
|||
search.Page = 0
|
||||
}
|
||||
if search.PageSize == 0 {
|
||||
search.PageSize = constant.Default_PageSize
|
||||
search.PageSize = constant.DefaultPageSize
|
||||
}
|
||||
offset := search.Page * search.PageSize
|
||||
session := ar.data.DB.Where("")
|
||||
|
@ -183,14 +187,14 @@ func (ar *answerRepo) SearchList(ctx context.Context, search *entity.AnswerSearc
|
|||
if len(search.UserID) > 0 {
|
||||
session = session.And("user_id = ?", search.UserID)
|
||||
}
|
||||
if search.Order == entity.Answer_Search_OrderBy_Time {
|
||||
switch search.Order {
|
||||
case entity.AnswerSearchOrderByTime:
|
||||
session = session.OrderBy("created_at desc")
|
||||
} else if search.Order == entity.Answer_Search_OrderBy_Vote {
|
||||
case entity.AnswerSearchOrderByVote:
|
||||
session = session.OrderBy("vote_count desc")
|
||||
} else {
|
||||
default:
|
||||
session = session.OrderBy("adopted desc,vote_count desc")
|
||||
}
|
||||
|
||||
session = session.And("status = ?", entity.AnswerStatusAvailable)
|
||||
|
||||
session = session.Limit(search.PageSize, offset)
|
||||
|
@ -202,11 +206,16 @@ func (ar *answerRepo) SearchList(ctx context.Context, search *entity.AnswerSearc
|
|||
}
|
||||
|
||||
func (ar *answerRepo) CmsSearchList(ctx context.Context, search *entity.CmsAnswerSearch) ([]*entity.Answer, int64, error) {
|
||||
var count int64
|
||||
var err error
|
||||
if search.Status == 0 {
|
||||
search.Status = 1
|
||||
}
|
||||
var (
|
||||
count int64
|
||||
err error
|
||||
session = ar.data.DB.Table([]string{entity.Answer{}.TableName(), "a"}).Select("a.*")
|
||||
)
|
||||
|
||||
session.Where(builder.Eq{
|
||||
"a.status": search.Status,
|
||||
})
|
||||
|
||||
rows := make([]*entity.Answer, 0)
|
||||
if search.Page > 0 {
|
||||
search.Page = search.Page - 1
|
||||
|
@ -214,13 +223,51 @@ func (ar *answerRepo) CmsSearchList(ctx context.Context, search *entity.CmsAnswe
|
|||
search.Page = 0
|
||||
}
|
||||
if search.PageSize == 0 {
|
||||
search.PageSize = constant.Default_PageSize
|
||||
search.PageSize = constant.DefaultPageSize
|
||||
}
|
||||
|
||||
// search by question title like or answer id
|
||||
if len(search.Query) > 0 {
|
||||
// check id search
|
||||
var (
|
||||
idSearch = false
|
||||
id = ""
|
||||
)
|
||||
|
||||
if strings.Contains(search.Query, "answer:") {
|
||||
idSearch = true
|
||||
id = strings.TrimSpace(strings.TrimPrefix(search.Query, "answer:"))
|
||||
for _, r := range id {
|
||||
if !unicode.IsDigit(r) {
|
||||
idSearch = false
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if idSearch {
|
||||
session.And(builder.Eq{
|
||||
"id": id,
|
||||
})
|
||||
} else {
|
||||
session.Join("LEFT", []string{entity.Question{}.TableName(), "q"}, "q.id = a.question_id")
|
||||
session.And(builder.Like{
|
||||
"q.title", search.Query,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// check search by question id
|
||||
if len(search.QuestionID) > 0 {
|
||||
session.And(builder.Eq{
|
||||
"question_id": search.QuestionID,
|
||||
})
|
||||
}
|
||||
|
||||
offset := search.Page * search.PageSize
|
||||
session := ar.data.DB.Where("")
|
||||
session = session.And("status =?", search.Status)
|
||||
session = session.OrderBy("updated_at desc")
|
||||
session = session.Limit(search.PageSize, offset)
|
||||
session.
|
||||
OrderBy("a.updated_at desc").
|
||||
Limit(search.PageSize, offset)
|
||||
count, err = session.FindAndCount(&rows)
|
||||
if err != nil {
|
||||
return rows, count, errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
|
|
@ -12,11 +12,12 @@ import (
|
|||
"github.com/segmentfault/pacman/errors"
|
||||
)
|
||||
|
||||
// authRepo activity repository
|
||||
// authRepo auth repository
|
||||
type authRepo struct {
|
||||
data *data.Data
|
||||
}
|
||||
|
||||
// GetUserCacheInfo get user cache info
|
||||
func (ar *authRepo) GetUserCacheInfo(ctx context.Context, accessToken string) (userInfo *entity.UserCacheInfo, err error) {
|
||||
userInfoCache, err := ar.data.Cache.GetString(ctx, constant.UserTokenCacheKey+accessToken)
|
||||
if err != nil {
|
||||
|
@ -30,27 +31,7 @@ func (ar *authRepo) GetUserCacheInfo(ctx context.Context, accessToken string) (u
|
|||
return userInfo, nil
|
||||
}
|
||||
|
||||
func (ar *authRepo) GetUserStatus(ctx context.Context, userID string) (userInfo *entity.UserCacheInfo, err error) {
|
||||
userInfoCache, err := ar.data.Cache.GetString(ctx, constant.UserStatusChangedCacheKey+userID)
|
||||
if err != nil {
|
||||
return nil, errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
|
||||
}
|
||||
userInfo = &entity.UserCacheInfo{}
|
||||
err = json.Unmarshal([]byte(userInfoCache), userInfo)
|
||||
if err != nil {
|
||||
return nil, errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
|
||||
}
|
||||
return userInfo, nil
|
||||
}
|
||||
|
||||
func (ar *authRepo) RemoveUserStatus(ctx context.Context, userID string) (err error) {
|
||||
err = ar.data.Cache.Del(ctx, constant.UserStatusChangedCacheKey+userID)
|
||||
if err != nil {
|
||||
return errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// SetUserCacheInfo set user cache info
|
||||
func (ar *authRepo) SetUserCacheInfo(ctx context.Context, accessToken string, userInfo *entity.UserCacheInfo) (err error) {
|
||||
userInfoCache, err := json.Marshal(userInfo)
|
||||
if err != nil {
|
||||
|
@ -64,16 +45,54 @@ func (ar *authRepo) SetUserCacheInfo(ctx context.Context, accessToken string, us
|
|||
return nil
|
||||
}
|
||||
|
||||
// RemoveUserCacheInfo remove user cache info
|
||||
func (ar *authRepo) RemoveUserCacheInfo(ctx context.Context, accessToken string) (err error) {
|
||||
err = ar.data.Cache.Del(ctx, constant.UserTokenCacheKey+accessToken)
|
||||
if err != nil {
|
||||
err = errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
|
||||
return err
|
||||
return errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (ar *authRepo) GetCmsUserCacheInfo(ctx context.Context, accessToken string) (userInfo *entity.UserCacheInfo, err error) {
|
||||
// SetUserStatus set user status
|
||||
func (ar *authRepo) SetUserStatus(ctx context.Context, userID string, userInfo *entity.UserCacheInfo) (err error) {
|
||||
userInfoCache, err := json.Marshal(userInfo)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = ar.data.Cache.SetString(ctx, constant.UserStatusChangedCacheKey+userID,
|
||||
string(userInfoCache), constant.UserStatusChangedCacheTime)
|
||||
if err != nil {
|
||||
return errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetUserStatus get user status
|
||||
func (ar *authRepo) GetUserStatus(ctx context.Context, userID string) (userInfo *entity.UserCacheInfo, err error) {
|
||||
userInfoCache, err := ar.data.Cache.GetString(ctx, constant.UserStatusChangedCacheKey+userID)
|
||||
if err != nil {
|
||||
return nil, errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
|
||||
}
|
||||
userInfo = &entity.UserCacheInfo{}
|
||||
err = json.Unmarshal([]byte(userInfoCache), userInfo)
|
||||
if err != nil {
|
||||
return nil, errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
|
||||
}
|
||||
return userInfo, nil
|
||||
}
|
||||
|
||||
// RemoveUserStatus remove user status
|
||||
func (ar *authRepo) RemoveUserStatus(ctx context.Context, userID string) (err error) {
|
||||
err = ar.data.Cache.Del(ctx, constant.UserStatusChangedCacheKey+userID)
|
||||
if err != nil {
|
||||
return errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetBackyardUserCacheInfo get backyard user cache info
|
||||
func (ar *authRepo) GetBackyardUserCacheInfo(ctx context.Context, accessToken string) (userInfo *entity.UserCacheInfo, err error) {
|
||||
userInfoCache, err := ar.data.Cache.GetString(ctx, constant.AdminTokenCacheKey+accessToken)
|
||||
if err != nil {
|
||||
err = errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
|
||||
|
@ -87,7 +106,8 @@ func (ar *authRepo) GetCmsUserCacheInfo(ctx context.Context, accessToken string)
|
|||
return userInfo, nil
|
||||
}
|
||||
|
||||
func (ar *authRepo) SetCmsUserCacheInfo(ctx context.Context, accessToken string, userInfo *entity.UserCacheInfo) (err error) {
|
||||
// SetBackyardUserCacheInfo set backyard user cache info
|
||||
func (ar *authRepo) SetBackyardUserCacheInfo(ctx context.Context, accessToken string, userInfo *entity.UserCacheInfo) (err error) {
|
||||
userInfoCache, err := json.Marshal(userInfo)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -96,25 +116,22 @@ func (ar *authRepo) SetCmsUserCacheInfo(ctx context.Context, accessToken string,
|
|||
err = ar.data.Cache.SetString(ctx, constant.AdminTokenCacheKey+accessToken, string(userInfoCache),
|
||||
constant.AdminTokenCacheTime)
|
||||
if err != nil {
|
||||
err = errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
|
||||
return err
|
||||
return errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (ar *authRepo) RemoveCmsUserCacheInfo(ctx context.Context, accessToken string) (err error) {
|
||||
// RemoveBackyardUserCacheInfo remove backyard user cache info
|
||||
func (ar *authRepo) RemoveBackyardUserCacheInfo(ctx context.Context, accessToken string) (err error) {
|
||||
err = ar.data.Cache.Del(ctx, constant.AdminTokenCacheKey+accessToken)
|
||||
if err != nil {
|
||||
err = errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
|
||||
return err
|
||||
return errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// NewAuthRepo new repository
|
||||
func NewAuthRepo(
|
||||
data *data.Data,
|
||||
) auth.AuthRepo {
|
||||
func NewAuthRepo(data *data.Data) auth.AuthRepo {
|
||||
return &authRepo{
|
||||
data: data,
|
||||
}
|
||||
|
|
|
@ -37,7 +37,7 @@ func (cr *collectionGroupRepo) AddCollectionGroup(ctx context.Context, collectio
|
|||
func (cr *collectionGroupRepo) AddCollectionDefaultGroup(ctx context.Context, userID string) (collectionGroup *entity.CollectionGroup, err error) {
|
||||
defaultGroup := &entity.CollectionGroup{
|
||||
Name: "default",
|
||||
DefaultGroup: schema.CG_DEFAULT,
|
||||
DefaultGroup: schema.CGDefault,
|
||||
UserID: userID,
|
||||
}
|
||||
_, err = cr.data.DB.Insert(defaultGroup)
|
||||
|
@ -60,7 +60,8 @@ func (cr *collectionGroupRepo) UpdateCollectionGroup(ctx context.Context, collec
|
|||
|
||||
// GetCollectionGroup get collection group one
|
||||
func (cr *collectionGroupRepo) GetCollectionGroup(ctx context.Context, id string) (
|
||||
collectionGroup *entity.CollectionGroup, exist bool, err error) {
|
||||
collectionGroup *entity.CollectionGroup, exist bool, err error,
|
||||
) {
|
||||
collectionGroup = &entity.CollectionGroup{}
|
||||
exist, err = cr.data.DB.ID(id).Get(collectionGroup)
|
||||
if err != nil {
|
||||
|
@ -84,9 +85,9 @@ func (cr *collectionGroupRepo) GetCollectionGroupPage(ctx context.Context, page,
|
|||
return
|
||||
}
|
||||
|
||||
func (cr *collectionGroupRepo) GetDefaultID(ctx context.Context, userId string) (collectionGroup *entity.CollectionGroup, has bool, err error) {
|
||||
func (cr *collectionGroupRepo) GetDefaultID(ctx context.Context, userID string) (collectionGroup *entity.CollectionGroup, has bool, err error) {
|
||||
collectionGroup = &entity.CollectionGroup{}
|
||||
has, err = cr.data.DB.Where("user_id =? and default_group = ?", userId, schema.CG_DEFAULT).Get(collectionGroup)
|
||||
has, err = cr.data.DB.Where("user_id =? and default_group = ?", userID, schema.CGDefault).Get(collectionGroup)
|
||||
if err != nil {
|
||||
err = errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
|
||||
return
|
||||
|
|
|
@ -74,9 +74,9 @@ func (cr *collectionRepo) GetCollectionList(ctx context.Context, collection *ent
|
|||
}
|
||||
|
||||
// GetOneByObjectIDAndUser get one by object TagID and user
|
||||
func (cr *collectionRepo) GetOneByObjectIDAndUser(ctx context.Context, userId string, objectId string) (collection *entity.Collection, exist bool, err error) {
|
||||
func (cr *collectionRepo) GetOneByObjectIDAndUser(ctx context.Context, userID string, objectID string) (collection *entity.Collection, exist bool, err error) {
|
||||
collection = &entity.Collection{}
|
||||
exist, err = cr.data.DB.Where("user_id = ? and object_id = ?", userId, objectId).Get(collection)
|
||||
exist, err = cr.data.DB.Where("user_id = ? and object_id = ?", userID, objectID).Get(collection)
|
||||
if err != nil {
|
||||
return nil, false, errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
|
||||
}
|
||||
|
@ -84,9 +84,9 @@ func (cr *collectionRepo) GetOneByObjectIDAndUser(ctx context.Context, userId st
|
|||
}
|
||||
|
||||
// SearchByObjectIDsAndUser search by object IDs and user
|
||||
func (cr *collectionRepo) SearchByObjectIDsAndUser(ctx context.Context, userId string, objectIds []string) ([]*entity.Collection, error) {
|
||||
func (cr *collectionRepo) SearchByObjectIDsAndUser(ctx context.Context, userID string, objectIDs []string) ([]*entity.Collection, error) {
|
||||
collectionList := make([]*entity.Collection, 0)
|
||||
err := cr.data.DB.Where("user_id = ?", userId).In("object_id", objectIds).Find(&collectionList)
|
||||
err := cr.data.DB.Where("user_id = ?", userID).In("object_id", objectIDs).Find(&collectionList)
|
||||
if err != nil {
|
||||
return collectionList, err
|
||||
}
|
||||
|
@ -94,9 +94,9 @@ func (cr *collectionRepo) SearchByObjectIDsAndUser(ctx context.Context, userId s
|
|||
}
|
||||
|
||||
// CountByObjectID count by object TagID
|
||||
func (cr *collectionRepo) CountByObjectID(ctx context.Context, objectId string) (total int64, err error) {
|
||||
func (cr *collectionRepo) CountByObjectID(ctx context.Context, objectID string) (total int64, err error) {
|
||||
collection := &entity.Collection{}
|
||||
total, err = cr.data.DB.Where("object_id = ?", objectId).Count(collection)
|
||||
total, err = cr.data.DB.Where("object_id = ?", objectID).Count(collection)
|
||||
if err != nil {
|
||||
return 0, errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
|
||||
}
|
||||
|
@ -105,7 +105,6 @@ func (cr *collectionRepo) CountByObjectID(ctx context.Context, objectId string)
|
|||
|
||||
// GetCollectionPage get collection page
|
||||
func (cr *collectionRepo) GetCollectionPage(ctx context.Context, page, pageSize int, collection *entity.Collection) (collectionList []*entity.Collection, total int64, err error) {
|
||||
|
||||
collectionList = make([]*entity.Collection, 0)
|
||||
|
||||
session := cr.data.DB.NewSession()
|
||||
|
@ -124,9 +123,9 @@ func (cr *collectionRepo) GetCollectionPage(ctx context.Context, page, pageSize
|
|||
}
|
||||
|
||||
// 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)
|
||||
list, err := cr.SearchByObjectIDsAndUser(ctx, userId, objectIds)
|
||||
list, err := cr.SearchByObjectIDsAndUser(ctx, userID, objectIds)
|
||||
if err != nil {
|
||||
err = errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
|
||||
return collectedMap, err
|
||||
|
@ -148,7 +147,7 @@ func (cr *collectionRepo) SearchList(ctx context.Context, search *entity.Collect
|
|||
search.Page = 0
|
||||
}
|
||||
if search.PageSize == 0 {
|
||||
search.PageSize = constant.Default_PageSize
|
||||
search.PageSize = constant.DefaultPageSize
|
||||
}
|
||||
offset := search.Page * search.PageSize
|
||||
session := cr.data.DB.Where("")
|
||||
|
|
|
@ -69,7 +69,8 @@ func (cr *commentRepo) UpdateComment(ctx context.Context, comment *entity.Commen
|
|||
|
||||
// GetComment get comment one
|
||||
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{}
|
||||
exist, err = cr.data.DB.ID(commentID).Get(comment)
|
||||
if err != nil {
|
||||
|
@ -80,7 +81,8 @@ func (cr *commentRepo) GetComment(ctx context.Context, commentID string) (
|
|||
|
||||
// GetCommentPage get comment page
|
||||
func (cr *commentRepo) GetCommentPage(ctx context.Context, commentQuery *comment.CommentQuery) (
|
||||
commentList []*entity.Comment, total int64, err error) {
|
||||
commentList []*entity.Comment, total int64, err error,
|
||||
) {
|
||||
commentList = make([]*entity.Comment, 0)
|
||||
|
||||
session := cr.data.DB.NewSession()
|
||||
|
|
|
@ -37,15 +37,13 @@ func (cr *CommonRepo) GetRootObjectID(objectID string) (rootObjectID string, err
|
|||
exist, err = cr.data.DB.ID(objectID).Get(&answer)
|
||||
if !exist {
|
||||
err = errors.BadRequest(reason.ObjectNotFound)
|
||||
} else {
|
||||
objectID = answer.QuestionID
|
||||
}
|
||||
case "comment":
|
||||
exist, err = cr.data.DB.ID(objectID).Get(&comment)
|
||||
exist, _ = cr.data.DB.ID(objectID).Get(&comment)
|
||||
if !exist {
|
||||
err = errors.BadRequest(reason.ObjectNotFound)
|
||||
} else {
|
||||
objectID, err = cr.GetRootObjectID(comment.ObjectID)
|
||||
_, err = cr.GetRootObjectID(comment.ObjectID)
|
||||
}
|
||||
default:
|
||||
rootObjectID = objectID
|
||||
|
@ -72,7 +70,7 @@ func (cr *CommonRepo) GetObjectIDMap(objectID string) (objectIDMap map[string]st
|
|||
}
|
||||
switch objectType {
|
||||
case "answer":
|
||||
exist, err = cr.data.DB.ID(objectID).Get(&answer)
|
||||
exist, _ = cr.data.DB.ID(objectID).Get(&answer)
|
||||
if !exist {
|
||||
err = errors.BadRequest(reason.ObjectNotFound)
|
||||
} else {
|
||||
|
@ -80,7 +78,7 @@ func (cr *CommonRepo) GetObjectIDMap(objectID string) (objectIDMap map[string]st
|
|||
ID = answer.ID
|
||||
}
|
||||
case "comment":
|
||||
exist, err = cr.data.DB.ID(objectID).Get(&comment)
|
||||
exist, _ = cr.data.DB.ID(objectID).Get(&comment)
|
||||
if !exist {
|
||||
err = errors.BadRequest(reason.ObjectNotFound)
|
||||
} else {
|
||||
|
|
|
@ -65,10 +65,14 @@ func (cr *configRepo) Get(key string) (interface{}, error) {
|
|||
// key string
|
||||
func (cr *configRepo) GetString(key string) (string, error) {
|
||||
value, err := cr.Get(key)
|
||||
if value != nil {
|
||||
return value.(string), err
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return "", err
|
||||
str, ok := value.(string)
|
||||
if !ok {
|
||||
return "", errors.InternalServer(reason.DatabaseError).WithMsg(fmt.Sprintf("config value is wrong type: %v", key))
|
||||
}
|
||||
return str, nil
|
||||
}
|
||||
|
||||
// GetInt method for getting the config value to int64
|
||||
|
@ -77,9 +81,8 @@ func (cr *configRepo) GetInt(key string) (int, error) {
|
|||
value, err := cr.GetString(key)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
} else {
|
||||
return converter.StringToInt(value), nil
|
||||
}
|
||||
return converter.StringToInt(value), nil
|
||||
}
|
||||
|
||||
// GetArrayString method for getting the config value to string array
|
||||
|
@ -96,31 +99,35 @@ func (cr *configRepo) GetArrayString(key string) ([]string, error) {
|
|||
// GetConfigType method for getting the config type
|
||||
func (cr *configRepo) GetConfigType(key string) (int, error) {
|
||||
value, ok := Key2IDMapping[key]
|
||||
if ok {
|
||||
return value, nil
|
||||
} else {
|
||||
if !ok {
|
||||
return 0, errors.InternalServer(reason.DatabaseError).WithMsg(fmt.Sprintf("no such config type: %v", key))
|
||||
}
|
||||
return value, nil
|
||||
}
|
||||
|
||||
// GetConfigById get config key from config id
|
||||
func (cr *configRepo) GetConfigById(id int, value any) (err error) {
|
||||
var (
|
||||
ok = true
|
||||
key string
|
||||
conf interface{}
|
||||
)
|
||||
key, ok = ID2KeyMapping[id]
|
||||
// GetJsonConfigByIDAndSetToObject get config key from config id
|
||||
func (cr *configRepo) GetJsonConfigByIDAndSetToObject(id int, object any) (err error) {
|
||||
key, ok := ID2KeyMapping[id]
|
||||
if !ok {
|
||||
err = errors.InternalServer(reason.DatabaseError).WithMsg(fmt.Sprintf("no such config id: %v", id))
|
||||
return
|
||||
return errors.InternalServer(reason.DatabaseError).WithMsg(fmt.Sprintf("no such config id: %v", id))
|
||||
}
|
||||
|
||||
conf, err = cr.Get(key)
|
||||
value = json.Unmarshal([]byte(conf.(string)), value)
|
||||
conf, err := cr.Get(key)
|
||||
if err != nil {
|
||||
return errors.InternalServer(reason.DatabaseError).WithError(err)
|
||||
}
|
||||
str, ok := conf.(string)
|
||||
if !ok {
|
||||
return errors.InternalServer(reason.DatabaseError).WithMsg(fmt.Sprintf("no such config id: %v", id))
|
||||
}
|
||||
err = json.Unmarshal([]byte(str), object)
|
||||
if err != nil {
|
||||
err = errors.InternalServer(reason.DatabaseError).WithMsg(fmt.Sprintf("no such config id: %v", id))
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// SetConfig set config
|
||||
func (cr *configRepo) SetConfig(key, value string) (err error) {
|
||||
id := Key2IDMapping[key]
|
||||
_, err = cr.data.DB.ID(id).Update(&entity.Config{Value: value})
|
||||
|
|
|
@ -22,6 +22,7 @@ func NewEmailRepo(data *data.Data) export.EmailRepo {
|
|||
}
|
||||
}
|
||||
|
||||
// SetCode The email code is used to verify that the link in the message is out of date
|
||||
func (e *emailRepo) SetCode(ctx context.Context, code, content string) error {
|
||||
err := e.data.Cache.SetString(ctx, code, content, 10*time.Minute)
|
||||
if err != nil {
|
||||
|
@ -30,6 +31,7 @@ func (e *emailRepo) SetCode(ctx context.Context, code, content string) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// VerifyCode verify the code if out of date
|
||||
func (e *emailRepo) VerifyCode(ctx context.Context, code string) (content string, err error) {
|
||||
content, err = e.data.Cache.GetString(ctx, code)
|
||||
if err != nil {
|
||||
|
|
|
@ -4,7 +4,6 @@ import (
|
|||
"context"
|
||||
|
||||
"github.com/answerdev/answer/internal/base/data"
|
||||
"github.com/answerdev/answer/internal/base/pager"
|
||||
"github.com/answerdev/answer/internal/base/reason"
|
||||
"github.com/answerdev/answer/internal/entity"
|
||||
"github.com/answerdev/answer/internal/service/meta"
|
||||
|
@ -65,17 +64,7 @@ func (mr *metaRepo) GetMetaByObjectIdAndKey(ctx context.Context, objectID, key s
|
|||
// GetMetaList get meta list all
|
||||
func (mr *metaRepo) GetMetaList(ctx context.Context, meta *entity.Meta) (metaList []*entity.Meta, err error) {
|
||||
metaList = make([]*entity.Meta, 0)
|
||||
err = mr.data.DB.Find(metaList, meta)
|
||||
if err != nil {
|
||||
err = errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// GetMetaPage get meta page
|
||||
func (mr *metaRepo) GetMetaPage(ctx context.Context, page, pageSize int, meta *entity.Meta) (metaList []*entity.Meta, total int64, err error) {
|
||||
metaList = make([]*entity.Meta, 0)
|
||||
total, err = pager.Help(page, pageSize, metaList, meta, mr.data.DB.NewSession())
|
||||
err = mr.data.DB.Find(&metaList, meta)
|
||||
if err != nil {
|
||||
err = errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
|
||||
}
|
||||
|
|
|
@ -4,8 +4,8 @@ import (
|
|||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/answerdev/answer/internal/base/constant"
|
||||
"github.com/answerdev/answer/internal/base/data"
|
||||
"github.com/answerdev/answer/internal/base/pager"
|
||||
"github.com/answerdev/answer/internal/base/reason"
|
||||
"github.com/answerdev/answer/internal/entity"
|
||||
"github.com/answerdev/answer/internal/schema"
|
||||
|
@ -29,8 +29,7 @@ func NewNotificationRepo(data *data.Data) notficationcommon.NotificationRepo {
|
|||
func (nr *notificationRepo) AddNotification(ctx context.Context, notification *entity.Notification) (err error) {
|
||||
_, err = nr.data.DB.Insert(notification)
|
||||
if err != nil {
|
||||
err = errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
|
||||
return
|
||||
return errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
|
||||
}
|
||||
return
|
||||
}
|
||||
|
@ -40,8 +39,7 @@ func (nr *notificationRepo) UpdateNotificationContent(ctx context.Context, notif
|
|||
notification.UpdatedAt = now
|
||||
_, err = nr.data.DB.Where("id =?", notification.ID).Cols("content", "updated_at").Update(notification)
|
||||
if err != nil {
|
||||
err = errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
|
||||
return
|
||||
return errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
|
||||
}
|
||||
return
|
||||
}
|
||||
|
@ -51,8 +49,7 @@ func (nr *notificationRepo) ClearUnRead(ctx context.Context, userID string, noti
|
|||
info.IsRead = schema.NotificationRead
|
||||
_, err = nr.data.DB.Where("user_id =?", userID).And("type =?", notificationType).Cols("is_read").Update(info)
|
||||
if err != nil {
|
||||
err = errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
|
||||
return
|
||||
return errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
|
||||
}
|
||||
return
|
||||
}
|
||||
|
@ -62,8 +59,7 @@ func (nr *notificationRepo) ClearIDUnRead(ctx context.Context, userID string, id
|
|||
info.IsRead = schema.NotificationRead
|
||||
_, err = nr.data.DB.Where("user_id =?", userID).And("id =?", id).Cols("is_read").Update(info)
|
||||
if err != nil {
|
||||
err = errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
|
||||
return
|
||||
return errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
|
||||
}
|
||||
return
|
||||
}
|
||||
|
@ -88,32 +84,22 @@ func (nr *notificationRepo) GetByUserIdObjectIdTypeId(ctx context.Context, userI
|
|||
return info, exist, nil
|
||||
}
|
||||
|
||||
func (nr *notificationRepo) SearchList(ctx context.Context, search *schema.NotificationSearch) ([]*entity.Notification, int64, error) {
|
||||
var count int64
|
||||
var err error
|
||||
func (nr *notificationRepo) GetNotificationPage(ctx context.Context, searchCond *schema.NotificationSearch) (
|
||||
notificationList []*entity.Notification, total int64, err error) {
|
||||
notificationList = make([]*entity.Notification, 0)
|
||||
if searchCond.UserID == "" {
|
||||
return notificationList, 0, nil
|
||||
}
|
||||
|
||||
rows := make([]*entity.Notification, 0)
|
||||
if search.UserID == "" {
|
||||
return rows, 0, nil
|
||||
session := nr.data.DB.NewSession()
|
||||
session = session.Desc("updated_at")
|
||||
cond := &entity.Notification{
|
||||
UserID: searchCond.UserID,
|
||||
Type: searchCond.Type,
|
||||
}
|
||||
if search.Page > 0 {
|
||||
search.Page = search.Page - 1
|
||||
} else {
|
||||
search.Page = 0
|
||||
}
|
||||
if search.PageSize == 0 {
|
||||
search.PageSize = constant.Default_PageSize
|
||||
}
|
||||
offset := search.Page * search.PageSize
|
||||
session := nr.data.DB.Where("")
|
||||
session = session.And("user_id = ?", search.UserID)
|
||||
session = session.And("type = ?", search.Type)
|
||||
session = session.OrderBy("updated_at desc")
|
||||
session = session.Limit(search.PageSize, offset)
|
||||
count, err = session.FindAndCount(&rows)
|
||||
total, err = pager.Help(searchCond.Page, searchCond.PageSize, ¬ificationList, cond, session)
|
||||
if err != nil {
|
||||
err = errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
|
||||
return rows, count, err
|
||||
}
|
||||
return rows, count, nil
|
||||
return
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ import (
|
|||
"github.com/answerdev/answer/internal/base/data"
|
||||
"github.com/answerdev/answer/internal/repo/activity"
|
||||
"github.com/answerdev/answer/internal/repo/activity_common"
|
||||
"github.com/answerdev/answer/internal/repo/answer"
|
||||
"github.com/answerdev/answer/internal/repo/auth"
|
||||
"github.com/answerdev/answer/internal/repo/captcha"
|
||||
"github.com/answerdev/answer/internal/repo/collection"
|
||||
|
@ -13,10 +14,13 @@ import (
|
|||
"github.com/answerdev/answer/internal/repo/export"
|
||||
"github.com/answerdev/answer/internal/repo/meta"
|
||||
"github.com/answerdev/answer/internal/repo/notification"
|
||||
"github.com/answerdev/answer/internal/repo/question"
|
||||
"github.com/answerdev/answer/internal/repo/rank"
|
||||
"github.com/answerdev/answer/internal/repo/reason"
|
||||
"github.com/answerdev/answer/internal/repo/report"
|
||||
"github.com/answerdev/answer/internal/repo/revision"
|
||||
"github.com/answerdev/answer/internal/repo/search_common"
|
||||
"github.com/answerdev/answer/internal/repo/site_info"
|
||||
"github.com/answerdev/answer/internal/repo/tag"
|
||||
"github.com/answerdev/answer/internal/repo/unique"
|
||||
"github.com/answerdev/answer/internal/repo/user"
|
||||
|
@ -40,24 +44,24 @@ var ProviderSetRepo = wire.NewSet(
|
|||
user.NewUserRepo,
|
||||
user.NewUserBackyardRepo,
|
||||
rank.NewUserRankRepo,
|
||||
NewQuestionRepo,
|
||||
NewAnswerRepo,
|
||||
NewActivityRepo,
|
||||
question.NewQuestionRepo,
|
||||
answer.NewAnswerRepo,
|
||||
activity_common.NewActivityRepo,
|
||||
activity.NewVoteRepo,
|
||||
activity.NewFollowRepo,
|
||||
activity.NewAnswerActivityRepo,
|
||||
activity.NewQuestionActivityRepo,
|
||||
activity.NewUserActiveActivityRepo,
|
||||
tag.NewTagRepo,
|
||||
tag.NewTagListRepo,
|
||||
tag.NewTagRelRepo,
|
||||
collection.NewCollectionRepo,
|
||||
collection.NewCollectionGroupRepo,
|
||||
auth.NewAuthRepo,
|
||||
revision.NewRevisionRepo,
|
||||
NewSearchRepo,
|
||||
search_common.NewSearchRepo,
|
||||
meta.NewMetaRepo,
|
||||
export.NewEmailRepo,
|
||||
reason.NewReasonRepo,
|
||||
NewSiteInfo,
|
||||
site_info.NewSiteInfo,
|
||||
notification.NewNotificationRepo,
|
||||
)
|
||||
|
|
|
@ -1,8 +1,11 @@
|
|||
package repo
|
||||
package question
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strings"
|
||||
"time"
|
||||
"unicode"
|
||||
"xorm.io/builder"
|
||||
|
||||
"github.com/answerdev/answer/internal/base/constant"
|
||||
"github.com/answerdev/answer/internal/base/data"
|
||||
|
@ -64,27 +67,27 @@ func (qr *questionRepo) UpdateQuestion(ctx context.Context, question *entity.Que
|
|||
return
|
||||
}
|
||||
|
||||
func (qr *questionRepo) UpdatePvCount(ctx context.Context, questionId string) (err error) {
|
||||
func (qr *questionRepo) UpdatePvCount(ctx context.Context, questionID string) (err error) {
|
||||
question := &entity.Question{}
|
||||
_, err = qr.data.DB.Where("id =?", questionId).Incr("view_count", 1).Update(question)
|
||||
_, err = qr.data.DB.Where("id =?", questionID).Incr("view_count", 1).Update(question)
|
||||
if err != nil {
|
||||
return errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (qr *questionRepo) UpdateAnswerCount(ctx context.Context, questionId string, num int) (err error) {
|
||||
func (qr *questionRepo) UpdateAnswerCount(ctx context.Context, questionID string, num int) (err error) {
|
||||
question := &entity.Question{}
|
||||
_, err = qr.data.DB.Where("id =?", questionId).Incr("answer_count", num).Update(question)
|
||||
_, err = qr.data.DB.Where("id =?", questionID).Incr("answer_count", num).Update(question)
|
||||
if err != nil {
|
||||
return errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (qr *questionRepo) UpdateCollectionCount(ctx context.Context, questionId string, num int) (err error) {
|
||||
func (qr *questionRepo) UpdateCollectionCount(ctx context.Context, questionID string, num int) (err error) {
|
||||
question := &entity.Question{}
|
||||
_, err = qr.data.DB.Where("id =?", questionId).Incr("collection_count", num).Update(question)
|
||||
_, err = qr.data.DB.Where("id =?", questionID).Incr("collection_count", num).Update(question)
|
||||
if err != nil {
|
||||
return errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
|
||||
}
|
||||
|
@ -119,7 +122,8 @@ func (qr *questionRepo) UpdateLastAnswer(ctx context.Context, question *entity.Q
|
|||
|
||||
// GetQuestion get question one
|
||||
func (qr *questionRepo) GetQuestion(ctx context.Context, id string) (
|
||||
question *entity.Question, exist bool, err error) {
|
||||
question *entity.Question, exist bool, err error,
|
||||
) {
|
||||
question = &entity.Question{}
|
||||
question.ID = id
|
||||
exist, err = qr.data.DB.Where("id = ?", id).Get(question)
|
||||
|
@ -179,7 +183,7 @@ func (qr *questionRepo) SearchList(ctx context.Context, search *schema.QuestionS
|
|||
search.Page = 0
|
||||
}
|
||||
if search.PageSize == 0 {
|
||||
search.PageSize = constant.Default_PageSize
|
||||
search.PageSize = constant.DefaultPageSize
|
||||
}
|
||||
offset := search.Page * search.PageSize
|
||||
session := qr.data.DB.Table("question")
|
||||
|
@ -187,7 +191,7 @@ func (qr *questionRepo) SearchList(ctx context.Context, search *schema.QuestionS
|
|||
if len(search.TagIDs) > 0 {
|
||||
session = session.Join("LEFT", "tag_rel", "question.id = tag_rel.object_id")
|
||||
session = session.And("tag_rel.tag_id =?", search.TagIDs[0])
|
||||
//session = session.In("tag_rel.tag_id ", search.TagIDs)
|
||||
// session = session.In("tag_rel.tag_id ", search.TagIDs)
|
||||
session = session.And("tag_rel.status =?", entity.TagRelStatusAvailable)
|
||||
}
|
||||
|
||||
|
@ -199,8 +203,8 @@ func (qr *questionRepo) SearchList(ctx context.Context, search *schema.QuestionS
|
|||
// if search.Status > 0 {
|
||||
// session = session.And("question.status = ?", search.Status)
|
||||
// }
|
||||
//switch
|
||||
//newest, active,frequent,score,unanswered
|
||||
// switch
|
||||
// newest, active,frequent,score,unanswered
|
||||
switch search.Order {
|
||||
case "newest":
|
||||
session = session.OrderBy("question.created_at desc")
|
||||
|
@ -225,8 +229,16 @@ func (qr *questionRepo) SearchList(ctx context.Context, search *schema.QuestionS
|
|||
}
|
||||
|
||||
func (qr *questionRepo) CmsSearchList(ctx context.Context, search *schema.CmsQuestionSearch) ([]*entity.Question, int64, error) {
|
||||
var count int64
|
||||
var err error
|
||||
var (
|
||||
count int64
|
||||
err error
|
||||
session = qr.data.DB.Table("question")
|
||||
)
|
||||
|
||||
session.Where(builder.Eq{
|
||||
"status": search.Status,
|
||||
})
|
||||
|
||||
rows := make([]*entity.Question, 0)
|
||||
if search.Page > 0 {
|
||||
search.Page = search.Page - 1
|
||||
|
@ -234,13 +246,42 @@ func (qr *questionRepo) CmsSearchList(ctx context.Context, search *schema.CmsQue
|
|||
search.Page = 0
|
||||
}
|
||||
if search.PageSize == 0 {
|
||||
search.PageSize = constant.Default_PageSize
|
||||
search.PageSize = constant.DefaultPageSize
|
||||
}
|
||||
|
||||
// search by question title like or question id
|
||||
if len(search.Query) > 0 {
|
||||
// check id search
|
||||
var (
|
||||
idSearch = false
|
||||
id = ""
|
||||
)
|
||||
if strings.Contains(search.Query, "question:") {
|
||||
idSearch = true
|
||||
id = strings.TrimSpace(strings.TrimPrefix(search.Query, "question:"))
|
||||
for _, r := range id {
|
||||
if !unicode.IsDigit(r) {
|
||||
idSearch = false
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if idSearch {
|
||||
session.And(builder.Eq{
|
||||
"id": id,
|
||||
})
|
||||
} else {
|
||||
session.And(builder.Like{
|
||||
"title", search.Query,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
offset := search.Page * search.PageSize
|
||||
session := qr.data.DB.Table("question")
|
||||
session = session.And("status =?", search.Status)
|
||||
session = session.OrderBy("updated_at desc")
|
||||
session = session.Limit(search.PageSize, offset)
|
||||
|
||||
session.OrderBy("updated_at desc").
|
||||
Limit(search.PageSize, offset)
|
||||
count, err = session.FindAndCount(&rows)
|
||||
if err != nil {
|
||||
err = errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
|
|
@ -34,26 +34,28 @@ func NewUserRankRepo(data *data.Data, configRepo config.ConfigRepo) rank.UserRan
|
|||
// session is need provider, it means this action must be success or failure
|
||||
// if outer action is failed then this action is need rollback
|
||||
func (ur *UserRankRepo) TriggerUserRank(ctx context.Context,
|
||||
session *xorm.Session, userId string, deltaRank int, activityType int) (isReachStandard bool, err error) {
|
||||
session *xorm.Session, userID string, deltaRank int, activityType int,
|
||||
) (isReachStandard bool, err error) {
|
||||
if deltaRank == 0 {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
if deltaRank < 0 {
|
||||
// if user rank is lower than 1 after this action, then user rank will be set to 1 only.
|
||||
isReachMin, err := ur.checkUserMinRank(ctx, session, userId, activityType)
|
||||
var isReachMin bool
|
||||
isReachMin, err = ur.checkUserMinRank(ctx, session, userID, activityType)
|
||||
if err != nil {
|
||||
return false, errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
|
||||
}
|
||||
if isReachMin {
|
||||
_, err = session.Where(builder.Eq{"id": userId}).Update(&entity.User{Rank: 1})
|
||||
_, err = session.Where(builder.Eq{"id": userID}).Update(&entity.User{Rank: 1})
|
||||
if err != nil {
|
||||
return false, errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
|
||||
}
|
||||
return false, nil
|
||||
}
|
||||
} else {
|
||||
isReachStandard, err = ur.checkUserTodayRank(ctx, session, userId, activityType)
|
||||
isReachStandard, err = ur.checkUserTodayRank(ctx, session, userID, activityType)
|
||||
if err != nil {
|
||||
return false, errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
|
||||
}
|
||||
|
@ -61,7 +63,7 @@ func (ur *UserRankRepo) TriggerUserRank(ctx context.Context,
|
|||
return isReachStandard, nil
|
||||
}
|
||||
}
|
||||
_, err = session.Where(builder.Eq{"id": userId}).Incr("`rank`", deltaRank).Update(&entity.User{})
|
||||
_, err = session.Where(builder.Eq{"id": userID}).Incr("`rank`", deltaRank).Update(&entity.User{})
|
||||
if err != nil {
|
||||
return false, errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
|
||||
}
|
||||
|
@ -69,7 +71,8 @@ func (ur *UserRankRepo) TriggerUserRank(ctx context.Context,
|
|||
}
|
||||
|
||||
func (ur *UserRankRepo) checkUserMinRank(ctx context.Context, session *xorm.Session, userID string, deltaRank int) (
|
||||
isReachStandard bool, err error) {
|
||||
isReachStandard bool, err error,
|
||||
) {
|
||||
bean := &entity.User{ID: userID}
|
||||
_, err = session.Select("rank").Get(bean)
|
||||
if err != nil {
|
||||
|
@ -83,11 +86,13 @@ func (ur *UserRankRepo) checkUserMinRank(ctx context.Context, session *xorm.Sess
|
|||
}
|
||||
|
||||
func (ur *UserRankRepo) checkUserTodayRank(ctx context.Context,
|
||||
session *xorm.Session, userID string, activityType int) (isReachStandard bool, err error) {
|
||||
session *xorm.Session, userID string, activityType int,
|
||||
) (isReachStandard bool, err error) {
|
||||
// exclude daily rank
|
||||
exclude, err := ur.configRepo.GetArrayString("daily_rank_limit.exclude")
|
||||
exclude, _ := ur.configRepo.GetArrayString("daily_rank_limit.exclude")
|
||||
for _, item := range exclude {
|
||||
excludeActivityType, err := ur.configRepo.GetInt(item)
|
||||
var excludeActivityType int
|
||||
excludeActivityType, err = ur.configRepo.GetInt(item)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
@ -123,14 +128,15 @@ func (ur *UserRankRepo) checkUserTodayRank(ctx context.Context,
|
|||
return true, nil
|
||||
}
|
||||
|
||||
func (ur *UserRankRepo) UserRankPage(ctx context.Context, userId string, page, pageSize int) (
|
||||
rankPage []*entity.Activity, total int64, err error) {
|
||||
func (ur *UserRankRepo) UserRankPage(ctx context.Context, userID string, page, pageSize int) (
|
||||
rankPage []*entity.Activity, total int64, err error,
|
||||
) {
|
||||
rankPage = make([]*entity.Activity, 0)
|
||||
|
||||
session := ur.data.DB.Where(builder.Eq{"has_rank": 1}.And(builder.Eq{"cancelled": 0}))
|
||||
session.Desc("created_at")
|
||||
|
||||
cond := &entity.Activity{UserID: userId}
|
||||
cond := &entity.Activity{UserID: userID}
|
||||
total, err = pager.Help(page, pageSize, &rankPage, cond, session)
|
||||
if err != nil {
|
||||
err = errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
|
||||
|
|
|
@ -21,9 +21,9 @@ func NewReasonRepo(configRepo config.ConfigRepo) reason_common.ReasonRepo {
|
|||
}
|
||||
}
|
||||
|
||||
func (rr *reasonRepo) ListReasons(ctx context.Context, req schema.ReasonReq) (resp []schema.ReasonItem, err error) {
|
||||
func (rr *reasonRepo) ListReasons(ctx context.Context, objectType, action string) (resp []schema.ReasonItem, err error) {
|
||||
var (
|
||||
reasonAction = fmt.Sprintf("%s.%s.reasons", req.ObjectType, req.Action)
|
||||
reasonAction = fmt.Sprintf("%s.%s.reasons", objectType, action)
|
||||
reasonKeys []string
|
||||
cfgValue string
|
||||
)
|
||||
|
|
|
@ -0,0 +1,86 @@
|
|||
package repo_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/answerdev/answer/internal/entity"
|
||||
"github.com/answerdev/answer/internal/repo/auth"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
var (
|
||||
token = "token"
|
||||
userID = "1"
|
||||
)
|
||||
|
||||
func Test_authRepo_SetUserCacheInfo(t *testing.T) {
|
||||
authRepo := auth.NewAuthRepo(testDataSource)
|
||||
|
||||
err := authRepo.SetUserCacheInfo(context.TODO(), token, &entity.UserCacheInfo{UserID: userID})
|
||||
assert.NoError(t, err)
|
||||
|
||||
cacheInfo, err := authRepo.GetUserCacheInfo(context.TODO(), token)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, userID, cacheInfo.UserID)
|
||||
}
|
||||
|
||||
func Test_authRepo_RemoveUserCacheInfo(t *testing.T) {
|
||||
authRepo := auth.NewAuthRepo(testDataSource)
|
||||
|
||||
err := authRepo.SetUserCacheInfo(context.TODO(), token, &entity.UserCacheInfo{UserID: userID})
|
||||
assert.NoError(t, err)
|
||||
|
||||
err = authRepo.RemoveUserCacheInfo(context.TODO(), token)
|
||||
assert.NoError(t, err)
|
||||
|
||||
_, err = authRepo.GetUserCacheInfo(context.TODO(), token)
|
||||
assert.Error(t, err)
|
||||
}
|
||||
|
||||
func Test_authRepo_SetUserStatus(t *testing.T) {
|
||||
authRepo := auth.NewAuthRepo(testDataSource)
|
||||
|
||||
err := authRepo.SetUserStatus(context.TODO(), userID, &entity.UserCacheInfo{UserID: userID})
|
||||
assert.NoError(t, err)
|
||||
|
||||
cacheInfo, err := authRepo.GetUserStatus(context.TODO(), userID)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, userID, cacheInfo.UserID)
|
||||
}
|
||||
func Test_authRepo_RemoveUserStatus(t *testing.T) {
|
||||
authRepo := auth.NewAuthRepo(testDataSource)
|
||||
|
||||
err := authRepo.SetUserStatus(context.TODO(), userID, &entity.UserCacheInfo{UserID: userID})
|
||||
assert.NoError(t, err)
|
||||
|
||||
err = authRepo.RemoveUserStatus(context.TODO(), userID)
|
||||
assert.NoError(t, err)
|
||||
|
||||
_, err = authRepo.GetUserStatus(context.TODO(), userID)
|
||||
assert.Error(t, err)
|
||||
}
|
||||
|
||||
func Test_authRepo_SetBackyardUserCacheInfo(t *testing.T) {
|
||||
authRepo := auth.NewAuthRepo(testDataSource)
|
||||
|
||||
err := authRepo.SetBackyardUserCacheInfo(context.TODO(), token, &entity.UserCacheInfo{UserID: userID})
|
||||
assert.NoError(t, err)
|
||||
|
||||
cacheInfo, err := authRepo.GetBackyardUserCacheInfo(context.TODO(), token)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, userID, cacheInfo.UserID)
|
||||
}
|
||||
|
||||
func Test_authRepo_RemoveBackyardUserCacheInfo(t *testing.T) {
|
||||
authRepo := auth.NewAuthRepo(testDataSource)
|
||||
|
||||
err := authRepo.SetBackyardUserCacheInfo(context.TODO(), token, &entity.UserCacheInfo{UserID: userID})
|
||||
assert.NoError(t, err)
|
||||
|
||||
err = authRepo.RemoveBackyardUserCacheInfo(context.TODO(), token)
|
||||
assert.NoError(t, err)
|
||||
|
||||
_, err = authRepo.GetBackyardUserCacheInfo(context.TODO(), token)
|
||||
assert.Error(t, err)
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
package repo_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/answerdev/answer/internal/repo/captcha"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
var (
|
||||
ip = "127.0.0.1"
|
||||
actionType = "actionType"
|
||||
amount = 1
|
||||
)
|
||||
|
||||
func Test_captchaRepo_DelActionType(t *testing.T) {
|
||||
captchaRepo := captcha.NewCaptchaRepo(testDataSource)
|
||||
err := captchaRepo.SetActionType(context.TODO(), ip, actionType, amount)
|
||||
assert.NoError(t, err)
|
||||
|
||||
gotAmount, err := captchaRepo.GetActionType(context.TODO(), ip, actionType)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, amount, gotAmount)
|
||||
|
||||
err = captchaRepo.DelActionType(context.TODO(), ip, actionType)
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
func Test_captchaRepo_SetCaptcha(t *testing.T) {
|
||||
captchaRepo := captcha.NewCaptchaRepo(testDataSource)
|
||||
key, capt := "key", "1234"
|
||||
err := captchaRepo.SetCaptcha(context.TODO(), key, capt)
|
||||
assert.NoError(t, err)
|
||||
|
||||
gotCaptcha, err := captchaRepo.GetCaptcha(context.TODO(), key)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, capt, gotCaptcha)
|
||||
}
|
|
@ -0,0 +1,81 @@
|
|||
package repo_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/answerdev/answer/internal/base/pager"
|
||||
"github.com/answerdev/answer/internal/entity"
|
||||
"github.com/answerdev/answer/internal/repo/comment"
|
||||
"github.com/answerdev/answer/internal/repo/unique"
|
||||
commentService "github.com/answerdev/answer/internal/service/comment"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func buildCommentEntity() *entity.Comment {
|
||||
return &entity.Comment{
|
||||
UserID: "1",
|
||||
ObjectID: "1",
|
||||
QuestionID: "1",
|
||||
VoteCount: 1,
|
||||
Status: entity.CommentStatusAvailable,
|
||||
OriginalText: "# title",
|
||||
ParsedText: "<h1>Title</h1>",
|
||||
}
|
||||
}
|
||||
|
||||
func Test_commentRepo_AddComment(t *testing.T) {
|
||||
uniqueIDRepo := unique.NewUniqueIDRepo(testDataSource)
|
||||
commentRepo := comment.NewCommentRepo(testDataSource, uniqueIDRepo)
|
||||
testCommentEntity := buildCommentEntity()
|
||||
err := commentRepo.AddComment(context.TODO(), testCommentEntity)
|
||||
assert.NoError(t, err)
|
||||
|
||||
err = commentRepo.RemoveComment(context.TODO(), testCommentEntity.ID)
|
||||
assert.NoError(t, err)
|
||||
return
|
||||
}
|
||||
|
||||
func Test_commentRepo_GetCommentPage(t *testing.T) {
|
||||
uniqueIDRepo := unique.NewUniqueIDRepo(testDataSource)
|
||||
commentRepo := comment.NewCommentRepo(testDataSource, uniqueIDRepo)
|
||||
testCommentEntity := buildCommentEntity()
|
||||
err := commentRepo.AddComment(context.TODO(), testCommentEntity)
|
||||
assert.NoError(t, err)
|
||||
|
||||
resp, total, err := commentRepo.GetCommentPage(context.TODO(), &commentService.CommentQuery{
|
||||
PageCond: pager.PageCond{
|
||||
Page: 1,
|
||||
PageSize: 10,
|
||||
},
|
||||
})
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, total, int64(1))
|
||||
assert.Equal(t, resp[0].ID, testCommentEntity.ID)
|
||||
|
||||
err = commentRepo.RemoveComment(context.TODO(), testCommentEntity.ID)
|
||||
assert.NoError(t, err)
|
||||
return
|
||||
}
|
||||
|
||||
func Test_commentRepo_UpdateComment(t *testing.T) {
|
||||
uniqueIDRepo := unique.NewUniqueIDRepo(testDataSource)
|
||||
commentRepo := comment.NewCommentRepo(testDataSource, uniqueIDRepo)
|
||||
commonCommentRepo := comment.NewCommentCommonRepo(testDataSource, uniqueIDRepo)
|
||||
testCommentEntity := buildCommentEntity()
|
||||
err := commentRepo.AddComment(context.TODO(), testCommentEntity)
|
||||
assert.NoError(t, err)
|
||||
|
||||
testCommentEntity.ParsedText = "test"
|
||||
err = commentRepo.UpdateComment(context.TODO(), testCommentEntity)
|
||||
assert.NoError(t, err)
|
||||
|
||||
newComment, exist, err := commonCommentRepo.GetComment(context.TODO(), testCommentEntity.ID)
|
||||
assert.NoError(t, err)
|
||||
assert.True(t, exist)
|
||||
assert.Equal(t, testCommentEntity.ParsedText, newComment.ParsedText)
|
||||
|
||||
err = commentRepo.RemoveComment(context.TODO(), testCommentEntity.ID)
|
||||
assert.NoError(t, err)
|
||||
return
|
||||
}
|
|
@ -0,0 +1,62 @@
|
|||
package repo_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/answerdev/answer/internal/repo/config"
|
||||
"github.com/answerdev/answer/internal/schema"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func Test_configRepo_Get(t *testing.T) {
|
||||
configRepo := config.NewConfigRepo(testDataSource)
|
||||
_, err := configRepo.Get("email.config")
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
func Test_configRepo_GetArrayString(t *testing.T) {
|
||||
configRepo := config.NewConfigRepo(testDataSource)
|
||||
got, err := configRepo.GetArrayString("daily_rank_limit.exclude")
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, 1, len(got))
|
||||
assert.Equal(t, "answer.accepted", got[0])
|
||||
}
|
||||
|
||||
func Test_configRepo_GetConfigById(t *testing.T) {
|
||||
configRepo := config.NewConfigRepo(testDataSource)
|
||||
|
||||
closeInfo := &schema.GetReportTypeResp{}
|
||||
err := configRepo.GetJsonConfigByIDAndSetToObject(74, closeInfo)
|
||||
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, "needs close", closeInfo.Name)
|
||||
}
|
||||
|
||||
func Test_configRepo_GetConfigType(t *testing.T) {
|
||||
configRepo := config.NewConfigRepo(testDataSource)
|
||||
configType, err := configRepo.GetConfigType("answer.accepted")
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, 1, configType)
|
||||
}
|
||||
|
||||
func Test_configRepo_GetInt(t *testing.T) {
|
||||
configRepo := config.NewConfigRepo(testDataSource)
|
||||
got, err := configRepo.GetInt("answer.accepted")
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, 15, got)
|
||||
}
|
||||
|
||||
func Test_configRepo_GetString(t *testing.T) {
|
||||
configRepo := config.NewConfigRepo(testDataSource)
|
||||
_, err := configRepo.GetString("email.config")
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
func Test_configRepo_SetConfig(t *testing.T) {
|
||||
configRepo := config.NewConfigRepo(testDataSource)
|
||||
got, err := configRepo.GetString("email.config")
|
||||
assert.NoError(t, err)
|
||||
|
||||
err = configRepo.SetConfig("email.config", got)
|
||||
assert.NoError(t, err)
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
package repo_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/answerdev/answer/internal/repo/export"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func Test_emailRepo_VerifyCode(t *testing.T) {
|
||||
emailRepo := export.NewEmailRepo(testDataSource)
|
||||
code, content := "1111", "test"
|
||||
err := emailRepo.SetCode(context.TODO(), code, content)
|
||||
assert.NoError(t, err)
|
||||
|
||||
verifyContent, err := emailRepo.VerifyCode(context.TODO(), code)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, content, verifyContent)
|
||||
}
|
|
@ -0,0 +1,86 @@
|
|||
package repo_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/answerdev/answer/internal/entity"
|
||||
"github.com/answerdev/answer/internal/repo/meta"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func buildMetaEntity() *entity.Meta {
|
||||
return &entity.Meta{
|
||||
ObjectID: "1",
|
||||
Key: "1",
|
||||
Value: "1",
|
||||
}
|
||||
}
|
||||
|
||||
func Test_metaRepo_GetMetaByObjectIdAndKey(t *testing.T) {
|
||||
metaRepo := meta.NewMetaRepo(testDataSource)
|
||||
metaEnt := buildMetaEntity()
|
||||
|
||||
err := metaRepo.AddMeta(context.TODO(), metaEnt)
|
||||
assert.NoError(t, err)
|
||||
|
||||
gotMeta, exist, err := metaRepo.GetMetaByObjectIdAndKey(context.TODO(), metaEnt.ObjectID, metaEnt.Key)
|
||||
assert.NoError(t, err)
|
||||
assert.True(t, exist)
|
||||
assert.Equal(t, metaEnt.ID, gotMeta.ID)
|
||||
|
||||
err = metaRepo.RemoveMeta(context.TODO(), metaEnt.ID)
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
func Test_metaRepo_GetMetaList(t *testing.T) {
|
||||
metaRepo := meta.NewMetaRepo(testDataSource)
|
||||
metaEnt := buildMetaEntity()
|
||||
|
||||
err := metaRepo.AddMeta(context.TODO(), metaEnt)
|
||||
assert.NoError(t, err)
|
||||
|
||||
gotMetaList, err := metaRepo.GetMetaList(context.TODO(), metaEnt)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, len(gotMetaList), 1)
|
||||
assert.Equal(t, gotMetaList[0].ID, metaEnt.ID)
|
||||
|
||||
err = metaRepo.RemoveMeta(context.TODO(), metaEnt.ID)
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
func Test_metaRepo_GetMetaPage(t *testing.T) {
|
||||
metaRepo := meta.NewMetaRepo(testDataSource)
|
||||
metaEnt := buildMetaEntity()
|
||||
|
||||
err := metaRepo.AddMeta(context.TODO(), metaEnt)
|
||||
assert.NoError(t, err)
|
||||
|
||||
gotMetaList, err := metaRepo.GetMetaList(context.TODO(), metaEnt)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, len(gotMetaList), 1)
|
||||
assert.Equal(t, gotMetaList[0].ID, metaEnt.ID)
|
||||
|
||||
err = metaRepo.RemoveMeta(context.TODO(), metaEnt.ID)
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
func Test_metaRepo_UpdateMeta(t *testing.T) {
|
||||
metaRepo := meta.NewMetaRepo(testDataSource)
|
||||
metaEnt := buildMetaEntity()
|
||||
|
||||
err := metaRepo.AddMeta(context.TODO(), metaEnt)
|
||||
assert.NoError(t, err)
|
||||
|
||||
metaEnt.Value = "testing"
|
||||
err = metaRepo.UpdateMeta(context.TODO(), metaEnt)
|
||||
assert.NoError(t, err)
|
||||
|
||||
gotMeta, exist, err := metaRepo.GetMetaByObjectIdAndKey(context.TODO(), metaEnt.ObjectID, metaEnt.Key)
|
||||
assert.NoError(t, err)
|
||||
assert.True(t, exist)
|
||||
assert.Equal(t, gotMeta.Value, metaEnt.Value)
|
||||
|
||||
err = metaRepo.RemoveMeta(context.TODO(), metaEnt.ID)
|
||||
assert.NoError(t, err)
|
||||
}
|
|
@ -0,0 +1,104 @@
|
|||
package repo_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/answerdev/answer/internal/entity"
|
||||
"github.com/answerdev/answer/internal/repo/notification"
|
||||
"github.com/answerdev/answer/internal/schema"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func buildNotificationEntity() *entity.Notification {
|
||||
return &entity.Notification{
|
||||
UserID: "1",
|
||||
ObjectID: "1",
|
||||
Content: "1",
|
||||
Type: schema.NotificationTypeInbox,
|
||||
IsRead: schema.NotificationNotRead,
|
||||
Status: schema.NotificationStatusNormal,
|
||||
}
|
||||
}
|
||||
|
||||
func Test_notificationRepo_ClearIDUnRead(t *testing.T) {
|
||||
notificationRepo := notification.NewNotificationRepo(testDataSource)
|
||||
ent := buildNotificationEntity()
|
||||
err := notificationRepo.AddNotification(context.TODO(), ent)
|
||||
assert.NoError(t, err)
|
||||
|
||||
err = notificationRepo.ClearIDUnRead(context.TODO(), ent.UserID, ent.ID)
|
||||
assert.NoError(t, err)
|
||||
|
||||
got, exists, err := notificationRepo.GetById(context.TODO(), ent.ID)
|
||||
assert.NoError(t, err)
|
||||
assert.True(t, exists)
|
||||
assert.Equal(t, schema.NotificationRead, got.IsRead)
|
||||
}
|
||||
|
||||
func Test_notificationRepo_ClearUnRead(t *testing.T) {
|
||||
notificationRepo := notification.NewNotificationRepo(testDataSource)
|
||||
ent := buildNotificationEntity()
|
||||
err := notificationRepo.AddNotification(context.TODO(), ent)
|
||||
assert.NoError(t, err)
|
||||
|
||||
err = notificationRepo.ClearUnRead(context.TODO(), ent.UserID, ent.Type)
|
||||
assert.NoError(t, err)
|
||||
|
||||
got, exists, err := notificationRepo.GetById(context.TODO(), ent.ID)
|
||||
assert.NoError(t, err)
|
||||
assert.True(t, exists)
|
||||
assert.Equal(t, schema.NotificationRead, got.IsRead)
|
||||
}
|
||||
|
||||
func Test_notificationRepo_GetById(t *testing.T) {
|
||||
notificationRepo := notification.NewNotificationRepo(testDataSource)
|
||||
ent := buildNotificationEntity()
|
||||
err := notificationRepo.AddNotification(context.TODO(), ent)
|
||||
assert.NoError(t, err)
|
||||
|
||||
got, exists, err := notificationRepo.GetById(context.TODO(), ent.ID)
|
||||
assert.NoError(t, err)
|
||||
assert.True(t, exists)
|
||||
assert.Equal(t, got.ID, ent.ID)
|
||||
}
|
||||
|
||||
func Test_notificationRepo_GetByUserIdObjectIdTypeId(t *testing.T) {
|
||||
notificationRepo := notification.NewNotificationRepo(testDataSource)
|
||||
ent := buildNotificationEntity()
|
||||
err := notificationRepo.AddNotification(context.TODO(), ent)
|
||||
assert.NoError(t, err)
|
||||
|
||||
got, exists, err := notificationRepo.GetByUserIdObjectIdTypeId(context.TODO(), ent.UserID, ent.ObjectID, ent.Type)
|
||||
assert.NoError(t, err)
|
||||
assert.True(t, exists)
|
||||
assert.Equal(t, got.ObjectID, ent.ObjectID)
|
||||
}
|
||||
|
||||
func Test_notificationRepo_GetNotificationPage(t *testing.T) {
|
||||
notificationRepo := notification.NewNotificationRepo(testDataSource)
|
||||
ent := buildNotificationEntity()
|
||||
err := notificationRepo.AddNotification(context.TODO(), ent)
|
||||
assert.NoError(t, err)
|
||||
|
||||
notificationPage, total, err := notificationRepo.GetNotificationPage(context.TODO(), &schema.NotificationSearch{UserID: userID})
|
||||
assert.NoError(t, err)
|
||||
assert.True(t, total > 0)
|
||||
assert.Equal(t, notificationPage[0].UserID, ent.UserID)
|
||||
}
|
||||
|
||||
func Test_notificationRepo_UpdateNotificationContent(t *testing.T) {
|
||||
notificationRepo := notification.NewNotificationRepo(testDataSource)
|
||||
ent := buildNotificationEntity()
|
||||
err := notificationRepo.AddNotification(context.TODO(), ent)
|
||||
assert.NoError(t, err)
|
||||
|
||||
ent.Content = "test"
|
||||
err = notificationRepo.UpdateNotificationContent(context.TODO(), ent)
|
||||
assert.NoError(t, err)
|
||||
|
||||
got, exists, err := notificationRepo.GetById(context.TODO(), ent.ID)
|
||||
assert.NoError(t, err)
|
||||
assert.True(t, exists)
|
||||
assert.Equal(t, got.Content, ent.Content)
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
package repo_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/answerdev/answer/internal/repo/config"
|
||||
"github.com/answerdev/answer/internal/repo/reason"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func Test_reasonRepo_ListReasons(t *testing.T) {
|
||||
configRepo := config.NewConfigRepo(testDataSource)
|
||||
reasonRepo := reason.NewReasonRepo(configRepo)
|
||||
reasonItems, err := reasonRepo.ListReasons(context.TODO(), "question", "close")
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, 4, len(reasonItems))
|
||||
}
|
|
@ -0,0 +1,172 @@
|
|||
package repo_test
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"os"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/answerdev/answer/internal/base/data"
|
||||
"github.com/answerdev/answer/internal/migrations"
|
||||
"github.com/ory/dockertest/v3"
|
||||
"github.com/ory/dockertest/v3/docker"
|
||||
"github.com/segmentfault/pacman/cache"
|
||||
"github.com/segmentfault/pacman/log"
|
||||
"xorm.io/xorm"
|
||||
"xorm.io/xorm/schemas"
|
||||
)
|
||||
|
||||
var (
|
||||
mysqlDBSetting = TestDBSetting{
|
||||
Driver: string(schemas.MYSQL),
|
||||
ImageName: "mariadb",
|
||||
ImageVersion: "10.4.7",
|
||||
ENV: []string{"MYSQL_ROOT_PASSWORD=root", "MYSQL_DATABASE=answer", "MYSQL_ROOT_HOST=%"},
|
||||
PortID: "3306/tcp",
|
||||
Connection: "root:root@(localhost:%s)/answer?parseTime=true", // port is not fixed, it will be got by port id
|
||||
}
|
||||
postgresDBSetting = TestDBSetting{
|
||||
Driver: string(schemas.POSTGRES),
|
||||
ImageName: "postgres",
|
||||
ImageVersion: "14",
|
||||
ENV: []string{"POSTGRES_USER=root", "POSTGRES_PASSWORD=root", "POSTGRES_DB=answer", "LISTEN_ADDRESSES='*'"},
|
||||
PortID: "5432/tcp",
|
||||
Connection: "host=localhost port=%s user=root password=root dbname=answer sslmode=disable",
|
||||
}
|
||||
sqlite3DBSetting = TestDBSetting{
|
||||
Driver: string(schemas.SQLITE),
|
||||
Connection: os.TempDir() + "answer-test-data.db",
|
||||
}
|
||||
dbSettingMapping = map[string]TestDBSetting{
|
||||
mysqlDBSetting.Driver: mysqlDBSetting,
|
||||
sqlite3DBSetting.Driver: sqlite3DBSetting,
|
||||
postgresDBSetting.Driver: postgresDBSetting,
|
||||
}
|
||||
// after all test down will execute tearDown function to clean-up
|
||||
tearDown func()
|
||||
// testDataSource used for repo testing
|
||||
testDataSource *data.Data
|
||||
)
|
||||
|
||||
func TestMain(t *testing.M) {
|
||||
dbSetting, ok := dbSettingMapping[os.Getenv("TEST_DB_DRIVER")]
|
||||
if !ok {
|
||||
dbSetting = dbSettingMapping[string(schemas.MYSQL)]
|
||||
}
|
||||
defer func() {
|
||||
if tearDown != nil {
|
||||
tearDown()
|
||||
}
|
||||
}()
|
||||
if err := initTestDataSource(dbSetting); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
log.Info("init test database successfully")
|
||||
|
||||
if ret := t.Run(); ret != 0 {
|
||||
panic(ret)
|
||||
}
|
||||
}
|
||||
|
||||
type TestDBSetting struct {
|
||||
Driver string
|
||||
ImageName string
|
||||
ImageVersion string
|
||||
ENV []string
|
||||
PortID string
|
||||
Connection string
|
||||
}
|
||||
|
||||
func initTestDataSource(dbSetting TestDBSetting) error {
|
||||
connection, imageCleanUp, err := initDatabaseImage(dbSetting)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
dbSetting.Connection = connection
|
||||
|
||||
dbEngine, err := initDatabase(dbSetting)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
newCache, err := initCache()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
newData, dbCleanUp, err := data.NewData(dbEngine, newCache)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
testDataSource = newData
|
||||
|
||||
tearDown = func() {
|
||||
dbCleanUp()
|
||||
log.Info("cleanup test database successfully")
|
||||
imageCleanUp()
|
||||
log.Info("cleanup test database image successfully")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func initDatabaseImage(dbSetting TestDBSetting) (connection string, cleanup func(), err error) {
|
||||
// sqlite3 don't need to set up image
|
||||
if dbSetting.Driver == string(schemas.SQLITE) {
|
||||
return dbSetting.Connection, func() {
|
||||
log.Info("remove database", dbSetting.Connection)
|
||||
err = os.Remove(dbSetting.Connection)
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
}
|
||||
}, nil
|
||||
}
|
||||
pool, err := dockertest.NewPool("")
|
||||
pool.MaxWait = time.Minute * 5
|
||||
if err != nil {
|
||||
return "", nil, fmt.Errorf("could not connect to docker: %s", err)
|
||||
}
|
||||
|
||||
//resource, err := pool.Run(dbSetting.ImageName, dbSetting.ImageVersion, dbSetting.ENV)
|
||||
resource, err := pool.RunWithOptions(&dockertest.RunOptions{
|
||||
Repository: dbSetting.ImageName,
|
||||
Tag: dbSetting.ImageVersion,
|
||||
Env: dbSetting.ENV,
|
||||
}, func(config *docker.HostConfig) {
|
||||
config.AutoRemove = true
|
||||
config.RestartPolicy = docker.RestartPolicy{Name: "no"}
|
||||
})
|
||||
if err != nil {
|
||||
return "", nil, fmt.Errorf("could not pull resource: %s", err)
|
||||
}
|
||||
|
||||
connection = fmt.Sprintf(dbSetting.Connection, resource.GetPort(dbSetting.PortID))
|
||||
if err := pool.Retry(func() error {
|
||||
db, err := sql.Open(dbSetting.Driver, connection)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return db.Ping()
|
||||
}); err != nil {
|
||||
return "", nil, fmt.Errorf("could not connect to database: %s", err)
|
||||
}
|
||||
return connection, func() { _ = pool.Purge(resource) }, nil
|
||||
}
|
||||
|
||||
func initDatabase(dbSetting TestDBSetting) (dbEngine *xorm.Engine, err error) {
|
||||
dataConf := &data.Database{Driver: dbSetting.Driver, Connection: dbSetting.Connection}
|
||||
dbEngine, err = data.NewDB(true, dataConf)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("connection to database failed: %s", err)
|
||||
}
|
||||
err = migrations.InitDB(dataConf)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("migrations init database failed: %s", err)
|
||||
}
|
||||
return dbEngine, nil
|
||||
}
|
||||
|
||||
func initCache() (newCache cache.Cache, err error) {
|
||||
newCache, _, err = data.NewCache(&data.CacheConf{})
|
||||
return newCache, err
|
||||
}
|
|
@ -0,0 +1,99 @@
|
|||
package repo_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"github.com/answerdev/answer/internal/entity"
|
||||
"github.com/answerdev/answer/internal/repo/question"
|
||||
"github.com/answerdev/answer/internal/repo/revision"
|
||||
"github.com/answerdev/answer/internal/repo/unique"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"testing"
|
||||
)
|
||||
|
||||
var q = &entity.Question{
|
||||
ID: "",
|
||||
UserID: "1",
|
||||
Title: "test",
|
||||
OriginalText: "test",
|
||||
ParsedText: "test",
|
||||
Status: entity.QuestionStatusAvailable,
|
||||
ViewCount: 0,
|
||||
UniqueViewCount: 0,
|
||||
VoteCount: 0,
|
||||
AnswerCount: 0,
|
||||
CollectionCount: 0,
|
||||
FollowCount: 0,
|
||||
AcceptedAnswerID: "",
|
||||
LastAnswerID: "",
|
||||
RevisionID: "0",
|
||||
}
|
||||
|
||||
func getRev(objID, title, content string) *entity.Revision {
|
||||
return &entity.Revision{
|
||||
ID: "",
|
||||
UserID: "1",
|
||||
ObjectID: objID,
|
||||
Title: title,
|
||||
Content: content,
|
||||
Log: "add rev",
|
||||
}
|
||||
}
|
||||
|
||||
func Test_revisionRepo_AddRevision(t *testing.T) {
|
||||
var (
|
||||
uniqueIDRepo = unique.NewUniqueIDRepo(testDataSource)
|
||||
revisionRepo = revision.NewRevisionRepo(testDataSource, uniqueIDRepo)
|
||||
questionRepo = question.NewQuestionRepo(testDataSource, uniqueIDRepo)
|
||||
)
|
||||
|
||||
// create question
|
||||
err := questionRepo.AddQuestion(context.TODO(), q)
|
||||
assert.NoError(t, err)
|
||||
assert.NotEqual(t, "", q.ID)
|
||||
|
||||
content, err := json.Marshal(q)
|
||||
// auto update false
|
||||
rev := getRev(q.ID, q.Title, string(content))
|
||||
err = revisionRepo.AddRevision(context.TODO(), rev, false)
|
||||
assert.NoError(t, err)
|
||||
qr, _, _ := questionRepo.GetQuestion(context.TODO(), q.ID)
|
||||
assert.NotEqual(t, rev.ID, qr.RevisionID)
|
||||
|
||||
// auto update false
|
||||
rev = getRev(q.ID, q.Title, string(content))
|
||||
err = revisionRepo.AddRevision(context.TODO(), rev, true)
|
||||
assert.NoError(t, err)
|
||||
qr, _, _ = questionRepo.GetQuestion(context.TODO(), q.ID)
|
||||
assert.Equal(t, rev.ID, qr.RevisionID)
|
||||
|
||||
// recovery
|
||||
t.Cleanup(func() {
|
||||
err = questionRepo.RemoveQuestion(context.TODO(), q.ID)
|
||||
assert.NoError(t, err)
|
||||
})
|
||||
}
|
||||
|
||||
func Test_revisionRepo_GetLastRevisionByObjectID(t *testing.T) {
|
||||
var (
|
||||
uniqueIDRepo = unique.NewUniqueIDRepo(testDataSource)
|
||||
revisionRepo = revision.NewRevisionRepo(testDataSource, uniqueIDRepo)
|
||||
)
|
||||
|
||||
Test_revisionRepo_AddRevision(t)
|
||||
rev, exists, err := revisionRepo.GetLastRevisionByObjectID(context.TODO(), q.ID)
|
||||
assert.NoError(t, err)
|
||||
assert.True(t, exists)
|
||||
assert.NotNil(t, rev)
|
||||
}
|
||||
|
||||
func Test_revisionRepo_GetRevisionList(t *testing.T) {
|
||||
var (
|
||||
uniqueIDRepo = unique.NewUniqueIDRepo(testDataSource)
|
||||
revisionRepo = revision.NewRevisionRepo(testDataSource, uniqueIDRepo)
|
||||
)
|
||||
Test_revisionRepo_AddRevision(t)
|
||||
revs, err := revisionRepo.GetRevisionList(context.TODO(), &entity.Revision{ObjectID: q.ID})
|
||||
assert.NoError(t, err)
|
||||
assert.GreaterOrEqual(t, len(revs), 1)
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
package repo_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/answerdev/answer/internal/entity"
|
||||
"github.com/answerdev/answer/internal/repo/site_info"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func Test_siteInfoRepo_SaveByType(t *testing.T) {
|
||||
siteInfoRepo := site_info.NewSiteInfo(testDataSource)
|
||||
|
||||
data := &entity.SiteInfo{Content: "site_info", Type: "test"}
|
||||
|
||||
err := siteInfoRepo.SaveByType(context.TODO(), data.Type, data)
|
||||
assert.NoError(t, err)
|
||||
|
||||
got, exist, err := siteInfoRepo.GetByType(context.TODO(), data.Type)
|
||||
assert.NoError(t, err)
|
||||
assert.True(t, exist)
|
||||
assert.Equal(t, data.Content, got.Content)
|
||||
|
||||
data.Content = "new site_info"
|
||||
err = siteInfoRepo.SaveByType(context.TODO(), data.Type, data)
|
||||
assert.NoError(t, err)
|
||||
|
||||
got, exist, err = siteInfoRepo.GetByType(context.TODO(), data.Type)
|
||||
assert.NoError(t, err)
|
||||
assert.True(t, exist)
|
||||
assert.Equal(t, data.Content, got.Content)
|
||||
}
|
|
@ -0,0 +1,91 @@
|
|||
package repo_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"sync"
|
||||
"testing"
|
||||
|
||||
"github.com/answerdev/answer/internal/entity"
|
||||
"github.com/answerdev/answer/internal/repo/tag"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
var (
|
||||
tagRelOnce sync.Once
|
||||
testTagRelList = []*entity.TagRel{
|
||||
{
|
||||
ObjectID: "1",
|
||||
TagID: "1",
|
||||
Status: entity.TagRelStatusAvailable,
|
||||
},
|
||||
{
|
||||
ObjectID: "2",
|
||||
TagID: "2",
|
||||
Status: entity.TagRelStatusAvailable,
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
func addTagRelList() {
|
||||
tagRelRepo := tag.NewTagRelRepo(testDataSource)
|
||||
err := tagRelRepo.AddTagRelList(context.TODO(), testTagRelList)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
func Test_tagListRepo_BatchGetObjectTagRelList(t *testing.T) {
|
||||
tagRelOnce.Do(addTagRelList)
|
||||
tagRelRepo := tag.NewTagRelRepo(testDataSource)
|
||||
relList, err :=
|
||||
tagRelRepo.BatchGetObjectTagRelList(context.TODO(), []string{testTagRelList[0].ObjectID, testTagRelList[1].ObjectID})
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, 2, len(relList))
|
||||
}
|
||||
|
||||
func Test_tagListRepo_CountTagRelByTagID(t *testing.T) {
|
||||
tagRelOnce.Do(addTagRelList)
|
||||
tagRelRepo := tag.NewTagRelRepo(testDataSource)
|
||||
count, err := tagRelRepo.CountTagRelByTagID(context.TODO(), "1")
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, int64(1), count)
|
||||
}
|
||||
|
||||
func Test_tagListRepo_GetObjectTagRelList(t *testing.T) {
|
||||
tagRelOnce.Do(addTagRelList)
|
||||
tagRelRepo := tag.NewTagRelRepo(testDataSource)
|
||||
|
||||
relList, err :=
|
||||
tagRelRepo.GetObjectTagRelList(context.TODO(), testTagRelList[0].ObjectID)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, 1, len(relList))
|
||||
}
|
||||
|
||||
func Test_tagListRepo_GetObjectTagRelWithoutStatus(t *testing.T) {
|
||||
tagRelOnce.Do(addTagRelList)
|
||||
tagRelRepo := tag.NewTagRelRepo(testDataSource)
|
||||
|
||||
relList, err :=
|
||||
tagRelRepo.BatchGetObjectTagRelList(context.TODO(), []string{testTagRelList[0].ObjectID, testTagRelList[1].ObjectID})
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, 2, len(relList))
|
||||
|
||||
ids := []int64{relList[0].ID, relList[1].ID}
|
||||
err = tagRelRepo.RemoveTagRelListByIDs(context.TODO(), ids)
|
||||
assert.NoError(t, err)
|
||||
|
||||
count, err := tagRelRepo.CountTagRelByTagID(context.TODO(), "1")
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, int64(0), count)
|
||||
|
||||
_, exist, err := tagRelRepo.GetObjectTagRelWithoutStatus(context.TODO(), relList[0].ObjectID, relList[0].TagID)
|
||||
assert.NoError(t, err)
|
||||
assert.True(t, exist)
|
||||
|
||||
err = tagRelRepo.EnableTagRelByIDs(context.TODO(), ids)
|
||||
assert.NoError(t, err)
|
||||
|
||||
count, err = tagRelRepo.CountTagRelByTagID(context.TODO(), "1")
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, int64(1), count)
|
||||
}
|
|
@ -0,0 +1,173 @@
|
|||
package repo_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"sync"
|
||||
"testing"
|
||||
|
||||
"github.com/answerdev/answer/internal/entity"
|
||||
"github.com/answerdev/answer/internal/repo/tag"
|
||||
"github.com/answerdev/answer/internal/repo/unique"
|
||||
"github.com/answerdev/answer/pkg/converter"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
var (
|
||||
tagOnce sync.Once
|
||||
testTagList = []*entity.Tag{
|
||||
{
|
||||
SlugName: "go",
|
||||
DisplayName: "Golang",
|
||||
OriginalText: "golang",
|
||||
ParsedText: "<p>golang</p>",
|
||||
Status: entity.TagStatusAvailable,
|
||||
},
|
||||
{
|
||||
SlugName: "js",
|
||||
DisplayName: "javascript",
|
||||
OriginalText: "javascript",
|
||||
ParsedText: "<p>javascript</p>",
|
||||
Status: entity.TagStatusAvailable,
|
||||
},
|
||||
{
|
||||
SlugName: "go2",
|
||||
DisplayName: "Golang2",
|
||||
OriginalText: "golang2",
|
||||
ParsedText: "<p>golang2</p>",
|
||||
Status: entity.TagStatusAvailable,
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
func addTagList() {
|
||||
uniqueIDRepo := unique.NewUniqueIDRepo(testDataSource)
|
||||
tagRepo := tag.NewTagRepo(testDataSource, uniqueIDRepo)
|
||||
err := tagRepo.AddTagList(context.TODO(), testTagList)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
func Test_tagRepo_GetTagByID(t *testing.T) {
|
||||
tagOnce.Do(addTagList)
|
||||
tagRepo := tag.NewTagRepo(testDataSource, unique.NewUniqueIDRepo(testDataSource))
|
||||
|
||||
gotTag, exist, err := tagRepo.GetTagByID(context.TODO(), testTagList[0].ID)
|
||||
assert.NoError(t, err)
|
||||
assert.True(t, exist)
|
||||
assert.Equal(t, testTagList[0].SlugName, gotTag.SlugName)
|
||||
}
|
||||
|
||||
func Test_tagRepo_GetTagBySlugName(t *testing.T) {
|
||||
tagOnce.Do(addTagList)
|
||||
tagRepo := tag.NewTagRepo(testDataSource, unique.NewUniqueIDRepo(testDataSource))
|
||||
|
||||
gotTag, exist, err := tagRepo.GetTagBySlugName(context.TODO(), testTagList[0].SlugName)
|
||||
assert.NoError(t, err)
|
||||
assert.True(t, exist)
|
||||
assert.Equal(t, testTagList[0].SlugName, gotTag.SlugName)
|
||||
}
|
||||
|
||||
func Test_tagRepo_GetTagList(t *testing.T) {
|
||||
tagOnce.Do(addTagList)
|
||||
tagRepo := tag.NewTagRepo(testDataSource, unique.NewUniqueIDRepo(testDataSource))
|
||||
|
||||
gotTags, err := tagRepo.GetTagList(context.TODO(), &entity.Tag{ID: testTagList[0].ID})
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, testTagList[0].SlugName, gotTags[0].SlugName)
|
||||
}
|
||||
|
||||
func Test_tagRepo_GetTagListByIDs(t *testing.T) {
|
||||
tagOnce.Do(addTagList)
|
||||
tagRepo := tag.NewTagRepo(testDataSource, unique.NewUniqueIDRepo(testDataSource))
|
||||
|
||||
gotTags, err := tagRepo.GetTagListByIDs(context.TODO(), []string{testTagList[0].ID})
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, testTagList[0].SlugName, gotTags[0].SlugName)
|
||||
}
|
||||
|
||||
func Test_tagRepo_GetTagListByName(t *testing.T) {
|
||||
tagOnce.Do(addTagList)
|
||||
tagRepo := tag.NewTagRepo(testDataSource, unique.NewUniqueIDRepo(testDataSource))
|
||||
|
||||
gotTags, err := tagRepo.GetTagListByName(context.TODO(), testTagList[0].SlugName, 1)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, testTagList[0].SlugName, gotTags[0].SlugName)
|
||||
}
|
||||
|
||||
func Test_tagRepo_GetTagListByNames(t *testing.T) {
|
||||
tagOnce.Do(addTagList)
|
||||
tagRepo := tag.NewTagRepo(testDataSource, unique.NewUniqueIDRepo(testDataSource))
|
||||
|
||||
gotTags, err := tagRepo.GetTagListByNames(context.TODO(), []string{testTagList[0].SlugName})
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, testTagList[0].SlugName, gotTags[0].SlugName)
|
||||
}
|
||||
|
||||
func Test_tagRepo_GetTagPage(t *testing.T) {
|
||||
tagOnce.Do(addTagList)
|
||||
tagRepo := tag.NewTagRepo(testDataSource, unique.NewUniqueIDRepo(testDataSource))
|
||||
|
||||
gotTags, _, err := tagRepo.GetTagPage(context.TODO(), 1, 1, &entity.Tag{SlugName: testTagList[0].SlugName}, "")
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, testTagList[0].SlugName, gotTags[0].SlugName)
|
||||
}
|
||||
|
||||
func Test_tagRepo_RemoveTag(t *testing.T) {
|
||||
tagOnce.Do(addTagList)
|
||||
uniqueIDRepo := unique.NewUniqueIDRepo(testDataSource)
|
||||
tagRepo := tag.NewTagRepo(testDataSource, uniqueIDRepo)
|
||||
err := tagRepo.RemoveTag(context.TODO(), testTagList[1].ID)
|
||||
assert.NoError(t, err)
|
||||
|
||||
_, exist, err := tagRepo.GetTagBySlugName(context.TODO(), testTagList[1].SlugName)
|
||||
assert.NoError(t, err)
|
||||
assert.False(t, exist)
|
||||
}
|
||||
|
||||
func Test_tagRepo_UpdateTag(t *testing.T) {
|
||||
uniqueIDRepo := unique.NewUniqueIDRepo(testDataSource)
|
||||
tagRepo := tag.NewTagRepo(testDataSource, uniqueIDRepo)
|
||||
|
||||
testTagList[0].DisplayName = "golang"
|
||||
err := tagRepo.UpdateTag(context.TODO(), testTagList[0])
|
||||
assert.NoError(t, err)
|
||||
|
||||
gotTag, exist, err := tagRepo.GetTagByID(context.TODO(), testTagList[0].ID)
|
||||
assert.NoError(t, err)
|
||||
assert.True(t, exist)
|
||||
assert.Equal(t, testTagList[0].DisplayName, gotTag.DisplayName)
|
||||
}
|
||||
|
||||
func Test_tagRepo_UpdateTagQuestionCount(t *testing.T) {
|
||||
uniqueIDRepo := unique.NewUniqueIDRepo(testDataSource)
|
||||
tagRepo := tag.NewTagRepo(testDataSource, uniqueIDRepo)
|
||||
|
||||
testTagList[0].DisplayName = "golang"
|
||||
err := tagRepo.UpdateTagQuestionCount(context.TODO(), testTagList[0].ID, 100)
|
||||
assert.NoError(t, err)
|
||||
|
||||
gotTag, exist, err := tagRepo.GetTagByID(context.TODO(), testTagList[0].ID)
|
||||
assert.NoError(t, err)
|
||||
assert.True(t, exist)
|
||||
assert.Equal(t, 100, gotTag.QuestionCount)
|
||||
}
|
||||
|
||||
func Test_tagRepo_UpdateTagSynonym(t *testing.T) {
|
||||
uniqueIDRepo := unique.NewUniqueIDRepo(testDataSource)
|
||||
tagRepo := tag.NewTagRepo(testDataSource, uniqueIDRepo)
|
||||
|
||||
testTagList[0].DisplayName = "golang"
|
||||
err := tagRepo.UpdateTag(context.TODO(), testTagList[0])
|
||||
assert.NoError(t, err)
|
||||
|
||||
err = tagRepo.UpdateTagSynonym(context.TODO(), []string{testTagList[2].SlugName},
|
||||
converter.StringToInt64(testTagList[0].ID), testTagList[0].SlugName)
|
||||
assert.NoError(t, err)
|
||||
|
||||
gotTag, exist, err := tagRepo.GetTagByID(context.TODO(), testTagList[2].ID)
|
||||
assert.NoError(t, err)
|
||||
assert.True(t, exist)
|
||||
assert.Equal(t, testTagList[0].ID, fmt.Sprintf("%d", gotTag.MainTagID))
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
package repo_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/answerdev/answer/internal/entity"
|
||||
"github.com/answerdev/answer/internal/repo/auth"
|
||||
"github.com/answerdev/answer/internal/repo/user"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func Test_userBackyardRepo_GetUserInfo(t *testing.T) {
|
||||
userBackyardRepo := user.NewUserBackyardRepo(testDataSource, auth.NewAuthRepo(testDataSource))
|
||||
got, exist, err := userBackyardRepo.GetUserInfo(context.TODO(), "1")
|
||||
assert.NoError(t, err)
|
||||
assert.True(t, exist)
|
||||
assert.Equal(t, "1", got.ID)
|
||||
}
|
||||
|
||||
func Test_userBackyardRepo_GetUserPage(t *testing.T) {
|
||||
userBackyardRepo := user.NewUserBackyardRepo(testDataSource, auth.NewAuthRepo(testDataSource))
|
||||
got, total, err := userBackyardRepo.GetUserPage(context.TODO(), 1, 1, &entity.User{Username: "admin"}, "")
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, int64(1), total)
|
||||
assert.Equal(t, "1", got[0].ID)
|
||||
}
|
||||
|
||||
func Test_userBackyardRepo_UpdateUserStatus(t *testing.T) {
|
||||
userBackyardRepo := user.NewUserBackyardRepo(testDataSource, auth.NewAuthRepo(testDataSource))
|
||||
got, exist, err := userBackyardRepo.GetUserInfo(context.TODO(), "1")
|
||||
assert.NoError(t, err)
|
||||
assert.True(t, exist)
|
||||
assert.Equal(t, entity.UserStatusAvailable, got.Status)
|
||||
|
||||
err = userBackyardRepo.UpdateUserStatus(context.TODO(), "1", entity.UserStatusSuspended, entity.EmailStatusAvailable,
|
||||
"admin@admin.com")
|
||||
assert.NoError(t, err)
|
||||
|
||||
got, exist, err = userBackyardRepo.GetUserInfo(context.TODO(), "1")
|
||||
assert.NoError(t, err)
|
||||
assert.True(t, exist)
|
||||
assert.Equal(t, entity.UserStatusSuspended, got.Status)
|
||||
|
||||
err = userBackyardRepo.UpdateUserStatus(context.TODO(), "1", entity.UserStatusAvailable, entity.EmailStatusAvailable,
|
||||
"admin@admin.com")
|
||||
assert.NoError(t, err)
|
||||
|
||||
got, exist, err = userBackyardRepo.GetUserInfo(context.TODO(), "1")
|
||||
assert.NoError(t, err)
|
||||
assert.True(t, exist)
|
||||
assert.Equal(t, entity.UserStatusAvailable, got.Status)
|
||||
}
|
|
@ -0,0 +1,121 @@
|
|||
package repo_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/answerdev/answer/internal/entity"
|
||||
"github.com/answerdev/answer/internal/repo/config"
|
||||
"github.com/answerdev/answer/internal/repo/user"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func Test_userRepo_AddUser(t *testing.T) {
|
||||
userRepo := user.NewUserRepo(testDataSource, config.NewConfigRepo(testDataSource))
|
||||
userInfo := &entity.User{
|
||||
Username: "answer",
|
||||
Pass: "answer",
|
||||
EMail: "answer@example.com",
|
||||
MailStatus: entity.EmailStatusAvailable,
|
||||
Status: entity.UserStatusAvailable,
|
||||
DisplayName: "answer",
|
||||
IsAdmin: false,
|
||||
}
|
||||
err := userRepo.AddUser(context.TODO(), userInfo)
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
func Test_userRepo_BatchGetByID(t *testing.T) {
|
||||
userRepo := user.NewUserRepo(testDataSource, config.NewConfigRepo(testDataSource))
|
||||
got, err := userRepo.BatchGetByID(context.TODO(), []string{"1"})
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, 1, len(got))
|
||||
assert.Equal(t, "admin", got[0].Username)
|
||||
}
|
||||
|
||||
func Test_userRepo_GetByEmail(t *testing.T) {
|
||||
userRepo := user.NewUserRepo(testDataSource, config.NewConfigRepo(testDataSource))
|
||||
got, exist, err := userRepo.GetByEmail(context.TODO(), "admin@admin.com")
|
||||
assert.NoError(t, err)
|
||||
assert.True(t, exist)
|
||||
assert.Equal(t, "admin", got.Username)
|
||||
}
|
||||
|
||||
func Test_userRepo_GetByUserID(t *testing.T) {
|
||||
userRepo := user.NewUserRepo(testDataSource, config.NewConfigRepo(testDataSource))
|
||||
got, exist, err := userRepo.GetByUserID(context.TODO(), "1")
|
||||
assert.NoError(t, err)
|
||||
assert.True(t, exist)
|
||||
assert.Equal(t, "admin", got.Username)
|
||||
}
|
||||
|
||||
func Test_userRepo_GetByUsername(t *testing.T) {
|
||||
userRepo := user.NewUserRepo(testDataSource, config.NewConfigRepo(testDataSource))
|
||||
got, exist, err := userRepo.GetByUsername(context.TODO(), "admin")
|
||||
assert.NoError(t, err)
|
||||
assert.True(t, exist)
|
||||
assert.Equal(t, "admin", got.Username)
|
||||
}
|
||||
|
||||
func Test_userRepo_IncreaseAnswerCount(t *testing.T) {
|
||||
userRepo := user.NewUserRepo(testDataSource, config.NewConfigRepo(testDataSource))
|
||||
err := userRepo.IncreaseAnswerCount(context.TODO(), "1", 1)
|
||||
assert.NoError(t, err)
|
||||
|
||||
got, exist, err := userRepo.GetByUserID(context.TODO(), "1")
|
||||
assert.NoError(t, err)
|
||||
assert.True(t, exist)
|
||||
assert.Equal(t, 1, got.AnswerCount)
|
||||
}
|
||||
|
||||
func Test_userRepo_IncreaseQuestionCount(t *testing.T) {
|
||||
userRepo := user.NewUserRepo(testDataSource, config.NewConfigRepo(testDataSource))
|
||||
err := userRepo.IncreaseQuestionCount(context.TODO(), "1", 1)
|
||||
assert.NoError(t, err)
|
||||
|
||||
got, exist, err := userRepo.GetByUserID(context.TODO(), "1")
|
||||
assert.NoError(t, err)
|
||||
assert.True(t, exist)
|
||||
assert.Equal(t, 1, got.AnswerCount)
|
||||
}
|
||||
|
||||
func Test_userRepo_UpdateEmail(t *testing.T) {
|
||||
userRepo := user.NewUserRepo(testDataSource, config.NewConfigRepo(testDataSource))
|
||||
err := userRepo.UpdateEmail(context.TODO(), "1", "admin@admin.com")
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
func Test_userRepo_UpdateEmailStatus(t *testing.T) {
|
||||
userRepo := user.NewUserRepo(testDataSource, config.NewConfigRepo(testDataSource))
|
||||
err := userRepo.UpdateEmailStatus(context.TODO(), "1", entity.EmailStatusToBeVerified)
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
func Test_userRepo_UpdateInfo(t *testing.T) {
|
||||
userRepo := user.NewUserRepo(testDataSource, config.NewConfigRepo(testDataSource))
|
||||
err := userRepo.UpdateInfo(context.TODO(), &entity.User{ID: "1", Bio: "test"})
|
||||
assert.NoError(t, err)
|
||||
|
||||
got, exist, err := userRepo.GetByUserID(context.TODO(), "1")
|
||||
assert.NoError(t, err)
|
||||
assert.True(t, exist)
|
||||
assert.Equal(t, "test", got.Bio)
|
||||
}
|
||||
|
||||
func Test_userRepo_UpdateLastLoginDate(t *testing.T) {
|
||||
userRepo := user.NewUserRepo(testDataSource, config.NewConfigRepo(testDataSource))
|
||||
err := userRepo.UpdateLastLoginDate(context.TODO(), "1")
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
func Test_userRepo_UpdateNoticeStatus(t *testing.T) {
|
||||
userRepo := user.NewUserRepo(testDataSource, config.NewConfigRepo(testDataSource))
|
||||
err := userRepo.UpdateNoticeStatus(context.TODO(), "1", 1)
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
func Test_userRepo_UpdatePass(t *testing.T) {
|
||||
userRepo := user.NewUserRepo(testDataSource, config.NewConfigRepo(testDataSource))
|
||||
err := userRepo.UpdatePass(context.TODO(), "1", "admin")
|
||||
assert.NoError(t, err)
|
||||
}
|
|
@ -86,7 +86,8 @@ func (ar *reportRepo) GetByID(ctx context.Context, id string) (report entity.Rep
|
|||
func (ar *reportRepo) UpdateByID(
|
||||
ctx context.Context,
|
||||
id string,
|
||||
handleData entity.Report) (err error) {
|
||||
handleData entity.Report,
|
||||
) (err error) {
|
||||
_, err = ar.data.DB.ID(id).Update(&handleData)
|
||||
if err != nil {
|
||||
err = errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
|
||||
|
|
|
@ -81,7 +81,8 @@ func (rr *revisionRepo) UpdateObjectRevisionId(ctx context.Context, revision *en
|
|||
|
||||
// GetRevision get revision one
|
||||
func (rr *revisionRepo) GetRevision(ctx context.Context, id string) (
|
||||
revision *entity.Revision, exist bool, err error) {
|
||||
revision *entity.Revision, exist bool, err error,
|
||||
) {
|
||||
revision = &entity.Revision{}
|
||||
exist, err = rr.data.DB.ID(id).Get(revision)
|
||||
if err != nil {
|
||||
|
@ -92,9 +93,10 @@ func (rr *revisionRepo) GetRevision(ctx context.Context, id string) (
|
|||
|
||||
// GetLastRevisionByObjectID get object's last revision by object TagID
|
||||
func (rr *revisionRepo) GetLastRevisionByObjectID(ctx context.Context, objectID string) (
|
||||
revision *entity.Revision, exist bool, err error) {
|
||||
revision *entity.Revision, exist bool, err error,
|
||||
) {
|
||||
revision = &entity.Revision{}
|
||||
exist, err = rr.data.DB.Where("object_id = ?", objectID).OrderBy("create_time DESC").Get(revision)
|
||||
exist, err = rr.data.DB.Where("object_id = ?", objectID).OrderBy("created_at DESC").Get(revision)
|
||||
if err != nil {
|
||||
return nil, false, errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
package repo
|
||||
package search_common
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
@ -21,7 +21,7 @@ import (
|
|||
)
|
||||
|
||||
var (
|
||||
q_fields = []string{
|
||||
qFields = []string{
|
||||
"`question`.`id`",
|
||||
"`question`.`id` as `question_id`",
|
||||
"`title`",
|
||||
|
@ -34,7 +34,7 @@ var (
|
|||
"`question`.`status` as `status`",
|
||||
"`post_update_time`",
|
||||
}
|
||||
a_fields = []string{
|
||||
aFields = []string{
|
||||
"`answer`.`id` as `id`",
|
||||
"`question_id`",
|
||||
"`question`.`title` as `title`",
|
||||
|
@ -67,11 +67,14 @@ func NewSearchRepo(data *data.Data, uniqueIDRepo unique.UniqueIDRepo, userCommon
|
|||
|
||||
// SearchContents search question and answer data
|
||||
func (sr *searchRepo) SearchContents(ctx context.Context, words []string, tagID, userID string, votes int, page, size int, order string) (resp []schema.SearchResp, total int64, err error) {
|
||||
if words = filterWords(words); len(words) == 0 {
|
||||
return
|
||||
}
|
||||
var (
|
||||
b *builder.Builder
|
||||
ub *builder.Builder
|
||||
qfs = q_fields
|
||||
afs = a_fields
|
||||
qfs = qFields
|
||||
afs = aFields
|
||||
argsQ = []interface{}{}
|
||||
argsA = []interface{}{}
|
||||
)
|
||||
|
@ -141,11 +144,11 @@ func (sr *searchRepo) SearchContents(ctx context.Context, words []string, tagID,
|
|||
|
||||
b = b.Union("all", ub)
|
||||
|
||||
querySql, _, err := builder.MySQL().Select("*").From(b, "t").OrderBy(sr.parseOrder(ctx, order)).Limit(size, page-1).ToSQL()
|
||||
querySQL, _, err := builder.MySQL().Select("*").From(b, "t").OrderBy(sr.parseOrder(ctx, order)).Limit(size, page-1).ToSQL()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
countSql, _, err := builder.MySQL().Select("count(*) total").From(b, "c").ToSQL()
|
||||
countSQL, _, err := builder.MySQL().Select("count(*) total").From(b, "c").ToSQL()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
@ -153,11 +156,11 @@ func (sr *searchRepo) SearchContents(ctx context.Context, words []string, tagID,
|
|||
queryArgs := []interface{}{}
|
||||
countArgs := []interface{}{}
|
||||
|
||||
queryArgs = append(queryArgs, querySql)
|
||||
queryArgs = append(queryArgs, querySQL)
|
||||
queryArgs = append(queryArgs, argsQ...)
|
||||
queryArgs = append(queryArgs, argsA...)
|
||||
|
||||
countArgs = append(countArgs, countSql)
|
||||
countArgs = append(countArgs, countSQL)
|
||||
countArgs = append(countArgs, argsQ...)
|
||||
countArgs = append(countArgs, argsA...)
|
||||
|
||||
|
@ -181,8 +184,11 @@ func (sr *searchRepo) SearchContents(ctx context.Context, words []string, tagID,
|
|||
|
||||
// SearchQuestions search question data
|
||||
func (sr *searchRepo) SearchQuestions(ctx context.Context, words []string, limitNoAccepted bool, answers, page, size int, order string) (resp []schema.SearchResp, total int64, err error) {
|
||||
if words = filterWords(words); len(words) == 0 {
|
||||
return
|
||||
}
|
||||
var (
|
||||
qfs = q_fields
|
||||
qfs = qFields
|
||||
args = []interface{}{}
|
||||
)
|
||||
if order == "relevance" {
|
||||
|
@ -223,18 +229,18 @@ func (sr *searchRepo) SearchQuestions(ctx context.Context, words []string, limit
|
|||
queryArgs := []interface{}{}
|
||||
countArgs := []interface{}{}
|
||||
|
||||
querySql, _, err := b.OrderBy(sr.parseOrder(ctx, order)).Limit(size, page-1).ToSQL()
|
||||
querySQL, _, err := b.OrderBy(sr.parseOrder(ctx, order)).Limit(size, page-1).ToSQL()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
countSql, _, err := builder.MySQL().Select("count(*) total").From(b, "c").ToSQL()
|
||||
countSQL, _, err := builder.MySQL().Select("count(*) total").From(b, "c").ToSQL()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
queryArgs = append(queryArgs, querySql)
|
||||
queryArgs = append(queryArgs, querySQL)
|
||||
queryArgs = append(queryArgs, args...)
|
||||
|
||||
countArgs = append(countArgs, countSql)
|
||||
countArgs = append(countArgs, countSQL)
|
||||
countArgs = append(countArgs, args...)
|
||||
|
||||
res, err := sr.data.DB.Query(queryArgs...)
|
||||
|
@ -250,10 +256,6 @@ func (sr *searchRepo) SearchQuestions(ctx context.Context, words []string, limit
|
|||
if len(tr) != 0 {
|
||||
total = converter.StringToInt64(string(tr[0]["total"]))
|
||||
}
|
||||
if err != nil {
|
||||
err = errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
|
||||
return
|
||||
}
|
||||
resp, err = sr.parseResult(ctx, res)
|
||||
if err != nil {
|
||||
err = errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
|
||||
|
@ -263,8 +265,11 @@ func (sr *searchRepo) SearchQuestions(ctx context.Context, words []string, limit
|
|||
|
||||
// SearchAnswers search answer data
|
||||
func (sr *searchRepo) SearchAnswers(ctx context.Context, words []string, limitAccepted bool, questionID string, page, size int, order string) (resp []schema.SearchResp, total int64, err error) {
|
||||
if words = filterWords(words); len(words) == 0 {
|
||||
return
|
||||
}
|
||||
var (
|
||||
afs = a_fields
|
||||
afs = aFields
|
||||
args = []interface{}{}
|
||||
)
|
||||
if order == "relevance" {
|
||||
|
@ -289,8 +294,8 @@ func (sr *searchRepo) SearchAnswers(ctx context.Context, words []string, limitAc
|
|||
}
|
||||
|
||||
if limitAccepted {
|
||||
b.Where(builder.Eq{"adopted": schema.Answer_Adopted_Enable})
|
||||
args = append(args, schema.Answer_Adopted_Enable)
|
||||
b.Where(builder.Eq{"adopted": schema.AnswerAdoptedEnable})
|
||||
args = append(args, schema.AnswerAdoptedEnable)
|
||||
}
|
||||
|
||||
if questionID != "" {
|
||||
|
@ -301,18 +306,18 @@ func (sr *searchRepo) SearchAnswers(ctx context.Context, words []string, limitAc
|
|||
queryArgs := []interface{}{}
|
||||
countArgs := []interface{}{}
|
||||
|
||||
querySql, _, err := b.OrderBy(sr.parseOrder(ctx, order)).Limit(size, page-1).ToSQL()
|
||||
querySQL, _, err := b.OrderBy(sr.parseOrder(ctx, order)).Limit(size, page-1).ToSQL()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
countSql, _, err := builder.MySQL().Select("count(*) total").From(b, "c").ToSQL()
|
||||
countSQL, _, err := builder.MySQL().Select("count(*) total").From(b, "c").ToSQL()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
queryArgs = append(queryArgs, querySql)
|
||||
queryArgs = append(queryArgs, querySQL)
|
||||
queryArgs = append(queryArgs, args...)
|
||||
|
||||
countArgs = append(countArgs, countSql)
|
||||
countArgs = append(countArgs, countSQL)
|
||||
countArgs = append(countArgs, args...)
|
||||
|
||||
res, err := sr.data.DB.Query(queryArgs...)
|
||||
|
@ -326,10 +331,6 @@ func (sr *searchRepo) SearchAnswers(ctx context.Context, words []string, limitAc
|
|||
}
|
||||
|
||||
total = converter.StringToInt64(string(tr[0]["total"]))
|
||||
if err != nil {
|
||||
err = errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
|
||||
return
|
||||
}
|
||||
resp, err = sr.parseResult(ctx, res)
|
||||
if err != nil {
|
||||
err = errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
|
||||
|
@ -438,7 +439,7 @@ func (sr *searchRepo) userBasicInfoFormat(ctx context.Context, dbinfo *entity.Us
|
|||
Avatar: dbinfo.Avatar,
|
||||
Website: dbinfo.Website,
|
||||
Location: dbinfo.Location,
|
||||
IpInfo: dbinfo.IPInfo,
|
||||
IPInfo: dbinfo.IPInfo,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -451,24 +452,24 @@ func cutOutParsedText(parsedText string) string {
|
|||
return parsedText
|
||||
}
|
||||
|
||||
func addRelevanceField(search_fields, words, fields []string) (res []string, args []interface{}) {
|
||||
var relevanceRes = []string{}
|
||||
func addRelevanceField(searchFields, words, fields []string) (res []string, args []interface{}) {
|
||||
relevanceRes := []string{}
|
||||
args = []interface{}{}
|
||||
|
||||
for _, search_field := range search_fields {
|
||||
for _, searchField := range searchFields {
|
||||
var (
|
||||
relevance = "(LENGTH(" + search_field + ") - LENGTH(%s))"
|
||||
replacement = "REPLACE(%s, ?, '')"
|
||||
replace_field = search_field
|
||||
replaced string
|
||||
argsField = []interface{}{}
|
||||
relevance = "(LENGTH(" + searchField + ") - LENGTH(%s))"
|
||||
replacement = "REPLACE(%s, ?, '')"
|
||||
replaceField = searchField
|
||||
replaced string
|
||||
argsField = []interface{}{}
|
||||
)
|
||||
|
||||
res = fields
|
||||
for i, word := range words {
|
||||
if i == 0 {
|
||||
argsField = append(argsField, word)
|
||||
replaced = fmt.Sprintf(replacement, replace_field)
|
||||
replaced = fmt.Sprintf(replacement, replaceField)
|
||||
} else {
|
||||
argsField = append(argsField, word)
|
||||
replaced = fmt.Sprintf(replacement, replaced)
|
||||
|
@ -483,3 +484,12 @@ func addRelevanceField(search_fields, words, fields []string) (res []string, arg
|
|||
res = append(res, "("+strings.Join(relevanceRes, " + ")+") as relevance")
|
||||
return
|
||||
}
|
||||
|
||||
func filterWords(words []string) (res []string) {
|
||||
for _, word := range words {
|
||||
if strings.TrimSpace(word) != "" {
|
||||
res = append(res, word)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package repo
|
||||
package site_info
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
@ -27,7 +27,7 @@ func (sr *siteInfoRepo) SaveByType(ctx context.Context, siteType string, data *e
|
|||
old = &entity.SiteInfo{}
|
||||
exist bool
|
||||
)
|
||||
exist, err = sr.data.DB.Where(builder.Eq{"type": siteType}).Get(old)
|
||||
exist, _ = sr.data.DB.Where(builder.Eq{"type": siteType}).Get(old)
|
||||
if exist {
|
||||
_, err = sr.data.DB.ID(old.ID).Update(data)
|
||||
if err != nil {
|
|
@ -10,20 +10,20 @@ import (
|
|||
"github.com/segmentfault/pacman/errors"
|
||||
)
|
||||
|
||||
// tagListRepo tagList repository
|
||||
type tagListRepo struct {
|
||||
// tagRelRepo tag rel repository
|
||||
type tagRelRepo struct {
|
||||
data *data.Data
|
||||
}
|
||||
|
||||
// NewTagListRepo new repository
|
||||
func NewTagListRepo(data *data.Data) tagcommon.TagRelRepo {
|
||||
return &tagListRepo{
|
||||
// NewTagRelRepo new repository
|
||||
func NewTagRelRepo(data *data.Data) tagcommon.TagRelRepo {
|
||||
return &tagRelRepo{
|
||||
data: data,
|
||||
}
|
||||
}
|
||||
|
||||
// AddTagRelList add tag list
|
||||
func (tr *tagListRepo) AddTagRelList(ctx context.Context, tagList []*entity.TagRel) (err error) {
|
||||
func (tr *tagRelRepo) AddTagRelList(ctx context.Context, tagList []*entity.TagRel) (err error) {
|
||||
_, err = tr.data.DB.Insert(tagList)
|
||||
if err != nil {
|
||||
err = errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
|
||||
|
@ -32,8 +32,8 @@ func (tr *tagListRepo) AddTagRelList(ctx context.Context, tagList []*entity.TagR
|
|||
}
|
||||
|
||||
// RemoveTagRelListByObjectID delete tag list
|
||||
func (tr *tagListRepo) RemoveTagRelListByObjectID(ctx context.Context, objectId string) (err error) {
|
||||
_, err = tr.data.DB.Where("object_id = ?", objectId).Update(&entity.TagRel{Status: entity.TagRelStatusDeleted})
|
||||
func (tr *tagRelRepo) RemoveTagRelListByObjectID(ctx context.Context, objectID string) (err error) {
|
||||
_, err = tr.data.DB.Where("object_id = ?", objectID).Update(&entity.TagRel{Status: entity.TagRelStatusDeleted})
|
||||
if err != nil {
|
||||
err = errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
|
||||
}
|
||||
|
@ -41,7 +41,7 @@ func (tr *tagListRepo) RemoveTagRelListByObjectID(ctx context.Context, objectId
|
|||
}
|
||||
|
||||
// RemoveTagRelListByIDs delete tag list
|
||||
func (tr *tagListRepo) RemoveTagRelListByIDs(ctx context.Context, ids []int64) (err error) {
|
||||
func (tr *tagRelRepo) RemoveTagRelListByIDs(ctx context.Context, ids []int64) (err error) {
|
||||
_, err = tr.data.DB.In("id", ids).Update(&entity.TagRel{Status: entity.TagRelStatusDeleted})
|
||||
if err != nil {
|
||||
err = errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
|
||||
|
@ -50,10 +50,11 @@ func (tr *tagListRepo) RemoveTagRelListByIDs(ctx context.Context, ids []int64) (
|
|||
}
|
||||
|
||||
// GetObjectTagRelWithoutStatus get object tag relation no matter status
|
||||
func (tr *tagListRepo) GetObjectTagRelWithoutStatus(ctx context.Context, objectId, tagID string) (
|
||||
tagRel *entity.TagRel, exist bool, err error) {
|
||||
func (tr *tagRelRepo) GetObjectTagRelWithoutStatus(ctx context.Context, objectID, tagID string) (
|
||||
tagRel *entity.TagRel, exist bool, err error,
|
||||
) {
|
||||
tagRel = &entity.TagRel{}
|
||||
session := tr.data.DB.Where("object_id = ?", objectId).And("tag_id = ?", tagID)
|
||||
session := tr.data.DB.Where("object_id = ?", objectID).And("tag_id = ?", tagID)
|
||||
exist, err = session.Get(tagRel)
|
||||
if err != nil {
|
||||
err = errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
|
||||
|
@ -62,7 +63,7 @@ func (tr *tagListRepo) GetObjectTagRelWithoutStatus(ctx context.Context, objectI
|
|||
}
|
||||
|
||||
// EnableTagRelByIDs update tag status to available
|
||||
func (tr *tagListRepo) EnableTagRelByIDs(ctx context.Context, ids []int64) (err error) {
|
||||
func (tr *tagRelRepo) EnableTagRelByIDs(ctx context.Context, ids []int64) (err error) {
|
||||
_, err = tr.data.DB.In("id", ids).Update(&entity.TagRel{Status: entity.TagRelStatusAvailable})
|
||||
if err != nil {
|
||||
err = errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
|
||||
|
@ -71,9 +72,9 @@ func (tr *tagListRepo) EnableTagRelByIDs(ctx context.Context, ids []int64) (err
|
|||
}
|
||||
|
||||
// GetObjectTagRelList get object tag relation list all
|
||||
func (tr *tagListRepo) GetObjectTagRelList(ctx context.Context, objectId string) (tagListList []*entity.TagRel, err error) {
|
||||
func (tr *tagRelRepo) GetObjectTagRelList(ctx context.Context, objectID string) (tagListList []*entity.TagRel, err error) {
|
||||
tagListList = make([]*entity.TagRel, 0)
|
||||
session := tr.data.DB.Where("object_id = ?", objectId)
|
||||
session := tr.data.DB.Where("object_id = ?", objectID)
|
||||
session.Where("status = ?", entity.TagRelStatusAvailable)
|
||||
err = session.Find(&tagListList)
|
||||
if err != nil {
|
||||
|
@ -83,7 +84,7 @@ func (tr *tagListRepo) GetObjectTagRelList(ctx context.Context, objectId string)
|
|||
}
|
||||
|
||||
// BatchGetObjectTagRelList get object tag relation list all
|
||||
func (tr *tagListRepo) BatchGetObjectTagRelList(ctx context.Context, objectIds []string) (tagListList []*entity.TagRel, err error) {
|
||||
func (tr *tagRelRepo) BatchGetObjectTagRelList(ctx context.Context, objectIds []string) (tagListList []*entity.TagRel, err error) {
|
||||
tagListList = make([]*entity.TagRel, 0)
|
||||
session := tr.data.DB.In("object_id", objectIds)
|
||||
session.Where("status = ?", entity.TagRelStatusAvailable)
|
||||
|
@ -95,7 +96,7 @@ func (tr *tagListRepo) BatchGetObjectTagRelList(ctx context.Context, objectIds [
|
|||
}
|
||||
|
||||
// CountTagRelByTagID count tag relation
|
||||
func (tr *tagListRepo) CountTagRelByTagID(ctx context.Context, tagID string) (count int64, err error) {
|
||||
func (tr *tagRelRepo) CountTagRelByTagID(ctx context.Context, tagID string) (count int64, err error) {
|
||||
count, err = tr.data.DB.Count(&entity.TagRel{TagID: tagID, Status: entity.AnswerStatusAvailable})
|
||||
if err != nil {
|
||||
err = errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
|
||||
|
|
|
@ -2,7 +2,6 @@ package tag
|
|||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/answerdev/answer/internal/base/data"
|
||||
"github.com/answerdev/answer/internal/base/pager"
|
||||
|
@ -34,12 +33,11 @@ func NewTagRepo(
|
|||
// AddTagList add tag
|
||||
func (tr *tagRepo) AddTagList(ctx context.Context, tagList []*entity.Tag) (err error) {
|
||||
for _, item := range tagList {
|
||||
ID, err := tr.uniqueIDRepo.GenUniqueID(ctx, item.TableName())
|
||||
item.ID, err = tr.uniqueIDRepo.GenUniqueIDStr(ctx, item.TableName())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
item.RevisionID = "0"
|
||||
item.ID = fmt.Sprintf("%d", ID)
|
||||
}
|
||||
_, err = tr.data.DB.Insert(tagList)
|
||||
if err != nil {
|
||||
|
@ -128,7 +126,8 @@ func (tr *tagRepo) UpdateTagQuestionCount(ctx context.Context, tagID string, que
|
|||
|
||||
// UpdateTagSynonym update synonym tag
|
||||
func (tr *tagRepo) UpdateTagSynonym(ctx context.Context, tagSlugNameList []string, mainTagID int64,
|
||||
mainTagSlugName string) (err error) {
|
||||
mainTagSlugName string,
|
||||
) (err error) {
|
||||
bean := &entity.Tag{MainTagID: mainTagID, MainTagSlugName: mainTagSlugName}
|
||||
session := tr.data.DB.In("slug_name", tagSlugNameList).MustCols("main_tag_id", "main_tag_slug_name")
|
||||
_, err = session.Update(bean)
|
||||
|
@ -140,7 +139,8 @@ func (tr *tagRepo) UpdateTagSynonym(ctx context.Context, tagSlugNameList []strin
|
|||
|
||||
// GetTagByID get tag one
|
||||
func (tr *tagRepo) GetTagByID(ctx context.Context, tagID string) (
|
||||
tag *entity.Tag, exist bool, err error) {
|
||||
tag *entity.Tag, exist bool, err error,
|
||||
) {
|
||||
tag = &entity.Tag{}
|
||||
session := tr.data.DB.Where(builder.Eq{"id": tagID})
|
||||
session.Where(builder.Eq{"status": entity.TagStatusAvailable})
|
||||
|
@ -164,7 +164,8 @@ func (tr *tagRepo) GetTagList(ctx context.Context, tag *entity.Tag) (tagList []*
|
|||
|
||||
// GetTagPage get tag page
|
||||
func (tr *tagRepo) GetTagPage(ctx context.Context, page, pageSize int, tag *entity.Tag, queryCond string) (
|
||||
tagList []*entity.Tag, total int64, err error) {
|
||||
tagList []*entity.Tag, total int64, err error,
|
||||
) {
|
||||
tagList = make([]*entity.Tag, 0)
|
||||
session := tr.data.DB.NewSession()
|
||||
|
||||
|
|
|
@ -3,7 +3,6 @@ package unique
|
|||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strconv"
|
||||
|
||||
"github.com/answerdev/answer/internal/base/constant"
|
||||
"github.com/answerdev/answer/internal/base/data"
|
||||
|
@ -25,21 +24,8 @@ func NewUniqueIDRepo(data *data.Data) unique.UniqueIDRepo {
|
|||
}
|
||||
}
|
||||
|
||||
// GenUniqueID generate unique id
|
||||
// 1 + 00x(objectType) + 000000000000x(id)
|
||||
func (ur *uniqueIDRepo) GenUniqueID(ctx context.Context, key string) (uniqueID int64, err error) {
|
||||
idStr, err := ur.GenUniqueIDStr(ctx, key)
|
||||
if err != nil {
|
||||
return 0, errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
|
||||
}
|
||||
uniqueID, err = strconv.ParseInt(idStr, 10, 64)
|
||||
if err != nil {
|
||||
return 0, errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
|
||||
}
|
||||
return uniqueID, nil
|
||||
}
|
||||
|
||||
// GenUniqueIDStr generate unique id string
|
||||
// 1 + 00x(objectType) + 000000000000x(id)
|
||||
func (ur *uniqueIDRepo) GenUniqueIDStr(ctx context.Context, key string) (uniqueID string, err error) {
|
||||
objectType := constant.ObjectTypeStrMapping[key]
|
||||
bean := &entity.Uniqid{UniqidType: objectType}
|
||||
|
|
|
@ -3,13 +3,17 @@ package user
|
|||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"net/mail"
|
||||
"strings"
|
||||
"time"
|
||||
"unicode"
|
||||
"xorm.io/builder"
|
||||
|
||||
"github.com/answerdev/answer/internal/base/constant"
|
||||
"github.com/answerdev/answer/internal/base/data"
|
||||
"github.com/answerdev/answer/internal/base/pager"
|
||||
"github.com/answerdev/answer/internal/base/reason"
|
||||
"github.com/answerdev/answer/internal/entity"
|
||||
"github.com/answerdev/answer/internal/service/auth"
|
||||
"github.com/answerdev/answer/internal/service/user_backyard"
|
||||
"github.com/segmentfault/pacman/errors"
|
||||
"github.com/segmentfault/pacman/log"
|
||||
|
@ -17,19 +21,22 @@ import (
|
|||
|
||||
// userBackyardRepo user repository
|
||||
type userBackyardRepo struct {
|
||||
data *data.Data
|
||||
data *data.Data
|
||||
authRepo auth.AuthRepo
|
||||
}
|
||||
|
||||
// NewUserBackyardRepo new repository
|
||||
func NewUserBackyardRepo(data *data.Data) user_backyard.UserBackyardRepo {
|
||||
func NewUserBackyardRepo(data *data.Data, authRepo auth.AuthRepo) user_backyard.UserBackyardRepo {
|
||||
return &userBackyardRepo{
|
||||
data: data,
|
||||
data: data,
|
||||
authRepo: authRepo,
|
||||
}
|
||||
}
|
||||
|
||||
// UpdateUserStatus update user status
|
||||
func (ur *userBackyardRepo) UpdateUserStatus(ctx context.Context, userID string, userStatus, mailStatus int,
|
||||
email string) (err error) {
|
||||
email string,
|
||||
) (err error) {
|
||||
cond := &entity.User{Status: userStatus, MailStatus: mailStatus, EMail: email}
|
||||
switch userStatus {
|
||||
case entity.UserStatusSuspended:
|
||||
|
@ -49,8 +56,7 @@ func (ur *userBackyardRepo) UpdateUserStatus(ctx context.Context, userID string,
|
|||
}
|
||||
t, _ := json.Marshal(userCacheInfo)
|
||||
log.Infof("user change status: %s", string(t))
|
||||
err = ur.data.Cache.SetString(ctx, constant.UserStatusChangedCacheKey+userID, string(t),
|
||||
constant.UserStatusChangedCacheTime)
|
||||
err = ur.authRepo.SetUserStatus(ctx, userID, userCacheInfo)
|
||||
if err != nil {
|
||||
return errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
|
||||
}
|
||||
|
@ -68,16 +74,51 @@ func (ur *userBackyardRepo) GetUserInfo(ctx context.Context, userID string) (use
|
|||
}
|
||||
|
||||
// GetUserPage get user page
|
||||
func (ur *userBackyardRepo) GetUserPage(ctx context.Context, page, pageSize int, user *entity.User) (users []*entity.User, total int64, err error) {
|
||||
func (ur *userBackyardRepo) GetUserPage(ctx context.Context, page, pageSize int, user *entity.User, query string) (users []*entity.User, total int64, err error) {
|
||||
users = make([]*entity.User, 0)
|
||||
session := ur.data.DB.NewSession()
|
||||
if user.Status == entity.UserStatusDeleted {
|
||||
switch user.Status {
|
||||
case entity.UserStatusDeleted:
|
||||
session.Desc("deleted_at")
|
||||
} else if user.Status == entity.UserStatusSuspended {
|
||||
case entity.UserStatusSuspended:
|
||||
session.Desc("suspended_at")
|
||||
} else {
|
||||
default:
|
||||
session.Desc("created_at")
|
||||
}
|
||||
|
||||
if len(query) > 0 {
|
||||
if email, e := mail.ParseAddress(query); e == nil {
|
||||
session.And(builder.Eq{"e_mail": email.Address})
|
||||
} else {
|
||||
var (
|
||||
idSearch = false
|
||||
id = ""
|
||||
)
|
||||
|
||||
if strings.Contains(query, "user:") {
|
||||
idSearch = true
|
||||
id = strings.TrimSpace(strings.TrimPrefix(query, "user:"))
|
||||
for _, r := range id {
|
||||
if !unicode.IsDigit(r) {
|
||||
idSearch = false
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if idSearch {
|
||||
session.And(builder.Eq{
|
||||
"id": id,
|
||||
})
|
||||
} else {
|
||||
session.And(builder.Or(
|
||||
builder.Like{"username", query},
|
||||
builder.Like{"display_name", query},
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
total, err = pager.Help(page, pageSize, &users, user, session)
|
||||
if err != nil {
|
||||
err = errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
|
||||
|
|
|
@ -2,7 +2,6 @@ package user
|
|||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/answerdev/answer/internal/base/data"
|
||||
|
@ -86,13 +85,10 @@ func (ur *userRepo) UpdateNoticeStatus(ctx context.Context, userID string, notic
|
|||
return nil
|
||||
}
|
||||
|
||||
func (ur *userRepo) UpdatePass(ctx context.Context, Data *entity.User) error {
|
||||
if Data.ID == "" {
|
||||
return fmt.Errorf("input error")
|
||||
}
|
||||
_, err := ur.data.DB.Where("id = ?", Data.ID).Cols("pass").Update(Data)
|
||||
func (ur *userRepo) UpdatePass(ctx context.Context, userID, pass string) error {
|
||||
_, err := ur.data.DB.Where("id = ?", userID).Cols("pass").Update(&entity.User{Pass: pass})
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -87,6 +87,7 @@ func (a *AnswerAPIRouter) RegisterUnAuthAnswerAPIRouter(r *gin.RouterGroup) {
|
|||
r.GET("/comment", a.commentController.GetComment)
|
||||
|
||||
// user
|
||||
r.GET("/user/info", a.userController.GetUserInfoByUserID)
|
||||
r.GET("/user/status", a.userController.GetUserStatus)
|
||||
r.GET("/user/action/record", a.userController.ActionRecord)
|
||||
r.POST("/user/login/email", a.userController.UserEmailLogin)
|
||||
|
@ -174,7 +175,6 @@ func (a *AnswerAPIRouter) RegisterAnswerAPIRouter(r *gin.RouterGroup) {
|
|||
r.DELETE("/answer", a.answerController.RemoveAnswer)
|
||||
|
||||
// user
|
||||
r.GET("/user/info", a.userController.GetUserInfoByUserID)
|
||||
r.PUT("/user/password", a.userController.UserModifyPassWord)
|
||||
r.PUT("/user/info", a.userController.UserUpdateInfo)
|
||||
r.POST("/user/avatar/upload", a.userController.UploadUserAvatar)
|
||||
|
|
|
@ -9,44 +9,44 @@ type RemoveAnswerReq struct {
|
|||
}
|
||||
|
||||
const (
|
||||
Answer_Adopted_Failed = 1
|
||||
Answer_Adopted_Enable = 2
|
||||
AnswerAdoptedFailed = 1
|
||||
AnswerAdoptedEnable = 2
|
||||
)
|
||||
|
||||
type AnswerAddReq struct {
|
||||
QuestionId string `json:"question_id" ` // question_id
|
||||
QuestionID string `json:"question_id" ` // question_id
|
||||
Content string `json:"content" ` // content
|
||||
Html string `json:"html" ` // html
|
||||
HTML string `json:"html" ` // html
|
||||
UserID string `json:"-" ` // user_id
|
||||
}
|
||||
|
||||
type AnswerUpdateReq struct {
|
||||
ID string `json:"id"` // id
|
||||
QuestionId string `json:"question_id" ` // question_id
|
||||
QuestionID string `json:"question_id" ` // question_id
|
||||
UserID string `json:"-" ` // user_id
|
||||
Title string `json:"title" ` // title
|
||||
Content string `json:"content"` // content
|
||||
Html string `json:"html" ` // html
|
||||
EditSummary string `validate:"omitempty" json:"edit_summary"` //edit_summary
|
||||
HTML string `json:"html" ` // html
|
||||
EditSummary string `validate:"omitempty" json:"edit_summary"` // edit_summary
|
||||
}
|
||||
|
||||
type AnswerList struct {
|
||||
QuestionId string `json:"question_id" form:"question_id"` // question_id
|
||||
QuestionID string `json:"question_id" form:"question_id"` // question_id
|
||||
Order string `json:"order" form:"order"` // 1 Default 2 time
|
||||
Page int `json:"page" form:"page"` //Query number of pages
|
||||
PageSize int `json:"page_size" form:"page_size"` //Search page size
|
||||
Page int `json:"page" form:"page"` // Query number of pages
|
||||
PageSize int `json:"page_size" form:"page_size"` // Search page size
|
||||
LoginUserID string `json:"-" `
|
||||
}
|
||||
|
||||
type AnswerInfo struct {
|
||||
ID string `json:"id" xorm:"id"` // id
|
||||
QuestionId string `json:"question_id" xorm:"question_id"` // question_id
|
||||
QuestionID string `json:"question_id" xorm:"question_id"` // question_id
|
||||
Content string `json:"content" xorm:"content"` // content
|
||||
Html string `json:"html" xorm:"html"` // html
|
||||
HTML string `json:"html" xorm:"html"` // html
|
||||
CreateTime int64 `json:"create_time" xorm:"created"` // create_time
|
||||
UpdateTime int64 `json:"update_time" xorm:"updated"` // update_time
|
||||
Adopted int `json:"adopted"` // 1 Failed 2 Adopted
|
||||
UserId string `json:"-" `
|
||||
UserID string `json:"-" `
|
||||
UserInfo *UserBasicInfo `json:"user_info,omitempty"`
|
||||
UpdateUserInfo *UserBasicInfo `json:"update_user_info,omitempty"`
|
||||
Collected bool `json:"collected"`
|
||||
|
@ -60,12 +60,12 @@ type AnswerInfo struct {
|
|||
|
||||
type AdminAnswerInfo struct {
|
||||
ID string `json:"id"`
|
||||
QuestionId string `json:"question_id"`
|
||||
QuestionID string `json:"question_id"`
|
||||
Description string `json:"description"`
|
||||
CreateTime int64 `json:"create_time"`
|
||||
UpdateTime int64 `json:"update_time"`
|
||||
Adopted int `json:"adopted"`
|
||||
UserId string `json:"-" `
|
||||
UserID string `json:"-" `
|
||||
UserInfo *UserBasicInfo `json:"user_info"`
|
||||
VoteCount int `json:"vote_count"`
|
||||
QuestionInfo struct {
|
||||
|
|
|
@ -26,10 +26,8 @@ type GetUserPageReq struct {
|
|||
Page int `validate:"omitempty,min=1" form:"page"`
|
||||
// page size
|
||||
PageSize int `validate:"omitempty,min=1" form:"page_size"`
|
||||
// username
|
||||
Username string `validate:"omitempty,gt=0,lte=50" form:"username"`
|
||||
// email
|
||||
EMail string `validate:"omitempty,gt=0,lte=100" form:"e_mail"`
|
||||
Query string `validate:"omitempty,gt=0,lte=100" form:"query"`
|
||||
// user status
|
||||
Status string `validate:"omitempty,oneof=suspended deleted inactive" form:"status"`
|
||||
}
|
||||
|
|
|
@ -3,8 +3,8 @@ package schema
|
|||
import "time"
|
||||
|
||||
const (
|
||||
CG_DEFAULT = 1
|
||||
CG_DIY = 2
|
||||
CGDefault = 1
|
||||
CGDIY = 2
|
||||
)
|
||||
|
||||
// CollectionSwitchReq switch collection request
|
||||
|
|
|
@ -2,7 +2,7 @@ package schema
|
|||
|
||||
const (
|
||||
ForbiddenReasonTypeInactive = "inactive"
|
||||
ForbiddenReasonTypeUrlExpired = "url_expired"
|
||||
ForbiddenReasonTypeURLExpired = "url_expired"
|
||||
ForbiddenReasonTypeUserSuspended = "suspended"
|
||||
)
|
||||
|
||||
|
|
|
@ -5,12 +5,11 @@ type RemoveQuestionReq struct {
|
|||
// question id
|
||||
ID string `validate:"required" comment:"question id" json:"id"`
|
||||
UserID string `json:"-" ` // user_id
|
||||
|
||||
}
|
||||
|
||||
type CloseQuestionReq struct {
|
||||
ID string `validate:"required" comment:"question id" json:"id"`
|
||||
UserId string `json:"-" ` // user_id
|
||||
UserID string `json:"-" ` // user_id
|
||||
CloseType int `json:"close_type" ` // close_type
|
||||
CloseMsg string `json:"close_msg" ` // close_type
|
||||
}
|
||||
|
@ -26,7 +25,7 @@ type QuestionAdd struct {
|
|||
// content
|
||||
Content string `validate:"required,gte=6,lte=65535" json:"content"`
|
||||
// html
|
||||
Html string `validate:"required,gte=6,lte=65535" json:"html"`
|
||||
HTML string `validate:"required,gte=6,lte=65535" json:"html"`
|
||||
// tags
|
||||
Tags []*TagItem `validate:"required,dive" json:"tags"`
|
||||
// user id
|
||||
|
@ -41,7 +40,7 @@ type QuestionUpdate struct {
|
|||
// content
|
||||
Content string `validate:"required,gte=6,lte=65535" json:"content"`
|
||||
// html
|
||||
Html string `validate:"required,gte=6,lte=65535" json:"html"`
|
||||
HTML string `validate:"required,gte=6,lte=65535" json:"html"`
|
||||
// tags
|
||||
Tags []*TagItem `validate:"required,dive" json:"tags"`
|
||||
// edit summary
|
||||
|
@ -65,7 +64,7 @@ type QuestionInfo struct {
|
|||
ID string `json:"id" `
|
||||
Title string `json:"title" xorm:"title"` // title
|
||||
Content string `json:"content" xorm:"content"` // content
|
||||
Html string `json:"html" xorm:"html"` // html
|
||||
HTML string `json:"html" xorm:"html"` // html
|
||||
Tags []*TagResp `json:"tags" ` // tags
|
||||
ViewCount int `json:"view_count" xorm:"view_count"` // view_count
|
||||
UniqueViewCount int `json:"unique_view_count" xorm:"unique_view_count"` // unique_view_count
|
||||
|
@ -73,15 +72,15 @@ type QuestionInfo struct {
|
|||
AnswerCount int `json:"answer_count" xorm:"answer_count"` // answer count
|
||||
CollectionCount int `json:"collection_count" xorm:"collection_count"` // collection count
|
||||
FollowCount int `json:"follow_count" xorm:"follow_count"` // follow count
|
||||
AcceptedAnswerId string `json:"accepted_answer_id" ` // accepted_answer_id
|
||||
LastAnswerId string `json:"last_answer_id" ` // last_answer_id
|
||||
AcceptedAnswerID string `json:"accepted_answer_id" ` // accepted_answer_id
|
||||
LastAnswerID string `json:"last_answer_id" ` // last_answer_id
|
||||
CreateTime int64 `json:"create_time" ` // create_time
|
||||
UpdateTime int64 `json:"-"` // update_time
|
||||
PostUpdateTime int64 `json:"update_time"`
|
||||
QuestionUpdateTime int64 `json:"edit_time"`
|
||||
Status int `json:"status"`
|
||||
Operation *Operation `json:"operation,omitempty"`
|
||||
UserId string `json:"-" `
|
||||
UserID string `json:"-" `
|
||||
UserInfo *UserBasicInfo `json:"user_info"`
|
||||
UpdateUserInfo *UserBasicInfo `json:"update_user_info,omitempty"`
|
||||
LastAnsweredUserInfo *UserBasicInfo `json:"last_answered_user_info,omitempty"`
|
||||
|
@ -108,10 +107,10 @@ type AdminQuestionInfo struct {
|
|||
}
|
||||
|
||||
type Operation struct {
|
||||
Operation_Type string `json:"operation_type"`
|
||||
Operation_Description string `json:"operation_description"`
|
||||
Operation_Msg string `json:"operation_msg"`
|
||||
Operation_Time int64 `json:"operation_time"`
|
||||
OperationType string `json:"operation_type"`
|
||||
OperationDescription string `json:"operation_description"`
|
||||
OperationMsg string `json:"operation_msg"`
|
||||
OperationTime int64 `json:"operation_time"`
|
||||
}
|
||||
|
||||
type GetCloseTypeResp struct {
|
||||
|
@ -151,26 +150,27 @@ type UserQuestionInfo struct {
|
|||
AnswerCount int `json:"answer_count"`
|
||||
CollectionCount int `json:"collection_count"`
|
||||
CreateTime int `json:"create_time"`
|
||||
AcceptedAnswerId string `json:"accepted_answer_id"`
|
||||
AcceptedAnswerID string `json:"accepted_answer_id"`
|
||||
Status string `json:"status"`
|
||||
}
|
||||
|
||||
type QuestionSearch struct {
|
||||
Page int `json:"page" form:"page"` //Query number of pages
|
||||
PageSize int `json:"page_size" form:"page_size"` //Search page size
|
||||
Order string `json:"order" form:"order"` //Search order by
|
||||
//Tags []string `json:"tags" form:"tags"` //Search tag
|
||||
Page int `json:"page" form:"page"` // Query number of pages
|
||||
PageSize int `json:"page_size" form:"page_size"` // Search page size
|
||||
Order string `json:"order" form:"order"` // Search order by
|
||||
// Tags []string `json:"tags" form:"tags"` // Search tag
|
||||
Tag string `json:"tag" form:"tag"` //Search tag
|
||||
TagIDs []string `json:"-" form:"-"` //Search tag
|
||||
UserName string `json:"username" form:"username"` //Search username
|
||||
TagIDs []string `json:"-" form:"-"` // Search tag
|
||||
UserName string `json:"username" form:"username"` // Search username
|
||||
UserID string `json:"-" form:"-"`
|
||||
}
|
||||
|
||||
type CmsQuestionSearch struct {
|
||||
Page int `json:"page" form:"page"` //Query number of pages
|
||||
PageSize int `json:"page_size" form:"page_size"` //Search page size
|
||||
Page int `json:"page" form:"page"` // Query number of pages
|
||||
PageSize int `json:"page_size" form:"page_size"` // Search page size
|
||||
Status int `json:"-" form:"-"`
|
||||
StatusStr string `json:"status" form:"status"` //Status 1 Available 2 closed 10 UserDeleted
|
||||
StatusStr string `json:"status" form:"status"` // Status 1 Available 2 closed 10 UserDeleted
|
||||
Query string `validate:"omitempty,gt=0,lte=100" json:"query" form:"query" ` //Query string
|
||||
}
|
||||
|
||||
type AdminSetQuestionStatusRequest struct {
|
||||
|
|
|
@ -107,7 +107,7 @@ func (tr *GetTagPageResp) GetExcerpt() {
|
|||
}
|
||||
|
||||
type TagChange struct {
|
||||
ObjectId string `json:"object_id"` // object_id
|
||||
ObjectID string `json:"object_id"` // object_id
|
||||
Tags []*TagItem `json:"tags"` // tags name
|
||||
// user id
|
||||
UserID string `json:"-"`
|
||||
|
|
|
@ -55,7 +55,7 @@ type GetUserResp struct {
|
|||
// bio markdown
|
||||
Bio string `json:"bio"`
|
||||
// bio html
|
||||
BioHtml string `json:"bio_html"`
|
||||
BioHTML string `json:"bio_html"`
|
||||
// website
|
||||
Website string `json:"website"`
|
||||
// location
|
||||
|
@ -72,6 +72,7 @@ type GetUserResp struct {
|
|||
|
||||
func (r *GetUserResp) GetFromUserEntity(userInfo *entity.User) {
|
||||
_ = copier.Copy(r, userInfo)
|
||||
r.Avatar = FormatAvatarInfo(userInfo.Avatar)
|
||||
r.CreatedAt = userInfo.CreatedAt.Unix()
|
||||
r.LastLoginDate = userInfo.LastLoginDate.Unix()
|
||||
statusShow, ok := UserStatusShow[userInfo.Status]
|
||||
|
@ -80,6 +81,44 @@ func (r *GetUserResp) GetFromUserEntity(userInfo *entity.User) {
|
|||
}
|
||||
}
|
||||
|
||||
type GetUserToSetShowResp struct {
|
||||
*GetUserResp
|
||||
Avatar *AvatarInfo `json:"avatar"`
|
||||
}
|
||||
|
||||
func (r *GetUserToSetShowResp) GetFromUserEntity(userInfo *entity.User) {
|
||||
_ = copier.Copy(r, userInfo)
|
||||
r.CreatedAt = userInfo.CreatedAt.Unix()
|
||||
r.LastLoginDate = userInfo.LastLoginDate.Unix()
|
||||
statusShow, ok := UserStatusShow[userInfo.Status]
|
||||
if ok {
|
||||
r.Status = statusShow
|
||||
}
|
||||
avatarInfo := &AvatarInfo{}
|
||||
_ = json.Unmarshal([]byte(userInfo.Avatar), avatarInfo)
|
||||
// if json.Unmarshal Error avatarInfo.Type is Empty
|
||||
r.Avatar = avatarInfo
|
||||
}
|
||||
|
||||
func FormatAvatarInfo(avatarJson string) string {
|
||||
if avatarJson == "" {
|
||||
return ""
|
||||
}
|
||||
AvatarInfo := &AvatarInfo{}
|
||||
err := json.Unmarshal([]byte(avatarJson), AvatarInfo)
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
switch AvatarInfo.Type {
|
||||
case "gravatar":
|
||||
return AvatarInfo.Gravatar
|
||||
case "custom":
|
||||
return AvatarInfo.Custom
|
||||
default:
|
||||
return ""
|
||||
}
|
||||
}
|
||||
|
||||
// GetUserStatusResp get user status info
|
||||
type GetUserStatusResp struct {
|
||||
// user status
|
||||
|
@ -114,7 +153,7 @@ type GetOtherUserInfoByUsernameResp struct {
|
|||
// bio markdown
|
||||
Bio string `json:"bio"`
|
||||
// bio html
|
||||
BioHtml string `json:"bio_html"`
|
||||
BioHTML string `json:"bio_html"`
|
||||
// website
|
||||
Website string `json:"website"`
|
||||
// location
|
||||
|
@ -129,6 +168,9 @@ type GetOtherUserInfoByUsernameResp struct {
|
|||
|
||||
func (r *GetOtherUserInfoByUsernameResp) GetFromUserEntity(userInfo *entity.User) {
|
||||
_ = copier.Copy(r, userInfo)
|
||||
Avatar := FormatAvatarInfo(userInfo.Avatar)
|
||||
r.Avatar = Avatar
|
||||
|
||||
r.CreatedAt = userInfo.CreatedAt.Unix()
|
||||
r.LastLoginDate = userInfo.LastLoginDate.Unix()
|
||||
statusShow, ok := UserStatusShow[userInfo.Status]
|
||||
|
@ -146,20 +188,18 @@ func (r *GetOtherUserInfoByUsernameResp) GetFromUserEntity(userInfo *entity.User
|
|||
r.StatusMsg = statusMsgShow
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
const (
|
||||
Mail_State_Pass = 1
|
||||
Mail_State_Verifi = 2
|
||||
MailStatePass = 1
|
||||
MailStateVerifi = 2
|
||||
|
||||
Notice_Status_On = 1
|
||||
Notice_Status_Off = 2
|
||||
NoticeStatusOn = 1
|
||||
NoticeStatusOff = 2
|
||||
|
||||
//ActionRecord ReportType
|
||||
ActionRecord_Type_Login = "login"
|
||||
ActionRecord_Type_Email = "e_mail"
|
||||
ActionRecord_Type_Find_Pass = "find_pass"
|
||||
ActionRecordTypeLogin = "login"
|
||||
ActionRecordTypeEmail = "e_mail"
|
||||
ActionRecordTypeFindPass = "find_pass"
|
||||
)
|
||||
|
||||
var UserStatusShow = map[int]string{
|
||||
|
@ -167,6 +207,7 @@ var UserStatusShow = map[int]string{
|
|||
9: "forbidden",
|
||||
10: "deleted",
|
||||
}
|
||||
|
||||
var UserStatusShowMsg = map[int]string{
|
||||
1: "",
|
||||
9: "<strong>This user was suspended forever.</strong> This user doesn’t meet a community guideline.",
|
||||
|
@ -207,7 +248,7 @@ func (u *UserRegisterReq) Check() (errField *validator.ErrorField, err error) {
|
|||
|
||||
// UserModifyPassWordRequest
|
||||
type UserModifyPassWordRequest struct {
|
||||
UserId string `json:"-" ` // user_id
|
||||
UserID string `json:"-" ` // user_id
|
||||
OldPass string `json:"old_pass" ` // old password
|
||||
Pass string `json:"pass" ` // password
|
||||
}
|
||||
|
@ -230,17 +271,23 @@ type UpdateInfoRequest struct {
|
|||
// username
|
||||
Username string `validate:"omitempty,gt=0,lte=30" json:"username"`
|
||||
// avatar
|
||||
Avatar string `validate:"omitempty,gt=0,lte=500" json:"avatar"`
|
||||
Avatar AvatarInfo `json:"avatar"`
|
||||
// bio
|
||||
Bio string `validate:"omitempty,gt=0,lte=4096" json:"bio"`
|
||||
// bio
|
||||
BioHtml string `validate:"omitempty,gt=0,lte=4096" json:"bio_html"`
|
||||
BioHTML string `validate:"omitempty,gt=0,lte=4096" json:"bio_html"`
|
||||
// website
|
||||
Website string `validate:"omitempty,gt=0,lte=500" json:"website"`
|
||||
// location
|
||||
Location string `validate:"omitempty,gt=0,lte=100" json:"location"`
|
||||
// user id
|
||||
UserId string `json:"-" `
|
||||
UserID string `json:"-" `
|
||||
}
|
||||
|
||||
type AvatarInfo struct {
|
||||
Type string `validate:"omitempty,gt=0,lte=100" json:"type"`
|
||||
Gravatar string `validate:"omitempty,gt=0,lte=200" json:"gravatar"`
|
||||
Custom string `validate:"omitempty,gt=0,lte=200" json:"custom"`
|
||||
}
|
||||
|
||||
func (u *UpdateInfoRequest) Check() (errField *validator.ErrorField, err error) {
|
||||
|
@ -283,7 +330,7 @@ func (u *UserRePassWordRequest) Check() (errField *validator.ErrorField, err err
|
|||
}
|
||||
|
||||
type UserNoticeSetRequest struct {
|
||||
UserId string `json:"-" ` // user_id
|
||||
UserID string `json:"-" ` // user_id
|
||||
NoticeSwitch bool `json:"notice_switch" `
|
||||
}
|
||||
|
||||
|
@ -294,7 +341,7 @@ type UserNoticeSetResp struct {
|
|||
type ActionRecordReq struct {
|
||||
// action
|
||||
Action string `validate:"required,oneof=login e_mail find_pass" form:"action"`
|
||||
Ip string `json:"-"`
|
||||
IP string `json:"-"`
|
||||
}
|
||||
|
||||
type ActionRecordResp struct {
|
||||
|
@ -311,7 +358,7 @@ type UserBasicInfo struct {
|
|||
Avatar string `json:"avatar" ` // avatar
|
||||
Website string `json:"website" ` // website
|
||||
Location string `json:"location" ` // location
|
||||
IpInfo string `json:"ip_info"` // ip info
|
||||
IPInfo string `json:"ip_info"` // ip info
|
||||
Status string `json:"status"` // status
|
||||
}
|
||||
|
||||
|
|
|
@ -36,7 +36,7 @@ func NewCaptchaService(captchaRepo CaptchaRepo) *CaptchaService {
|
|||
// ActionRecord action record
|
||||
func (cs *CaptchaService) ActionRecord(ctx context.Context, req *schema.ActionRecordReq) (resp *schema.ActionRecordResp, err error) {
|
||||
resp = &schema.ActionRecordResp{}
|
||||
num, err := cs.captchaRepo.GetActionType(ctx, req.Ip, req.Action)
|
||||
num, err := cs.captchaRepo.GetActionType(ctx, req.IP, req.Action)
|
||||
if err != nil {
|
||||
num = 0
|
||||
}
|
||||
|
@ -51,7 +51,8 @@ func (cs *CaptchaService) ActionRecord(ctx context.Context, req *schema.ActionRe
|
|||
// ActionRecordVerifyCaptcha
|
||||
// Verify that you need to enter a CAPTCHA, and that the CAPTCHA is correct
|
||||
func (cs *CaptchaService) ActionRecordVerifyCaptcha(
|
||||
ctx context.Context, actionType string, ip string, id string, VerifyValue string) bool {
|
||||
ctx context.Context, actionType string, ip string, id string, VerifyValue string,
|
||||
) bool {
|
||||
num, cahceErr := cs.captchaRepo.GetActionType(ctx, ip, actionType)
|
||||
if cahceErr != nil {
|
||||
return true
|
||||
|
|
|
@ -14,9 +14,9 @@ type AnswerRepo interface {
|
|||
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)
|
||||
GetAnswerPage(ctx context.Context, page, pageSize int, answer *entity.Answer) (answerList []*entity.Answer, total int64, err error)
|
||||
UpdateAdopted(ctx context.Context, id string, questionId string) error
|
||||
UpdateAdopted(ctx context.Context, id string, questionID string) error
|
||||
GetByID(ctx context.Context, id string) (*entity.Answer, bool, error)
|
||||
GetByUserIdQuestionId(ctx context.Context, userId string, questionId string) (*entity.Answer, bool, error)
|
||||
GetByUserIDQuestionID(ctx context.Context, userID string, questionID string) (*entity.Answer, bool, error)
|
||||
SearchList(ctx context.Context, search *entity.AnswerSearch) ([]*entity.Answer, int64, error)
|
||||
CmsSearchList(ctx context.Context, search *entity.CmsAnswerSearch) ([]*entity.Answer, int64, error)
|
||||
UpdateAnswerStatus(ctx context.Context, answer *entity.Answer) (err error)
|
||||
|
@ -33,8 +33,8 @@ func NewAnswerCommon(answerRepo AnswerRepo) *AnswerCommon {
|
|||
}
|
||||
}
|
||||
|
||||
func (as *AnswerCommon) SearchAnswered(ctx context.Context, userId, questionId string) (bool, error) {
|
||||
_, has, err := as.answerRepo.GetByUserIdQuestionId(ctx, userId, questionId)
|
||||
func (as *AnswerCommon) SearchAnswered(ctx context.Context, userID, questionID string) (bool, error) {
|
||||
_, has, err := as.answerRepo.GetByUserIDQuestionID(ctx, userID, questionID)
|
||||
if err != nil {
|
||||
return has, err
|
||||
}
|
||||
|
@ -42,6 +42,9 @@ func (as *AnswerCommon) SearchAnswered(ctx context.Context, userId, questionId s
|
|||
}
|
||||
|
||||
func (as *AnswerCommon) CmsSearchList(ctx context.Context, search *entity.CmsAnswerSearch) ([]*entity.Answer, int64, error) {
|
||||
if search.Status == 0 {
|
||||
search.Status = 1
|
||||
}
|
||||
return as.answerRepo.CmsSearchList(ctx, search)
|
||||
}
|
||||
|
||||
|
@ -56,26 +59,26 @@ func (as *AnswerCommon) Search(ctx context.Context, search *entity.AnswerSearch)
|
|||
func (as *AnswerCommon) ShowFormat(ctx context.Context, data *entity.Answer) *schema.AnswerInfo {
|
||||
info := schema.AnswerInfo{}
|
||||
info.ID = data.ID
|
||||
info.QuestionId = data.QuestionID
|
||||
info.QuestionID = data.QuestionID
|
||||
info.Content = data.OriginalText
|
||||
info.Html = data.ParsedText
|
||||
info.HTML = data.ParsedText
|
||||
info.Adopted = data.Adopted
|
||||
info.VoteCount = data.VoteCount
|
||||
info.CreateTime = data.CreatedAt.Unix()
|
||||
info.UpdateTime = data.UpdatedAt.Unix()
|
||||
info.UserId = data.UserID
|
||||
info.UserID = data.UserID
|
||||
return &info
|
||||
}
|
||||
|
||||
func (as *AnswerCommon) AdminShowFormat(ctx context.Context, data *entity.Answer) *schema.AdminAnswerInfo {
|
||||
info := schema.AdminAnswerInfo{}
|
||||
info.ID = data.ID
|
||||
info.QuestionId = data.QuestionID
|
||||
info.QuestionID = data.QuestionID
|
||||
info.Description = data.ParsedText
|
||||
info.Adopted = data.Adopted
|
||||
info.VoteCount = data.VoteCount
|
||||
info.CreateTime = data.CreatedAt.Unix()
|
||||
info.UpdateTime = data.UpdatedAt.Unix()
|
||||
info.UserId = data.UserID
|
||||
info.UserID = data.UserID
|
||||
return &info
|
||||
}
|
||||
|
|
|
@ -74,7 +74,7 @@ func (as *AnswerService) RemoveAnswer(ctx context.Context, id string) (err error
|
|||
return nil
|
||||
}
|
||||
|
||||
//user add question count
|
||||
// user add question count
|
||||
err = as.questionCommon.UpdateAnswerCount(ctx, answerInfo.QuestionID, -1)
|
||||
if err != nil {
|
||||
log.Error("IncreaseAnswerCount error", err.Error())
|
||||
|
@ -97,7 +97,7 @@ func (as *AnswerService) RemoveAnswer(ctx context.Context, id string) (err error
|
|||
}
|
||||
|
||||
func (as *AnswerService) Insert(ctx context.Context, req *schema.AnswerAddReq) (string, error) {
|
||||
questionInfo, exist, err := as.questionRepo.GetQuestion(ctx, req.QuestionId)
|
||||
questionInfo, exist, err := as.questionRepo.GetQuestion(ctx, req.QuestionID)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
@ -108,24 +108,24 @@ func (as *AnswerService) Insert(ctx context.Context, req *schema.AnswerAddReq) (
|
|||
insertData := new(entity.Answer)
|
||||
insertData.UserID = req.UserID
|
||||
insertData.OriginalText = req.Content
|
||||
insertData.ParsedText = req.Html
|
||||
insertData.Adopted = schema.Answer_Adopted_Failed
|
||||
insertData.QuestionID = req.QuestionId
|
||||
insertData.ParsedText = req.HTML
|
||||
insertData.Adopted = schema.AnswerAdoptedFailed
|
||||
insertData.QuestionID = req.QuestionID
|
||||
insertData.RevisionID = "0"
|
||||
insertData.Status = entity.AnswerStatusAvailable
|
||||
insertData.UpdatedAt = now
|
||||
if err := as.answerRepo.AddAnswer(ctx, insertData); err != nil {
|
||||
if err = as.answerRepo.AddAnswer(ctx, insertData); err != nil {
|
||||
return "", err
|
||||
}
|
||||
err = as.questionCommon.UpdateAnswerCount(ctx, req.QuestionId, 1)
|
||||
err = as.questionCommon.UpdateAnswerCount(ctx, req.QuestionID, 1)
|
||||
if err != nil {
|
||||
log.Error("IncreaseAnswerCount error", err.Error())
|
||||
}
|
||||
err = as.questionCommon.UpdateLastAnswer(ctx, req.QuestionId, insertData.ID)
|
||||
err = as.questionCommon.UpdateLastAnswer(ctx, req.QuestionID, insertData.ID)
|
||||
if err != nil {
|
||||
log.Error("UpdateLastAnswer error", err.Error())
|
||||
}
|
||||
err = as.questionCommon.UpdataPostTime(ctx, req.QuestionId)
|
||||
err = as.questionCommon.UpdataPostTime(ctx, req.QuestionID)
|
||||
if err != nil {
|
||||
return insertData.ID, err
|
||||
}
|
||||
|
@ -140,8 +140,8 @@ func (as *AnswerService) Insert(ctx context.Context, req *schema.AnswerAddReq) (
|
|||
ObjectID: insertData.ID,
|
||||
Title: "",
|
||||
}
|
||||
InfoJson, _ := json.Marshal(insertData)
|
||||
revisionDTO.Content = string(InfoJson)
|
||||
infoJSON, _ := json.Marshal(insertData)
|
||||
revisionDTO.Content = string(infoJSON)
|
||||
err = as.revisionService.AddRevision(ctx, revisionDTO, true)
|
||||
if err != nil {
|
||||
return insertData.ID, err
|
||||
|
@ -151,7 +151,7 @@ func (as *AnswerService) Insert(ctx context.Context, req *schema.AnswerAddReq) (
|
|||
}
|
||||
|
||||
func (as *AnswerService) Update(ctx context.Context, req *schema.AnswerUpdateReq) (string, error) {
|
||||
questionInfo, exist, err := as.questionRepo.GetQuestion(ctx, req.QuestionId)
|
||||
questionInfo, exist, err := as.questionRepo.GetQuestion(ctx, req.QuestionID)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
@ -161,15 +161,15 @@ func (as *AnswerService) Update(ctx context.Context, req *schema.AnswerUpdateReq
|
|||
now := time.Now()
|
||||
insertData := new(entity.Answer)
|
||||
insertData.ID = req.ID
|
||||
insertData.QuestionID = req.QuestionId
|
||||
insertData.QuestionID = req.QuestionID
|
||||
insertData.UserID = req.UserID
|
||||
insertData.OriginalText = req.Content
|
||||
insertData.ParsedText = req.Html
|
||||
insertData.ParsedText = req.HTML
|
||||
insertData.UpdatedAt = now
|
||||
if err := as.answerRepo.UpdateAnswer(ctx, insertData, []string{"original_text", "parsed_text", "update_time"}); err != nil {
|
||||
if err = as.answerRepo.UpdateAnswer(ctx, insertData, []string{"original_text", "parsed_text", "update_time"}); err != nil {
|
||||
return "", err
|
||||
}
|
||||
err = as.questionCommon.UpdataPostTime(ctx, req.QuestionId)
|
||||
err = as.questionCommon.UpdataPostTime(ctx, req.QuestionID)
|
||||
if err != nil {
|
||||
return insertData.ID, err
|
||||
}
|
||||
|
@ -179,8 +179,8 @@ func (as *AnswerService) Update(ctx context.Context, req *schema.AnswerUpdateReq
|
|||
Title: "",
|
||||
Log: req.EditSummary,
|
||||
}
|
||||
InfoJson, _ := json.Marshal(insertData)
|
||||
revisionDTO.Content = string(InfoJson)
|
||||
infoJSON, _ := json.Marshal(insertData)
|
||||
revisionDTO.Content = string(infoJSON)
|
||||
err = as.revisionService.AddRevision(ctx, revisionDTO, true)
|
||||
if err != nil {
|
||||
return insertData.ID, err
|
||||
|
@ -228,7 +228,7 @@ func (as *AnswerService) UpdateAdopted(ctx context.Context, req *schema.AnswerAd
|
|||
|
||||
var oldAnswerInfo *entity.Answer
|
||||
if len(questionInfo.AcceptedAnswerID) > 0 && questionInfo.AcceptedAnswerID != "0" {
|
||||
oldAnswerInfo, exist, err = as.answerRepo.GetByID(ctx, questionInfo.AcceptedAnswerID)
|
||||
oldAnswerInfo, _, err = as.answerRepo.GetByID(ctx, questionInfo.AcceptedAnswerID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -249,8 +249,8 @@ func (as *AnswerService) UpdateAdopted(ctx context.Context, req *schema.AnswerAd
|
|||
}
|
||||
|
||||
func (as *AnswerService) updateAnswerRank(ctx context.Context, userID string,
|
||||
questionInfo *entity.Question, newAnswerInfo *entity.Answer, oldAnswerInfo *entity.Answer) {
|
||||
|
||||
questionInfo *entity.Question, newAnswerInfo *entity.Answer, oldAnswerInfo *entity.Answer,
|
||||
) {
|
||||
// if this question is already been answered, should cancel old answer rank
|
||||
if oldAnswerInfo != nil {
|
||||
err := as.answerActivityService.CancelAcceptAnswer(
|
||||
|
@ -266,21 +266,20 @@ func (as *AnswerService) updateAnswerRank(ctx context.Context, userID string,
|
|||
log.Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func (as *AnswerService) Get(ctx context.Context, answerID, loginUserId string) (*schema.AnswerInfo, *schema.QuestionInfo, bool, error) {
|
||||
func (as *AnswerService) Get(ctx context.Context, answerID, loginUserID string) (*schema.AnswerInfo, *schema.QuestionInfo, bool, error) {
|
||||
answerInfo, has, err := as.answerRepo.GetByID(ctx, answerID)
|
||||
if err != nil {
|
||||
return nil, nil, has, err
|
||||
}
|
||||
info := as.ShowFormat(ctx, answerInfo)
|
||||
//todo questionFunc
|
||||
questionInfo, err := as.questionCommon.Info(ctx, answerInfo.QuestionID, loginUserId)
|
||||
// todo questionFunc
|
||||
questionInfo, err := as.questionCommon.Info(ctx, answerInfo.QuestionID, loginUserID)
|
||||
if err != nil {
|
||||
return nil, nil, has, err
|
||||
}
|
||||
//todo UserFunc
|
||||
// todo UserFunc
|
||||
userinfo, has, err := as.userCommon.GetUserBasicInfoByID(ctx, answerInfo.UserID)
|
||||
if err != nil {
|
||||
return nil, nil, has, err
|
||||
|
@ -290,13 +289,13 @@ func (as *AnswerService) Get(ctx context.Context, answerID, loginUserId string)
|
|||
info.UpdateUserInfo = userinfo
|
||||
}
|
||||
|
||||
if loginUserId == "" {
|
||||
if loginUserID == "" {
|
||||
return info, questionInfo, has, nil
|
||||
}
|
||||
|
||||
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 {
|
||||
log.Error("CollectionFunc.SearchObjectCollected error", err)
|
||||
}
|
||||
|
@ -348,7 +347,7 @@ func (as *AnswerService) AdminSetAnswerStatus(ctx context.Context, answerID stri
|
|||
func (as *AnswerService) SearchList(ctx context.Context, search *schema.AnswerList) ([]*schema.AnswerInfo, int64, error) {
|
||||
list := make([]*schema.AnswerInfo, 0)
|
||||
dbSearch := entity.AnswerSearch{}
|
||||
dbSearch.QuestionID = search.QuestionId
|
||||
dbSearch.QuestionID = search.QuestionID
|
||||
dbSearch.Page = search.Page
|
||||
dbSearch.PageSize = search.PageSize
|
||||
dbSearch.Order = search.Order
|
||||
|
@ -363,7 +362,7 @@ func (as *AnswerService) SearchList(ctx context.Context, search *schema.AnswerLi
|
|||
return AnswerList, count, nil
|
||||
}
|
||||
|
||||
func (as *AnswerService) SearchFormatInfo(ctx context.Context, dblist []*entity.Answer, loginUserId string) ([]*schema.AnswerInfo, error) {
|
||||
func (as *AnswerService) SearchFormatInfo(ctx context.Context, dblist []*entity.Answer, loginUserID string) ([]*schema.AnswerInfo, error) {
|
||||
list := make([]*schema.AnswerInfo, 0)
|
||||
objectIds := make([]string, 0)
|
||||
userIds := make([]string, 0)
|
||||
|
@ -372,9 +371,9 @@ func (as *AnswerService) SearchFormatInfo(ctx context.Context, dblist []*entity.
|
|||
list = append(list, item)
|
||||
objectIds = append(objectIds, dbitem.ID)
|
||||
userIds = append(userIds, dbitem.UserID)
|
||||
if loginUserId != "" {
|
||||
//item.VoteStatus = as.activityFunc.GetVoteStatus(ctx, item.TagID, loginUserId)
|
||||
item.VoteStatus = as.voteRepo.GetVoteStatus(ctx, item.ID, loginUserId)
|
||||
if loginUserID != "" {
|
||||
// item.VoteStatus = as.activityFunc.GetVoteStatus(ctx, item.TagID, loginUserId)
|
||||
item.VoteStatus = as.voteRepo.GetVoteStatus(ctx, item.ID, loginUserID)
|
||||
}
|
||||
}
|
||||
userInfoMap, err := as.userCommon.BatchUserBasicInfoByID(ctx, userIds)
|
||||
|
@ -382,18 +381,18 @@ func (as *AnswerService) SearchFormatInfo(ctx context.Context, dblist []*entity.
|
|||
return list, err
|
||||
}
|
||||
for _, item := range list {
|
||||
_, ok := userInfoMap[item.UserId]
|
||||
_, ok := userInfoMap[item.UserID]
|
||||
if ok {
|
||||
item.UserInfo = userInfoMap[item.UserId]
|
||||
item.UpdateUserInfo = userInfoMap[item.UserId]
|
||||
item.UserInfo = userInfoMap[item.UserID]
|
||||
item.UpdateUserInfo = userInfoMap[item.UserID]
|
||||
}
|
||||
}
|
||||
|
||||
if loginUserId == "" {
|
||||
if loginUserID == "" {
|
||||
return list, nil
|
||||
}
|
||||
|
||||
CollectedMap, err := as.collectionCommon.SearchObjectCollected(ctx, loginUserId, objectIds)
|
||||
CollectedMap, err := as.collectionCommon.SearchObjectCollected(ctx, loginUserID, objectIds)
|
||||
if err != nil {
|
||||
log.Error("CollectionFunc.SearchObjectCollected error", err)
|
||||
}
|
||||
|
@ -406,7 +405,7 @@ func (as *AnswerService) SearchFormatInfo(ctx context.Context, dblist []*entity.
|
|||
}
|
||||
|
||||
for _, item := range list {
|
||||
item.MemberActions = permission.GetAnswerPermission(loginUserId, item.UserId)
|
||||
item.MemberActions = permission.GetAnswerPermission(loginUserID, item.UserID)
|
||||
}
|
||||
|
||||
return list, nil
|
||||
|
|
|
@ -13,11 +13,12 @@ type AuthRepo interface {
|
|||
GetUserCacheInfo(ctx context.Context, accessToken string) (userInfo *entity.UserCacheInfo, err error)
|
||||
SetUserCacheInfo(ctx context.Context, accessToken string, userInfo *entity.UserCacheInfo) error
|
||||
RemoveUserCacheInfo(ctx context.Context, accessToken string) (err error)
|
||||
SetUserStatus(ctx context.Context, userID string, userInfo *entity.UserCacheInfo) (err error)
|
||||
GetUserStatus(ctx context.Context, userID string) (userInfo *entity.UserCacheInfo, err error)
|
||||
RemoveUserStatus(ctx context.Context, userID string) (err error)
|
||||
GetCmsUserCacheInfo(ctx context.Context, accessToken string) (userInfo *entity.UserCacheInfo, err error)
|
||||
SetCmsUserCacheInfo(ctx context.Context, accessToken string, userInfo *entity.UserCacheInfo) error
|
||||
RemoveCmsUserCacheInfo(ctx context.Context, accessToken string) (err error)
|
||||
GetBackyardUserCacheInfo(ctx context.Context, accessToken string) (userInfo *entity.UserCacheInfo, err error)
|
||||
SetBackyardUserCacheInfo(ctx context.Context, accessToken string, userInfo *entity.UserCacheInfo) error
|
||||
RemoveBackyardUserCacheInfo(ctx context.Context, accessToken string) (err error)
|
||||
}
|
||||
|
||||
// AuthService kit service
|
||||
|
@ -75,14 +76,14 @@ func (as *AuthService) RemoveUserCacheInfo(ctx context.Context, accessToken stri
|
|||
//cms
|
||||
|
||||
func (as *AuthService) GetCmsUserCacheInfo(ctx context.Context, accessToken string) (userInfo *entity.UserCacheInfo, err error) {
|
||||
return as.authRepo.GetCmsUserCacheInfo(ctx, accessToken)
|
||||
return as.authRepo.GetBackyardUserCacheInfo(ctx, accessToken)
|
||||
}
|
||||
|
||||
func (as *AuthService) SetCmsUserCacheInfo(ctx context.Context, accessToken string, userInfo *entity.UserCacheInfo) (err error) {
|
||||
err = as.authRepo.SetCmsUserCacheInfo(ctx, accessToken, userInfo)
|
||||
err = as.authRepo.SetBackyardUserCacheInfo(ctx, accessToken, userInfo)
|
||||
return err
|
||||
}
|
||||
|
||||
func (as *AuthService) RemoveCmsUserCacheInfo(ctx context.Context, accessToken string) (err error) {
|
||||
return as.authRepo.RemoveCmsUserCacheInfo(ctx, accessToken)
|
||||
return as.authRepo.RemoveBackyardUserCacheInfo(ctx, accessToken)
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@ type CollectionGroupRepo interface {
|
|||
UpdateCollectionGroup(ctx context.Context, collectionGroup *entity.CollectionGroup, cols []string) (err error)
|
||||
GetCollectionGroup(ctx context.Context, id string) (collectionGroup *entity.CollectionGroup, exist bool, err error)
|
||||
GetCollectionGroupPage(ctx context.Context, page, pageSize int, collectionGroup *entity.CollectionGroup) (collectionGroupList []*entity.CollectionGroup, total int64, err error)
|
||||
GetDefaultID(ctx context.Context, userId string) (collectionGroup *entity.CollectionGroup, has bool, err error)
|
||||
GetDefaultID(ctx context.Context, userID string) (collectionGroup *entity.CollectionGroup, has bool, err error)
|
||||
}
|
||||
|
||||
// CollectionGroupService user service
|
||||
|
|
|
@ -23,7 +23,6 @@ func NewCollectionService(
|
|||
collectionRepo collectioncommon.CollectionRepo,
|
||||
collectionGroupRepo CollectionGroupRepo,
|
||||
questionCommon *questioncommon.QuestionCommon,
|
||||
|
||||
) *CollectionService {
|
||||
return &CollectionService{
|
||||
collectionRepo: collectionRepo,
|
||||
|
@ -31,6 +30,7 @@ func NewCollectionService(
|
|||
questionCommon: questionCommon,
|
||||
}
|
||||
}
|
||||
|
||||
func (cs *CollectionService) CollectionSwitch(ctx context.Context, dto *schema.CollectionSwitchDTO) (resp *schema.CollectionSwitchResp, err error) {
|
||||
resp = &schema.CollectionSwitchResp{}
|
||||
dbData, has, err := cs.collectionRepo.GetOneByObjectIDAndUser(ctx, dto.UserID, dto.ObjectID)
|
||||
|
@ -46,7 +46,8 @@ func (cs *CollectionService) CollectionSwitch(ctx context.Context, dto *schema.C
|
|||
if err != nil {
|
||||
log.Error("UpdateCollectionCount", err.Error())
|
||||
}
|
||||
count, err := cs.objectCollectionCount(ctx, dto.ObjectID)
|
||||
var count int64
|
||||
count, err = cs.objectCollectionCount(ctx, dto.ObjectID)
|
||||
if err != nil {
|
||||
return resp, err
|
||||
}
|
||||
|
@ -56,12 +57,17 @@ func (cs *CollectionService) CollectionSwitch(ctx context.Context, dto *schema.C
|
|||
}
|
||||
|
||||
if dto.GroupID == "" || dto.GroupID == "0" {
|
||||
defaultGroup, has, err := cs.collectionGroupRepo.GetDefaultID(ctx, dto.UserID)
|
||||
var (
|
||||
defaultGroup *entity.CollectionGroup
|
||||
has bool
|
||||
)
|
||||
defaultGroup, has, err = cs.collectionGroupRepo.GetDefaultID(ctx, dto.UserID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !has {
|
||||
dbdefaultGroup, err := cs.collectionGroupRepo.AddCollectionDefaultGroup(ctx, dto.UserID)
|
||||
var dbdefaultGroup *entity.CollectionGroup
|
||||
dbdefaultGroup, err = cs.collectionGroupRepo.AddCollectionDefaultGroup(ctx, dto.UserID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -93,8 +99,8 @@ func (cs *CollectionService) CollectionSwitch(ctx context.Context, dto *schema.C
|
|||
return
|
||||
}
|
||||
|
||||
func (cs *CollectionService) objectCollectionCount(ctx context.Context, objectId string) (int64, error) {
|
||||
count, err := cs.collectionRepo.CountByObjectID(ctx, objectId)
|
||||
func (cs *CollectionService) objectCollectionCount(ctx context.Context, objectID string) (int64, error) {
|
||||
count, err := cs.collectionRepo.CountByObjectID(ctx, objectID)
|
||||
return count, err
|
||||
}
|
||||
|
||||
|
@ -108,12 +114,16 @@ func (cs *CollectionService) add(ctx context.Context, collection *entity.Collect
|
|||
}
|
||||
|
||||
if collection.UserCollectionGroupID == "" || collection.UserCollectionGroupID == "0" {
|
||||
defaultGroup, has, err := cs.collectionGroupRepo.GetDefaultID(ctx, collection.UserID)
|
||||
var (
|
||||
defaultGroup *entity.CollectionGroup
|
||||
has bool
|
||||
)
|
||||
defaultGroup, has, err = cs.collectionGroupRepo.GetDefaultID(ctx, collection.UserID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !has {
|
||||
defaultGroup, err := cs.collectionGroupRepo.AddCollectionDefaultGroup(ctx, collection.UserID)
|
||||
defaultGroup, err = cs.collectionGroupRepo.AddCollectionDefaultGroup(ctx, collection.UserID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@ type CommentRepo interface {
|
|||
AddComment(ctx context.Context, comment *entity.Comment) (err error)
|
||||
RemoveComment(ctx context.Context, commentID string) (err error)
|
||||
UpdateComment(ctx context.Context, comment *entity.Comment) (err error)
|
||||
GetComment(ctx context.Context, commentID string) (comment *entity.Comment, exist bool, err error)
|
||||
GetCommentPage(ctx context.Context, commentQuery *CommentQuery) (
|
||||
comments []*entity.Comment, total int64, err error)
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@ type ConfigRepo interface {
|
|||
GetInt(key string) (int, error)
|
||||
GetArrayString(key string) ([]string, error)
|
||||
GetConfigType(key string) (int, error)
|
||||
GetConfigById(id int, value any) (err error)
|
||||
GetJsonConfigByIDAndSetToObject(id int, value any) (err error)
|
||||
SetConfig(key, value string) (err error)
|
||||
}
|
||||
|
||||
|
|
|
@ -95,15 +95,15 @@ func (ns *NotificationService) ClearIDUnRead(ctx context.Context, userID string,
|
|||
return nil
|
||||
}
|
||||
|
||||
func (ns *NotificationService) GetList(ctx context.Context, search *schema.NotificationSearch) (
|
||||
func (ns *NotificationService) GetNotificationPage(ctx context.Context, searchCond *schema.NotificationSearch) (
|
||||
pageModel *pager.PageModel, err error) {
|
||||
resp := make([]*schema.NotificationContent, 0)
|
||||
searchType, ok := schema.NotificationType[search.TypeStr]
|
||||
searchType, ok := schema.NotificationType[searchCond.TypeStr]
|
||||
if !ok {
|
||||
return pager.NewPageModel(0, resp), nil
|
||||
}
|
||||
search.Type = searchType
|
||||
notifications, count, err := ns.notificationRepo.SearchList(ctx, search)
|
||||
searchCond.Type = searchType
|
||||
notifications, total, err := ns.notificationRepo.GetNotificationPage(ctx, searchCond)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -123,5 +123,5 @@ func (ns *NotificationService) GetList(ctx context.Context, search *schema.Notif
|
|||
}
|
||||
resp = append(resp, item)
|
||||
}
|
||||
return pager.NewPageModel(count, resp), nil
|
||||
return pager.NewPageModel(total, resp), nil
|
||||
}
|
||||
|
|
|
@ -22,7 +22,7 @@ import (
|
|||
|
||||
type NotificationRepo interface {
|
||||
AddNotification(ctx context.Context, notification *entity.Notification) (err error)
|
||||
SearchList(ctx context.Context, search *schema.NotificationSearch) ([]*entity.Notification, int64, error)
|
||||
GetNotificationPage(ctx context.Context, search *schema.NotificationSearch) ([]*entity.Notification, int64, error)
|
||||
ClearUnRead(ctx context.Context, userID string, notificationType int) (err error)
|
||||
ClearIDUnRead(ctx context.Context, userID string, id string) (err error)
|
||||
GetByUserIdObjectIdTypeId(ctx context.Context, userID, objectID string, notificationType int) (*entity.Notification, bool, error)
|
||||
|
|
|
@ -31,9 +31,9 @@ type QuestionRepo interface {
|
|||
SearchList(ctx context.Context, search *schema.QuestionSearch) ([]*entity.QuestionTag, int64, error)
|
||||
UpdateQuestionStatus(ctx context.Context, question *entity.Question) (err error)
|
||||
SearchByTitleLike(ctx context.Context, title string) (questionList []*entity.Question, err error)
|
||||
UpdatePvCount(ctx context.Context, questionId string) (err error)
|
||||
UpdateAnswerCount(ctx context.Context, questionId string, num int) (err error)
|
||||
UpdateCollectionCount(ctx context.Context, questionId string, num int) (err error)
|
||||
UpdatePvCount(ctx context.Context, questionID string) (err error)
|
||||
UpdateAnswerCount(ctx context.Context, questionID string, num int) (err error)
|
||||
UpdateCollectionCount(ctx context.Context, questionID string, num int) (err error)
|
||||
UpdateAccepted(ctx context.Context, question *entity.Question) (err error)
|
||||
UpdateLastAnswer(ctx context.Context, question *entity.Question) (err error)
|
||||
FindByID(ctx context.Context, id []string) (questionList []*entity.Question, err error)
|
||||
|
@ -64,7 +64,6 @@ func NewQuestionCommon(questionRepo QuestionRepo,
|
|||
answerCommon *answercommon.AnswerCommon,
|
||||
metaService *meta.MetaService,
|
||||
configRepo config.ConfigRepo,
|
||||
|
||||
) *QuestionCommon {
|
||||
return &QuestionCommon{
|
||||
questionRepo: questionRepo,
|
||||
|
@ -80,42 +79,44 @@ func NewQuestionCommon(questionRepo QuestionRepo,
|
|||
}
|
||||
}
|
||||
|
||||
func (qs *QuestionCommon) UpdataPv(ctx context.Context, questionId string) error {
|
||||
return qs.questionRepo.UpdatePvCount(ctx, questionId)
|
||||
}
|
||||
func (qs *QuestionCommon) UpdateAnswerCount(ctx context.Context, questionId string, num int) error {
|
||||
return qs.questionRepo.UpdateAnswerCount(ctx, questionId, num)
|
||||
}
|
||||
func (qs *QuestionCommon) UpdateCollectionCount(ctx context.Context, questionId string, num int) error {
|
||||
return qs.questionRepo.UpdateCollectionCount(ctx, questionId, num)
|
||||
func (qs *QuestionCommon) UpdataPv(ctx context.Context, questionID string) error {
|
||||
return qs.questionRepo.UpdatePvCount(ctx, questionID)
|
||||
}
|
||||
|
||||
func (qs *QuestionCommon) UpdateAccepted(ctx context.Context, questionId, AnswerId string) error {
|
||||
func (qs *QuestionCommon) UpdateAnswerCount(ctx context.Context, questionID string, num int) error {
|
||||
return qs.questionRepo.UpdateAnswerCount(ctx, questionID, num)
|
||||
}
|
||||
|
||||
func (qs *QuestionCommon) UpdateCollectionCount(ctx context.Context, questionID string, num int) error {
|
||||
return qs.questionRepo.UpdateCollectionCount(ctx, questionID, num)
|
||||
}
|
||||
|
||||
func (qs *QuestionCommon) UpdateAccepted(ctx context.Context, questionID, AnswerID string) error {
|
||||
question := &entity.Question{}
|
||||
question.ID = questionId
|
||||
question.AcceptedAnswerID = AnswerId
|
||||
question.ID = questionID
|
||||
question.AcceptedAnswerID = AnswerID
|
||||
return qs.questionRepo.UpdateAccepted(ctx, question)
|
||||
}
|
||||
|
||||
func (qs *QuestionCommon) UpdateLastAnswer(ctx context.Context, questionId, AnswerId string) error {
|
||||
func (qs *QuestionCommon) UpdateLastAnswer(ctx context.Context, questionID, AnswerID string) error {
|
||||
question := &entity.Question{}
|
||||
question.ID = questionId
|
||||
question.LastAnswerID = AnswerId
|
||||
question.ID = questionID
|
||||
question.LastAnswerID = AnswerID
|
||||
return qs.questionRepo.UpdateLastAnswer(ctx, question)
|
||||
}
|
||||
|
||||
func (qs *QuestionCommon) UpdataPostTime(ctx context.Context, questionId string) error {
|
||||
func (qs *QuestionCommon) UpdataPostTime(ctx context.Context, questionID string) error {
|
||||
questioninfo := &entity.Question{}
|
||||
now := time.Now()
|
||||
questioninfo.ID = questionId
|
||||
questioninfo.ID = questionID
|
||||
questioninfo.PostUpdateTime = now
|
||||
return qs.questionRepo.UpdateQuestion(ctx, questioninfo, []string{"post_update_time"})
|
||||
}
|
||||
|
||||
func (qs *QuestionCommon) FindInfoByID(ctx context.Context, questionIds []string, loginUserID string) (map[string]*schema.QuestionInfo, error) {
|
||||
func (qs *QuestionCommon) FindInfoByID(ctx context.Context, questionIDs []string, loginUserID string) (map[string]*schema.QuestionInfo, error) {
|
||||
list := make(map[string]*schema.QuestionInfo)
|
||||
listAddTag := make([]*entity.QuestionTag, 0)
|
||||
questionList, err := qs.questionRepo.FindByID(ctx, questionIds)
|
||||
questionList, err := qs.questionRepo.FindByID(ctx, questionIDs)
|
||||
if err != nil {
|
||||
return list, err
|
||||
}
|
||||
|
@ -134,8 +135,8 @@ func (qs *QuestionCommon) FindInfoByID(ctx context.Context, questionIds []string
|
|||
return list, nil
|
||||
}
|
||||
|
||||
func (qs *QuestionCommon) Info(ctx context.Context, questionId string, loginUserID string) (showinfo *schema.QuestionInfo, err error) {
|
||||
dbinfo, has, err := qs.questionRepo.GetQuestion(ctx, questionId)
|
||||
func (qs *QuestionCommon) Info(ctx context.Context, questionID string, loginUserID string) (showinfo *schema.QuestionInfo, err error) {
|
||||
dbinfo, has, err := qs.questionRepo.GetQuestion(ctx, questionID)
|
||||
if err != nil {
|
||||
return showinfo, err
|
||||
}
|
||||
|
@ -145,26 +146,27 @@ func (qs *QuestionCommon) Info(ctx context.Context, questionId string, loginUser
|
|||
showinfo = qs.ShowFormat(ctx, dbinfo)
|
||||
|
||||
if showinfo.Status == 2 {
|
||||
metainfo, err := qs.metaService.GetMetaByObjectIdAndKey(ctx, dbinfo.ID, entity.QuestionCloseReasonKey)
|
||||
var metainfo *entity.Meta
|
||||
metainfo, err = qs.metaService.GetMetaByObjectIdAndKey(ctx, dbinfo.ID, entity.QuestionCloseReasonKey)
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
} else {
|
||||
//metainfo.Value
|
||||
// metainfo.Value
|
||||
closemsg := &schema.CloseQuestionMeta{}
|
||||
err := json.Unmarshal([]byte(metainfo.Value), closemsg)
|
||||
err = json.Unmarshal([]byte(metainfo.Value), closemsg)
|
||||
if err != nil {
|
||||
log.Error("json.Unmarshal CloseQuestionMeta error", err.Error())
|
||||
} else {
|
||||
closeinfo := &schema.GetReportTypeResp{}
|
||||
err = qs.configRepo.GetConfigById(closemsg.CloseType, closeinfo)
|
||||
err = qs.configRepo.GetJsonConfigByIDAndSetToObject(closemsg.CloseType, closeinfo)
|
||||
if err != nil {
|
||||
log.Error("json.Unmarshal QuestionCloseJson error", err.Error())
|
||||
} else {
|
||||
operation := &schema.Operation{}
|
||||
operation.Operation_Type = closeinfo.Name
|
||||
operation.Operation_Description = closeinfo.Description
|
||||
operation.Operation_Msg = closemsg.CloseMsg
|
||||
operation.Operation_Time = metainfo.CreatedAt.Unix()
|
||||
operation.OperationType = closeinfo.Name
|
||||
operation.OperationDescription = closeinfo.Description
|
||||
operation.OperationMsg = closemsg.CloseMsg
|
||||
operation.OperationTime = metainfo.CreatedAt.Unix()
|
||||
showinfo.Operation = operation
|
||||
}
|
||||
|
||||
|
@ -173,7 +175,7 @@ func (qs *QuestionCommon) Info(ctx context.Context, questionId string, loginUser
|
|||
}
|
||||
}
|
||||
|
||||
tagmap, err := qs.tagCommon.GetObjectTag(ctx, questionId)
|
||||
tagmap, err := qs.tagCommon.GetObjectTag(ctx, questionID)
|
||||
if err != nil {
|
||||
return showinfo, err
|
||||
}
|
||||
|
@ -193,10 +195,10 @@ func (qs *QuestionCommon) Info(ctx context.Context, questionId string, loginUser
|
|||
return showinfo, nil
|
||||
}
|
||||
|
||||
showinfo.VoteStatus = qs.voteRepo.GetVoteStatus(ctx, questionId, loginUserID)
|
||||
showinfo.VoteStatus = qs.voteRepo.GetVoteStatus(ctx, questionID, loginUserID)
|
||||
|
||||
// // check is followed
|
||||
isFollowed, _ := qs.followCommon.IsFollowed(loginUserID, questionId)
|
||||
isFollowed, _ := qs.followCommon.IsFollowed(loginUserID, questionID)
|
||||
showinfo.IsFollowed = isFollowed
|
||||
|
||||
has, err = qs.AnswerCommon.SearchAnswered(ctx, loginUserID, dbinfo.ID)
|
||||
|
@ -205,7 +207,7 @@ func (qs *QuestionCommon) Info(ctx context.Context, questionId string, loginUser
|
|||
}
|
||||
showinfo.Answered = has
|
||||
|
||||
//login user Collected information
|
||||
// login user Collected information
|
||||
|
||||
CollectedMap, err := qs.collectionCommon.SearchObjectCollected(ctx, loginUserID, []string{dbinfo.ID})
|
||||
if err != nil {
|
||||
|
@ -245,11 +247,11 @@ func (qs *QuestionCommon) ListFormat(ctx context.Context, questionList []*entity
|
|||
if ok {
|
||||
item.Tags = tagsMap[item.ID]
|
||||
}
|
||||
_, ok = userInfoMap[item.UserId]
|
||||
_, ok = userInfoMap[item.UserID]
|
||||
if ok {
|
||||
item.UserInfo = userInfoMap[item.UserId]
|
||||
item.UpdateUserInfo = userInfoMap[item.UserId]
|
||||
item.LastAnsweredUserInfo = userInfoMap[item.UserId]
|
||||
item.UserInfo = userInfoMap[item.UserID]
|
||||
item.UpdateUserInfo = userInfoMap[item.UserID]
|
||||
item.LastAnsweredUserInfo = userInfoMap[item.UserID]
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -286,7 +288,7 @@ func (qs *QuestionCommon) RemoveQuestion(ctx context.Context, req *schema.Remove
|
|||
return err
|
||||
}
|
||||
|
||||
//user add question count
|
||||
// user add question count
|
||||
err = qs.userCommon.UpdateQuestionCount(ctx, questionInfo.UserID, -1)
|
||||
if err != nil {
|
||||
log.Error("user UpdateQuestionCount error", err.Error())
|
||||
|
@ -332,7 +334,7 @@ func (as *QuestionCommon) RemoveAnswer(ctx context.Context, id string) (err erro
|
|||
return nil
|
||||
}
|
||||
|
||||
//user add question count
|
||||
// user add question count
|
||||
|
||||
err = as.UpdateAnswerCount(ctx, answerinfo.QuestionID, -1)
|
||||
if err != nil {
|
||||
|
@ -356,21 +358,21 @@ func (qs *QuestionCommon) ShowFormat(ctx context.Context, data *entity.Question)
|
|||
info.ID = data.ID
|
||||
info.Title = data.Title
|
||||
info.Content = data.OriginalText
|
||||
info.Html = data.ParsedText
|
||||
info.HTML = data.ParsedText
|
||||
info.ViewCount = data.ViewCount
|
||||
info.UniqueViewCount = data.UniqueViewCount
|
||||
info.VoteCount = data.VoteCount
|
||||
info.AnswerCount = data.AnswerCount
|
||||
info.CollectionCount = data.CollectionCount
|
||||
info.FollowCount = data.FollowCount
|
||||
info.AcceptedAnswerId = data.AcceptedAnswerID
|
||||
info.LastAnswerId = data.LastAnswerID
|
||||
info.AcceptedAnswerID = data.AcceptedAnswerID
|
||||
info.LastAnswerID = data.LastAnswerID
|
||||
info.CreateTime = data.CreatedAt.Unix()
|
||||
info.UpdateTime = data.UpdatedAt.Unix()
|
||||
info.PostUpdateTime = data.PostUpdateTime.Unix()
|
||||
info.QuestionUpdateTime = data.UpdatedAt.Unix()
|
||||
info.Status = data.Status
|
||||
info.UserId = data.UserID
|
||||
info.UserID = data.UserID
|
||||
info.Tags = make([]*schema.TagResp, 0)
|
||||
return &info
|
||||
}
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue