zlwu před 9 měsíci
rodič
revize
3c629d2d58

+ 33 - 2
backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/controller/XgConductScoreController.java

@@ -4,6 +4,7 @@ import java.util.List;
 import java.util.Map;
 import java.util.HashMap;
 import java.math.BigDecimal;
+import jakarta.servlet.http.HttpServletRequest;
 import jakarta.servlet.http.HttpServletResponse;
 import jakarta.validation.constraints.*;
 import cn.dev33.satoken.annotation.SaCheckPermission;
@@ -51,8 +52,38 @@ public class XgConductScoreController extends BaseController {
     public R<XgConductScoreClassSummaryVo> classStudents(
             @NotNull(message = "学年不能为空") Integer academicYear,
             @NotNull(message = "学期不能为空") Integer semester,
-            @NotNull(message = "月份不能为空") Integer month) {
-        return R.ok(xgConductScoreService.getClassStudentsByTeacher(academicYear, semester, month));
+            @NotNull(message = "月份不能为空") Integer month,
+            @RequestParam(required = false) List<String> studentStatus,
+            HttpServletRequest request) {
+        // 兼容前端参数序列化 studentStatus[0]=1&studentStatus[1]=3 的情况
+        if ((studentStatus == null || studentStatus.isEmpty())) {
+            // 1) 尝试直接读取 studentStatus 数组参数
+            String[] vals = request.getParameterValues("studentStatus");
+            if (vals != null && vals.length > 0) {
+                studentStatus = java.util.Arrays.asList(vals);
+            } else {
+                // 2) 尝试按下标的方式收集 studentStatus[0], studentStatus[1], ...
+                java.util.List<String> collected = new java.util.ArrayList<>();
+                java.util.Map<String, String[]> paramMap = request.getParameterMap();
+                for (String key : paramMap.keySet()) {
+                    if (key != null && key.startsWith("studentStatus")) {
+                        String[] ps = paramMap.get(key);
+                        if (ps != null && ps.length > 0) {
+                            for (String p : ps) {
+                                if (p != null && !p.isEmpty()) {
+                                    collected.add(p);
+                                }
+                            }
+                        }
+                    }
+                }
+                if (!collected.isEmpty()) {
+                    studentStatus = collected;
+                }
+            }
+        }
+
+        return R.ok(xgConductScoreService.getClassStudentsByTeacher(academicYear, semester, month, studentStatus));
     }
 
     /**

+ 5 - 0
backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/domain/vo/XgConductScoreClassStudentVo.java

@@ -35,6 +35,11 @@ public class XgConductScoreClassStudentVo {
      */
     private String gender;
 
+    /**
+     * 学生状态
+     */
+    private String studentStatus;
+
     /**
      * 上月分数
      */

+ 4 - 2
backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/mapper/IXgConductScoreMapper.java

@@ -62,10 +62,12 @@ public interface IXgConductScoreMapper extends BaseMapperPlus<XgConductScore, Xg
      * @param academicYear 学年
      * @param semester     学期
      * @param month        月份
+     * @param studentStatus 学生状态列表
      * @return 学生列表
      */
-    List<Map<String, Object>> selectClassStudentsByTeacher(Long teacherId, Integer academicYear, Integer semester,
-            Integer month);
+    List<Map<String, Object>> selectClassStudentsByTeacher(@Param("teacherId") Long teacherId,
+            @Param("academicYear") Integer academicYear, @Param("semester") Integer semester,
+            @Param("month") Integer month, @Param("studentStatus") List<String> studentStatus);
 
     /**
      * 查询学期平均分统计列表

+ 2 - 1
backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/service/IXgConductScoreService.java

@@ -107,9 +107,10 @@ public interface IXgConductScoreService {
      * @param academicYear 学年
      * @param semester     学期
      * @param month        月份
+     * @param studentStatus 学生状态列表
      * @return 班级学生汇总信息
      */
-    XgConductScoreClassSummaryVo getClassStudentsByTeacher(Integer academicYear, Integer semester, Integer month);
+    XgConductScoreClassSummaryVo getClassStudentsByTeacher(Integer academicYear, Integer semester, Integer month, List<String> studentStatus);
 
     /**
      * 查询学期平均分统计

+ 3 - 2
backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/service/impl/XgConductScoreServiceImpl.java

@@ -395,10 +395,10 @@ public class XgConductScoreServiceImpl implements IXgConductScoreService {
      */
     @Override
     public XgConductScoreClassSummaryVo getClassStudentsByTeacher(Integer academicYear, Integer semester,
-            Integer month) {
+            Integer month, List<String> studentStatus) {
         Long teacherId = LoginHelper.getUserId();
         List<Map<String, Object>> rawData = baseMapper.selectClassStudentsByTeacher(teacherId, academicYear, semester,
-                month);
+                month, studentStatus);
 
         // 手动组装数据结构
         XgConductScoreClassSummaryVo result = new XgConductScoreClassSummaryVo();
@@ -430,6 +430,7 @@ public class XgConductScoreServiceImpl implements IXgConductScoreService {
             studentVo.setStudentNo((String) row.get("student_no"));
             studentVo.setStudentName((String) row.get("student_name"));
             studentVo.setGender((String) row.get("gender"));
+            studentVo.setStudentStatus((String) row.get("student_status"));
 
             // 设置上月分数
             if (row.get("last_score") != null) {

+ 9 - 0
backend/ruoyi-modules/ruoyi-xg/src/main/resources/mapper/conductScore/XgConductScoreMapper.xml

@@ -320,6 +320,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             s.student_no,
             s.name AS student_name,
             s.gender,
+            s.student_status,
             cs_last.score AS last_score,
             cs_last.month AS last_month,
             cs_current.id AS score_id,
@@ -366,6 +367,14 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
                 AND CONCAT(LPAD(cs_inner.academic_year, 4, '0'), LPAD(cs_inner.semester, 1, '0'), LPAD(cs_inner.month, 2, '0')) = latest.max_date
                 AND cs_inner.deleted = 0
         ) cs_last ON s.id = cs_last.student_id
+        <where>
+            <if test="studentStatus != null and studentStatus.size() > 0">
+                AND s.student_status IN
+                <foreach collection="studentStatus" item="status" open="(" close=")" separator=",">
+                    #{status}
+                </foreach>
+            </if>
+        </where>
         ORDER BY tc.class_name, s.student_no
     </select>
 

+ 88 - 14
web/src/views/xg/xsjcxx/ConductScoreInput/index.vue

@@ -31,39 +31,57 @@
             <el-card shadow="hover">
               <el-form ref="queryFormRef" :model="queryParams" label-width="80px">
                 <el-row :gutter="20">
-                  <el-col :span="6">
+                  <el-col :span="4">
                     <el-form-item label="学年" prop="academicYear">
                       <el-select v-model="queryParams.academicYear" placeholder="选择学年" clearable @change="handleQuery">
                         <el-option v-for="year in yearOptions" :key="year.value" :label="year.label" :value="year.value" />
                       </el-select>
                     </el-form-item>
                   </el-col>
-                  <el-col :span="6">
+                  <el-col :span="4">
                     <el-form-item label="学期" prop="semester">
                       <el-select v-model="queryParams.semester" placeholder="选择学期" clearable @change="handleQuery">
                         <el-option v-for="semester in semesterOptions" :key="semester.value" :label="semester.label" :value="semester.value" />
                       </el-select>
                     </el-form-item>
                   </el-col>
-                  <el-col :span="6">
+                  <el-col :span="4">
                     <el-form-item label="月份" prop="month">
                       <el-select v-model="queryParams.month" placeholder="选择月份" clearable @change="handleQuery">
                         <el-option v-for="month in monthOptions" :key="month.value" :label="month.label" :value="month.value" />
                       </el-select>
                     </el-form-item>
                   </el-col>
-                  <el-col :span="6">
+                  <el-col :span="4">
                     <el-form-item label="学号" prop="studentNo">
                       <el-input v-model="queryParams.studentNo" placeholder="请输入学号" clearable @keyup.enter="handleQuery" />
                     </el-form-item>
                   </el-col>
-                </el-row>
-                <el-row :gutter="20">
-                  <el-col :span="6">
+                  <el-col :span="4">
                     <el-form-item label="学生姓名" prop="studentName">
                       <el-input v-model="queryParams.studentName" placeholder="请输入学生姓名" clearable @keyup.enter="handleQuery" />
                     </el-form-item>
                   </el-col>
+                  <el-col :span="4">
+                    <el-form-item label="学生状态" prop="studentStatus">
+                      <el-select
+                        v-model="queryParams.studentStatus"
+                        placeholder="选择学生状态"
+                        multiple
+                        clearable
+                        collapse-tags
+                        collapse-tags-tooltip
+                        @change="handleQuery"
+                      >
+                        <el-option
+                          v-for="status in student_status"
+                          :key="status.value"
+                          :label="status.label"
+                          :value="status.value"
+                        />
+                      </el-select>
+                    </el-form-item>
+                  </el-col>
                 </el-row>
                 <el-row>
                   <el-col :span="24" class="search-btn-container">
@@ -161,6 +179,14 @@
                   </el-tag>
                 </template>
               </el-table-column>
+              <el-table-column v-if="columns[8].visible" key="studentStatus" label="学生状态" align="center" width="100">
+                <template #default="scope">
+                  <el-tag v-if="getStudentStatusText(scope.row.studentStatus)" :type="getStudentStatusType(scope.row.studentStatus)" size="small">
+                    {{ getStudentStatusText(scope.row.studentStatus) }}
+                  </el-tag>
+                  <span v-else class="text-gray-400">-</span>
+                </template>
+              </el-table-column>
               <el-table-column v-if="columns[3].visible" key="score" label="分数" align="center" width="150">
                 <template #default="scope">
                   <el-input-number v-model="scope.row.score" :min="0" :max="100" :precision="2" :step="0.5" size="small" placeholder="输入分数" />
@@ -168,9 +194,19 @@
               </el-table-column>
               <el-table-column v-if="columns[4].visible" key="evaluation" label="评判结果" align="center" width="100">
                 <template #default="scope">
-                  <el-tag v-if="getEvaluationResult(scope.row.score)" :type="getEvaluationResult(scope.row.score) === '优秀' ? 'success' :
-                        getEvaluationResult(scope.row.score) === '良好' ? 'primary' :
-                        getEvaluationResult(scope.row.score) === '合格' ? 'warning' : 'danger'" size="small">
+                  <el-tag
+                    v-if="getEvaluationResult(scope.row.score)"
+                    :type="
+                      getEvaluationResult(scope.row.score) === '优秀'
+                        ? 'success'
+                        : getEvaluationResult(scope.row.score) === '良好'
+                          ? 'primary'
+                          : getEvaluationResult(scope.row.score) === '合格'
+                            ? 'warning'
+                            : 'danger'
+                    "
+                    size="small"
+                  >
                     {{ getEvaluationResult(scope.row.score) }}
                   </el-tag>
                   <span v-else class="text-gray-400">-</span>
@@ -214,19 +250,27 @@
 </template>
 
 <script setup lang="ts" name="ConductScoreInput">
-import { ref, reactive, onMounted, computed } from 'vue';
-import { ElMessage, ElMessageBox } from 'element-plus';
+import { ref, reactive, onMounted, computed, getCurrentInstance, toRefs } from 'vue';
+import ElMessage from 'element-plus/es/components/message/index';
+import ElMessageBox from 'element-plus/es/components/message-box/index';
 
 // API接口
 import { conductScoreClassStudents, conductScoreBatchAdd } from '@/api/xg/conductScore';
 
+// 获取当前实例
+const { proxy } = getCurrentInstance() as any;
+
+// 字典数据
+const { student_status } = toRefs<any>(proxy?.useDict('student_status'));
+
 // 响应式数据
 const queryParams = reactive({
   academicYear: new Date().getFullYear(),
   semester: 1,
   month: new Date().getMonth() + 1,
   studentNo: '',
-  studentName: ''
+  studentName: '',
+  studentStatus: ['1', '3'] // 默认选中1-在读,3-复学
 });
 
 // 班级Tab页数据
@@ -294,6 +338,7 @@ const columns = ref([
   { key: 0, label: `学号`, visible: true },
   { key: 1, label: `姓名`, visible: true },
   { key: 2, label: `性别`, visible: true },
+  { key: 8, label: `学生状态`, visible: true },
   { key: 3, label: `分数`, visible: true },
   { key: 4, label: `评判结果`, visible: true },
   { key: 5, label: `备注`, visible: true },
@@ -342,6 +387,33 @@ const getEvaluationResult = (score) => {
   }
 };
 
+// 获取学生状态文本
+const getStudentStatusText = (status) => {
+  if (!status || !student_status.value || !Array.isArray(student_status.value)) {
+    return status || '';
+  }
+  const dictItem = student_status.value.find((item) => item.value === status);
+  return dictItem ? dictItem.label : status;
+};
+
+// 获取学生状态类型(用于标签颜色)
+const getStudentStatusType = (status) => {
+  if (!status) return 'info';
+  // 根据状态值返回不同的标签类型
+  switch (status) {
+    case '1':
+      return 'success'; // 在读
+    case '2':
+      return 'warning'; // 休学
+    case '3':
+      return 'danger'; // 退学
+    case '4':
+      return 'info'; // 毕业
+    default:
+      return 'info';
+  }
+};
+
 // 方法
 const handleQuery = () => {
   getList();
@@ -349,6 +421,8 @@ const handleQuery = () => {
 
 const resetQuery = () => {
   queryFormRef.value?.resetFields();
+  // 重置为默认值
+  queryParams.studentStatus = ['1', '3'];
   getList();
 };
 
@@ -375,7 +449,6 @@ const getList = async () => {
       ElMessage.warning('暂无班级数据,请检查是否已分配班主任权限或联系管理员');
       classTabs.value = [];
       classStudentData.value.clear();
-      summary.value = null;
       return;
     }
 
@@ -416,6 +489,7 @@ const getList = async () => {
             studentNo: student.studentNo || '',
             studentName: student.studentName || '',
             gender: student.gender || '0',
+            studentStatus: student.studentStatus || '',
             lastScore: student.lastScore || null,
             existingScore: hasExistingScore ? student.existingScore : null,
             score: hasExistingScore ? student.existingScore.score : null,