-
Notifications
You must be signed in to change notification settings - Fork 1
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
feat(all):新增搜查圈子推荐等功能;fix(test,practice,user):部分错误 #2
base: main
Are you sure you want to change the base?
Conversation
WalkthroughThe latest changes introduce extensive API documentation and new endpoints covering user management, practice exercises, tests, circles, and search functionalities. Controllers now leverage a DAO layer for structured database interaction, and error handling has been improved. Updated models and database migrations accommodate new entities such as Circle, FollowCircle, and SearchHistory, while main application routes are enhanced to support the expanded API. Overall, the architecture is refactored for greater modularity and maintainability. Changes
Sequence Diagram(s)sequenceDiagram
participant C as Client
participant R as Router (Main)
participant Ctrl as Controller
participant DAO as DAO Layer
participant DB as Database
C->>R: Send API request (e.g., create circle)
R->>Ctrl: Route request to handler
Ctrl->>DAO: Invoke corresponding DAO function
DAO->>DB: Perform database operation
DB-->>DAO: Return operation result
DAO-->>Ctrl: Pass data/error back
Ctrl->>R: Format response via views
R-->>C: Return JSON response
Poem
Tip 🌐 Web search-backed reviews and chat
✨ Finishing Touches
🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 40
🔭 Outside diff range comments (4)
circle/models/practice_models.go (2)
2-14
: Add missing constraints and follow Go naming conventions in Practice model.
- Add GORM tags for better database constraints:
- Add
not null
constraints for required fields- Add foreign key constraint for
Userid
- Follow Go naming conventions:
- Rename
Practiceid
toPracticeID
- Rename
Userid
toUserID
- Rename
Imageurl
toImageURL
type Practice struct { - Practiceid int `gorm:"primaryKey;autoIncrement"` - Content string `gorm:"type:text"` - Difficulty string - Circle string - Userid int - Answer string - Variety string - Imageurl string - Status string - Explain string `gorm:"type:text"` - Good int + PracticeID int `gorm:"primaryKey;autoIncrement"` + Content string `gorm:"type:text;not null"` + Difficulty string `gorm:"not null"` + Circle string `gorm:"not null"` + UserID int `gorm:"not null;index;constraint:fk_practice_user,references:id"` + Answer string `gorm:"not null"` + Variety string `gorm:"not null"` + ImageURL string + Status string `gorm:"not null;default:'active'"` + Explain string `gorm:"type:text"` + Good int `gorm:"default:0"` }
21-26
: Add missing constraints and follow Go naming conventions in PracticeComment model.
- Add GORM tags for better database constraints:
- Add
not null
constraints for required fields- Add foreign key constraints
- Follow Go naming conventions:
- Rename
Commentid
toCommentID
- Rename
Practiceid
toPracticeID
- Rename
Userid
toUserID
type PracticeComment struct { - Commentid int `gorm:"primaryKey;autoIncrement"` - Content string `gorm:"type:text"` - Practiceid int - Userid int + CommentID int `gorm:"primaryKey;autoIncrement"` + Content string `gorm:"type:text;not null"` + PracticeID int `gorm:"not null;index;constraint:fk_practice_comment_practice,references:id"` + UserID int `gorm:"not null;index;constraint:fk_practice_comment_user,references:id"` }circle/models/test_models.go (2)
13-22
: Add missing constraints and follow Go naming conventions in TestQuestion model.
- Add GORM tags for better database constraints:
- Add
not null
constraints for required fields- Add foreign key constraint for
Testid
- Follow Go naming conventions:
- Rename
Testid
toTestID
- Rename
Questionid
toQuestionID
- Rename
Imageurl
toImageURL
type TestQuestion struct { - Testid int - Questionid int `gorm:"primaryKey;autoIncrement"` - Content string `gorm:"type:text"` - Difficulty string - Answer string - Variety string - Imageurl string - Explain string `gorm:"type:text"` + TestID int `gorm:"not null;index;constraint:fk_test_question_test,references:id"` + QuestionID int `gorm:"primaryKey;autoIncrement"` + Content string `gorm:"type:text;not null"` + Difficulty string `gorm:"not null"` + Answer string `gorm:"not null"` + Variety string `gorm:"not null"` + ImageURL string + Explain string `gorm:"type:text"` }
29-35
: Add missing constraints and follow Go naming conventions in Top model.
- Add GORM tags for better database constraints:
- Add
not null
constraints for required fields- Add foreign key constraints
- Follow Go naming conventions:
- Rename
Topid
toTopID
- Rename
Userid
toUserID
- Rename
Correctnum
toCorrectNum
- Rename
Testid
toTestID
type Top struct { - Topid int `gorm:"primaryKey;autoIncrement"` - Userid int - Correctnum int - Time int - Testid int + TopID int `gorm:"primaryKey;autoIncrement"` + UserID int `gorm:"not null;index;constraint:fk_top_user,references:id"` + CorrectNum int `gorm:"not null;default:0"` + Time int `gorm:"not null"` + TestID int `gorm:"not null;index;constraint:fk_top_test,references:id"` }
🧹 Nitpick comments (21)
circle/controllers/practice_contorllers.go (4)
59-70
: Capture errors returned by DAO calls.
GetPracticeByPracticeID
andGetPracticeByCircle
might fail. Consider handling their errors to provide a proper response.
104-113
: Validate practice ID conversion.
p, _ := strconv.Atoi(practiceid)
should handle and report conversion errors to the user.
114-154
: Avoid ignoring parse errors & consider typed 'answer'.
You discard conversion errors for bothpracticeid
andtime
. Also, string-based “true” checks can be brittle if future requirements change.
162-172
: Prevent silent failures for user practice data.
id, _ := dao.GetIdByUser(name)
with no error handling could lead to an incorrect ID.circle/controllers/test_contorllesrs.go (5)
33-57
: Validate 'testid' conversion.
p, _ := strconv.Atoi(testid)
may introduce invalid data. Return an error if parsing fails.
58-74
: Check parsing errors for 'practiceid'.
Silent failures can cause confusing behavior.
93-102
: Validate 'testid'.
If the provided test ID is invalid, the DAO call won’t retrieve the intended questions.
185-189
: Consider DAO error returns.
Ifdao.RecommentTest(circle)
fails, users see no error message.
195-199
: Capture errors from 'NewTest'.
Return an error if the DAO call is unsuccessful.circle/controllers/user_contorllers.go (5)
49-49
: Avoid calling 'rand.Seed' in Go 1.20
The recommended approach is to use a local random source or remove it if not necessary.🧰 Tools
🪛 golangci-lint (1.62.2)
49-49: SA1019: rand.Seed has been deprecated since Go 1.20 and an alternative has been available since Go 1.0: As of Go 1.20 there is no reason to call Seed with a random value. Programs that call Seed with a known value to get a specific sequence of results should use New(NewSource(seed)) to obtain a local random generator.
(staticcheck)
53-61
: Consider returning an error from 'Getemail'.
If email sending fails, you currently provide no runtime indication to the caller.
151-172
: Validate errors for 'CountUsersByName'.
count, _ := dao.CountUsersByName(newusername)
might mask DB errors. Also, rename function toChangeUsername
for consistency.
227-233
: Handle errors on user ID lookups.
userid, _ := dao.GetIdByUser(...)
can fail, leaving the subsequent logic uncertain.
234-240
: Check errors in 'Mypractice'.
Similar to 'Mytest', ignoring user or practice retrieval failures could yield misleading data.circle/dao/circle_dao.go (2)
9-13
: Consider adding pagination to SelectPendingCircle.The current implementation only returns the first pending circle. Consider adding pagination to handle multiple pending circles efficiently.
-func SelectPendingCircle() (models.Circle, error) { - var circles models.Circle - err := database.DB.Where("status = ?", "pending").First(&circles).Error - return circles, err +func SelectPendingCircle(page, pageSize int) ([]models.Circle, error) { + var circles []models.Circle + offset := (page - 1) * pageSize + err := database.DB.Where("status = ?", "pending"). + Offset(offset). + Limit(pageSize). + Find(&circles).Error + return circles, err +}
22-24
: Fix code formatting in UpdateCircle.There are missing spaces around operators and after commas.
-func UpdateCircle(circle *models.Circle,id int) error { - return database.DB.Model(&models.Circle{}).Where("id=?",id).Updates(circle).Error +func UpdateCircle(circle *models.Circle, id int) error { + return database.DB.Model(&models.Circle{}).Where("id = ?", id).Updates(circle).Error +}circle/database/database.go (1)
62-64
: Consider adding database indexes for search performance.The new models would benefit from indexes on frequently searched columns.
Consider adding the following indexes:
Circle
: Index onname
column for text searchSearchHistory
: Composite index on(userid, created_at)
for history queriesFollowCircle
: Unique index on(userid, circleid)
to prevent duplicatesYou can add these using GORM tags in your model definitions:
type Circle struct { gorm.Model Name string `gorm:"index:idx_circle_name,type:btree"` // other fields... } type SearchHistory struct { gorm.Model Userid int `gorm:"index:idx_search_user_time"` CreatedAt time.Time `gorm:"index:idx_search_user_time"` // other fields... } type FollowCircle struct { gorm.Model Userid int `gorm:"uniqueIndex:idx_follow_unique"` Circleid int `gorm:"uniqueIndex:idx_follow_unique"` // other fields... }circle/views/views.go (1)
66-68
: Consolidate duplicate response structures.
ShowCircle
andShowManyCircle
use the same response key "circles" for both single and multiple items, which can be confusing.Apply this diff to differentiate single and multiple responses:
func ShowCircle(c *gin.Context,circles models.Circle){ - c.JSON(200,gin.H{"circles":circles}) + c.JSON(200,gin.H{"circle":circles}) } func ShowManyCircle(c *gin.Context,circles []models.Circle){ c.JSON(200,gin.H{"circles":circles}) }Also applies to: 69-71
circle/dao/user_dao.go (2)
8-12
: Add indexes for frequently queried fields.The functions
GetUserByEmail
,GetUserByName
, andGetUserByID
perform queries on fields that should be indexed for better performance.Consider adding the following indexes to your database schema:
name
(unique index)id
(primary key)Example migration:
CREATE UNIQUE INDEX idx_users_email ON users(email); CREATE UNIQUE INDEX idx_users_name ON users(name);Also applies to: 14-18, 20-24
42-44
: Use selective updates instead of Save.The
UpdateUser
function usesSave
which updates all fields. This can be inefficient and potentially override fields unintentionally.Consider using selective updates:
func UpdateUser(user *models.User) error { - return database.DB.Save(user).Error + return database.DB.Model(user).Updates(map[string]interface{}{ + "name": user.Name, + "email": user.Email, + // Add other fields that should be updatable + }).Error }circle/api.md (1)
649-679
: Improve API response documentation.The response example is unclear and lacks proper formatting.
Replace the vague description with a proper JSON example:
-```json -{ 多个。。 - Testid - Questionid:题目id - Content - Difficulty - Answer - Variety - Imageurl - Explain -} -``` +```json +{ + "questions": [ + { + "testid": 1, + "questionid": 1, + "content": "题目内容", + "difficulty": 3, + "answer": "A", + "variety": "单选题", + "imageurl": "https://example.com/image.jpg", + "explain": "题目解析" + } + ] +} +``` <details> <summary>🧰 Tools</summary> <details> <summary>🪛 markdownlint-cli2 (0.17.2)</summary> 652-652: Hard tabs Column: 1 (MD010, no-hard-tabs) --- 652-652: Hard tabs Column: 18 (MD010, no-hard-tabs) --- 653-653: Hard tabs Column: 1 (MD010, no-hard-tabs) --- 654-654: Hard tabs Column: 1 (MD010, no-hard-tabs) --- 655-655: Hard tabs Column: 1 (MD010, no-hard-tabs) --- 656-656: Hard tabs Column: 1 (MD010, no-hard-tabs) --- 657-657: Hard tabs Column: 1 (MD010, no-hard-tabs) --- 658-658: Hard tabs Column: 1 (MD010, no-hard-tabs) </details> </details> </blockquote></details> </blockquote></details> <details> <summary>📜 Review details</summary> **Configuration used: CodeRabbit UI** **Review profile: CHILL** **Plan: Pro** <details> <summary>📥 Commits</summary> Reviewing files that changed from the base of the PR and between 8eb06476df345169a3e87655a3488e057989a7c2 and f3bde251d5c43fc286ae6d5f94ac15fe97d6a377. </details> <details> <summary>⛔ Files ignored due to path filters (1)</summary> * `circle/go.sum` is excluded by `!**/*.sum` </details> <details> <summary>📒 Files selected for processing (22)</summary> * `circle/api.md` (1 hunks) * `circle/controllers/circle_contorllers.go` (1 hunks) * `circle/controllers/data.txt` (1 hunks) * `circle/controllers/practice_contorllers.go` (1 hunks) * `circle/controllers/search_controllers.go` (1 hunks) * `circle/controllers/test_contorllesrs.go` (1 hunks) * `circle/controllers/user_contorllers.go` (5 hunks) * `circle/dao/circle_dao.go` (1 hunks) * `circle/dao/practice_dao.go` (1 hunks) * `circle/dao/search_dao.go` (1 hunks) * `circle/dao/test_dao.go` (1 hunks) * `circle/dao/user_dao.go` (1 hunks) * `circle/database/data.txt` (1 hunks) * `circle/database/database.go` (2 hunks) * `circle/go.mod` (1 hunks) * `circle/main.go` (4 hunks) * `circle/models/circle_models.go` (1 hunks) * `circle/models/practice_models.go` (2 hunks) * `circle/models/search_models.go` (1 hunks) * `circle/models/test_models.go` (3 hunks) * `circle/models/user_models.go` (0 hunks) * `circle/views/views.go` (3 hunks) </details> <details> <summary>💤 Files with no reviewable changes (1)</summary> * circle/models/user_models.go </details> <details> <summary>✅ Files skipped from review due to trivial changes (3)</summary> * circle/controllers/data.txt * circle/database/data.txt * circle/go.mod </details> <details> <summary>🧰 Additional context used</summary> <details> <summary>🪛 golangci-lint (1.62.2)</summary> <details> <summary>circle/controllers/user_contorllers.go</summary> 9-9: SA1019: "io/ioutil" has been deprecated since Go 1.19: As of Go 1.16, the same functionality is now provided by package [io] or package [os], and those implementations should be preferred in new code. See the specific function documentation for details. (staticcheck) --- 46-46: Error return value of `e.Send` is not checked (errcheck) --- 49-49: SA1019: rand.Seed has been deprecated since Go 1.20 and an alternative has been available since Go 1.0: As of Go 1.20 there is no reason to call Seed with a random value. Programs that call Seed with a known value to get a specific sequence of results should use New(NewSource(seed)) to obtain a local random generator. (staticcheck) </details> <details> <summary>circle/main.go</summary> 87-87: Error return value of `r.Run` is not checked (errcheck) </details> </details> <details> <summary>🪛 LanguageTool</summary> <details> <summary>circle/api.md</summary> [uncategorized] ~3-~3: There should be a space after a closing quote. Context: ...务器:112.126.68.22:8080/… ## 除了前三个都要加请求头:”Authorization“(存储token) # 用户 /user/… ### 获取验证码 /get... (NO_SPACE_CLOSING_QUOTE) --- [typographical] ~353-~353: Two consecutive dots Context: ... | | answer | 答案(A/B/ABC/true/false..) | | explain | 解析 ... (DOUBLE_PUNCTUATION) --- [typographical] ~846-~846: Two consecutive dots Context: ...on { 多条test的信息 } ``` # 圈子 /circle/.. ### 创圈/createcircle POST Body:表单 |... (DOUBLE_PUNCTUATION) --- [typographical] ~960-~960: Two consecutive dots Context: ... "success":关注成功 } ``` # 搜索 /search/.. ### 搜索圈子/searchcircle POST Body:... (DOUBLE_PUNCTUATION) </details> </details> <details> <summary>🪛 markdownlint-cli2 (0.17.2)</summary> <details> <summary>circle/api.md</summary> 7-7: Heading levels should only increment by one level at a time Expected: h2; Actual: h3 (MD001, heading-increment) --- 341-341: Heading levels should only increment by one level at a time Expected: h2; Actual: h3 (MD001, heading-increment) --- 361-361: Hard tabs Column: 1 (MD010, no-hard-tabs) --- 380-380: Hard tabs Column: 1 (MD010, no-hard-tabs) --- 548-548: Heading levels should only increment by one level at a time Expected: h2; Actual: h3 (MD001, heading-increment) --- 566-566: Hard tabs Column: 1 (MD010, no-hard-tabs) --- 590-590: Hard tabs Column: 1 (MD010, no-hard-tabs) --- 610-610: Hard tabs Column: 1 (MD010, no-hard-tabs) --- 627-627: Hard tabs Column: 12 (MD010, no-hard-tabs) --- 628-628: Hard tabs Column: 1 (MD010, no-hard-tabs) --- 629-629: Hard tabs Column: 1 (MD010, no-hard-tabs) --- 630-630: Hard tabs Column: 1 (MD010, no-hard-tabs) --- 631-631: Hard tabs Column: 1 (MD010, no-hard-tabs) --- 632-632: Hard tabs Column: 1 (MD010, no-hard-tabs) --- 633-633: Hard tabs Column: 1 (MD010, no-hard-tabs) --- 634-634: Hard tabs Column: 1 (MD010, no-hard-tabs) --- 652-652: Hard tabs Column: 1 (MD010, no-hard-tabs) --- 652-652: Hard tabs Column: 18 (MD010, no-hard-tabs) --- 653-653: Hard tabs Column: 1 (MD010, no-hard-tabs) --- 654-654: Hard tabs Column: 1 (MD010, no-hard-tabs) --- 655-655: Hard tabs Column: 1 (MD010, no-hard-tabs) --- 656-656: Hard tabs Column: 1 (MD010, no-hard-tabs) --- 657-657: Hard tabs Column: 1 (MD010, no-hard-tabs) --- 658-658: Hard tabs Column: 1 (MD010, no-hard-tabs) --- 759-759: Multiple spaces after hash on atx style heading null (MD019, no-multiple-space-atx) --- 776-776: Multiple spaces after hash on atx style heading null (MD019, no-multiple-space-atx) --- 793-793: Multiple spaces after hash on atx style heading null (MD019, no-multiple-space-atx) --- 810-810: Multiple spaces after hash on atx style heading null (MD019, no-multiple-space-atx) --- 827-827: Multiple spaces after hash on atx style heading null (MD019, no-multiple-space-atx) --- 846-846: Trailing punctuation in heading Punctuation: '..' (MD026, no-trailing-punctuation) --- 848-848: Heading levels should only increment by one level at a time Expected: h2; Actual: h3 (MD001, heading-increment) --- 848-848: Multiple spaces after hash on atx style heading null (MD019, no-multiple-space-atx) --- 867-867: Multiple spaces after hash on atx style heading null (MD019, no-multiple-space-atx) --- 890-890: Multiple spaces after hash on atx style heading null (MD019, no-multiple-space-atx) --- 914-914: Multiple spaces after hash on atx style heading null (MD019, no-multiple-space-atx) --- 931-931: Multiple spaces after hash on atx style heading null (MD019, no-multiple-space-atx) --- 943-943: Multiple spaces after hash on atx style heading null (MD019, no-multiple-space-atx) --- 960-960: Trailing punctuation in heading Punctuation: '..' (MD026, no-trailing-punctuation) --- 962-962: Heading levels should only increment by one level at a time Expected: h2; Actual: h3 (MD001, heading-increment) --- 962-962: Multiple spaces after hash on atx style heading null (MD019, no-multiple-space-atx) --- 979-979: Multiple spaces after hash on atx style heading null (MD019, no-multiple-space-atx) --- 996-996: Multiple spaces after hash on atx style heading null (MD019, no-multiple-space-atx) --- 1013-1013: Multiple spaces after hash on atx style heading null (MD019, no-multiple-space-atx) --- 1027-1027: Multiple spaces after hash on atx style heading null (MD019, no-multiple-space-atx) </details> </details> </details> <details> <summary>🔇 Additional comments (21)</summary><blockquote> <details> <summary>circle/controllers/practice_contorllers.go (5)</summary> `6-6`: **DAO import looks appropriate.** No concerns. --- `8-8`: **Importing 'fmt' is acceptable.** No immediate issues. --- `42-58`: **Validate integer parsing for 'practiceid'.** Currently, `p, _ := strconv.Atoi(practiceid)` discards potential errors, possibly leading to an unintended default value (0). --- `71-84`: **Consistent error handling.** This function correctly checks for invalid input and DAO retrieval failures. --- `155-161`: **Add error handling for user ID retrieval and rank.** Check if `dao.GetIdByUser` or `dao.Showrank` fails and return appropriate feedback if needed. </details> <details> <summary>circle/controllers/test_contorllesrs.go (5)</summary> `6-6`: **DAO import is reasonable.** No issues noted. --- `103-112`: **Confirm 'practiceid' is valid.** Use robust error handling to avoid passing a bad ID to the DAO. --- `140-148`: **Proper error flow for top records.** This code gracefully checks for DAO errors. Nicely done. --- `167-176`: **Handle possible integer parse failure for 'testid'.** Prevent unexpected queries by validating user input. --- `190-194`: **Add error handling for 'HotTest'.** A fallback response is advisable if the DB query fails. </details> <details> <summary>circle/controllers/user_contorllers.go (10)</summary> `4-7`: **Updated import statements** The addition of `circle/dao`, `circle/models`, `circle/views`, and `encoding/base64` aligns with the refactor. --- `10-11`: **Usage of 'math/rand' and 'net/smtp'** Be mindful of changes to `rand` usage in Go 1.20. --- `13-15`: **Import synergy** No issues for `sync`, `time`, and `strconv`. --- `17-18`: **Third-party dependencies** Use of `github.com/gin-gonic/gin` and `github.com/jordan-wright/email` is acceptable. --- `71-100`: **Registration flow well-handled.** Existing user checks, name auto-generation, and DB error handling look solid. --- `173-194`: **Sufficient error-handling approach.** `Setphoto` properly checks for user query and update failures. --- `195-212`: **Good pattern for updating user description.** Errors are handled systematically. --- `213-226`: **Appropriate checks for invalid user IDs.** The function thoroughly verifies parameters. --- `241-247`: **Ensure 'GetHistoryTestByUserid' success.** If the DAO fails, the user remains uninformed. --- `255-264`: **Robust error handling for user retrieval.** If `dao.GetUserByName(name)` fails, the function properly returns an error. </details> <details> <summary>circle/dao/circle_dao.go (1)</summary> `6-8`: **LGTM! The CreateCircle implementation is correct.** The function properly uses GORM's Create method and handles errors appropriately. </details> </blockquote></details> </details> <!-- This is an auto-generated comment by CodeRabbit for review status -->
func Commentpractice(c *gin.Context) { | ||
practiceid := c.PostForm("practiceid") | ||
p, _ := strconv.Atoi(practiceid) | ||
content := c.PostForm("content") | ||
token := c.GetHeader("Authorization") | ||
name:=Username(token) | ||
comment:=models.PracticeComment{ | ||
Content:content, | ||
Practiceid:p, | ||
Name:name, | ||
} | ||
database.DB.Create(&comment) | ||
views.Success(c,"评论成功") | ||
name := Username(token) | ||
id,_:=dao.GetIdByUser(name) | ||
comment := models.PracticeComment{ | ||
Content: content, | ||
Practiceid: p, | ||
Userid: id, | ||
} | ||
err := dao.CreatePracticeComment(&comment) | ||
if err != nil { | ||
views.Fail(c, "评论失败") | ||
return | ||
} | ||
views.Success(c, "评论成功") | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Check errors for 'practiceid' and user retrieval.
Ignoring strconv.Atoi
and dao.GetIdByUser
errors can result in undefined behavior.
func Lovepractice(c *gin.Context) { | ||
practiceid := c.PostForm("practiceid") | ||
p, _ := strconv.Atoi(practiceid) | ||
practice := dao.GetPracticeByPracticeID(p) | ||
practice.Good++ | ||
_ = dao.UpdatePractice(&practice) | ||
views.Success(c, "点赞成功") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Check errors during 'lovepractice'.
Currently, the calls to dao.GetPracticeByPracticeID
and dao.UpdatePractice
are unchecked. Handle potential failures.
func Createpractice(c *gin.Context) { | ||
variety := c.PostForm("variety") | ||
difficulty := c.PostForm("difficulty") | ||
circle := c.PostForm("circle") | ||
imageurl := c.PostForm("imageurl") | ||
content := c.PostForm("content") | ||
answer := c.PostForm("answer") | ||
explain := c.PostForm("explain") | ||
token := c.GetHeader("Authorization") | ||
name := Username(token) | ||
id,_:=dao.GetIdByUser(name) | ||
practice := models.Practice{ | ||
Userid: id, | ||
Content: content, | ||
Difficulty: difficulty, | ||
Circle: circle, | ||
Answer: answer, | ||
Variety: variety, | ||
Imageurl: imageurl, | ||
Explain: explain, | ||
Good: 0, | ||
Status: "approved", // 待审核 | ||
} | ||
err := dao.CreatePractice(&practice) | ||
if err != nil { | ||
views.Fail(c, "创建练习失败") | ||
return | ||
} | ||
views.Showid(c, practice.Practiceid) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Handle potential errors when retrieving the user ID.
id,_ := dao.GetIdByUser(name)
drops the error. If the query fails or returns an invalid ID, the code proceeds regardless.
-id,_ := dao.GetIdByUser(name)
+id, err := dao.GetIdByUser(name)
+if err != nil {
+ views.Fail(c, "无法获取用户ID")
+ return
+}
📝 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.
func Createpractice(c *gin.Context) { | |
variety := c.PostForm("variety") | |
difficulty := c.PostForm("difficulty") | |
circle := c.PostForm("circle") | |
imageurl := c.PostForm("imageurl") | |
content := c.PostForm("content") | |
answer := c.PostForm("answer") | |
explain := c.PostForm("explain") | |
token := c.GetHeader("Authorization") | |
name := Username(token) | |
id,_:=dao.GetIdByUser(name) | |
practice := models.Practice{ | |
Userid: id, | |
Content: content, | |
Difficulty: difficulty, | |
Circle: circle, | |
Answer: answer, | |
Variety: variety, | |
Imageurl: imageurl, | |
Explain: explain, | |
Good: 0, | |
Status: "approved", // 待审核 | |
} | |
err := dao.CreatePractice(&practice) | |
if err != nil { | |
views.Fail(c, "创建练习失败") | |
return | |
} | |
views.Showid(c, practice.Practiceid) | |
} | |
func Createpractice(c *gin.Context) { | |
variety := c.PostForm("variety") | |
difficulty := c.PostForm("difficulty") | |
circle := c.PostForm("circle") | |
imageurl := c.PostForm("imageurl") | |
content := c.PostForm("content") | |
answer := c.PostForm("answer") | |
explain := c.PostForm("explain") | |
token := c.GetHeader("Authorization") | |
name := Username(token) | |
id, err := dao.GetIdByUser(name) | |
if err != nil { | |
views.Fail(c, "无法获取用户ID") | |
return | |
} | |
practice := models.Practice{ | |
Userid: id, | |
Content: content, | |
Difficulty: difficulty, | |
Circle: circle, | |
Answer: answer, | |
Variety: variety, | |
Imageurl: imageurl, | |
Explain: explain, | |
Good: 0, | |
Status: "approved", // 待审核 | |
} | |
err = dao.CreatePractice(&practice) | |
if err != nil { | |
views.Fail(c, "创建练习失败") | |
return | |
} | |
views.Showid(c, practice.Practiceid) | |
} |
name := Username(token) | ||
discription := c.PostForm("discription") | ||
circle := c.PostForm("circle") | ||
testname:=c.PostForm("testname") | ||
id,_:=dao.GetIdByUser(name) | ||
test := models.Test{ | ||
Userid: id, | ||
Testname: testname, | ||
Discription: discription, | ||
Circle: circle, | ||
Good: 0, | ||
Status: "approved", // 待审核 | ||
} | ||
id, err := dao.CreateTest(&test) | ||
if err != nil { | ||
views.Fail(c, "创建测试记录失败") | ||
return | ||
} | ||
views.Showid(c, id) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Avoid variable shadowing & handle user retrieval errors.
id, _ := dao.GetIdByUser(name)
can overshadow the id
used later. Also, you lose the chance to handle potential DAO errors.
func Gettest(c *gin.Context) { | ||
testid := c.PostForm("testid") | ||
p, _ := strconv.Atoi(testid) | ||
test, err := dao.GetTestByID(p) | ||
if err != nil { | ||
views.Fail(c, "获取测试信息失败") | ||
return | ||
} | ||
token := c.GetHeader("Authorization") | ||
name := Username(token) | ||
id,_:=dao.GetIdByUser(name) | ||
err = dao.RecordTestHistory(p, id) | ||
if err != nil { | ||
views.Fail(c, "记录测试历史失败") | ||
return | ||
} | ||
views.Showtest(c, test) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Ensure proper error handling for user retrieval.
id, _ := dao.GetIdByUser(name)
might fail, resulting in invalid test history records.
func UpdateTest(test *models.Test) error { | ||
return database.DB.Save(test).Error | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Add error handling for UpdateTest.
The function returns the error directly without wrapping it with context.
Apply this diff to improve error handling:
func UpdateTest(test *models.Test) error {
- return database.DB.Save(test).Error
+ if err := database.DB.Save(test).Error; err != nil {
+ return fmt.Errorf("更新测试失败: %w", err)
+ }
+ return nil
}
📝 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.
func UpdateTest(test *models.Test) error { | |
return database.DB.Save(test).Error | |
} | |
func UpdateTest(test *models.Test) error { | |
if err := database.DB.Save(test).Error; err != nil { | |
return fmt.Errorf("更新测试失败: %w", err) | |
} | |
return nil | |
} |
func GetTopByTestID(testid string) ([]models.Top, error) { | ||
var tops []models.Top | ||
err := database.DB.Order("correctnum desc, time asc"). | ||
Where("testid = ?", testid). | ||
Limit(10). | ||
Find(&tops).Error | ||
return tops, err | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Add error handling for GetTopByTestID.
The function returns the error directly without wrapping it with context.
Apply this diff to improve error handling:
func GetTopByTestID(testid string) ([]models.Top, error) {
var tops []models.Top
err := database.DB.Order("correctnum desc, time asc").
Where("testid = ?", testid).
Limit(10).
Find(&tops).Error
- return tops, err
+ if err != nil {
+ return nil, fmt.Errorf("获取排行榜失败: %w", err)
+ }
+ return tops, nil
}
📝 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.
func GetTopByTestID(testid string) ([]models.Top, error) { | |
var tops []models.Top | |
err := database.DB.Order("correctnum desc, time asc"). | |
Where("testid = ?", testid). | |
Limit(10). | |
Find(&tops).Error | |
return tops, err | |
} | |
func GetTopByTestID(testid string) ([]models.Top, error) { | |
var tops []models.Top | |
err := database.DB.Order("correctnum desc, time asc"). | |
Where("testid = ?", testid). | |
Limit(10). | |
Find(&tops).Error | |
if err != nil { | |
return nil, fmt.Errorf("获取排行榜失败: %w", err) | |
} | |
return tops, nil | |
} |
func CreateTestComment(comment *models.TestComment) error { | ||
return database.DB.Create(comment).Error | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Add error handling for CreateTestComment.
The function returns the error directly without wrapping it with context.
Apply this diff to improve error handling:
func CreateTestComment(comment *models.TestComment) error {
- return database.DB.Create(comment).Error
+ if err := database.DB.Create(comment).Error; err != nil {
+ return fmt.Errorf("创建测试评论失败: %w", err)
+ }
+ return nil
}
📝 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.
func CreateTestComment(comment *models.TestComment) error { | |
return database.DB.Create(comment).Error | |
} | |
func CreateTestComment(comment *models.TestComment) error { | |
if err := database.DB.Create(comment).Error; err != nil { | |
return fmt.Errorf("创建测试评论失败: %w", err) | |
} | |
return nil | |
} |
} | ||
``` | ||
|
||
七牛云token:0bNiwJGpdwmvvuVAzLDjM6gnxj9MiwmSagVpIW81:85DTubmQkSKtCyWaL5KoaucrQKU=:eyJkZWFkbGluZSI6MTczODU3NjI0MCwic2NvcGUiOiJtdXhpLW1pbmlwcm9qZWN0In0= |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove sensitive information from documentation.
The Qiniu Cloud token should not be exposed in public documentation.
Remove the token and provide instructions for obtaining it securely:
-七牛云token:0bNiwJGpdwmvvuVAzLDjM6gnxj9MiwmSagVpIW81:85DTubmQkSKtCyWaL5KoaucrQKU=:eyJkZWFkbGluZSI6MTczODU3NjI0MCwic2NvcGUiOiJtdXhpLW1pbmlwcm9qZWN0In0=
+# 七牛云配置
+请联系管理员获取七牛云token。不要在代码或文档中硬编码token。
📝 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.
七牛云token:0bNiwJGpdwmvvuVAzLDjM6gnxj9MiwmSagVpIW81:85DTubmQkSKtCyWaL5KoaucrQKU=:eyJkZWFkbGluZSI6MTczODU3NjI0MCwic2NvcGUiOiJtdXhpLW1pbmlwcm9qZWN0In0= | |
# 七牛云配置 | |
请联系管理员获取七牛云token。不要在代码或文档中硬编码token。 |
@@ -0,0 +1,1039 @@ | |||
## 我的服务器:112.126.68.22:8080/… | |||
|
|||
## 除了前三个都要加请求头:”Authorization“(存储token) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Improve authentication documentation.
The current description of authentication requirements is unclear.
Add more detailed authentication documentation:
-## 除了前三个都要加请求头:"Authorization"(存储token)
+## 认证
+所有API端点(除了获取验证码、确认验证码和注册)都需要在请求头中包含认证token:
+
+```
+Authorization: Bearer <your_token>
+```
+
+token通过登录API获取。token有效期为24小时。
📝 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.
## 除了前三个都要加请求头:”Authorization“(存储token) | |
## 认证 | |
所有API端点(除了获取验证码、确认验证码和注册)都需要在请求头中包含认证token: | |
🧰 Tools
🪛 LanguageTool
[uncategorized] ~3-~3: There should be a space after a closing quote.
Context: ...务器:112.126.68.22:8080/… ## 除了前三个都要加请求头:”Authorization“(存储token) # 用户 /user/… ### 获取验证码 /get...
(NO_SPACE_CLOSING_QUOTE)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
整体还行,但是不写swagger注释吗?测试比较费劲吧
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
可以用json标签获取的,全是form写起来有点费劲c.ShouldBindJSON(&struct)之类的方式,看起来也更清晰点
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Controller层直接操作dao层吗?不是不行,项目大了之后比较费劲,一般service层才回去处理具体逻辑,dao层通常只负责基本的curd
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
可以尝试写个身份验证的中间件,Authorization直接解析完然后把username之类的信息存到上下文去
circle/database/data.txt
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
酷,被我看到数据库账号密码了
rt
Summary by CodeRabbit
New Features
Documentation