Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

第一次提交 #21

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions go_web_1
Submodule go_web_1 added at c69c0a
28 changes: 28 additions & 0 deletions roboko12/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
FROM golang:alpine AS builder

# 为我们的镜像设置必要的环境变量
ENV GO111MODULE=on \
GOPROXY=https://goproxy.cn,direct \
CGO_ENABLED=0 \
GOOS=linux \
GOARCH=amd64

# 移动到工作目录:/build
WORKDIR /build

# 将代码复制到容器中
COPY . .
Comment on lines +10 to +14
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Consider optimizing the file copying process.

While setting the working directory is good, copying all files from the build context might include unnecessary files in the image.

Consider being more selective about what files are copied:

WORKDIR /build
COPY go.mod go.sum ./
RUN go mod download
COPY . .

This approach:

  1. Copies only the dependency files first.
  2. Downloads dependencies (which can be cached).
  3. Then copies the rest of the source code.

This can improve build times by leveraging Docker's layer caching mechanism.


# 将我们的代码编译成二进制可执行文件 app
RUN go build -o app .
Comment on lines +16 to +17
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Consider adding build flags for optimization.

The current build command is functional but could be optimized further.

Consider adding flags to reduce binary size and improve performance:

RUN go build -ldflags="-s -w" -o app .

The -ldflags="-s -w" flags strip debugging information and the symbol table, reducing the binary size.

Additionally, you might want to add a step to run tests before building:

RUN go test ./...
RUN go build -ldflags="-s -w" -o app .

This ensures that all tests pass before creating the final binary.


###################
# 接下来创建一个小镜像
###################
FROM scratch

# 从builder镜像中把/dist/app 拷贝到当前目录
COPY --from=builder /build/app /

# 需要运行的命令
ENTRYPOINT ["/app"]
Binary file added roboko12/__debug_bin1067692169.exe
Binary file not shown.
Binary file added roboko12/__debug_bin1222785051.exe
Binary file not shown.
Binary file added roboko12/__debug_bin197326567.exe
Binary file not shown.
Binary file added roboko12/__debug_bin630280278.exe
Binary file not shown.
Binary file added roboko12/__debug_bin708761844.exe
Binary file not shown.
43 changes: 43 additions & 0 deletions roboko12/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
module sample-app

go 1.23.1
Comment on lines +1 to +3
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Incorrect Go version specified

The Go version specified (1.23.1) is not a valid Go version. As of October 2024, the latest stable version is in the 1.22.x series.

Please update the Go version to a valid, stable version. For example:

-go 1.23.1
+go 1.22.0

Make sure to test your code with the corrected Go version to ensure compatibility.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
module sample-app
go 1.23.1
module sample-app
go 1.22.0


