You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于Go的学生考勤Web应用后端逻辑实现咨询

学生考勤按钮后端逻辑实现方案

1. 新增出勤记录结构体与数据库表

首先需要定义存储每日考勤状态的结构体,同时在数据库中创建对应表,确保每个学生每天只有一条考勤记录:

// 以Go语言为例,可根据自身技术栈调整
type AttendanceRecord struct {
    ID         uint      `gorm:"primaryKey"`
    StudentID  uint      `gorm:"index"` // 关联学生表ID
    AttendDate time.Time `gorm:"index"` // 考勤日期
    IsPresent  bool      // true=出勤,false=缺勤
}

对应的MySQL表结构:

CREATE TABLE attendance_records (
    id INT AUTO_INCREMENT PRIMARY KEY,
    student_id INT NOT NULL,
    attend_date DATE NOT NULL,
    is_present BOOLEAN NOT NULL,
    FOREIGN KEY (student_id) REFERENCES students(id),
    UNIQUE KEY unique_student_date (student_id, attend_date) -- 防止重复提交同一日期考勤
);

2. 实现考勤提交接口

后端新增MarkAttendance接口,处理前端按钮的提交请求,逻辑为:校验参数→查询当日是否已有记录→更新或插入记录:

func MarkAttendance(c *gin.Context) {
    studentID, _ := strconv.Atoi(c.PostForm("student_id"))
    attendDate, _ := time.Parse("2006-01-02", c.PostForm("date"))
    isPresent := c.PostForm("is_present") == "true"

    // 校验学生是否存在
    var student Student
    if err := db.First(&student, studentID).Error; err != nil {
        c.JSON(http.StatusBadRequest, gin.H{"error": "学生不存在"})
        return
    }

    // 处理考勤记录
    var record AttendanceRecord
    if err := db.Where("student_id = ? AND attend_date = ?", studentID, attendDate).First(&record).Error; err != nil {
        // 无记录则创建
        record = AttendanceRecord{
            StudentID:  uint(studentID),
            AttendDate: attendDate,
            IsPresent:  isPresent,
        }
        db.Create(&record)
    } else {
        // 有记录则更新状态
        db.Model(&record).Update("is_present", isPresent)
    }

    c.JSON(http.StatusOK, gin.H{"message": "考勤记录已更新"})
}

3. 前端按钮请求绑定

在list.html中给Yes/No按钮绑定点击事件,发送POST请求到后端接口:

{{range .students}}
<div class="student-item">
    <span>{{.Name}}</span>
    <button onclick="markAttendance({{.ID}}, '{{.Today}}', true)">Yes</button>
    <button onclick="markAttendance({{.ID}}, '{{.Today}}', false)">No</button>
</div>
{{end}}

<script>
function markAttendance(studentId, date, isPresent) {
    fetch('/api/mark-attendance', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/x-www-form-urlencoded',
        },
        body: `student_id=${studentId}&date=${date}&is_present=${isPresent}`
    })
    .then(response => response.json())
    .then(data => {
        alert(data.message);
        // 可添加按钮状态更新逻辑,比如高亮已选状态
    })
    .catch(error => console.error('提交失败:', error));
}
</script>

注:.Today是后端传递给前端的当日日期,格式为YYYY-MM-DD。

4. 月度考勤表查询逻辑

要实现学生为行、日期为列的考勤表,需按月份查询并整理数据:

func GetMonthlyAttendance(c *gin.Context) {
    year, _ := strconv.Atoi(c.Query("year"))
    month, _ := strconv.Atoi(c.Query("month"))

    // 获取当月首尾日期
    firstDay := time.Date(year, time.Month(month), 1, 0, 0, 0, 0, time.UTC)
    lastDay := firstDay.AddDate(0, 1, -1)

    // 查询所有学生
    var students []Student
    db.Find(&students)

    // 查询当月所有考勤记录
    var records []AttendanceRecord
    db.Where("attend_date BETWEEN ? AND ?", firstDay, lastDay).Find(&records)

    // 构建学生-日期-状态的映射
    attendanceMap := make(map[uint]map[string]bool)
    for _, record := range records {
        if _, ok := attendanceMap[record.StudentID]; !ok {
            attendanceMap[record.StudentID] = make(map[string]bool)
        }
        dateStr := record.AttendDate.Format("2006-01-02")
        attendanceMap[record.StudentID][dateStr] = record.IsPresent
    }

    // 整理为前端可用结构
    type StudentAttendance struct {
        Student    Student
        DailyStatus map[string]bool
    }
    var result []StudentAttendance
    for _, student := range students {
        status := attendanceMap[student.ID]
        if status == nil {
            status = make(map[string]bool)
        }
        result = append(result, StudentAttendance{Student: student, DailyStatus: status})
    }

    c.JSON(http.StatusOK, result)
}

前端拿到数据后,可循环生成表格:行对应学生,列对应当月日期,根据DailyStatus的值渲染出勤(如绿色√)或缺勤(如红色×)标记。


内容的提问来源于stack exchange,提问作者Awesome Lerman

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 19:01:02