🚀 AI 近视防控系统 - 生产环境上线版本 v1.0

 已完成功能:
- 后端 Go 服务 (认证/授权/检测)
- JWT 认证 + RBAC 权限控制
- 登录速率限制 (5 次失败锁定 15 分钟)
- 密码强度校验
- 敏感数据脱敏
- Vue3 管理后台
- 路由守卫
- 删除二次确认

📦 部署配置:
- Docker Compose 生产环境配置
- MySQL/Redis/MongoDB 数据库
- Nginx 前端服务
- 强密码安全配置

⚠️ P2 待办 (下次迭代):
- 学生/检测/预警等业务模块实现
- 错误处理统一化
- 缓存策略优化
- 日志分级

📍 生产环境:
- 服务器:192.168.15.222
- 管理后台:http://192.168.15.222:8081
- API 服务:http://192.168.15.222:8080

2026-03-29 上线部署完成
This commit is contained in:
虾司令
2026-03-29 18:16:41 +08:00
commit 881144269c
38 changed files with 4967 additions and 0 deletions

122
db/models/alert.go Normal file
View File

@@ -0,0 +1,122 @@
package models
import (
"time"
)
// Alert 预警记录模型
type Alert struct {
ID uint `gorm:"primaryKey" json:"id"`
StudentID uint `json:"student_id"`
Student Student `gorm:"foreignKey:StudentID" json:"student"`
DetectionID *uint `json:"detection_id"`
Detection *Detection `gorm:"foreignKey:DetectionID" json:"detection"`
AlertLevel int `json:"alert_level"` // 1:关注, 2:预警, 3:告警
AlertType string `gorm:"type:varchar(32)" json:"alert_type"` // vision_drop, fatigue_high, abnormal
AlertContent string `gorm:"type:text" json:"alert_content"`
Status int `gorm:"default:0" json:"status"` // 0:未处理, 1:已通知, 2:已处理
NotifiedAt *time.Time `json:"notified_at"`
HandledAt *time.Time `json:"handled_at"`
HandlerID *uint `json:"handler_id"` // 处理人ID
HandleRemark string `gorm:"type:text" json:"handle_remark"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
// AlertConfig 预警配置模型
type AlertConfig struct {
ID uint `gorm:"primaryKey" json:"id"`
SchoolID *uint `json:"school_id"`
School *School `gorm:"foreignKey:SchoolID" json:"school"`
AlertLevel int `json:"alert_level"` // 1:关注, 2:预警, 3:告警
VisionThreshold float64 `json:"vision_threshold"` // 视力阈值
DropThreshold float64 `json:"drop_threshold"` // 下降幅度阈值
NotifyParent bool `gorm:"default:true" json:"notify_parent"` // 通知家长
NotifyTeacher bool `gorm:"default:true" json:"notify_teacher"` // 通知老师
NotifySchoolDoctor bool `gorm:"default:false" json:"notify_school_doctor"` // 通知校医
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
// AlertSummary 预警摘要
type AlertSummary struct {
ID uint `gorm:"primaryKey" json:"id"`
EntityID uint `json:"entity_id"` // 学生/班级/学校的ID
EntityType string `gorm:"type:varchar(20)" json:"entity_type"` // student, class, school
TotalAlerts int `json:"total_alerts"`
HighRiskCount int `json:"high_risk_count"` // 高风险数量
MediumRiskCount int `json:"medium_risk_count"` // 中风险数量
LowRiskCount int `json:"low_risk_count"` // 低风险数量
LastAlertDate *time.Time `json:"last_alert_date"`
LastAlertType string `gorm:"type:varchar(32)" json:"last_alert_type"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
// AlertNotification 预警通知模型
type AlertNotification struct {
ID uint `gorm:"primaryKey" json:"id"`
AlertID uint `json:"alert_id"`
Alert Alert `gorm:"foreignKey:AlertID" json:"alert"`
RecipientID uint `json:"recipient_id"` // 接收者ID
RecipientType string `gorm:"type:varchar(20)" json:"recipient_type"` // parent, teacher, school_doctor
Channel string `gorm:"type:varchar(20)" json:"channel"` // sms, email, app_push
Title string `gorm:"type:varchar(255)" json:"title"`
Content string `gorm:"type:text" json:"content"`
SentAt time.Time `json:"sent_at"`
ReadAt *time.Time `json:"read_at"`
Status int `gorm:"default:0" json:"status"` // 0:待发送, 1:已发送, 2:已读
CreatedAt time.Time `json:"created_at"`
}
// AlertDistribution 预警分布统计
type AlertDistribution struct {
ID uint `gorm:"primaryKey" json:"id"`
Date time.Time `json:"date"`
EntityType string `gorm:"type:varchar(20)" json:"entity_type"` // student, class, school
EntityID uint `json:"entity_id"`
GreenCount int `json:"green_count"` // 绿色预警数量
YellowCount int `json:"yellow_count"` // 黄色预警数量
OrangeCount int `json:"orange_count"` // 橙色预警数量
RedCount int `json:"red_count"` // 红色预警数量
CreatedAt time.Time `json:"created_at"`
}
// VisionDistribution 视力分布统计
type VisionDistribution struct {
ID uint `gorm:"primaryKey" json:"id"`
Date time.Time `json:"date"`
EntityType string `gorm:"type:varchar(20)" json:"entity_type"` // student, class, school
EntityID uint `json:"entity_id"`
NormalCount int `json:"normal_count"` // 正常人数
MildMyopiaCount int `json:"mild_myopia_count"` // 轻度近视人数
ModerateMyopiaCount int `json:"moderate_myopia_count"` // 中度近视人数
SevereMyopiaCount int `json:"severe_myopia_count"` // 高度近视人数
CreatedAt time.Time `json:"created_at"`
}
// JSONMap 自定义JSON类型已在其他模型中定义这里引用
// 为避免重复定义,我们可以将其移到公共包中
// AlertType 预警类型枚举
const (
AlertTypeVisionDrop = "vision_drop" // 视力下降
AlertTypeFatigueHigh = "fatigue_high" // 疲劳度过高
AlertTypeAbnormalBehavior = "abnormal_behavior" // 异常行为
AlertTypeDeviceError = "device_error" // 设备异常
)
// AlertLevel 预警级别枚举
const (
AlertLevelGreen = 0 // 正常
AlertLevelYellow = 1 // 关注
AlertLevelOrange = 2 // 预警
AlertLevelRed = 3 // 告警
)
// AlertStatus 预警状态枚举
const (
AlertStatusUnhandled = 0 // 未处理
AlertStatusNotified = 1 // 已通知
AlertStatusHandled = 2 // 已处理
)

130
db/models/detection.go Normal file
View File

@@ -0,0 +1,130 @@
package models
import (
"database/sql/driver"
"encoding/json"
"errors"
"time"
)
// DetectionTask 检测任务模型
type DetectionTask struct {
ID uint `gorm:"primaryKey" json:"id"`
TaskNo string `gorm:"type:varchar(32);uniqueIndex" json:"task_no"`
ClassID uint `json:"class_id"`
TeacherID uint `json:"teacher_id"`
StartTime time.Time `json:"start_time"`
EndTime *time.Time `json:"end_time"`
StudentCount int `json:"student_count"`
DetectionType string `gorm:"type:varchar(32)" json:"detection_type"`
Status int `gorm:"default:0" json:"status"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
// Detection 检测记录模型
type Detection struct {
ID uint `gorm:"primaryKey" json:"id"`
TaskID uint `json:"task_id"`
StudentID uint `json:"student_id"`
DetectionTime time.Time `json:"detection_time"`
VisionLeft float64 `json:"vision_left"`
VisionRight float64 `json:"vision_right"`
FatigueScore float64 `json:"fatigue_score"`
AlertLevel int `gorm:"default:0" json:"alert_level"`
DeviceID *uint `json:"device_id"`
RawDataURL string `gorm:"type:text" json:"raw_data_url"`
AIAnalysis JSONMap `gorm:"type:json" json:"ai_analysis"`
Status int `gorm:"default:1" json:"status"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
// DetectionReport 检测报告
type DetectionReport struct {
ID uint `gorm:"primaryKey" json:"id"`
StudentID uint `json:"student_id"`
DetectionID uint `json:"detection_id"`
VisionLeft float64 `gorm:"column:vision_left" json:"vision_left"`
VisionRight float64 `gorm:"column:vision_right" json:"vision_right"`
LeftEyeX float64 `gorm:"column:left_eye_x" json:"left_eye_x"`
LeftEyeY float64 `gorm:"column:left_eye_y" json:"left_eye_y"`
RightEyeX float64 `gorm:"column:right_eye_x" json:"right_eye_x"`
RightEyeY float64 `gorm:"column:right_eye_y" json:"right_eye_y"`
GazePointX float64 `gorm:"column:gaze_point_x" json:"gaze_point_x"`
GazePointY float64 `gorm:"column:gaze_point_y" json:"gaze_point_y"`
FatigueScore float64 `json:"fatigue_score"`
AlertLevel string `gorm:"type:varchar(16)" json:"alert_level"`
AIAnalysis JSONMap `gorm:"type:json" json:"ai_analysis"`
CreatedAt time.Time `json:"created_at"`
}
// VisionData 视力数据 (简化)
type VisionData struct {
VisionLeft float64 `gorm:"-" json:"vision_left"`
VisionRight float64 `gorm:"-" json:"vision_right"`
Confidence string `gorm:"-" json:"confidence"`
}
// EyeMovementData 眼动数据 (简化)
type EyeMovementData struct {
LeftEyeX float64 `gorm:"-" json:"left_eye_x"`
LeftEyeY float64 `gorm:"-" json:"left_eye_y"`
RightEyeX float64 `gorm:"-" json:"right_eye_x"`
RightEyeY float64 `gorm:"-" json:"right_eye_y"`
Timestamp int64 `gorm:"-" json:"timestamp"`
}
// ResponseData 响应数据
type ResponseData struct {
Accuracy float64 `gorm:"-" json:"accuracy"`
ResponseType float64 `gorm:"-" json:"response_time"`
Errors int `gorm:"-" json:"errors"`
}
// JSONMap 自定义 JSON 类型
type JSONMap map[string]interface{}
func (j JSONMap) Value() (driver.Value, error) {
if len(j) == 0 {
return nil, nil
}
return json.Marshal(j)
}
func (j *JSONMap) Scan(value interface{}) error {
if value == nil {
*j = make(JSONMap)
return nil
}
data, ok := value.([]byte)
if !ok {
return errors.New("type assertion to []byte failed")
}
return json.Unmarshal(data, j)
}
// DetectionHistory 检测历史
type DetectionHistory struct {
ID uint `gorm:"primaryKey" json:"id"`
StudentID uint `json:"student_id"`
ClassID uint `json:"class_id"`
VisionLeft float64 `json:"vision_left"`
VisionRight float64 `json:"vision_right"`
FatigueScore float64 `json:"fatigue_score"`
AlertLevel string `gorm:"type:varchar(16)" json:"alert_level"`
DetectionTime time.Time `json:"detection_time"`
CreatedAt time.Time `json:"created_at"`
}
// VisionChangeTrend 视力变化趋势
type VisionChangeTrend struct {
ID uint `gorm:"primaryKey" json:"id"`
StudentID uint `json:"student_id"`
VisionLeft float64 `json:"vision_left"`
VisionRight float64 `json:"vision_right"`
ChangeValue float64 `json:"change_value"`
Trend string `gorm:"type:varchar(16)" json:"trend"`
RecordedAt time.Time `json:"recorded_at"`
CreatedAt time.Time `json:"created_at"`
}

182
db/models/device.go Normal file
View File

@@ -0,0 +1,182 @@
package models
import (
"time"
)
// Device 设备模型
type Device struct {
ID uint `gorm:"primaryKey" json:"id"`
DeviceNo string `gorm:"type:varchar(64);uniqueIndex" json:"device_no"`
DeviceName string `gorm:"type:varchar(128)" json:"device_name"`
DeviceType string `gorm:"type:varchar(32)" json:"device_type"` // terminal, camera, edge_box, gateway
SchoolID *uint `json:"school_id"`
School *School `gorm:"foreignKey:SchoolID" json:"school"`
ClassID *uint `json:"class_id"`
Class *Class `gorm:"foreignKey:ClassID" json:"class"`
IPAddress string `gorm:"type:varchar(45)" json:"ip_address"`
MacAddress string `gorm:"type:varchar(32)" json:"mac_address"`
Status int `json:"status"` // 0:离线, 1:在线, 2:故障, 3:维护中
LastHeartbeat *time.Time `json:"last_heartbeat"`
FirmwareVersion string `gorm:"type:varchar(32)" json:"firmware_version"`
ConfigVersion int `json:"config_version"`
Attributes JSONMap `gorm:"type:json" json:"attributes"` // 设备属性
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
// 关联的设备日志
DeviceLogs []DeviceLog `gorm:"foreignKey:DeviceID" json:"device_logs"`
}
// DeviceConfig 设备配置模型
type DeviceConfig struct {
ID uint `gorm:"primaryKey" json:"id"`
DeviceID uint `json:"device_id"`
Device Device `gorm:"foreignKey:DeviceID" json:"device"`
Settings JSONMap `gorm:"type:json" json:"settings"` // 配置项
Version int `json:"version"` // 配置版本
UpdatedAt time.Time `json:"updated_at"`
}
// DeviceLog 设备日志模型
type DeviceLog struct {
ID uint `gorm:"primaryKey" json:"id"`
DeviceID uint `json:"device_id"`
Device Device `gorm:"foreignKey:DeviceID" json:"device"`
LogType string `gorm:"type:varchar(32)" json:"log_type"` // status, command, error
Content JSONMap `gorm:"type:json" json:"content"` // 日志内容
CreatedAt time.Time `json:"created_at"`
}
// DeviceStatusInfo 设备状态信息模型
type DeviceStatusInfo struct {
ID uint `gorm:"primaryKey" json:"id"`
DeviceID uint `json:"device_id"`
Device Device `gorm:"foreignKey:DeviceID" json:"device"`
Status int `json:"status"` // 0:离线, 1:在线, 2:故障, 3:维护中
CPUUsage float64 `json:"cpu_usage"`
MemoryUsage float64 `json:"memory_usage"`
DiskUsage float64 `json:"disk_usage"`
NetworkStatus string `gorm:"type:varchar(32)" json:"network_status"`
CameraStatus string `gorm:"type:varchar(32)" json:"camera_status"`
Temperature float64 `json:"temperature"`
FirmwareVersion string `gorm:"type:varchar(32)" json:"firmware_version"`
HealthInfo JSONMap `gorm:"type:json" json:"health_info"` // 健康信息
ReportedAt time.Time `json:"reported_at"`
}
// DeviceCommand 设备指令模型
type DeviceCommand struct {
ID uint `gorm:"primaryKey" json:"id"`
DeviceID uint `json:"device_id"`
Device Device `gorm:"foreignKey:DeviceID" json:"device"`
CommandType string `gorm:"type:varchar(64)" json:"command_type"`
Params JSONMap `gorm:"type:json" json:"params"` // 参数
Timeout int `json:"timeout"` // 超时时间
CreatedAt time.Time `json:"created_at"`
ExecutedAt *time.Time `json:"executed_at"`
ExecutionResult string `gorm:"type:text" json:"execution_result"` // 执行结果
Status int `json:"status"` // 0:待执行, 1:执行中, 2:成功, 3:失败
}
// DeviceMessage 设备消息模型
type DeviceMessage struct {
ID uint `gorm:"primaryKey" json:"id"`
DeviceID uint `json:"device_id"`
Device Device `gorm:"foreignKey:DeviceID" json:"device"`
MessageType string `gorm:"type:varchar(32)" json:"message_type"` // detection.data, device.status, device.command
Header JSONMap `gorm:"type:json" json:"header"` // 消息头
Payload JSONMap `gorm:"type:json" json:"payload"` // 消息体
Signature string `gorm:"type:varchar(255)" json:"signature"` // 签名
CreatedAt time.Time `json:"created_at"`
}
// DeviceHeartbeat 设备心跳模型
type DeviceHeartbeat struct {
ID uint `gorm:"primaryKey" json:"id"`
DeviceID uint `json:"device_id"`
Device Device `gorm:"foreignKey:DeviceID" json:"device"`
IPAddress string `gorm:"type:varchar(45)" json:"ip_address"`
LastSeen time.Time `json:"last_seen"`
Status int `json:"status"` // 0:离线, 1:在线
}
// DeviceGroup 设备分组模型
type DeviceGroup struct {
ID uint `gorm:"primaryKey" json:"id"`
Name string `gorm:"type:varchar(128)" json:"name"`
Type string `gorm:"type:varchar(32)" json:"type"` // classroom, school, campus
EntityID uint `json:"entity_id"` // 关联的学校或班级ID
Entity string `gorm:"type:varchar(32)" json:"entity"` // school, class
Description string `gorm:"type:text" json:"description"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
// 关联的设备
Devices []Device `gorm:"many2many:device_group_relations;" json:"devices"`
}
// DeviceGroupRelation 设备与分组关联模型
type DeviceGroupRelation struct {
ID uint `gorm:"primaryKey" json:"id"`
DeviceID uint `json:"device_id"`
GroupID uint `json:"group_id"`
CreatedAt time.Time `json:"created_at"`
}
// DeviceMaintenance 设备维护模型
type DeviceMaintenance struct {
ID uint `gorm:"primaryKey" json:"id"`
DeviceID uint `json:"device_id"`
Device Device `gorm:"foreignKey:DeviceID" json:"device"`
Type string `gorm:"type:varchar(32)" json:"type"` // repair, upgrade, calibration
Description string `gorm:"type:text" json:"description"`
StartedAt time.Time `json:"started_at"`
EndedAt *time.Time `json:"ended_at"`
Status int `json:"status"` // 0:待处理, 1:进行中, 2:已完成, 3:已取消
Technician string `gorm:"type:varchar(64)" json:"technician"`
Notes string `gorm:"type:text" json:"notes"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
// DeviceType 设备类型枚举
const (
DeviceTypeTerminal = "terminal" // 终端设备(触摸屏一体机)
DeviceTypeCamera = "camera" // 摄像头
DeviceTypeEdgeBox = "edge_box" // 边缘计算盒子
DeviceTypeGateway = "gateway" // 网关设备
)
// DeviceStatus 设备状态枚举
const (
DeviceStatusOffline = 0 // 离线
DeviceStatusOnline = 1 // 在线
DeviceStatusFault = 2 // 故障
DeviceStatusMaintenance = 3 // 维护中
)
// DeviceMessageType 设备消息类型枚举
const (
DeviceMessageTypeStatus = "device.status" // 设备状态
DeviceMessageTypeCommand = "device.command" // 控制指令
DeviceMessageTypeDetection = "detection.data" // 检测数据
DeviceMessageTypeAlert = "alert" // 预警事件
DeviceMessageTypeConfig = "config" // 配置更新
DeviceMessageTypeHeartbeat = "heartbeat" // 心跳上报
)
// DeviceCommandStatus 指令状态枚举
const (
DeviceCommandStatusPending = 0 // 待执行
DeviceCommandStatusExecuting = 1 // 执行中
DeviceCommandStatusSuccess = 2 // 成功
DeviceCommandStatusFailed = 3 // 失败
)
// DeviceMaintenanceType 维护类型枚举
const (
DeviceMaintenanceTypeRepair = "repair" // 维修
DeviceMaintenanceTypeUpgrade = "upgrade" // 升级
DeviceMaintenanceTypeCalibration = "calibration" // 校准
)

156
db/models/training.go Normal file
View File

@@ -0,0 +1,156 @@
package models
import (
"time"
)
// TrainingContent 训练内容模型
type TrainingContent struct {
ID uint `gorm:"primaryKey" json:"id"`
Name string `gorm:"type:varchar(128)" json:"name"`
Type string `gorm:"type:varchar(32)" json:"type"` // eye_exercise, crystal_ball, acupoint, relax
Duration int `json:"duration"` // 时长 (秒)
VideoURL string `gorm:"type:text" json:"video_url"`
ThumbnailURL string `gorm:"type:text" json:"thumbnail_url"`
Description string `gorm:"type:text" json:"description"`
Difficulty int `gorm:"default:1" json:"difficulty"` // 1-5
Status int `gorm:"default:1" json:"status"` // 1:启用, 0:禁用
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
// 关联的训练任务
TrainingTasks []TrainingTask `gorm:"foreignKey:ContentID" json:"training_tasks"`
}
// TrainingTask 训练任务模型
type TrainingTask struct {
ID uint `gorm:"primaryKey" json:"id"`
StudentID uint `json:"student_id"`
Student Student `gorm:"foreignKey:StudentID" json:"student"`
ContentID uint `json:"content_id"`
Content TrainingContent `gorm:"foreignKey:ContentID" json:"content"`
ScheduledDate time.Time `json:"scheduled_date"`
ScheduledTime *time.Time `json:"scheduled_time"`
Status int `json:"status"` // 0:待完成, 1:已完成, 2:已跳过
CompletedAt *time.Time `json:"completed_at"`
Score *int `json:"score"` // 动作评分
PointsEarned int `json:"points_earned"` // 获得积分
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
// 关联的训练记录
TrainingRecords []TrainingRecord `gorm:"foreignKey:TaskID" json:"training_records"`
}
// TrainingRecord 训练记录模型
type TrainingRecord struct {
ID uint `gorm:"primaryKey" json:"id"`
StudentID uint `json:"student_id"`
Student Student `gorm:"foreignKey:StudentID" json:"student"`
TaskID uint `json:"task_id"`
Task TrainingTask `gorm:"foreignKey:TaskID" json:"task"`
ContentID uint `json:"content_id"`
Content TrainingContent `gorm:"foreignKey:ContentID" json:"content"`
Score int `json:"score"` // 动作评分
Accuracy float64 `json:"accuracy"` // 准确率
Duration float64 `json:"duration"` // 实际用时
PerformanceMetrics JSONMap `gorm:"type:json" json:"performance_metrics"` // 性能指标
Feedback string `gorm:"type:text" json:"feedback"` // 反馈信息
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
// TrainingPerformance 训练表现统计
type TrainingPerformance struct {
ID uint `gorm:"primaryKey" json:"id"`
EntityID uint `json:"entity_id"` // 学生/班级/学校ID
EntityType string `gorm:"type:varchar(20)" json:"entity_type"` // student, class, school
CompletionRate float64 `json:"completion_rate"` // 完成率
AverageScore float64 `json:"average_score"` // 平均分数
TotalTrainingCount int `json:"total_training_count"` // 总训练次数
EngagementRate float64 `json:"engagement_rate"` // 参与率
ImprovementRate float64 `json:"improvement_rate"` // 改善率
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
// UserPoints 用户积分模型
type UserPoints struct {
ID uint `gorm:"primaryKey" json:"id"`
UserID uint `json:"user_id"`
UserType string `gorm:"type:varchar(16)" json:"user_type"` // student, parent, teacher
TotalPoints int `gorm:"default:0" json:"total_points"`
UsedPoints int `gorm:"default:0" json:"used_points"`
Level string `gorm:"type:varchar(32);default:'bronze'" json:"level"` // bronze, silver, gold, diamond
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
// 关联的积分流水
}
// PointTransaction 积分流水模型
type PointTransaction struct {
ID uint `gorm:"primaryKey" json:"id"`
UserID uint `json:"user_id"`
UserType string `gorm:"type:varchar(16)" json:"user_type"`
ChangeType string `gorm:"type:varchar(32)" json:"change_type"` // earn, use
Points int `json:"points"` // 变化积分数
BalanceAfter int `json:"balance_after"` // 变化后的余额
Source string `gorm:"type:varchar(64)" json:"source"` // 来源: training, detection, activity
Description string `gorm:"type:varchar(256)" json:"description"`
CreatedAt time.Time `json:"created_at"`
}
// TrainingRecommendation 训练建议模型
type TrainingRecommendation struct {
ID uint `gorm:"primaryKey" json:"id"`
StudentID uint `json:"student_id"`
Student Student `gorm:"foreignKey:StudentID" json:"student"`
Recommendation string `gorm:"type:text" json:"recommendation"`
Priority int `json:"priority"` // 优先级: 1-5
ValidFrom time.Time `json:"valid_from"`
ValidUntil time.Time `json:"valid_until"`
IsApplied bool `json:"is_applied"` // 是否已采纳
AppliedAt *time.Time `json:"applied_at"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
// TrainingType 训练类型枚举
const (
TrainingTypeEyeExercise = "eye_exercise" // 眼保健操
TrainingTypeCrystalBall = "crystal_ball" // 晶状体调焦训练
TrainingTypeAcupoint = "acupoint" // 穴位按摩
TrainingTypeRelax = "relax" // 放松训练
)
// TrainingStatus 训练状态枚举
const (
TrainingStatusPending = 0 // 待完成
TrainingStatusDone = 1 // 已完成
TrainingStatusSkipped = 2 // 已跳过
)
// PointsChangeType 积分变化类型枚举
const (
PointsChangeTypeEarn = "earn" // 获得
PointsChangeTypeUse = "use" // 使用
)
// PointsSource 积分来源枚举
const (
PointsSourceTraining = "training" // 训练获得
PointsSourceDetection = "detection" // 检测获得
PointsSourceActivity = "activity" // 活动获得
PointsSourceAttendance = "attendance" // 出勤获得
PointsSourceAchievement = "achievement" // 成就获得
)
// UserLevel 用户等级枚举
const (
UserLevelBronze = "bronze" // 青铜
UserLevelSilver = "silver" // 白银
UserLevelGold = "gold" // 黄金
UserLevelDiamond = "diamond" // 钻石
)

127
db/models/user.go Normal file
View File

@@ -0,0 +1,127 @@
package models
import (
"time"
)
// User 通用用户模型
type User struct {
ID uint `gorm:"primaryKey" json:"id"`
UUID string `gorm:"type:varchar(64);uniqueIndex" json:"uuid"`
Name string `gorm:"type:varchar(64)" json:"name"`
Username string `gorm:"type:varchar(64);uniqueIndex" json:"username"`
Phone string `gorm:"type:varchar(20);uniqueIndex" json:"phone"`
Password string `gorm:"type:varchar(255)" json:"-"` // 不返回密码
Role string `gorm:"type:varchar(20)" json:"role"` // student, parent, teacher, admin
Status int `gorm:"default:1" json:"status"` // 1:正常, 0:禁用
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
// Student 学生模型
type Student struct {
ID uint `gorm:"primaryKey" json:"id"`
StudentNo string `gorm:"type:varchar(32);uniqueIndex" json:"student_no"`
Name string `gorm:"type:varchar(64)" json:"name"`
Gender int `gorm:"default:1" json:"gender"` // 1:男, 2:女
BirthDate *time.Time `json:"birth_date"`
ClassID uint `json:"class_id"`
Class Class `gorm:"foreignKey:ClassID" json:"class"`
ParentID *uint `json:"parent_id"` // 关联家长
Status int `gorm:"default:1" json:"status"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
// Parent 家长模型
type Parent struct {
ID uint `gorm:"primaryKey" json:"id"`
Name string `gorm:"type:varchar(64)" json:"name"`
Phone string `gorm:"type:varchar(20);uniqueIndex" json:"phone"`
IDCard string `gorm:"type:varchar(32)" json:"id_card"`
Status int `gorm:"default:1" json:"status"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
// 关联的学生
}
// Teacher 教师模型
type Teacher struct {
ID uint `gorm:"primaryKey" json:"id"`
Name string `gorm:"type:varchar(64)" json:"name"`
Phone string `gorm:"type:varchar(20);uniqueIndex" json:"phone"`
SchoolID uint `json:"school_id"`
School School `gorm:"foreignKey:SchoolID" json:"school"`
Role string `gorm:"type:varchar(32)" json:"role"` // homeroom, school_doctor, sports
Status int `gorm:"default:1" json:"status"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
// 所带班级
ClassIDs []byte `gorm:"type:json" json:"class_ids"` // JSON格式存储班级ID数组
}
// School 学校模型
type School struct {
ID uint `gorm:"primaryKey" json:"id"`
Name string `gorm:"type:varchar(128)" json:"name"`
Code string `gorm:"type:varchar(32);uniqueIndex" json:"code"`
Address string `gorm:"type:varchar(256)" json:"address"`
ContactName string `gorm:"type:varchar(64)" json:"contact_name"`
ContactPhone string `gorm:"type:varchar(20)" json:"contact_phone"`
Status int `gorm:"default:1" json:"status"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
// 关联的班级和教师
Classes []Class `gorm:"foreignKey:SchoolID" json:"classes"`
Teachers []Teacher `gorm:"foreignKey:SchoolID" json:"teachers"`
}
// Class 班级模型
type Class struct {
ID uint `gorm:"primaryKey" json:"id"`
Name string `gorm:"type:varchar(64)" json:"name"`
Grade string `gorm:"type:varchar(16)" json:"grade"` // 年级
SchoolID uint `json:"school_id"`
School School `gorm:"foreignKey:SchoolID" json:"school"`
TeacherID *uint `json:"teacher_id"` // 班主任
Teacher *Teacher `gorm:"foreignKey:TeacherID" json:"teacher"`
StudentCount int `gorm:"default:0" json:"student_count"`
Status int `gorm:"default:1" json:"status"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
// 关联的学生
Students []Student `gorm:"foreignKey:ClassID" json:"students"`
}
// ParentStudentRel 家长-学生关联表
type ParentStudentRel struct {
ID uint `gorm:"primaryKey" json:"id"`
ParentID uint `json:"parent_id"`
StudentID uint `json:"student_id"`
Relation string `gorm:"type:varchar(16)" json:"relation"` // father, mother, other
IsPrimary bool `gorm:"default:false" json:"is_primary"` // 是否主要监护人
CreatedAt time.Time `json:"created_at"`
}
// UserAccount 用户账号模型(统一账号体系)
type UserAccount struct {
ID uint `gorm:"primaryKey" json:"id"`
Username string `gorm:"type:varchar(64);uniqueIndex" json:"username"`
PasswordHash string `gorm:"type:varchar(128)" json:"-"`
Phone string `gorm:"type:varchar(20);uniqueIndex" json:"phone"`
UserType string `gorm:"type:varchar(16)" json:"user_type"` // student, parent, teacher, admin
UserID uint `json:"user_id"` // 关联的具体用户ID
Status int `gorm:"default:1" json:"status"`
LastLoginAt *time.Time `json:"last_login_at"`
LastLoginIP string `gorm:"type:varchar(45)" json:"last_login_ip"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}