Browse Source

前台接口基本功能完成

wangguixi/feature-20251107144650-股票知识测评
wangguixi 2 months ago
parent
commit
ad4fef81da
  1. 15
      Knowledge_Test_Go/api/hello/hello.go
  2. 12
      Knowledge_Test_Go/api/hello/v1/hello.go
  3. 77
      Knowledge_Test_Go/api/v1/questionBank.go
  4. 49
      Knowledge_Test_Go/go.mod
  5. 118
      Knowledge_Test_Go/go.sum
  6. 34
      Knowledge_Test_Go/hack/config.yaml
  7. 37
      Knowledge_Test_Go/internal/cmd/cmd.go
  8. 5
      Knowledge_Test_Go/internal/controller/hello/hello.go
  9. 15
      Knowledge_Test_Go/internal/controller/hello/hello_new.go
  10. 13
      Knowledge_Test_Go/internal/controller/hello/hello_v1_hello.go
  11. 108
      Knowledge_Test_Go/internal/controller/knowledge.go
  12. 1
      Knowledge_Test_Go/internal/controller/questionBank.go
  13. 159
      Knowledge_Test_Go/internal/logic/knowledge/knowledge.go
  14. 22
      Knowledge_Test_Go/internal/logic/questionBank/questionBank.go
  15. 6
      Knowledge_Test_Go/main.go
  16. 128
      Knowledge_Test_Go/utility/response/response.go

15
Knowledge_Test_Go/api/hello/hello.go

@ -1,15 +0,0 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package hello
import (
"context"
"Knowledge_Test_Go/api/hello/v1"
)
type IHelloV1 interface {
Hello(ctx context.Context, req *v1.HelloReq) (res *v1.HelloRes, err error)
}

12
Knowledge_Test_Go/api/hello/v1/hello.go

@ -1,12 +0,0 @@
package v1
import (
"github.com/gogf/gf/v2/frame/g"
)
type HelloReq struct {
g.Meta `path:"/hello" tags:"Hello" method:"get" summary:"You first hello api"`
}
type HelloRes struct {
g.Meta `mime:"text/html" example:"string"`
}

77
Knowledge_Test_Go/api/v1/questionBank.go

@ -0,0 +1,77 @@
package v1
// GetQuestionsReq 获取题目请求
type GetQuestionsReq struct {
Page int `json:"page"`
PageSize int `json:"page_size"`
}
// GetQuestionsRes 获取题目响应
type GetQuestionsRes struct {
Id int `json:"id"`
Stem string `json:"stem"`
A string `json:"A"`
B string `json:"B"`
C string `json:"C"`
D string `json:"D"`
}
// SubmitAnswersReq 提交答案请求
type SubmitAnswersReq struct {
Jwcode int `v:"required" dc:"精网号"`
Answers []*AnswerItem `v:"required" dc:"答案列表"`
}
// AnswerItem 答案项
type AnswerItem struct {
QuestionId int `json:"questionId" dc:"题目ID"`
UserAnswer string `json:"userAnswer" dc:"用户答案"`
}
// SubmitAnswersRes 提交答案响应
type SubmitAnswersRes struct {
Score int `json:"score" dc:"得分"`
Total int `json:"total" dc:"总分"`
}
// GetWrongQuestionsReq 获取错题请求
type GetWrongQuestionsReq struct {
Jwcode int `v:"required" dc:"精网号(查询参数传递)"`
Page int `json:"page"`
PageSize int `json:"page_size"`
}
// GetUserScoresReq 获取用户成绩请求
type GetUserScoresReq struct {
Jwcode int `v:"required" dc:"精网号"`
}
// GetUserScoresRes 获取用户成绩响应
type GetUserScoresRes struct {
Score int `json:"score"`
}
// QuestionOutput 题目输出
type QuestionOutput struct {
Id int `json:"id"`
Stem string `json:"stem"`
A string `json:"A"`
B string `json:"B"`
C string `json:"C"`
D string `json:"D"`
}
// GetWrongQuestionsRes 错题详情
type GetWrongQuestionsRes struct {
QuestionOutput `json:"question"`
UserAnswer string `json:"userAnswer" dc:"用户答案"`
CorrectAnswer string `json:"correctAnswer" dc:"正确答案"`
}
// TotalScoreOutput 成绩输出
type TotalScoreOutput struct {
Id int `json:"id"`
Jwcode int `json:"jwcode"`
Score int `json:"score"`
CreatedAt string `json:"createdAt"`
}