require (
filippo.io/edwards25519 v1.1.0 // indirect
github.com/bytedance/sonic v1.12.3 // indirect
github.com/bytedance/sonic/loader v0.2.0 // indirect
github.com/cloudwego/base64x v0.1.4 // indirect
github.com/cloudwego/iasm v0.2.0 // indirect
github.com/gabriel-vasile/mimetype v1.4.5 // indirect
github.com/gin-contrib/sessions v1.0.1 // indirect
github.com/gin-contrib/sse v0.1.0 // indirect
github.com/gin-gonic/gin v1.10.0 // indirect
github.com/go-playground/locales v0.14.1 // indirect
github.com/go-playground/universal-translator v0.18.1 // indirect
github.com/go-playground/validator/v10 v10.22.1 // indirect
github.com/go-sql-driver/mysql v1.8.1 // indirect
github.com/goccy/go-json v0.10.3 // indirect
github.com/gorilla/context v1.1.2 // indirect
github.com/gorilla/securecookie v1.1.2 // indirect
github.com/gorilla/sessions v1.2.2 // indirect
github.com/jinzhu/inflection v1.0.0 // indirect
github.com/jinzhu/now v1.1.5 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/klauspost/cpuid/v2 v2.2.8 // indirect
github.com/leodido/go-urn v1.4.0 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/pelletier/go-toml/v2 v2.2.3 // indirect
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
github.com/ugorji/go/codec v1.2.12 // indirect
golang.org/x/arch v0.10.0 // indirect
golang.org/x/crypto v0.27.0 // indirect
golang.org/x/net v0.29.0 // indirect
golang.org/x/sys v0.25.0 // indirect
golang.org/x/text v0.18.0 // indirect
google.golang.org/protobuf v1.34.2 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
gorm.io/driver/mysql v1.5.7 // indirect
gorm.io/gorm v1.25.12 // indirect
)
127 changes: 127 additions & 0 deletions roboko12/go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA=
filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4=
github.com/bytedance/sonic v1.11.6 h1:oUp34TzMlL+OY1OUWxHqsdkgC/Zfc85zGqw9siXjrc0=
github.com/bytedance/sonic v1.11.6/go.mod h1:LysEHSvpvDySVdC2f87zGWf6CIKJcAvqab1ZaiQtds4=
github.com/bytedance/sonic v1.12.3 h1:W2MGa7RCU1QTeYRTPE3+88mVC0yXmsRQRChiyVocVjU=
github.com/bytedance/sonic v1.12.3/go.mod h1:B8Gt/XvtZ3Fqj+iSKMypzymZxw/FVwgIGKzMzT9r/rk=
github.com/bytedance/sonic/loader v0.1.1 h1:c+e5Pt1k/cy5wMveRDyk2X4B9hF4g7an8N3zCYjJFNM=
github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU=
github.com/bytedance/sonic/loader v0.2.0 h1:zNprn+lsIP06C/IqCHs3gPQIvnvpKbbxyXQP1iU4kWM=
github.com/bytedance/sonic/loader v0.2.0/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU=
github.com/cloudwego/base64x v0.1.4 h1:jwCgWpFanWmN8xoIUHa2rtzmkd5J2plF/dnLS6Xd/0Y=
github.com/cloudwego/base64x v0.1.4/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w=
github.com/cloudwego/iasm v0.2.0 h1:1KNIy1I1H9hNNFEEH3DVnI4UujN+1zjpuk6gwHLTssg=
github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0=
github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk=
github.com/gabriel-vasile/mimetype v1.4.5 h1:J7wGKdGu33ocBOhGy0z653k/lFKLFDPJMG8Gql0kxn4=
github.com/gabriel-vasile/mimetype v1.4.5/go.mod h1:ibHel+/kbxn9x2407k1izTA1S81ku1z/DlgOW2QE0M4=
github.com/gin-contrib/sessions v1.0.1 h1:3hsJyNs7v7N8OtelFmYXFrulAf6zSR7nW/putcPEHxI=
github.com/gin-contrib/sessions v1.0.1/go.mod h1:ouxSFM24/OgIud5MJYQJLpy6AwxQ5EYO9yLhbtObGkM=
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
github.com/gin-gonic/gin v1.10.0 h1:nTuyha1TYqgedzytsKYqna+DfLos46nTv2ygFy86HFU=
github.com/gin-gonic/gin v1.10.0/go.mod h1:4PMNQiOhvDRa013RKVbsiNwoyezlm2rm0uX/T7kzp5Y=
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
github.com/go-playground/validator/v10 v10.20.0 h1:K9ISHbSaI0lyB2eWMPJo+kOS/FBExVwjEviJTixqxL8=
github.com/go-playground/validator/v10 v10.20.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM=
github.com/go-playground/validator/v10 v10.22.1 h1:40JcKH+bBNGFczGuoBYgX4I6m/i27HYW8P9FDk5PbgA=
github.com/go-playground/validator/v10 v10.22.1/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM=
github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y=
github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg=
github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU=
github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
github.com/goccy/go-json v0.10.3 h1:KZ5WoDbxAIgm2HNbYckL0se1fHD6rz5j4ywS6ebzDqA=
github.com/goccy/go-json v0.10.3/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/gorilla/context v1.1.2 h1:WRkNAv2uoa03QNIc1A6u4O7DAGMUVoopZhkiXWA2V1o=
github.com/gorilla/context v1.1.2/go.mod h1:KDPwT9i/MeWHiLl90fuTgrt4/wPcv75vFAZLaOOcbxM=
github.com/gorilla/securecookie v1.1.2 h1:YCIWL56dvtr73r6715mJs5ZvhtnY73hBvEF8kXD8ePA=
github.com/gorilla/securecookie v1.1.2/go.mod h1:NfCASbcHqRSY+3a8tlWJwsQap2VX5pwzwo4h3eOamfo=
github.com/gorilla/sessions v1.2.2 h1:lqzMYz6bOfvn2WriPUjNByzeXIlVzURcPmgMczkmTjY=
github.com/gorilla/sessions v1.2.2/go.mod h1:ePLdVu+jbEgHH+KWw8I1z2wqd0BAdAQh/8LRvBeoNcQ=
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
github.com/klauspost/cpuid/v2 v2.2.7 h1:ZWSB3igEs+d0qvnxR/ZBzXVmxkgt8DdzP6m9pfuVLDM=
github.com/klauspost/cpuid/v2 v2.2.7/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
github.com/klauspost/cpuid/v2 v2.2.8 h1:+StwCXwm9PdpiEkPyzBXIy+M9KUb4ODm0Zarf1kS5BM=
github.com/klauspost/cpuid/v2 v2.2.8/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M=
github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=
github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
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=
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM=
github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs=
github.com/pelletier/go-toml/v2 v2.2.3 h1:YmeHyLY8mFWbdkNWwpr+qIL2bEqT0o95WSdkNHvL12M=
github.com/pelletier/go-toml/v2 v2.2.3/go.mod h1:MfCQTFTvCcUyyvvwm1+G6H/jORL20Xlb6rzQu9GuUkc=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
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/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
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/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=
github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE=
github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
golang.org/x/arch v0.8.0 h1:3wRIsP3pM4yUptoR96otTUOXI367OS0+c9eeRi9doIc=
golang.org/x/arch v0.8.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys=
golang.org/x/arch v0.10.0 h1:S3huipmSclq3PJMNe76NGwkBR504WFkQ5dhzWzP8ZW8=
golang.org/x/arch v0.10.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys=
golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI=
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A=
golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70=
golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac=
golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo=
golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y=
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34=
golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk=
golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224=
golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg=
google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg=
google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/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=
gorm.io/driver/mysql v1.5.7 h1:MndhOPYOfEp2rHKgkZIhJ16eVUIRf2HmzgoPmh7FCWo=
gorm.io/driver/mysql v1.5.7/go.mod h1:sEtPWMiqiN1N1cMXoXmBbd8C6/l+TESwriotuRRpkDM=
gorm.io/gorm v1.25.7/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8=
gorm.io/gorm v1.25.12 h1:I0u8i2hWQItBq1WfE0o2+WuL9+8L21K9e2HHSTE/0f8=
gorm.io/gorm v1.25.12/go.mod h1:xh7N7RHfYlNc5EmcI/El95gXusucDrQnHXe0+CgWcLQ=
nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50=
rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=
189 changes: 189 additions & 0 deletions roboko12/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,189 @@
package main

