Version:0.0.5.dev.260204
feat: 🏗️ 完成任务分类创建与列表查询接口并通过测试 - 历经复杂嵌套逻辑处理 🌀 - 实现创建任务分类接口 ✅ - 实现获取任务分类列表接口 📋 - 接口测试全部通过 🧪 perf: 🚀 下个版本将为任务分类列表接口加入 Redis 缓存以提升查询速度 ⚡
This commit is contained in:
120
backend/model/task-class.go
Normal file
120
backend/model/task-class.go
Normal file
@@ -0,0 +1,120 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"database/sql/driver"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"time"
|
||||
)
|
||||
|
||||
type TaskClass struct {
|
||||
//section 1
|
||||
ID int `gorm:"column:id;primaryKey;autoIncrement"`
|
||||
UserID *int `gorm:"column:user_id;index:idx_task_classes_user_id"`
|
||||
//section 2
|
||||
Name *string `gorm:"column:name;size:255"`
|
||||
Mode *string `gorm:"column:mode;type:enum('auto','manual')"`
|
||||
StartDate *time.Time `gorm:"column:start_date"`
|
||||
EndDate *time.Time `gorm:"column:end_date"`
|
||||
//section 3
|
||||
TotalSlots *int `gorm:"column:total_slots;comment:分配的总节数"`
|
||||
AllowFillerCourse *bool `gorm:"column:allow_filler_course;default:true"`
|
||||
Strategy *string `gorm:"column:strategy;type:enum('steady','rapid')"`
|
||||
ExcludedSlots *string `gorm:"column:excluded_slots;type:json;comment:不想要的时段切片"`
|
||||
}
|
||||
|
||||
// TableName 设定 TaskClass 的表名为 task_classes
|
||||
func (TaskClass) TableName() string {
|
||||
return "task_classes"
|
||||
}
|
||||
|
||||
type UserAddTaskClassRequest struct {
|
||||
Name string `json:"name" binding:"required"`
|
||||
StartDate string `json:"start_date" binding:"required"` // YYYY-MM-DD
|
||||
EndDate string `json:"end_date" binding:"required"` // YYYY-MM-DD
|
||||
Mode string `json:"mode" binding:"required,oneof=auto manual"`
|
||||
Config UserAddTaskClassConfig `json:"config" binding:"required"`
|
||||
Items []UserAddTaskClassItemRequest `json:"items" binding:"required"`
|
||||
}
|
||||
|
||||
type UserAddTaskClassConfig struct {
|
||||
TotalSlots int `json:"total_slots" binding:"required,min=1"`
|
||||
AllowFillerCourse bool `json:"allow_filler_course"`
|
||||
Strategy string `json:"strategy" binding:"required,oneof=steady rapid"`
|
||||
ExcludedSlots []int `json:"excluded_slots"`
|
||||
}
|
||||
|
||||
type UserAddTaskClassItemRequest struct {
|
||||
Order int `json:"order" binding:"required,min=1"`
|
||||
Content string `json:"content" binding:"required"`
|
||||
EmbeddedTime *TargetTime `json:"embedded_time"` // 例: 2025-12-22 1-2节; nil 表示未安排
|
||||
}
|
||||
|
||||
type TaskClassItem struct {
|
||||
//section 1
|
||||
ID int `gorm:"column:id;primaryKey;autoIncrement"`
|
||||
CategoryID *int `gorm:"column:category_id"` //对应 TaskClass 的 ID
|
||||
//section 2
|
||||
Order *int `gorm:"column:order"`
|
||||
Content *string `gorm:"column:content;type:text"`
|
||||
EmbeddedTime *TargetTime `gorm:"column:embedded_time;type:json;comment:目标时间{date,section_from,section_to}"`
|
||||
Status *int `gorm:"column:status;comment:1:未安排, 2:已应用"`
|
||||
}
|
||||
|
||||
type TargetTime struct {
|
||||
Date string `json:"date"` // 例: 2025-12-22
|
||||
SectionFrom int `json:"section_from"` // 起始节次
|
||||
SectionTo int `json:"section_to"` // 结束节次
|
||||
}
|
||||
|
||||
func (t *TargetTime) Value() (driver.Value, error) {
|
||||
if t == nil {
|
||||
return nil, nil
|
||||
}
|
||||
// 💡 关键:调用 json.Marshal 将结构体转为 []byte
|
||||
// 这样 GORM 就能把这一串 JSON 存进数据库的 text/json 字段了
|
||||
return json.Marshal(t)
|
||||
}
|
||||
|
||||
func (t *TargetTime) Scan(value any) error {
|
||||
if value == nil {
|
||||
// 如果数据库是 NULL,保持指针对应的对象为零值即可
|
||||
// 或者在业务层判断 nil
|
||||
return nil
|
||||
}
|
||||
|
||||
var data []byte
|
||||
switch v := value.(type) {
|
||||
case []byte:
|
||||
data = v
|
||||
case string:
|
||||
data = []byte(v)
|
||||
default:
|
||||
return fmt.Errorf("TargetTime: 不支持的扫描类型: %T", value)
|
||||
}
|
||||
|
||||
return json.Unmarshal(data, t)
|
||||
}
|
||||
|
||||
func (TaskClassItem) TableName() string {
|
||||
return "task_items"
|
||||
}
|
||||
|
||||
const (
|
||||
TaskItemStatusUnscheduled = 1
|
||||
TaskItemStatusApplied = 2
|
||||
)
|
||||
|
||||
type UserGetTaskClassesResponse struct {
|
||||
TaskClasses []TaskClassSummary `json:"task_classes"`
|
||||
}
|
||||
|
||||
type TaskClassSummary struct {
|
||||
ID int `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Mode string `json:"mode"`
|
||||
Strategy string `json:"strategy"`
|
||||
StartDate time.Time `json:"start_date"`
|
||||
EndDate time.Time `json:"end_date"`
|
||||
TotalSlots int `json:"total_slots"`
|
||||
}
|
||||
Reference in New Issue
Block a user