49
Knowledge_Test_Go/go.mod

@ -1,28 +1,43 @@
module Knowledge_Test_Go
go 1.18
go 1.23.0
require github.com/gogf/gf/v2 v2.7.1
require (
github.com/gogf/gf/contrib/drivers/mysql/v2 v2.9.4
github.com/gogf/gf/contrib/nosql/redis/v2 v2.9.4
github.com/gogf/gf/v2 v2.9.4
)
require (
github.com/BurntSushi/toml v1.3.2 // indirect
github.com/BurntSushi/toml v1.5.0 // indirect
github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/clbanning/mxj/v2 v2.7.0 // indirect
github.com/fatih/color v1.16.0 // indirect
github.com/fsnotify/fsnotify v1.7.0 // indirect
github.com/go-logr/logr v1.2.3 // indirect
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
github.com/emirpasic/gods v1.18.1 // indirect
github.com/fatih/color v1.18.0 // indirect
github.com/fsnotify/fsnotify v1.9.0 // indirect
github.com/go-logr/logr v1.4.3 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/gorilla/websocket v1.5.1 // indirect
github.com/go-sql-driver/mysql v1.7.1 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/gorilla/websocket v1.5.3 // indirect
github.com/grokify/html-strip-tags-go v0.1.0 // indirect
github.com/magiconair/properties v1.8.7 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/magiconair/properties v1.8.10 // indirect
github.com/mattn/go-colorable v0.1.14 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/mattn/go-runewidth v0.0.9 // indirect
github.com/olekukonko/tablewriter v0.0.5 // indirect
go.opentelemetry.io/otel v1.14.0 // indirect
go.opentelemetry.io/otel/sdk v1.14.0 // indirect
go.opentelemetry.io/otel/trace v1.14.0 // indirect
golang.org/x/net v0.24.0 // indirect
golang.org/x/sys v0.19.0 // indirect
golang.org/x/text v0.14.0 // indirect
github.com/mattn/go-runewidth v0.0.16 // indirect
github.com/olekukonko/errors v1.1.0 // indirect
github.com/olekukonko/ll v0.0.9 // indirect
github.com/olekukonko/tablewriter v1.1.0 // indirect
github.com/redis/go-redis/v9 v9.12.1 // indirect
github.com/rivo/uniseg v0.4.7 // indirect
go.opentelemetry.io/auto/sdk v1.1.0 // indirect
go.opentelemetry.io/otel v1.38.0 // indirect
go.opentelemetry.io/otel/metric v1.38.0 // indirect
go.opentelemetry.io/otel/sdk v1.38.0 // indirect
go.opentelemetry.io/otel/trace v1.38.0 // indirect
golang.org/x/net v0.43.0 // indirect
golang.org/x/sys v0.35.0 // indirect
golang.org/x/text v0.28.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)

118
Knowledge_Test_Go/go.sum

