个人作业老师登录的主页面与部分功能

Spring后端:
DailySummaryController

package com.example.demo.controller;

import com.example.demo.entity.DailySummary;
import com.example.demo.service.DailySummaryService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("/dailySummary")
public class DailySummaryController {
    @Autowired
    private DailySummaryService dailySummaryService;

    @PostMapping("/create")
    public Map<String, Object> createSummary(@RequestBody DailySummary summary) {
        Map<String, Object> result = new HashMap<>();
        DailySummary created = dailySummaryService.createSummary(summary);
        result.put("success", true);
        result.put("data", created);
        return result;
    }

    @GetMapping("/list/{studentId}")
    public Map<String, Object> getStudentSummaries(@PathVariable String studentId) {
        Map<String, Object> result = new HashMap<>();
        List<DailySummary> summaries = dailySummaryService.getStudentSummaries(studentId);
        result.put("success", true);
        result.put("data", summaries);
        return result;
    }

    @GetMapping("/today/{studentId}")
    public Map<String, Object> getTodaySummary(@PathVariable String studentId) {
        Map<String, Object> result = new HashMap<>();
        DailySummary summary = dailySummaryService.getTodaySummary(studentId);
        result.put("success", true);
        result.put("data", summary);
        return result;
    }

    @PutMapping("/update")
    public Map<String, Object> updateSummary(@RequestBody DailySummary summary) {
        Map<String, Object> result = new HashMap<>();
        boolean success = dailySummaryService.updateSummary(summary);
        result.put("success", success);
        return result;
    }

    @DeleteMapping("/delete/{id}")
    public Map<String, Object> deleteSummary(@PathVariable Integer id) {
        Map<String, Object> result = new HashMap<>();
        boolean success = dailySummaryService.deleteSummary(id);
        result.put("success", success);
        return result;
    }

    @GetMapping("/all")
    public Map<String, Object> getAllSummaries() {
        Map<String, Object> result = new HashMap<>();
        List<DailySummary> summaries = dailySummaryService.getAllSummaries();
        result.put("success", true);
        result.put("data", summaries);
        result.put("total", dailySummaryService.getTotalCheckInCount());
        return result;
    }

    @GetMapping("/search")
    public Map<String, Object> searchSummaries(@RequestParam String keyword) {
        Map<String, Object> result = new HashMap<>();
        List<DailySummary> summaries = dailySummaryService.searchSummaries(keyword);
        result.put("success", true);
        result.put("data", summaries);
        return result;
    }

    @GetMapping("/statistics")
    public Map<String, Object> getStatistics() {
        Map<String, Object> result = new HashMap<>();
        long uniqueCount = dailySummaryService.getUniqueCheckInCount();
        result.put("success", true);
        result.put("totalCheckIn", uniqueCount);
        return result;
    }
}

DailySummaryServiceImpl

package com.example.demo.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.example.demo.entity.DailySummary;
import com.example.demo.mapper.DailySummaryMapper;
import com.example.demo.service.DailySummaryService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.util.List;

@Service
public class DailySummaryServiceImpl implements DailySummaryService {
    @Autowired
    private DailySummaryMapper dailySummaryMapper;

    @Override
    public DailySummary createSummary(DailySummary summary) {
        if (summary.getSummaryDate() == null) {
            summary.setSummaryDate(LocalDate.now());
        }
        dailySummaryMapper.insert(summary);
        return summary;
    }

    @Override
    public List<DailySummary> getStudentSummaries(String studentId) {
        QueryWrapper<DailySummary> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("student_id", studentId)
                   .orderByDesc("summary_date");
        return dailySummaryMapper.selectList(queryWrapper);
    }

    @Override
    public DailySummary getTodaySummary(String studentId) {
        QueryWrapper<DailySummary> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("student_id", studentId)
                   .eq("summary_date", LocalDate.now());
        return dailySummaryMapper.selectOne(queryWrapper);
    }

    @Override
    public boolean updateSummary(DailySummary summary) {
        return dailySummaryMapper.updateById(summary) > 0;
    }

    @Override
    public boolean deleteSummary(Integer id) {
        return dailySummaryMapper.deleteById(id) > 0;
    }

    @Override
    public List<DailySummary> getAllSummaries() {
        return dailySummaryMapper.selectList(null);
    }

    @Override
    public List<DailySummary> searchSummaries(String keyword) {
        QueryWrapper<DailySummary> queryWrapper = new QueryWrapper<>();
        queryWrapper.like("summary_content", keyword)
                .or()
                .like("student_id", keyword)
                .or()
                .like("blog_url", keyword)
                .orderByDesc("summary_date");
        return dailySummaryMapper.selectList(queryWrapper);
    }

