feat: PhotoWall 毕业照存储系统初始版本
后端: 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
This commit is contained in:
@@ -0,0 +1,155 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"photowall/internal/model"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type SchoolService struct {
|
||||
db *gorm.DB
|
||||
}
|
||||
|
||||
func NewSchoolService(db *gorm.DB) *SchoolService {
|
||||
return &SchoolService{db: db}
|
||||
}
|
||||
|
||||
type SchoolQuery struct {
|
||||
RegionID uint `form:"region_id"`
|
||||
SchoolType model.SchoolType `form:"school_type"`
|
||||
Keyword string `form:"keyword"`
|
||||
Page int `form:"page"`
|
||||
PageSize int `form:"page_size"`
|
||||
}
|
||||
|
||||
// PageResp 通用分页响应
|
||||
type PageResp struct {
|
||||
List interface{} `json:"list"`
|
||||
Total int64 `json:"total"`
|
||||
Page int `json:"page"`
|
||||
}
|
||||
|
||||
type SchoolListResp = PageResp // 别名兼容
|
||||
|
||||
func (s *SchoolService) List(q *SchoolQuery) (*SchoolListResp, error) {
|
||||
if q.Page <= 0 {
|
||||
q.Page = 1
|
||||
}
|
||||
if q.PageSize <= 0 || q.PageSize > 100 {
|
||||
q.PageSize = 20
|
||||
}
|
||||
db := s.db.Model(&model.School{})
|
||||
if q.RegionID > 0 {
|
||||
db = db.Where("region_id = ?", q.RegionID)
|
||||
}
|
||||
if q.SchoolType != "" {
|
||||
db = db.Where("school_type = ?", q.SchoolType)
|
||||
}
|
||||
if q.Keyword != "" {
|
||||
db = db.Where("name LIKE ? OR name_en LIKE ?", "%"+q.Keyword+"%", "%"+q.Keyword+"%")
|
||||
}
|
||||
var total int64
|
||||
db.Count(&total)
|
||||
var list []model.School
|
||||
err := db.Order("id desc").Offset((q.Page - 1) * q.PageSize).Limit(q.PageSize).Find(&list).Error
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &SchoolListResp{List: list, Total: total, Page: q.Page}, nil
|
||||
}
|
||||
|
||||
// Create 创建学校(必须挂在 county 级地区下)
|
||||
func (s *SchoolService) Create(school *model.School) error {
|
||||
// 校验 region 必须是 county 级
|
||||
var region model.Region
|
||||
if err := s.db.First(®ion, school.RegionID).Error; err != nil {
|
||||
return errors.New("所属地区不存在")
|
||||
}
|
||||
if region.Level != model.LevelCounty {
|
||||
return errors.New("学校必须挂载在区/县级地区下")
|
||||
}
|
||||
if school.Name == "" {
|
||||
return errors.New("学校名称不能为空")
|
||||
}
|
||||
if school.SchoolType == "" {
|
||||
return errors.New("请选择学校类型")
|
||||
}
|
||||
return s.db.Create(school).Error
|
||||
}
|
||||
|
||||
func (s *SchoolService) GetByID(id uint) (*model.School, error) {
|
||||
var school model.School
|
||||
if err := s.db.First(&school, id).Error; err != nil {
|
||||
return nil, errors.New("学校不存在")
|
||||
}
|
||||
return &school, nil
|
||||
}
|
||||
|
||||
func (s *SchoolService) Update(id uint, updates map[string]interface{}) error {
|
||||
res := s.db.Model(&model.School{}).Where("id = ?", id).Updates(updates)
|
||||
if res.Error != nil {
|
||||
return res.Error
|
||||
}
|
||||
if res.RowsAffected == 0 {
|
||||
return errors.New("学校不存在")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *SchoolService) Delete(id uint) error {
|
||||
// 检查是否有班级引用
|
||||
var count int64
|
||||
s.db.Model(&model.Class{}).Where("school_id = ?", id).Count(&count)
|
||||
if count > 0 {
|
||||
return errors.New("该学校下已有班级,无法删除")
|
||||
}
|
||||
return s.db.Delete(&model.School{}, id).Error
|
||||
}
|
||||
|
||||
// ---- 学院 ----
|
||||
|
||||
func (s *SchoolService) ListColleges(schoolID uint) ([]model.College, error) {
|
||||
var list []model.College
|
||||
err := s.db.Where("school_id = ?", schoolID).Order("name").Find(&list).Error
|
||||
return list, err
|
||||
}
|
||||
|
||||
func (s *SchoolService) CreateCollege(schoolID uint, name string) (*model.College, error) {
|
||||
if name == "" {
|
||||
return nil, errors.New("学院名称不能为空")
|
||||
}
|
||||
// 校验学校是否支持学院
|
||||
var school model.School
|
||||
if err := s.db.First(&school, schoolID).Error; err != nil {
|
||||
return nil, errors.New("学校不存在")
|
||||
}
|
||||
if !school.SchoolType.HasCollege() {
|
||||
return nil, errors.New("该学校类型不支持学院层级")
|
||||
}
|
||||
c := &model.College{SchoolID: schoolID, Name: name}
|
||||
if err := s.db.Create(c).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return c, nil
|
||||
}
|
||||
|
||||
func (s *SchoolService) UpdateCollege(id uint, name string) error {
|
||||
res := s.db.Model(&model.College{}).Where("id = ?", id).Update("name", name)
|
||||
if res.Error != nil {
|
||||
return res.Error
|
||||
}
|
||||
if res.RowsAffected == 0 {
|
||||
return errors.New("学院不存在")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *SchoolService) DeleteCollege(id uint) error {
|
||||
var count int64
|
||||
s.db.Model(&model.Class{}).Where("college_id = ?", id).Count(&count)
|
||||
if count > 0 {
|
||||
return errors.New("该学院下已有班级,无法删除")
|
||||
}
|
||||
return s.db.Delete(&model.College{}, id).Error
|
||||
}
|
||||
Reference in New Issue
Block a user