import (
"log"
"strconv"
"time"

"github.com/gin-contrib/sessions"
"github.com/gin-contrib/sessions/cookie"
"github.com/gin-gonic/gin"
"gorm.io/driver/mysql"
"gorm.io/gorm"
)

// 用户结构体
type User struct {
gorm.Model
Username string `gorm:"unique;not null"`
Password string `gorm:"not null"`
IsManager bool
}

type KeyWord struct {
Keyword string
}

// 问题结构体
type Question struct {
gorm.Model
Title string
Content string
UserID uint
Answers []Answer `gorm:"foreignKey:QuestionID"`
IsDeleted bool
Deleted_Time time.Time
}

type AgreeOrNot struct {
AgreeNum uint
DisagreeNum uint
}

// 答案中的评论结构体
type Comment struct {
gorm.Model
AgreeOrNot
Content string
UserID uint
AnswerID uint
}
Comment on lines +44 to +50
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Reconsider embedding AgreeOrNot in Comment struct

The Comment struct embeds the AgreeOrNot struct, which includes AgreeNum and DisagreeNum fields. It's unusual for individual comments to have agree/disagree counts. Consider removing this embedding if it's not intentional or necessary for your application's logic.


// 回复评论结构体
type ReplyComment struct {
gorm.Model
CommentUserID uint
CommentID uint
ReplyCommentID uint
ReplyUserID uint
}

// 答案结构体
type Answer struct {
gorm.Model
AgreeOrNot
Content string
UserID uint
QuestionID uint
IsDeleted bool
// 评论
Comments []Comment `gorm:"foreignKey:AnswerID"`
}

var db *gorm.DB

const max_question_num = 30

var resultCh chan Question = make(chan Question, max_question_num)
Comment on lines +73 to +77
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Consider refactoring global variables

Global variables like db and resultCh can make the code harder to test and maintain. Consider the following improvements:

  1. Pass db as a parameter to functions that need it, or use a struct to encapsulate the application state.
  2. Add a comment explaining the purpose of resultCh and consider moving its declaration closer to where it's used.

Example refactoring:

type App struct {
    DB *gorm.DB
    ResultCh chan Question
}

func NewApp(db *gorm.DB) *App {
    return &App{
        DB: db,
        ResultCh: make(chan Question, max_question_num),
    }
}

This approach would make the code more modular and easier to test.