    @Override
    public long getTotalCheckInCount() {
        return dailySummaryMapper.selectCount(null);
    }

    @Override
    public long getUniqueCheckInCount() {
        QueryWrapper<DailySummary> queryWrapper = new QueryWrapper<>();
        queryWrapper.select("DISTINCT student_id, DATE(summary_date)");
        return dailySummaryMapper.selectCount(queryWrapper);
    }
}

DailySummaryService

package com.example.demo.service;

import com.example.demo.entity.DailySummary;
import java.time.LocalDate;
import java.util.List;

public interface DailySummaryService {
    DailySummary createSummary(DailySummary summary);
    List<DailySummary> getStudentSummaries(String studentId);
    DailySummary getTodaySummary(String studentId);
    boolean updateSummary(DailySummary summary);
    boolean deleteSummary(Integer id);

    List<DailySummary> getAllSummaries();
    List<DailySummary> searchSummaries(String keyword);
    long getTotalCheckInCount();
    long getUniqueCheckInCount(); // 添加新方法
}

安卓前端:
TeacherSummaryAdapter

package com.qi.demo.adapter

import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import com.qi.demo.R
import com.qi.demo.entity.DailySummary

class TeacherSummaryAdapter(
    private val summaries: MutableList<DailySummary> = mutableListOf()
) : RecyclerView.Adapter<TeacherSummaryAdapter.ViewHolder>() {

    class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
        val studentIdText: TextView = view.findViewById(R.id.studentIdText)
        val dateText: TextView = view.findViewById(R.id.dateText)
        val contentText: TextView = view.findViewById(R.id.contentText)
        val blogUrlText: TextView = view.findViewById(R.id.blogUrlText)
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
        val view = LayoutInflater.from(parent.context)
            .inflate(R.layout.item_teacher_summary, parent, false)
        return ViewHolder(view)
    }

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        val summary = summaries[position]
        holder.studentIdText.text = "学号:${summary.studentId}"
        holder.dateText.text = "日期:${summary.summaryDate}"
        holder.contentText.text = summary.summaryContent
        holder.blogUrlText.text = summary.blogUrl
    }

    override fun getItemCount() = summaries.size

    fun updateSummaries(newSummaries: List<DailySummary>) {
        summaries.clear()
        summaries.addAll(newSummaries)
        notifyDataSetChanged()
    }
}

DailySummaryService

package com.qi.demo.service

import com.qi.demo.entity.DailySummary
import retrofit2.Call
import retrofit2.http.*

interface DailySummaryService {
    @POST("/dailySummary/create")
    fun createSummary(@Body summary: DailySummary): Call<Map<String, Any>>

    @GET("/dailySummary/list/{studentId}")
    fun getStudentSummaries(@Path("studentId") studentId: String): Call<Map<String, Any>>

    @GET("/dailySummary/today/{studentId}")
    fun getTodaySummary(@Path("studentId") studentId: String): Call<Map<String, Any>>

    @PUT("/dailySummary/update")
    fun updateSummary(@Body summary: DailySummary): Call<Map<String, Any>>

    @DELETE("/dailySummary/delete/{id}")
    fun deleteSummary(@Path("id") id: Int): Call<Map<String, Any>>

    @GET("/dailySummary/all")
    fun getAllSummaries(): Call<Map<String, Any>>

    @GET("/dailySummary/search")
    fun searchSummaries(@Query("keyword") keyword: String): Call<Map<String, Any>>
}

DailySummaryActivity

package com.qi.demo

import android.os.Build
import android.os.Bundle
import android.widget.Button
import android.widget.EditText
import android.widget.Toast
import androidx.annotation.RequiresApi
import androidx.appcompat.app.AppCompatActivity
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.qi.demo.adapter.DailySummaryAdapter
import com.qi.demo.entity.DailySummary
import com.qi.demo.network.ServiceCreator
import com.qi.demo.service.DailySummaryService
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response
import java.time.LocalDate

class DailySummaryActivity : AppCompatActivity() {
    private lateinit var summaryInput: EditText
    private lateinit var blogUrlInput: EditText
    private lateinit var submitButton: Button
    private lateinit var summaryList: RecyclerView
    private lateinit var adapter: DailySummaryAdapter
    private val dailySummaryService = ServiceCreator.create<DailySummaryService>()
    private var studentId: String? = null

