Skip to content

refactor: 重构项目#58

Open
Penryn wants to merge 1 commit intodevfrom
refactor
Open

refactor: 重构项目#58
Penryn wants to merge 1 commit intodevfrom
refactor

Conversation

@Penryn
Copy link
Copy Markdown
Collaborator

@Penryn Penryn commented Mar 3, 2026

No description provided.

- 提取 bootstrap 包,简化 main.go 入口
- 新增 model/dto.go 统一 DTO 类型
- 修复 pkg/extension 非法导入 internal 的问题
- 消除 init() 副作用,改为显式 Init() 调用
- 拆分 handler/admin、handler/user、service 大文件
- 文件名与功能语义对齐(export/statistics/preset/manage 等)
- 合并鉴权守卫到 auth.go,删除多余的 permission.go
- 重命名 userCenter→oauth、eventInfo→notify、redis→rate_limit
Copilot AI review requested due to automatic review settings March 3, 2026 14:38
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

该 PR 以“重构项目”为目标,将原本集中在 main.go、大型 handler/service 文件中的多职责逻辑进行拆分与模块化,推动启动流程收敛、DTO 统一、以及 admin/user 相关能力解耦,以便后续渐进式重构更易推进。

Changes:

  • 引入 internal/bootstrap,将时区/Gin 模式/日志/ID/Redis/OSS/数据库/插件/HTTP 引擎初始化从 main.go 拆分出来。
  • 将原本聚合在单文件中的 service/admin 与 handler/user 逻辑拆分为多个职责单一文件,并将部分 DTO 迁移到 internal/model
  • 调整插件管理器加载/执行接口为显式传入插件顺序,并将 Redis/OSS 客户端初始化从 init() 改为显式 Init()

Reviewed changes

Copilot reviewed 37 out of 39 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
pkg/extension/manager.go 插件加载/执行接口改为显式传入插件名列表,减少对全局配置耦合
main.go 启动流程收敛为 bootstrap 调用,简化入口职责
internal/bootstrap/*.go 新增启动初始化模块(timezone/gin/logger/id/redis/oss/db/crypto/plugins/http)
internal/pkg/redis/config.go Redis 客户端改为显式 Init() 初始化
internal/pkg/oss/cube.go OSS 客户端改为显式 Init() 初始化
internal/model/dto.go 新增 DTO(BaseConfig/QuestionConfig/QuestionList/QuestionSubmit 等)
internal/dao/question.go, internal/dao/option.go DTO 迁移后用类型别名保持向后兼容
internal/service/* service 拆分(oauth/notify/admin_* 等),提交后触发通知插件
internal/handler/user/* user handler 从单文件拆分为 survey/submit/stat/oauth/answer/upload 等
internal/handler/admin/* admin handler 拆分新增 answer/export/preset/statistics,并抽取鉴权辅助函数
.github/skills/refactor-guide/SKILL.md 新增仓库重构指导文档
Comments suppressed due to low confidence (1)

internal/service/rate_limit.go:22

  • *gin.Context does not implement context.Context, but go-redis methods (e.g. RedisClient.Get/Set/Incr) require a context.Context. Passing c here will not compile. Consider using ctx := c.Request.Context() (or accept a context.Context parameter) and pass that to Redis, while keeping the *gin.Context only where HTTP-specific data is needed.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +139 to +140
fileName := survey.Title + ".xlsx"
filePath := "./public/xlsx/"
Copy link

Copilot AI Mar 3, 2026

Choose a reason for hiding this comment

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

Same filename issue here: survey.Title is used directly for the exported file name, which can allow path traversal or invalid filenames. Please sanitize/normalize the title (or use a safe generated name) before writing to disk and generating the URL.

Copilot uses AI. Check for mistakes.
Comment on lines +39 to +42
options, err := GetOptionsByQuestionID(question.ID)
if err != nil {
log.Println("Error fetching options for questionID:", question.ID)
continue
Copy link

Copilot AI Mar 3, 2026

Choose a reason for hiding this comment

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

This service uses the standard library log.Println, while the rest of the service layer appears to use structured zap logging (e.g. zap.L().Warn/Error). Using zap here would keep logs consistent and preserve fields (questionID, error) for filtering and observability.

Copilot uses AI. Check for mistakes.
Comment on lines +74 to +80
colName, err := excelize.ColumnNumberToName(j + 3)
if err != nil {
return "", errors.New("转换列名失败原因: " + err.Error())
}
if err := f.SetCellValue("Sheet1", colName+strconv.Itoa(i+2), answer); err != nil {
return "", errors.New("写入数据失败原因: " + err.Error())
}
Copy link

Copilot AI Mar 3, 2026

Choose a reason for hiding this comment

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

This mixes StreamWriter mode (NewStreamWriter/SetRow) with regular cell APIs (f.SetCellValue). In excelize, once a StreamWriter is used for a sheet, writing via the normal APIs can error or produce a corrupted file. Pick one approach: either build the full row and only call streamWriter.SetRow, or drop StreamWriter and use SetCellValue throughout.

Copilot uses AI. Check for mistakes.
Comment on lines +91 to +92
fileName := survey.Title + ".xlsx"
filePath := "./public/xlsx/" + fileName
Copy link

Copilot AI Mar 3, 2026

Choose a reason for hiding this comment

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

survey.Title is used directly as part of the filename. Since titles are user-controlled, this can lead to path traversal (e.g. ../...) or invalid filenames on some OSes. Please sanitize/normalize the title into a safe filename (strip path separators, trim length, fall back to survey ID, etc.) before building filePath.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants