后端: Go(Gin+GORM+MySQL+Redis) - 17张业务表(yz_pw_前缀), 自动迁移 - JWT认证(3小时) + 盐+MD5密码 + 图形验证码 - 班级CRUD/加入(8人姓名验证/邀请码)/审核/30天自动清理 - 系统配置(16项)/菜单管理(动态路由)/数据统计 - 文件MD5去重/数据隔离/账号封禁/敏感词DFA检测 前端: Vue3+Vite+Element Plus+Less+ECharts+FontAwesome - 动态路由(数据库菜单驱动) - 蓝白配色, H5响应式 - 登录/注册/忘记密码/个人中心 - 班级创建向导/详情/加入/列表 - 管理后台: 审核/配置/菜单/统计/用户/敏感词 数据库: MySQL 10.31.100.3:3306/photowall 管理员: hero920103 / 920103
117 lines
4.3 KiB
Go
117 lines
4.3 KiB
Go
package model
|
|
|
|
import (
|
|
"encoding/json"
|
|
"time"
|
|
)
|
|
|
|
// ClassStatus 班级审核状态
|
|
type ClassStatus string
|
|
|
|
const (
|
|
ClassPending ClassStatus = "pending" // 待审核(名字不足或等待平台审核)
|
|
ClassActive ClassStatus = "active" // 正常
|
|
ClassRejected ClassStatus = "rejected" // 被打回,需补齐
|
|
ClassDeleted ClassStatus = "deleted" // 已删除(30天未补齐自动删除或手动删除)
|
|
)
|
|
|
|
// Class 班级
|
|
// 唯一性:同一学校+学院+年级+班级序号+毕业年份 唯一
|
|
type Class struct {
|
|
ID uint `gorm:"primaryKey" json:"id"`
|
|
SchoolID uint `gorm:"index:idx_class_unique,priority:1;not null" json:"school_id"`
|
|
CollegeID uint `gorm:"index:idx_class_unique,priority:2" json:"college_id"`
|
|
Name string `gorm:"size:128;not null" json:"name"` // 班级展示名,如"计算机科学与技术2018级1班"
|
|
Grade string `gorm:"size:32;index:idx_class_unique,priority:3" json:"grade"` // 年级,如"2018级"
|
|
ClassNo string `gorm:"size:32;index:idx_class_unique,priority:4" json:"class_no"` // 班级序号,如"1班"/"3班"
|
|
GraduateYear int `gorm:"index:idx_class_unique,priority:5" json:"graduate_year"` // 毕业年份
|
|
AdminUserID uint `gorm:"index;not null" json:"admin_user_id"`
|
|
GraduationPhoto string `gorm:"size:512" json:"graduation_photo"` // 毕业照URL(每个班级唯一一张)
|
|
StudentNamesJSON string `gorm:"type:text" json:"-"` // 班级所有同学名字 JSON 数组
|
|
TeacherNamesJSON string `gorm:"type:text" json:"-"` // 老师名字 JSON 数组
|
|
Status ClassStatus `gorm:"size:16;default:pending;index" json:"status"`
|
|
RejectReason string `gorm:"size:512" json:"reject_reason"`
|
|
AuditDeadline time.Time `json:"audit_deadline"` // 补齐截止时间(创建+30天)
|
|
CreatedAt time.Time `json:"created_at"`
|
|
UpdatedAt time.Time `json:"updated_at"`
|
|
}
|
|
|
|
// StudentNames 读写同学名单
|
|
func (c *Class) StudentNames() []string {
|
|
var list []string
|
|
if c.StudentNamesJSON == "" {
|
|
return list
|
|
}
|
|
_ = json.Unmarshal([]byte(c.StudentNamesJSON), &list)
|
|
return list
|
|
}
|
|
|
|
func (c *Class) SetStudentNames(names []string) {
|
|
if names == nil {
|
|
names = []string{}
|
|
}
|
|
b, _ := json.Marshal(names)
|
|
c.StudentNamesJSON = string(b)
|
|
}
|
|
|
|
// TeacherNames 读写老师名单
|
|
func (c *Class) TeacherNames() []string {
|
|
var list []string
|
|
if c.TeacherNamesJSON == "" {
|
|
return list
|
|
}
|
|
_ = json.Unmarshal([]byte(c.TeacherNamesJSON), &list)
|
|
return list
|
|
}
|
|
|
|
func (c *Class) SetTeacherNames(names []string) {
|
|
if names == nil {
|
|
names = []string{}
|
|
}
|
|
b, _ := json.Marshal(names)
|
|
c.TeacherNamesJSON = string(b)
|
|
}
|
|
|
|
// MinStudentCount 加入班级验证所需最少同学数,也是创建班级录入名单的下限
|
|
const MinStudentCount = 8
|
|
|
|
// ClassMemberRole 班级成员角色
|
|
type ClassMemberRole string
|
|
|
|
const (
|
|
MemberRoleAdmin ClassMemberRole = "admin"
|
|
MemberRoleMember ClassMemberRole = "member"
|
|
)
|
|
|
|
// JoinMethod 加入方式
|
|
type JoinMethod string
|
|
|
|
const (
|
|
JoinByInvite JoinMethod = "invite" // 管理员邀请/邀请码
|
|
JoinBySearch JoinMethod = "search" // 搜索+8人验证
|
|
)
|
|
|
|
// ClassMember 班级成员
|
|
type ClassMember struct {
|
|
ID uint `gorm:"primaryKey" json:"id"`
|
|
ClassID uint `gorm:"uniqueIndex:idx_class_user,priority:1;not null" json:"class_id"`
|
|
UserID uint `gorm:"uniqueIndex:idx_class_user,priority:2;not null" json:"user_id"`
|
|
Role ClassMemberRole `gorm:"size:16;default:member;index" json:"role"`
|
|
JoinMethod JoinMethod `gorm:"size:16" json:"join_method"`
|
|
JoinedAt time.Time `json:"joined_at"`
|
|
CreatedAt time.Time `json:"created_at"`
|
|
}
|
|
|
|
// Invitation 班级邀请码
|
|
type Invitation struct {
|
|
ID uint `gorm:"primaryKey" json:"id"`
|
|
ClassID uint `gorm:"index;not null" json:"class_id"`
|
|
InviterID uint `gorm:"not null" json:"inviter_id"`
|
|
Code string `gorm:"size:32;uniqueIndex;not null" json:"code"`
|
|
MaxUses int `gorm:"default:50" json:"max_uses"`
|
|
UsedCount int `gorm:"default:0" json:"used_count"`
|
|
ExpiresAt time.Time `json:"expires_at"`
|
|
Status string `gorm:"size:16;default:active" json:"status"` // active / disabled
|
|
CreatedAt time.Time `json:"created_at"`
|
|
}
|