func main() {
var err error
// 使用mysql.Open创建Dialector实例
dialector := mysql.Open("root:123Qbz123@tcp(localhost:3306)/go_web_1?charset=utf8mb4&parseTime=True&loc=Local")
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Security Risk: Hardcoded Database Credentials

The database credentials are hardcoded in the code, which poses a significant security risk. Exposing sensitive information like usernames and passwords in the codebase can lead to unauthorized access if the code is ever compromised. It is recommended to use environment variables or a secure configuration management system to store and access sensitive data.

Apply this diff to remove the hardcoded credentials:

-	dialector := mysql.Open("root:123Qbz123@tcp(localhost:3306)/go_web_1?charset=utf8mb4&parseTime=True&loc=Local")
+	dsn := os.Getenv("DATABASE_DSN")
+	dialector := mysql.Open(dsn)

Make sure to set the DATABASE_DSN environment variable in your deployment environment.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
dialector := mysql.Open("root:123Qbz123@tcp(localhost:3306)/go_web_1?charset=utf8mb4&parseTime=True&loc=Local")
dsn := os.Getenv("DATABASE_DSN")
dialector := mysql.Open(dsn)

// 将Dialector实例传递给gorm.Open
db, err = gorm.Open(dialector, &gorm.Config{})
if err != nil {
log.Fatal("数据库连接失败:", err)
}
db.AutoMigrate(&User{}, &Question{}, &Answer{}, &Comment{}, &ReplyComment{})
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Caution: Auto-migration in production

Using AutoMigrate in a production environment can be risky as it may lead to unintended schema changes or data loss. Consider using a dedicated migration tool or implementing a more controlled migration process for production deployments.

Example:

if os.Getenv("ENVIRONMENT") != "production" {
    db.AutoMigrate(&User{}, &Question{}, &Answer{}, &Comment{}, &ReplyComment{})
} else {
    log.Println("Skipping auto-migration in production. Please run migrations manually.")
}


r := gin.Default()

// 设置会话
store := cookie.NewStore([]byte("secret"))
r.Use(sessions.Sessions("mysession", store))

v_post := r.Group("/")
{
//注册
v_post.POST("register", Register)
//登录
v_post.POST("login", Login)
// 提出问题
v_post.POST("questions", CreateQuestion)
// 回答问题
v_post.POST("questions/:question_id/answers", CreateAnswer)
// 评论答案,需要查询参数,传入答案id和所属问题id
v_post.POST("questions/answers/comments", CreateCommentToAnswer)
//回复其他评论,需要传入查询参数,传入其他评论id和所属答案id
v_post.POST("questions/answers/comments/comments", CreateReplyToComment)

}

v_get := r.Group("/")
{
// 查看某个用户提出的问题
v_get.GET(":user_id/questions", GetQuestions)
// 查看某问题的答案
v_get.GET("questions/:question_id/answers", GetAnswers)
// 查看被逻辑删除删除的问题
v_get.GET("deleted_questions", GetDeletedQuestions)
//按关键词搜索问题
v_get.GET("questions/search", SearchQuestionsByKeyword)
//查看对自己评论的回复
v_get.GET("questions/answers/comments/comments", GetReplysToSelf)

}

v_put := r.Group("/")
{
//申请管理员权限
v_put.PUT("users", ApplyManager)
// 更新问题内容
v_put.PUT("questions/:id", UpdateQuestionContent)
// 恢复被逻辑删除的问题
v_put.PUT("deleted_questions/:id", RestoreQuestion)
// 赞同答案
v_put.PUT("questions/answers/agree", AgreeAnswer)
// 反对答案
v_put.PUT("questions/answers/disagree", DisagreeAnswer)
Comment on lines +137 to +139
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Consider Using POST Instead of PUT for Action Endpoints

The routes for agreeing and disagreeing with an answer are using the PUT method:

v_put.PUT("questions/answers/agree", AgreeAnswer)
v_put.PUT("questions/answers/disagree", DisagreeAnswer)

In RESTful API design, actions that do not idempotently update a resource state are often better suited to the POST method. Consider using POST for these endpoints to align with RESTful principles.

Apply this diff to update the HTTP methods:

- v_put.PUT("questions/answers/agree", AgreeAnswer)
+ v_post.POST("questions/answers/agree", AgreeAnswer)

- v_put.PUT("questions/answers/disagree", DisagreeAnswer)
+ v_post.POST("questions/answers/disagree", DisagreeAnswer)

//恢复被删除的答案,需要传入查询参数,传入答案id和所属问题id
v_put.PUT("questions/answers/restore", RestoreAnswer)
//恢复对答案的评论,需要传入查询参数,传入评论id和所属答案id
v_put.PUT("questions/answers/comments/restore", RestoreCommentToAnswer)
}

v_delete := r.Group("/")
{
// 逻辑删除问题
v_delete.DELETE("questions/:id", DeleteQuestion)
// 永久删除问题
v_delete.DELETE("deleted_questions/:id", DeleteQuestionForever)
// 永久删除答案
v_delete.DELETE("questions/answers", DeleteAnswerForever)
//逻辑删除答案,需要传入查询参数,传入答案id和所属问题id
v_delete.DELETE("questions/deleted_answers", DeleteAnswer)
Comment on lines +153 to +155
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Use Path Parameters Instead of Query Parameters for Resource Identification

The DELETE routes for answers require query parameters to identify the answer and its associated question:

v_delete.DELETE("questions/answers", DeleteAnswerForever)
v_delete.DELETE("questions/deleted_answers", DeleteAnswer)

It's recommended to use path parameters to uniquely identify resources in RESTful APIs. This enhances clarity and aligns with RESTful design principles. Consider modifying the routes as follows:

- v_delete.DELETE("questions/answers", DeleteAnswerForever)
+ v_delete.DELETE("questions/:question_id/answers/:answer_id", DeleteAnswerForever)

- v_delete.DELETE("questions/deleted_answers", DeleteAnswer)
+ v_delete.DELETE("questions/:question_id/deleted_answers/:answer_id", DeleteAnswer)

Update the corresponding handler functions to accept the path parameters.

//软删除评论,需要传入查询参数,传入评论id和所属答案id
v_delete.DELETE("questions/answers/comments", DeleteCommentToAnswer)
//永久删除评论,需要传入查询参数,传入评论id和所属答案id
v_delete.DELETE("questions/answers/deleted_comments", DeleteCommentForever)
}

//统计每个被删除的删除天数,超过15天则永久删除
go func() {
flag := true
for flag {
time.Sleep(time.Second * 30) // 添加延迟
deleted_questions.mux.Lock()
for _, q := range deleted_questions.deleted {
if q.IsDeleted && time.Since(q.Deleted_Time) > time.Second*10 {
Comment on lines +163 to +169
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Inconsistency Between Comment and Code Regarding Deletion Timing

The comment suggests that deleted questions should be permanently removed after 15 days:

//统计每个被删除的删除天数,超过15天则永久删除

However, the code deletes questions after they have been deleted for more than 10 seconds:

if q.IsDeleted && time.Since(q.Deleted_Time) > time.Second*10 {

This inconsistency could result in questions being deleted much sooner than intended. Please adjust the code to match the intended deletion threshold.

Apply this diff to correct the deletion timing:

- if q.IsDeleted && time.Since(q.Deleted_Time) > time.Second*10 {
+ if q.IsDeleted && time.Since(q.Deleted_Time) > time.Hour*24*15 {

This change sets the threshold to 15 days.

resultCh <- q
db.Unscoped().Delete(&q)
}
}
deleted_questions.mux.Unlock()
}
Comment on lines +167 to +175
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Undefined Variable: 'deleted_questions'

The variable deleted_questions is used but not defined within the provided code. This will lead to a compilation error due to undefined variable usage. Please ensure that deleted_questions is properly declared and initialized before it's used.

}()

// 收集结果
go func() {
for {
select {
case q := <-resultCh:
delete(deleted_questions.deleted, strconv.FormatUint(uint64(q.ID), 10))
Comment on lines +182 to +183
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Undefined Variable: 'deleted_questions'

Again, the variable deleted_questions is referenced but not defined:

delete(deleted_questions.deleted, strconv.FormatUint(uint64(q.ID), 10))

This will cause a runtime error. Ensure that deleted_questions is properly declared and initialized.

}
}
}()
Comment on lines +179 to +186
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Potential issue: Unbuffered channel usage

The goroutine collecting results from resultCh runs in an infinite loop without any exit condition. This could lead to a goroutine leak if the main function exits before this goroutine. Consider adding a way to signal this goroutine to stop, such as using a context or a dedicated stop channel.

Example:

stopCh := make(chan struct{})
go func() {
    for {
        select {
        case q := <-resultCh:
            delete(deleted_questions.deleted, strconv.FormatUint(uint64(q.ID), 10))
        case <-stopCh:
            return
        }
    }
}()

// In the main function, before r.Run(":8080"):
defer close(stopCh)

This allows the goroutine to be properly stopped when the main function exits.


r.Run(":8080")
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Consider using environment variable for port configuration

Hardcoding the port number (8080) reduces the flexibility of the application in different environments. Consider using an environment variable to set the port:

import "os"

// ...

port := os.Getenv("PORT")
if port == "" {
    port = "8080" // Default port if not set
}
r.Run(":" + port)

This change allows easy configuration of the port through environment variables, making the application more flexible for different deployment scenarios.

}
Empty file.
Loading