feat(grpc): add gRPC server infrastructure and schedule sync service

Add gRPC server support with configurable TLS, environment-based settings, and Wire injection. Implement schedule synchronization service with task runner integration for external course data fetching.

- Add gRPC configuration with env var overrides (APP_GRPC_ENABLED, APP_GRPC_PORT, etc.)
- Create gRPC server infrastructure with runner task management
- Implement ScheduleSyncService for course data synchronization
- Add sync endpoint to schedule handler for external system integration
- Update repository with context-aware batch delete operation
- Wire all dependencies including zap logger for structured logging
This commit is contained in:
2026-03-13 20:40:20 +08:00
parent cf36b1350d
commit c561a0bb0c
20 changed files with 3241 additions and 5 deletions

View File

@@ -10,11 +10,15 @@ import (
)
type ScheduleHandler struct {
scheduleService service.ScheduleService
scheduleService service.ScheduleService
scheduleSyncService service.ScheduleSyncService
}
func NewScheduleHandler(scheduleService service.ScheduleService) *ScheduleHandler {
return &ScheduleHandler{scheduleService: scheduleService}
func NewScheduleHandler(scheduleService service.ScheduleService, scheduleSyncService service.ScheduleSyncService) *ScheduleHandler {
return &ScheduleHandler{
scheduleService: scheduleService,
scheduleSyncService: scheduleSyncService,
}
}
type createScheduleCourseRequest struct {
@@ -138,3 +142,42 @@ func (h *ScheduleHandler) DeleteCourse(c *gin.Context) {
}
response.SuccessWithMessage(c, "course deleted", nil)
}
// syncScheduleRequest 同步课表请求
type syncScheduleRequest struct {
Username string `json:"username" binding:"required"`
Password string `json:"password" binding:"required"`
Semester string `json:"semester"`
}
// SyncSchedule 同步课表接口
func (h *ScheduleHandler) SyncSchedule(c *gin.Context) {
userID := c.GetString("user_id")
if userID == "" {
response.Unauthorized(c, "")
return
}
var req syncScheduleRequest
if err := c.ShouldBindJSON(&req); err != nil {
response.BadRequest(c, "invalid request: "+err.Error())
return
}
result, err := h.scheduleSyncService.SyncUserSchedule(c.Request.Context(), userID, &service.SyncScheduleRequest{
Username: req.Username,
Password: req.Password,
Semester: req.Semester,
})
if err != nil {
response.HandleError(c, err, "failed to sync schedule")
return
}
if !result.Success {
response.Success(c, result)
return
}
response.SuccessWithMessage(c, result.Message, result)
}