@ -1,52 +1,96 @@
github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8=
github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
github.com/BurntSushi/toml v1.5.0 h1:W5quZX/G/csjUnuI8SUYlsHs9M38FC7znL0lIO+DvMg=
github.com/BurntSushi/toml v1.5.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
github.com/bsm/ginkgo/v2 v2.12.0 h1:Ny8MWAHyOepLGlLKYmXG4IEkioBysk6GpaRTLC8zwWs=
github.com/bsm/ginkgo/v2 v2.12.0/go.mod h1:SwYbGRRDovPVboqFv0tPTcG1sN61LM1Z4ARdbAV9g4c=
github.com/bsm/gomega v1.27.10 h1:yeMWxP2pV2fG3FgAODIY8EiRE3dy0aeFYt4l7wh6yKA=
github.com/bsm/gomega v1.27.10/go.mod h1:JyEr/xRbxbtgWNi8tIEVPUYZ5Dzef52k01W3YH0H+O0=
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/clbanning/mxj/v2 v2.7.0 h1:WA/La7UGCanFe5NpHF0Q3DNtnCsVoxbPKuyBNHWRyME=
github.com/clbanning/mxj/v2 v2.7.0/go.mod h1:hNiWqW14h+kc+MdF9C6/YoRfjEJoR3ou6tn/Qo+ve2s=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM=
github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE=
github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc=
github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ=
github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM=
github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU=
github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k=
github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0=
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0=
github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=
github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
github.com/gogf/gf/v2 v2.7.1 h1:Ukp7vzwh6VKnivEEx/xiMc61dL1HVZqCCHl//3GBRxc=
github.com/gogf/gf/v2 v2.7.1/go.mod h1:3oyGjyLHtSSo8kQ57Nj1TPdUNc0e2HS0A2J+KkXoW+I=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY=
github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY=
github.com/go-sql-driver/mysql v1.7.1 h1:lUIinVbN1DY0xBg0eMOzmmtGoHwWBbvnWubQUrtU8EI=
github.com/go-sql-driver/mysql v1.7.1/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
github.com/gogf/gf/contrib/drivers/mysql/v2 v2.9.4 h1:ntAPahCjQwQ79CC6tI67QDgj17NTWp+lMd1SaL2jJhs=
github.com/gogf/gf/contrib/drivers/mysql/v2 v2.9.4/go.mod h1:/350+9clTW5ktUvF+hePMN9yDknB2ipslqcx3Y2rLDQ=
github.com/gogf/gf/contrib/nosql/redis/v2 v2.9.4 h1:iKXUQ+8TklSriAqOQjfwioI36zlByqrDqz4ISaRFvm8=
github.com/gogf/gf/contrib/nosql/redis/v2 v2.9.4/go.mod h1:PYVwyQ0gN+w3wL7zKAoeUpy2WFs4/V8+Ls+eNsy7Uo0=
github.com/gogf/gf/v2 v2.9.4 h1:6vleEWypot9WBPncP2GjbpgAUeG6Mzb1YESb9nPMkjY=
github.com/gogf/gf/v2 v2.9.4/go.mod h1:Ukl+5HUH9S7puBmNLR4L1zUqeRwi0nrW4OigOknEztU=
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg=
github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/grokify/html-strip-tags-go v0.1.0 h1:03UrQLjAny8xci+R+qjCce/MYnpNXCtgzltlQbOBae4=
github.com/grokify/html-strip-tags-go v0.1.0/go.mod h1:ZdzgfHEzAfz9X6Xe5eBLVblWIxXfYSQ40S/VKrAOGpc=
github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY=
github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0=
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/magiconair/properties v1.8.10 h1:s31yESBquKXCV9a/ScB3ESkOjUYYv+X0rg8SYxI99mE=
github.com/magiconair/properties v1.8.10/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0=
github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE=
github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8=
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/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0=
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec=
github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc=
github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
github.com/olekukonko/errors v1.1.0 h1:RNuGIh15QdDenh+hNvKrJkmxxjV4hcS50Db478Ou5sM=
github.com/olekukonko/errors v1.1.0/go.mod h1:ppzxA5jBKcO1vIpCXQ9ZqgDh8iwODz6OXIGKU8r5m4Y=
github.com/olekukonko/ll v0.0.9 h1:Y+1YqDfVkqMWuEQMclsF9HUR5+a82+dxJuL1HHSRpxI=
github.com/olekukonko/ll v0.0.9/go.mod h1:En+sEW0JNETl26+K8eZ6/W4UQ7CYSrrgg/EdIYT2H8g=
github.com/olekukonko/tablewriter v1.1.0 h1:N0LHrshF4T39KvI96fn6GT8HEjXRXYNDrDjKFDB7RIY=
github.com/olekukonko/tablewriter v1.1.0/go.mod h1:5c+EBPeSqvXnLLgkm9isDdzR3wjfBkHR9Nhfp3NWrzo=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8=
go.opentelemetry.io/otel v1.14.0 h1:/79Huy8wbf5DnIPhemGB+zEPVwnN6fuQybr/SRXa6hM=
go.opentelemetry.io/otel v1.14.0/go.mod h1:o4buv+dJzx8rohcUeRmWUZhqupFvzWis188WlggnNeU=
go.opentelemetry.io/otel/sdk v1.14.0 h1:PDCppFRDq8A1jL9v6KMI6dYesaq+DFcDZvjsoGvxGzY=
go.opentelemetry.io/otel/sdk v1.14.0/go.mod h1:bwIC5TjrNG6QDCHNWvW4HLHtUQ4I+VQDsnjhvyZCALM=
go.opentelemetry.io/otel/trace v1.14.0 h1:wp2Mmvj41tDsyAJXiWDWpfNsOiIyd38fy85pyKcFq/M=
go.opentelemetry.io/otel/trace v1.14.0/go.mod h1:8avnQLK+CG77yNLUae4ea2JDQ6iT+gozhnZjy/rw9G8=
golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w=
golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/redis/go-redis/v9 v9.12.1 h1:k5iquqv27aBtnTm2tIkROUDp8JBXhXZIVu1InSgvovg=
github.com/redis/go-redis/v9 v9.12.1/go.mod h1:huWgSWd8mW6+m0VPhJjSSQ+d6Nh1VICQ6Q5lHuCH/Iw=
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII=
github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o=
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=
go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
go.opentelemetry.io/otel v1.38.0 h1:RkfdswUDRimDg0m2Az18RKOsnI8UDzppJAtj01/Ymk8=
go.opentelemetry.io/otel v1.38.0/go.mod h1:zcmtmQ1+YmQM9wrNsTGV/q/uyusom3P8RxwExxkZhjM=
go.opentelemetry.io/otel/metric v1.38.0 h1:Kl6lzIYGAh5M159u9NgiRkmoMKjvbsKtYRwgfrA6WpA=
go.opentelemetry.io/otel/metric v1.38.0/go.mod h1:kB5n/QoRM8YwmUahxvI3bO34eVtQf2i4utNVLr9gEmI=
go.opentelemetry.io/otel/sdk v1.38.0 h1:l48sr5YbNf2hpCUj/FoGhW9yDkl+Ma+LrVl8qaM5b+E=
go.opentelemetry.io/otel/sdk v1.38.0/go.mod h1:ghmNdGlVemJI3+ZB5iDEuk4bWA3GkTpW+DOoZMYBVVg=
go.opentelemetry.io/otel/sdk/metric v1.38.0 h1:aSH66iL0aZqo//xXzQLYozmWrXxyFkBJ6qT5wthqPoM=
go.opentelemetry.io/otel/sdk/metric v1.38.0/go.mod h1:dg9PBnW9XdQ1Hd6ZnRz689CbtrUp0wMMs9iPcgT9EZA=
go.opentelemetry.io/otel/trace v1.38.0 h1:Fxk5bKrDZJUH+AMyyIXGcFAPah0oRcT+LuNtJrmcNLE=
go.opentelemetry.io/otel/trace v1.38.0/go.mod h1:j1P9ivuFsTceSWe1oY+EeW3sc+Pp42sO++GHkg4wwhs=
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
golang.org/x/net v0.43.0 h1:lat02VYK2j4aLzMzecihNvTlJNQUq316m2Mr9rnM6YE=
golang.org/x/net v0.43.0/go.mod h1:vhO1fvI4dGsIjh73sWfUVjj3N7CA9WkKJNQm2svM6Jg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o=
golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
golang.org/x/sys v0.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI=
golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
golang.org/x/text v0.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng=
golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

34
Knowledge_Test_Go/hack/config.yaml

@ -1,20 +1,16 @@
# https://goframe.org/docs/web/server-config-file-template
server:
address: ":8000"
openapiPath: "/api.json"
swaggerPath: "/swagger"
# https://goframe.org/docs/core/glog-config
logger:
level : "all"
stdout: true
# https://goframe.org/docs/core/gdb-config-file
database:
default:
debug: true
link: "mysql:root:123456@tcp(127.0.0.1:3306)/练习1?loc=Local&parseTime=true"
# CLI tool, only in development environment.
# https://goframe.org/pages/viewpage.action?pageId=3673173
gfcli:
# 工具编译配置
build:
name: "Knowledge_Test_Go"
path: "./bin"
arch: "amd64"
system: "linux"
packSrc: "manifest/i18n"
# dao生成
gen:
dao:
- link: "mysql:root:123456@tcp(127.0.0.1:3306)/knowledge_test?loc=Local&parseTime=true"
tables: ""

37
Knowledge_Test_Go/internal/cmd/cmd.go

@ -1,13 +1,12 @@
package cmd
import (
"Knowledge_Test_Go/internal/controller"
"context"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/net/ghttp"
"github.com/gogf/gf/v2/os/gcmd"
"Knowledge_Test_Go/internal/controller/hello"
)
var (
@ -17,18 +16,34 @@ var (
Brief: "start http server",
Func: func(ctx context.Context, parser *gcmd.Parser) (err error) {
s := g.Server()
// 前台路由组 - 知识测评
s.Group("/api", func(group *ghttp.RouterGroup) {
group.Middleware(ghttp.MiddlewareHandlerResponse)
group.Bind(
hello.NewV1(),
)
})
s.Group("/admin", func(group *ghttp.RouterGroup) {
group.Middleware(ghttp.MiddlewareHandlerResponse)
group.Bind(
hello.NewV1(),
group.Middleware(
ghttp.MiddlewareHandlerResponse,
ghttp.MiddlewareCORS,
)
group.POST("/knowledge/questions", controller.NewKnowledgeTest().GetQuestions) // 获取题目列表
group.POST("/knowledge/submit", controller.NewKnowledgeTest().SubmitAnswers) // 提交答案
group.POST("/knowledge/scores", controller.NewKnowledgeTest().GetUserScores) // 获取用户成绩
group.POST("/knowledge/wrong-questions", controller.NewKnowledgeTest().GetWrongQuestions) // 获取错题列表
})
//// 后台路由组
//s.Group("/admin", func(group *ghttp.RouterGroup) {
// group.Middleware(
// ghttp.MiddlewareHandlerResponse,
// )
//
// kt := controller.NewKnowledgeTest()
// qb := controller.NewQuestionBank()
//
// group.GET("/users", kt.AdminUserList)
// group.GET("/wrong-statistics", kt.AdminWrongStatistics)
// group.GET("/questions", qb.AdminQuestionList)
// group.POST("/questions/update", qb.UpdateQuestion)
//})
s.Run()
return nil
},

5
Knowledge_Test_Go/internal/controller/hello/hello.go

@ -1,5 +0,0 @@
// =================================================================================
// This is auto-generated by GoFrame CLI tool only once. Fill this file as you wish.
// =================================================================================
package hello

15
Knowledge_Test_Go/internal/controller/hello/hello_new.go

@ -1,15 +0,0 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package hello
import (
"Knowledge_Test_Go/api/hello"
)
type ControllerV1 struct{}
func NewV1() hello.IHelloV1 {
return &ControllerV1{}
}

13
Knowledge_Test_Go/internal/controller/hello/hello_v1_hello.go

@ -1,13 +0,0 @@
package hello
import (
"context"
"github.com/gogf/gf/v2/frame/g"
"Knowledge_Test_Go/api/hello/v1"
)
func (c *ControllerV1) Hello(ctx context.Context, req *v1.HelloReq) (res *v1.HelloRes, err error) {
g.RequestFromCtx(ctx).Response.Writeln("Hello World!")
return
}

108
Knowledge_Test_Go/internal/controller/knowledge.go

@ -0,0 +1,108 @@
package controller
import (
"Knowledge_Test_Go/api/v1"
"Knowledge_Test_Go/internal/service"
"Knowledge_Test_Go/utility/response"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/net/ghttp"
)
type cKnowledgeTest struct{}
func NewKnowledgeTest() *cKnowledgeTest {
return &cKnowledgeTest{}
}
// GetQuestions 获取题目列表
func (c *cKnowledgeTest) GetQuestions(r *ghttp.Request) {
ctx := r.GetCtx()
var req *v1.GetQuestionsReq
if err := r.Parse(&req); err != nil {
response.JsonExit(r, 400, err.Error())
}
res, total, err := service.KnowledgeTest().GetQuestions(ctx, req)
if err != nil {
response.JsonExit(r, 400, err.Error())
}
response.JsonExit(r, 200, "success", g.Map{
"list": res,
"total": total,
})
}
// GetUserScores 获取用户成绩
func (c *cKnowledgeTest) GetUserScores(r *ghttp.Request) {
ctx := r.GetCtx()
var req *v1.GetUserScoresReq
if err := r.Parse(&req); err != nil {
response.JsonExit(r, 400, err.Error())
}
res, err := service.KnowledgeTest().GetUserScores(ctx, req)
if err != nil {
response.JsonExit(r, 400, err.Error())
}
response.JsonExit(r, 200, "success", res)
}
// SubmitAnswers 提交答案
func (c *cKnowledgeTest) SubmitAnswers(r *ghttp.Request) {
ctx := r.GetCtx()
var req v1.SubmitAnswersReq
if err := r.Parse(&req); err != nil {
response.JsonExit(r, 400, err.Error())
}
res, err := service.KnowledgeTest().SubmitAnswers(ctx, &req)
if err != nil {
response.JsonExit(r, 400, err.Error())
}
response.JsonExit(r, 200, "success", g.Map{
"data": res,
})
}
// GetWrongQuestions 获取错题列表
func (c *cKnowledgeTest) GetWrongQuestions(r *ghttp.Request) {
ctx := r.GetCtx()
var req *v1.GetWrongQuestionsReq
if err := r.Parse(&req); err != nil {
response.JsonExit(r, 400, err.Error())
}
res, total, err := service.KnowledgeTest().GetWrongQuestions(ctx, req)
if err != nil {
response.JsonExit(r, 400, err.Error())
}
response.JsonExit(r, 200, "success", g.Map{
"list": res,
"total": total,
})
}
//
//// GetUserScores 获取用户成绩
//func (c *KnowledgeTest) GetUserScores(r *ghttp.Request) {
// var req v1.GetUserScoresReq
// if err := r.Parse(&req); err != nil {
// r.Response.WriteJson(g.Map{
// "code": 500,
// "msg": err.Error(),
// })
// return
// }
//
// res, err := knowledge.NewKnowledgeTestLogic(r.Context()).GetUserScores(&req)
// if err != nil {
// r.Response.WriteJson(g.Map{
// "code": 500,
// "msg": err.Error(),
// })
// return
// }
//
// r.Response.WriteJson(g.Map{
// "code": 200,
// "msg": "success",
// "data": res,
// })
//}*/

1
Knowledge_Test_Go/internal/controller/questionBank.go

@ -0,0 +1 @@
package controller

159
Knowledge_Test_Go/internal/logic/knowledge/knowledge.go

@ -0,0 +1,159 @@
package knowledge
import (
v1 "Knowledge_Test_Go/api/v1"
"Knowledge_Test_Go/internal/dao"
"Knowledge_Test_Go/internal/model/do"
"Knowledge_Test_Go/internal/service"
"context"
"fmt"
"github.com/gogf/gf/v2/database/gdb"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/util/gconv"
)
type sKnowledgeTest struct{}
func init() {
service.RegisterKnowledgeTest(&sKnowledgeTest{})
}
// GetQuestions 获取题目列表
func (s *sKnowledgeTest) GetQuestions(ctx context.Context, req *v1.GetQuestionsReq) (res []*v1.GetQuestionsRes, total int, err error) {
db := g.Model("question_bank a").Fields("a.id", "a.stem", "a.a", "a.b", "a.c", "a.d")
err = db.Page(req.Page, req.PageSize).ScanAndCount(&res, &total, false)
return
}
// GetUserScores 获取用户成绩
func (s *sKnowledgeTest) GetUserScores(ctx context.Context, req *v1.GetUserScoresReq) (res []*v1.GetUserScoresRes, err error) {
err = g.Model("total_score").Fields("score").Where("jwcode=?", req.Jwcode).Ctx(ctx).Scan(&res)
if err != nil {
return nil, fmt.Errorf("获取用户成绩失败: %w", err)
}
return res, nil
}
// SubmitAnswers 提交答案并计算分数
func (s *sKnowledgeTest) SubmitAnswers(ctx context.Context, req *v1.SubmitAnswersReq) (*v1.SubmitAnswersRes, error) {
if len(req.Answers) == 0 {
return nil, fmt.Errorf("答案列表不能为空")
}
// 获取所有题目ID
questionIds := make([]interface{}, len(req.Answers))
for i, answer := range req.Answers {
questionIds[i] = answer.QuestionId
}
// 批量查询题目
var questions []*do.QuestionBank
err := dao.QuestionBank.Ctx(ctx).
Where(dao.QuestionBank.Columns().Id, questionIds).
Where(dao.QuestionBank.Columns().Isdel, 0).
Scan(&questions)
if err != nil {
return nil, err
}
// 构建题目ID到正确答案的映射
questionMap := make(map[int]string)
for _, q := range questions {
questionMap[gconv.Int(q.Id)] = gconv.String(q.CorrectAnswer)
}
// 计算分数并准备记录数据
score := 0
total := len(req.Answers) * 2 // 每题2分
records := make([]*do.QuestionRecord, 0, len(req.Answers))
// 收集所有被回答的题目ID(用于更新引用次数)
allAnsweredQuestionIds := make([]int, 0, len(req.Answers))
// 收集错误题目的ID(用于更新错误次数)
errorQuestionIds := make([]int, 0)
for _, answer := range req.Answers {
correctAnswer, exists := questionMap[answer.QuestionId]
if !exists {
continue
}
// 记录所有被回答的题目
allAnsweredQuestionIds = append(allAnsweredQuestionIds, answer.QuestionId)
isCorrect := 0 // 0为正确
if answer.UserAnswer == correctAnswer {
score += 2
} else {
isCorrect = 1 // 1为错误
errorQuestionIds = append(errorQuestionIds, answer.QuestionId)
}
records = append(records, &do.QuestionRecord{
Jwcode: req.Jwcode,
QuestionBankId: answer.QuestionId,
UserAnswer: answer.UserAnswer,
IsCorrect: isCorrect,
})
}
// 批量保存记录(使用事务确保原子性)
err = dao.QuestionRecord.Ctx(ctx).Transaction(ctx, func(ctx context.Context, tx gdb.TX) error {
// 批量插入答题记录
if len(records) > 0 {
_, err := tx.Model(dao.QuestionRecord.Table()).Data(records).Insert()
if err != nil {
return err
}
}
// 更新所有被回答题目的引用次数
if len(allAnsweredQuestionIds) > 0 {
_, err := tx.Model(dao.QuestionBank.Table()).
Where(dao.QuestionBank.Columns().Id, allAnsweredQuestionIds).
Increment(dao.QuestionBank.Columns().CitationCount, 1)
if err != nil {
return err
}
}
// 更新错误题目的错误次数
if len(errorQuestionIds) > 0 {
_, err := tx.Model(dao.QuestionBank.Table()).
Where(dao.QuestionBank.Columns().Id, errorQuestionIds).
Increment(dao.QuestionBank.Columns().ErrorCount, 1)
if err != nil {
return err
}
}
// 插入总成绩记录
_, err = tx.Model(dao.TotalScore.Table()).Data(&do.TotalScore{
Jwcode: req.Jwcode,
Score: score,
}).Insert()
if err != nil {
return err
}
return nil
})
if err != nil {
return nil, err
}
return &v1.SubmitAnswersRes{
Score: score,
Total: total,
}, nil
}
// GetWrongQuestions 获取错题列表
func (s *sKnowledgeTest) GetWrongQuestions(ctx context.Context, req *v1.GetWrongQuestionsReq) (res []*v1.GetWrongQuestionsRes, total int, err error) {
db := g.Model("question_record b").
LeftJoin("question_bank a", "a.id=b.question_bank_id").
Where("b.jwcode=?", req.Jwcode).Fields("a.id", "a.stem", "a.a", "a.b", "a.c", "a.d", "a.correct_answer", "b.user_answer")
err = db.Page(req.Page, req.PageSize).ScanAndCount(&res, &total, false)
return
}

22
Knowledge_Test_Go/internal/logic/questionBank/questionBank.go

@ -0,0 +1,22 @@
package questionBank
import (
v1 "Knowledge_Test_Go/api/v1"
"Knowledge_Test_Go/internal/service"
"context"
"github.com/gogf/gf/v2/frame/g"
)
type sQuestionBank struct{}
func init() {
service.RegisterQuestionBank(&sQuestionBank{})
}
// GetQuestions 获取题目列表
func (s *sQuestionBank) GetQuestions(ctx context.Context, req *v1.GetQuestionsReq) (res []*v1.GetQuestionsRes, total int, err error) {
db := g.Model("question_bank a").Fields("a.id", "a.stem", "a.a", "a.b", "a.c", "a.d")
err = db.Page(req.Page, req.PageSize).ScanAndCount(&res, &total, false)
return
}

6
Knowledge_Test_Go/main.go

@ -3,9 +3,15 @@ package main
import (
_ "Knowledge_Test_Go/internal/packed"
_ "Knowledge_Test_Go/internal/logic"
"github.com/gogf/gf/v2/os/gctx"
"Knowledge_Test_Go/internal/cmd"
_ "github.com/gogf/gf/contrib/drivers/mysql/v2"
_ "github.com/gogf/gf/contrib/nosql/redis/v2"
)
func main() {

128
Knowledge_Test_Go/utility/response/response.go

@ -0,0 +1,128 @@
package response
import (
"net/http"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/net/ghttp"
"github.com/gogf/gf/v2/util/gconv"
)
// JsonRes 数据返回通用JSON数据结构
type JsonRes struct {
Code int `json:"code"` // 错误码((0:成功, 1:失败, >1:错误码))
Message string `json:"msg"` // 提示信息
Data interface{} `json:"data"` // 返回数据(业务接口定义具体数据结构)
// Redirect string `json:"redirect"` // 引导客户端跳转到指定路由
}
// Json 返回标准JSON数据。
func Json(r *ghttp.Request, code int, message string, data ...interface{}) {
var responseData interface{}
if len(data) > 0 {
responseData = data[0]
} else {
responseData = g.Map{}
}
r.Response.WriteJson(JsonRes{
Code: code,
Message: message,
Data: responseData,
})
}
// JsonExit 返回标准JSON数据并退出当前HTTP执行函数。
func JsonExit(r *ghttp.Request, code int, message string, data ...interface{}) {
if code == http.StatusBadRequest {
g.Log().Error(r.Context(), code, message)
}
Json(r, code, message, data...)
r.Exit()
}
func dataReturn(r *ghttp.Request, code int, req ...interface{}) *JsonRes {
var msg string
var data interface{}
if len(req) > 0 {
msg = gconv.String(req[0])
}
if len(req) > 1 {
data = req[1]
}
// msg = GetCodeMsg(code, msg)
if code != 1 && !gconv.Bool(r.GetCtxVar("api_code")) {
code = 0
}
response := &JsonRes{
// ID: r.GetCtxVar("RequestId").String(),
Code: code,
Message: msg,
Data: data,
}
r.SetParam("apiReturnRes", response)
return response
}
// Auth 认证失败
func Auth(r *ghttp.Request) {
res := dataReturn(r, 999, "请登录")
r.Response.WriteJsonExit(res)
}
// AuthBlack Auth 认证失败 被冻结拉黑
func AuthBlack(r *ghttp.Request) {
res := dataReturn(r, 888, "您的账号被冻结拉黑,请联系管理员")
r.Response.WriteJsonExit(res)
}
// JsonRedirect 返回标准JSON数据引导客户端跳转。
func JsonRedirect(r *ghttp.Request, code int, message, redirect string, data ...interface{}) {
responseData := interface{}(nil)
if len(data) > 0 {
responseData = data[0]
}
r.Response.WriteJson(JsonRes{
Code: code,
Message: message,
Data: responseData,
// Redirect: redirect,
})
}
// JsonRedirectExit 返回标准JSON数据引导客户端跳转,并退出当前HTTP执行函数。
func JsonRedirectExit(r *ghttp.Request, code int, message, redirect string, data ...interface{}) {
JsonRedirect(r, code, message, redirect, data...)
r.Exit()
}
func SuccessWithData(r *ghttp.Request, data interface{}) {
res := dataReturn(r, 1, "ok", data)
r.Response.WriteJsonExit(res)
}
// JsonResponse 数据返回通用JSON数据结构
type JsonResponse struct {
// ID string `json:"id"` //
Code int `json:"code"` // 错误码((1:成功, 0:失败, >1:错误码))
Message string `json:"message"` // 提示信息
Data interface{} `json:"data,omitempty"` // 返回数据(业务接口定义具体数据结构)
Redirect string `json:"redirect,omitempty"` // 引导客户端跳转到指定路由
}
/*错误,只有错误信息,错误码0*/
func Error(msg string) *JsonRes {
return &JsonRes{
Code: 400, // 错误码
Message: msg, // 错误信息
Data: nil,
}
}
/*成功,有数据*/
func SuccessWithDataNoReq(data interface{}) *JsonRes {
return &JsonRes{
Code: 200,
Message: "success",
Data: data,
}
}
Loading…
Cancel
Save