    @RequiresApi(Build.VERSION_CODES.O)
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_daily_summary)

        studentId = intent.getStringExtra("studentId")
        initViews()
        setupRecyclerView()
        loadSummaries()

        submitButton.setOnClickListener {
            submitSummary()
        }

        findViewById<Button>(R.id.backButton).setOnClickListener {
            finish()
        }
    }

    private fun initViews() {
        summaryInput = findViewById(R.id.summaryInput)
        blogUrlInput = findViewById(R.id.blogUrlInput)
        submitButton = findViewById(R.id.submitButton)
        summaryList = findViewById(R.id.summaryList)
    }

    private fun setupRecyclerView() {
        adapter = DailySummaryAdapter()
        summaryList.layoutManager = LinearLayoutManager(this)
        summaryList.adapter = adapter
    }

    private fun loadSummaries() {
        studentId?.let { id ->
            dailySummaryService.getStudentSummaries(id).enqueue(object : Callback<Map<String, Any>> {
                override fun onResponse(call: Call<Map<String, Any>>, response: Response<Map<String, Any>>) {
                    val result = response.body()
                    if (result?.get("success") == true) {
                        @Suppress("UNCHECKED_CAST")
                        val dataList = result["data"] as List<Map<String, Any>>
                        val summaries = dataList.map { map ->
                            DailySummary(
                                id = (map["id"] as Double).toInt(),
                                studentId = map["studentId"] as String,
                                summaryContent = map["summaryContent"] as String,
                                blogUrl = map["blogUrl"] as String?,
                                summaryDate = map["summaryDate"] as String?
                            )
                        }
                        adapter.updateSummaries(summaries)
                    }
                }

                override fun onFailure(call: Call<Map<String, Any>>, t: Throwable) {
                    Toast.makeText(this@DailySummaryActivity, "加载失败", Toast.LENGTH_SHORT).show()
                }
            })
        }
    }

    @RequiresApi(Build.VERSION_CODES.O)
    private fun submitSummary() {
        val content = summaryInput.text.toString()
        val blogUrl = blogUrlInput.text.toString()
        
        if (content.isEmpty() || blogUrl.isEmpty()) {
            Toast.makeText(this, "请填写完整信息", Toast.LENGTH_SHORT).show()
            return
        }

        val summary = DailySummary(
            studentId = studentId ?: "",
            summaryContent = content,
            blogUrl = blogUrl,
            summaryDate = LocalDate.now().toString()
        )

        dailySummaryService.createSummary(summary).enqueue(object : Callback<Map<String, Any>> {
            override fun onResponse(call: Call<Map<String, Any>>, response: Response<Map<String, Any>>) {
                val result = response.body()
                if (result?.get("success") == true) {
                    Toast.makeText(this@DailySummaryActivity, "提交成功", Toast.LENGTH_SHORT).show()
                    summaryInput.text.clear()
                    blogUrlInput.text.clear()
                    loadSummaries()
                } else {
                    Toast.makeText(this@DailySummaryActivity, "提交失败", Toast.LENGTH_SHORT).show()
                }
            }

            override fun onFailure(call: Call<Map<String, Any>>, t: Throwable) {
                Toast.makeText(this@DailySummaryActivity, "提交失败", Toast.LENGTH_SHORT).show()
            }
        })
    }
}

activity_teacher_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:padding="16dp">

    <TextView
        android:id="@+id/welcomeText"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="教师管理系统"
        android:textSize="24sp"
        android:gravity="center"
        android:layout_marginBottom="32dp"/>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:layout_marginBottom="16dp">

        <Button
            android:id="@+id/viewStudentsButton"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="查看学生列表"
            android:layout_marginEnd="8dp"/>

        <Button
            android:id="@+id/viewRecordsButton"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="查看打卡记录"/>
    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:layout_marginBottom="16dp">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="总打卡人数:"
            android:textSize="16sp"/>

        <TextView
            android:id="@+id/totalCheckInCount"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textSize="16sp"
            android:textColor="@android:color/holo_blue_dark"/>
    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:layout_marginBottom="16dp">

        <EditText
            android:id="@+id/searchInput"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:hint="输入关键字搜索"/>

        <Button
            android:id="@+id/searchButton"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="搜索"/>
    </LinearLayout>

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/summaryList"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"/>
</LinearLayout>

item_teacher_summary.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_margin="8dp"
    app:cardElevation="4dp">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:padding="16dp">

        <TextView
            android:id="@+id/studentIdText"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textStyle="bold"/>

        <TextView
            android:id="@+id/dateText"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="4dp"/>

        <TextView
            android:id="@+id/contentText"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="8dp"/>

        <TextView
            android:id="@+id/blogUrlText"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="8dp"
            android:textColor="@android:color/holo_blue_dark"
            android:autoLink="web"/>
    </LinearLayout>
</androidx.cardview.widget.CardView>
posted @ 2025-03-31 21:55  QixunQiu  阅读(11)  评论(0)    收藏  举报