提交代码
This commit is contained in:
1 parent
edaf8dbacf
commit
9c3741562d
13 files changed
+1574
-9
No files matched your search
+2
-1
@@ -326,4 +326,5 @@ docs/变更管理/
|
||||
查找界面中涉及到的权限字符.md
|
||||
docs/部署文档/nginx配置/hzdyjsweb.camasort.com.conf
|
||||
首页完善的提示词.md
|
||||
scripts/
|
||||
scripts/
|
||||
学生宿舍卫生检查、学生违纪记录统计.md
|
||||
+82
@@ -0,0 +1,82 @@
|
||||
package org.dromara.xg.controller;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import jakarta.validation.constraints.*;
|
||||
import cn.dev33.satoken.annotation.SaCheckPermission;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.dromara.common.log.annotation.Log;
|
||||
import org.dromara.common.web.core.BaseController;
|
||||
import org.dromara.common.core.domain.R;
|
||||
import org.dromara.common.log.enums.BusinessType;
|
||||
import org.dromara.xg.domain.bo.XgStudentStatisticsBo;
|
||||
import org.dromara.xg.domain.vo.XgStudentStatisticsVo;
|
||||
import org.dromara.xg.domain.vo.XgCascadeOptionVo;
|
||||
import org.dromara.xg.service.IXgStudentStatisticsService;
|
||||
|
||||
/**
|
||||
* 学生宿舍卫生检查、违纪记录统计
|
||||
*
|
||||
* @author zlwu
|
||||
* @date 2025-01-14
|
||||
*/
|
||||
@Validated
|
||||
@RequiredArgsConstructor
|
||||
@RestController
|
||||
@RequestMapping("/xg/studentStatistics")
|
||||
public class XgStudentStatisticsController extends BaseController {
|
||||
|
||||
private final IXgStudentStatisticsService studentStatisticsService;
|
||||
|
||||
/**
|
||||
* 查询学生宿舍卫生检查、违纪记录统计数据
|
||||
*/
|
||||
@SaCheckPermission("xg:studentStatistics:query")
|
||||
@PostMapping("/statistics")
|
||||
public R<XgStudentStatisticsVo> getStatistics(@Validated @RequestBody XgStudentStatisticsBo bo) {
|
||||
return R.ok(studentStatisticsService.getStatistics(bo));
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出学生宿舍卫生检查、违纪记录统计数据
|
||||
*/
|
||||
@SaCheckPermission("xg:studentStatistics:export")
|
||||
@Log(title = "学生统计数据", businessType = BusinessType.EXPORT)
|
||||
@PostMapping("/export")
|
||||
public void exportStatistics(@Validated @RequestBody XgStudentStatisticsBo bo,
|
||||
jakarta.servlet.http.HttpServletResponse response) {
|
||||
studentStatisticsService.exportStatistics(bo, response);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取二级学院列表
|
||||
*/
|
||||
@SaCheckPermission("xg:studentStatistics:query")
|
||||
@GetMapping("/colleges")
|
||||
public R<List<XgCascadeOptionVo>> getColleges() {
|
||||
return R.ok(studentStatisticsService.getColleges());
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据学院ID获取专业列表
|
||||
*/
|
||||
@SaCheckPermission("xg:studentStatistics:query")
|
||||
@GetMapping("/majors/{collegeId}")
|
||||
public R<List<XgCascadeOptionVo>> getMajorsByCollegeId(
|
||||
@NotNull(message = "学院ID不能为空") @PathVariable Long collegeId) {
|
||||
return R.ok(studentStatisticsService.getMajorsByCollegeId(collegeId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据专业ID获取班级列表
|
||||
*/
|
||||
@SaCheckPermission("xg:studentStatistics:query")
|
||||
@GetMapping("/classes/{majorId}")
|
||||
public R<List<XgCascadeOptionVo>> getClassesByMajorId(
|
||||
@NotNull(message = "专业ID不能为空") @PathVariable Long majorId) {
|
||||
return R.ok(studentStatisticsService.getClassesByMajorId(majorId));
|
||||
}
|
||||
|
||||
}
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
package org.dromara.xg.domain.bo;
|
||||
|
||||
import org.dromara.common.core.validate.AddGroup;
|
||||
import org.dromara.common.core.validate.EditGroup;
|
||||
import org.dromara.common.mybatis.core.domain.BaseEntity;
|
||||
import jakarta.validation.constraints.*;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 学生宿舍卫生检查、违纪记录统计查询业务对象
|
||||
*
|
||||
* @author zlwu
|
||||
* @date 2025-01-14
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class XgStudentStatisticsBo extends BaseEntity {
|
||||
|
||||
/**
|
||||
* 统计开始时间
|
||||
*/
|
||||
@NotNull(message = "统计开始时间不能为空")
|
||||
private LocalDateTime startTime;
|
||||
|
||||
/**
|
||||
* 统计结束时间
|
||||
*/
|
||||
@NotNull(message = "统计结束时间不能为空")
|
||||
private LocalDateTime endTime;
|
||||
|
||||
/**
|
||||
* 二级学院ID
|
||||
*/
|
||||
private Long collegeId;
|
||||
|
||||
/**
|
||||
* 专业ID
|
||||
*/
|
||||
private Long majorId;
|
||||
|
||||
/**
|
||||
* 班级ID
|
||||
*/
|
||||
private Long classId;
|
||||
|
||||
}
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
package org.dromara.xg.domain.vo;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 级联选择器选项视图对象
|
||||
*
|
||||
* @author zlwu
|
||||
* @date 2025-01-14
|
||||
*/
|
||||
@Data
|
||||
public class XgCascadeOptionVo {
|
||||
|
||||
/**
|
||||
* ID
|
||||
*/
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 显示名称
|
||||
*/
|
||||
private String label;
|
||||
|
||||
/**
|
||||
* 值
|
||||
*/
|
||||
private String value;
|
||||
|
||||
/**
|
||||
* 排序
|
||||
*/
|
||||
private Integer sort;
|
||||
|
||||
}
|
||||
+117
@@ -0,0 +1,117 @@
|
||||
package org.dromara.xg.domain.vo;
|
||||
|
||||
import lombok.Data;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 学生宿舍卫生检查、违纪记录统计视图对象
|
||||
*
|
||||
* @author zlwu
|
||||
* @date 2025-01-14
|
||||
*/
|
||||
@Data
|
||||
public class XgStudentStatisticsVo {
|
||||
|
||||
/**
|
||||
* 统计维度 (college-学院, major-专业, class-班级, classDetail-班级详情)
|
||||
*/
|
||||
private String dimension;
|
||||
|
||||
/**
|
||||
* 统计图表数据
|
||||
*/
|
||||
private List<StatisticsChartData> chartData;
|
||||
|
||||
/**
|
||||
* 明细数据
|
||||
*/
|
||||
private List<StatisticsDetailData> detailData;
|
||||
|
||||
/**
|
||||
* 图表数据内部类
|
||||
*/
|
||||
@Data
|
||||
public static class StatisticsChartData {
|
||||
/**
|
||||
* 名称 (学院名、专业名、班级名)
|
||||
*/
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 宿舍扣分总数
|
||||
*/
|
||||
private Integer dormDeductionCount;
|
||||
|
||||
/**
|
||||
* 宿舍违纪记录总数
|
||||
*/
|
||||
private Integer dormViolationCount;
|
||||
|
||||
/**
|
||||
* 宿舍违纪记录扣分总数
|
||||
*/
|
||||
private Double dormViolationDeduction;
|
||||
|
||||
/**
|
||||
* 教学区违纪记录总数
|
||||
*/
|
||||
private Integer teachingViolationCount;
|
||||
|
||||
/**
|
||||
* 教学区违纪记录扣分总数
|
||||
*/
|
||||
private Double teachingViolationDeduction;
|
||||
}
|
||||
|
||||
/**
|
||||
* 明细数据内部类
|
||||
*/
|
||||
@Data
|
||||
public static class StatisticsDetailData {
|
||||
/**
|
||||
* ID
|
||||
*/
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 名称
|
||||
*/
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 上级名称(如学院下的专业名称显示学院名)
|
||||
*/
|
||||
private String parentName;
|
||||
|
||||
/**
|
||||
* 宿舍扣分总数
|
||||
*/
|
||||
private Integer dormDeductionCount;
|
||||
|
||||
/**
|
||||
* 宿舍违纪记录总数
|
||||
*/
|
||||
private Integer dormViolationCount;
|
||||
|
||||
/**
|
||||
* 宿舍违纪记录扣分总数
|
||||
*/
|
||||
private Double dormViolationDeduction;
|
||||
|
||||
/**
|
||||
* 教学区违纪记录总数
|
||||
*/
|
||||
private Integer teachingViolationCount;
|
||||
|
||||
/**
|
||||
* 教学区违纪记录扣分总数
|
||||
*/
|
||||
private Double teachingViolationDeduction;
|
||||
|
||||
/**
|
||||
* 合计扣分
|
||||
*/
|
||||
private Double totalDeduction;
|
||||
}
|
||||
|
||||
}
|
||||
+63
@@ -0,0 +1,63 @@
|
||||
package org.dromara.xg.mapper;
|
||||
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.dromara.xg.domain.bo.XgStudentStatisticsBo;
|
||||
import org.dromara.xg.domain.vo.XgStudentStatisticsVo;
|
||||
import org.dromara.xg.domain.vo.XgCascadeOptionVo;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 学生宿舍卫生检查、违纪记录统计Mapper接口
|
||||
*
|
||||
* @author zlwu
|
||||
* @date 2025-01-14
|
||||
*/
|
||||
public interface XgStudentStatisticsMapper {
|
||||
|
||||
/**
|
||||
* 按学院维度统计图表数据
|
||||
*/
|
||||
List<XgStudentStatisticsVo.StatisticsChartData> getCollegeStatistics(@Param("bo") XgStudentStatisticsBo bo);
|
||||
|
||||
/**
|
||||
* 按学院维度统计明细数据
|
||||
*/
|
||||
List<XgStudentStatisticsVo.StatisticsDetailData> getCollegeDetailStatistics(@Param("bo") XgStudentStatisticsBo bo);
|
||||
|
||||
/**
|
||||
* 按专业维度统计图表数据
|
||||
*/
|
||||
List<XgStudentStatisticsVo.StatisticsChartData> getMajorStatistics(@Param("bo") XgStudentStatisticsBo bo);
|
||||
|
||||
/**
|
||||
* 按专业维度统计明细数据
|
||||
*/
|
||||
List<XgStudentStatisticsVo.StatisticsDetailData> getMajorDetailStatistics(@Param("bo") XgStudentStatisticsBo bo);
|
||||
|
||||
/**
|
||||
* 按班级维度统计图表数据
|
||||
*/
|
||||
List<XgStudentStatisticsVo.StatisticsChartData> getClassStatistics(@Param("bo") XgStudentStatisticsBo bo);
|
||||
|
||||
/**
|
||||
* 按班级维度统计明细数据
|
||||
*/
|
||||
List<XgStudentStatisticsVo.StatisticsDetailData> getClassDetailStatistics(@Param("bo") XgStudentStatisticsBo bo);
|
||||
|
||||
/**
|
||||
* 获取二级学院列表
|
||||
*/
|
||||
List<XgCascadeOptionVo> getColleges();
|
||||
|
||||
/**
|
||||
* 根据学院ID获取专业列表
|
||||
*/
|
||||
List<XgCascadeOptionVo> getMajorsByCollegeId(@Param("collegeId") Long collegeId);
|
||||
|
||||
/**
|
||||
* 根据专业ID获取班级列表
|
||||
*/
|
||||
List<XgCascadeOptionVo> getClassesByMajorId(@Param("majorId") Long majorId);
|
||||
|
||||
}
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
package org.dromara.xg.service;
|
||||
|
||||
import java.util.List;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.dromara.xg.domain.bo.XgStudentStatisticsBo;
|
||||
import org.dromara.xg.domain.vo.XgStudentStatisticsVo;
|
||||
import org.dromara.xg.domain.vo.XgCascadeOptionVo;
|
||||
|
||||
/**
|
||||
* 学生宿舍卫生检查、违纪记录统计Service接口
|
||||
*
|
||||
* @author zlwu
|
||||
* @date 2025-01-14
|
||||
*/
|
||||
public interface IXgStudentStatisticsService {
|
||||
|
||||
/**
|
||||
* 获取统计数据
|
||||
*
|
||||
* @param bo 查询条件
|
||||
* @return 统计结果
|
||||
*/
|
||||
XgStudentStatisticsVo getStatistics(XgStudentStatisticsBo bo);
|
||||
|
||||
/**
|
||||
* 导出统计数据
|
||||
*
|
||||
* @param bo 查询条件
|
||||
* @param response HTTP响应
|
||||
*/
|
||||
void exportStatistics(XgStudentStatisticsBo bo, HttpServletResponse response);
|
||||
|
||||
/**
|
||||
* 获取二级学院列表
|
||||
*
|
||||
* @return 学院列表
|
||||
*/
|
||||
List<XgCascadeOptionVo> getColleges();
|
||||
|
||||
/**
|
||||
* 根据学院ID获取专业列表
|
||||
*
|
||||
* @param collegeId 学院ID
|
||||
* @return 专业列表
|
||||
*/
|
||||
List<XgCascadeOptionVo> getMajorsByCollegeId(Long collegeId);
|
||||
|
||||
/**
|
||||
* 根据专业ID获取班级列表
|
||||
*
|
||||
* @param majorId 专业ID
|
||||
* @return 班级列表
|
||||
*/
|
||||
List<XgCascadeOptionVo> getClassesByMajorId(Long majorId);
|
||||
|
||||
}
|
||||
+117
@@ -0,0 +1,117 @@
|
||||
package org.dromara.xg.service.impl;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Service;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.dromara.common.excel.utils.ExcelUtil;
|
||||
import org.dromara.xg.service.IXgStudentStatisticsService;
|
||||
import org.dromara.xg.domain.bo.XgStudentStatisticsBo;
|
||||
import org.dromara.xg.domain.vo.XgStudentStatisticsVo;
|
||||
import org.dromara.xg.domain.vo.XgCascadeOptionVo;
|
||||
import org.dromara.xg.mapper.XgStudentStatisticsMapper;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 学生宿舍卫生检查、违纪记录统计Service业务层处理
|
||||
*
|
||||
* @author zlwu
|
||||
* @date 2025-01-14
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
@Service
|
||||
public class XgStudentStatisticsServiceImpl implements IXgStudentStatisticsService {
|
||||
|
||||
private final XgStudentStatisticsMapper statisticsMapper;
|
||||
|
||||
@Override
|
||||
public XgStudentStatisticsVo getStatistics(XgStudentStatisticsBo bo) {
|
||||
XgStudentStatisticsVo result = new XgStudentStatisticsVo();
|
||||
|
||||
// 确定统计维度
|
||||
String dimension = determineDimension(bo);
|
||||
result.setDimension(dimension);
|
||||
|
||||
// 获取图表数据和明细数据
|
||||
switch (dimension) {
|
||||
case "college":
|
||||
result.setChartData(statisticsMapper.getCollegeStatistics(bo));
|
||||
result.setDetailData(statisticsMapper.getCollegeDetailStatistics(bo));
|
||||
break;
|
||||
case "major":
|
||||
result.setChartData(statisticsMapper.getMajorStatistics(bo));
|
||||
result.setDetailData(statisticsMapper.getMajorDetailStatistics(bo));
|
||||
break;
|
||||
case "class":
|
||||
result.setChartData(statisticsMapper.getClassStatistics(bo));
|
||||
result.setDetailData(statisticsMapper.getClassDetailStatistics(bo));
|
||||
break;
|
||||
case "classDetail":
|
||||
// 班级详情统计:图表数据和明细数据都只显示指定班级
|
||||
List<XgStudentStatisticsVo.StatisticsDetailData> detailData = statisticsMapper
|
||||
.getClassDetailStatistics(bo);
|
||||
result.setDetailData(detailData);
|
||||
// 将明细数据转换为图表数据格式
|
||||
result.setChartData(convertDetailToChartData(detailData));
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exportStatistics(XgStudentStatisticsBo bo, HttpServletResponse response) {
|
||||
XgStudentStatisticsVo statistics = getStatistics(bo);
|
||||
ExcelUtil.exportExcel(statistics.getDetailData(), "学生统计数据", XgStudentStatisticsVo.StatisticsDetailData.class,
|
||||
response);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<XgCascadeOptionVo> getColleges() {
|
||||
return statisticsMapper.getColleges();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<XgCascadeOptionVo> getMajorsByCollegeId(Long collegeId) {
|
||||
return statisticsMapper.getMajorsByCollegeId(collegeId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<XgCascadeOptionVo> getClassesByMajorId(Long majorId) {
|
||||
return statisticsMapper.getClassesByMajorId(majorId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 确定统计维度
|
||||
*/
|
||||
private String determineDimension(XgStudentStatisticsBo bo) {
|
||||
if (bo.getClassId() != null) {
|
||||
return "classDetail";
|
||||
} else if (bo.getMajorId() != null) {
|
||||
return "class";
|
||||
} else if (bo.getCollegeId() != null) {
|
||||
return "major";
|
||||
} else {
|
||||
return "college";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 将明细数据转换为图表数据格式
|
||||
*/
|
||||
private List<XgStudentStatisticsVo.StatisticsChartData> convertDetailToChartData(
|
||||
List<XgStudentStatisticsVo.StatisticsDetailData> detailData) {
|
||||
return detailData.stream().map(detail -> {
|
||||
XgStudentStatisticsVo.StatisticsChartData chartData = new XgStudentStatisticsVo.StatisticsChartData();
|
||||
chartData.setName(detail.getName());
|
||||
chartData.setDormDeductionCount(detail.getDormDeductionCount());
|
||||
chartData.setDormViolationCount(detail.getDormViolationCount());
|
||||
chartData.setDormViolationDeduction(detail.getDormViolationDeduction());
|
||||
chartData.setTeachingViolationCount(detail.getTeachingViolationCount());
|
||||
chartData.setTeachingViolationDeduction(detail.getTeachingViolationDeduction());
|
||||
return chartData;
|
||||
}).collect(java.util.stream.Collectors.toList());
|
||||
}
|
||||
|
||||
}
|
||||
+504
@@ -0,0 +1,504 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!DOCTYPE mapper
|
||||
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="org.dromara.xg.mapper.XgStudentStatisticsMapper">
|
||||
|
||||
<!-- 按学院维度统计图表数据 -->
|
||||
<select id="getCollegeStatistics" resultType="org.dromara.xg.domain.vo.XgStudentStatisticsVo$StatisticsChartData">
|
||||
SELECT
|
||||
d.dept_name as name,
|
||||
COALESCE(dorm_stats.dormDeductionCount, 0) as dormDeductionCount,
|
||||
COALESCE(dorm_violation_stats.dormViolationCount, 0) as dormViolationCount,
|
||||
COALESCE(dorm_violation_stats.dormViolationDeduction, 0) as dormViolationDeduction,
|
||||
COALESCE(teaching_violation_stats.teachingViolationCount, 0) as teachingViolationCount,
|
||||
COALESCE(teaching_violation_stats.teachingViolationDeduction, 0) as teachingViolationDeduction
|
||||
FROM sys_dept d
|
||||
LEFT JOIN (
|
||||
-- 宿舍卫生检查扣分统计
|
||||
SELECT
|
||||
c.college_id,
|
||||
COUNT(h.id) as dormDeductionCount
|
||||
FROM xg_dorm_hygiene_check h
|
||||
INNER JOIN xg_class_msg c ON h.room_id IN (
|
||||
SELECT DISTINCT bs.room_id
|
||||
FROM xg_dorm_bed_student bs
|
||||
INNER JOIN xg_student_msg s ON bs.student_id = s.id
|
||||
WHERE s.class_id = c.id AND s.deleted = 0
|
||||
)
|
||||
WHERE h.deleted = 0
|
||||
AND h.check_date BETWEEN #{bo.startTime} AND #{bo.endTime}
|
||||
AND h.total_score > 0
|
||||
GROUP BY c.college_id
|
||||
) dorm_stats ON d.dept_id = dorm_stats.college_id
|
||||
LEFT JOIN (
|
||||
-- 宿舍区违纪记录统计
|
||||
SELECT
|
||||
dr.college_id,
|
||||
COUNT(dr.id) as dormViolationCount,
|
||||
COALESCE(SUM(dr.score_deduction), 0) as dormViolationDeduction
|
||||
FROM xskh_discipline_record dr
|
||||
WHERE dr.deleted = 0
|
||||
AND dr.violation_source = '1'
|
||||
AND dr.status = '1'
|
||||
AND dr.discipline_date BETWEEN #{bo.startTime} AND #{bo.endTime}
|
||||
GROUP BY dr.college_id
|
||||
) dorm_violation_stats ON d.dept_id = dorm_violation_stats.college_id
|
||||
LEFT JOIN (
|
||||
-- 教学区违纪记录统计
|
||||
SELECT
|
||||
dr.college_id,
|
||||
COUNT(dr.id) as teachingViolationCount,
|
||||
COALESCE(SUM(dr.score_deduction), 0) as teachingViolationDeduction
|
||||
FROM xskh_discipline_record dr
|
||||
WHERE dr.deleted = 0
|
||||
AND dr.violation_source = '2'
|
||||
AND dr.status = '1'
|
||||
AND dr.discipline_date BETWEEN #{bo.startTime} AND #{bo.endTime}
|
||||
GROUP BY dr.college_id
|
||||
) teaching_violation_stats ON d.dept_id = teaching_violation_stats.college_id
|
||||
WHERE d.parent_id = 101 AND d.del_flag = '0'
|
||||
ORDER BY d.order_num ASC, d.dept_name ASC
|
||||
</select>
|
||||
|
||||
<!-- 按学院维度统计明细数据 -->
|
||||
<select id="getCollegeDetailStatistics" resultType="org.dromara.xg.domain.vo.XgStudentStatisticsVo$StatisticsDetailData">
|
||||
SELECT
|
||||
d.dept_id as id,
|
||||
d.dept_name as name,
|
||||
'' as parentName,
|
||||
COALESCE(dorm_stats.dormDeductionCount, 0) as dormDeductionCount,
|
||||
COALESCE(dorm_violation_stats.dormViolationCount, 0) as dormViolationCount,
|
||||
COALESCE(dorm_violation_stats.dormViolationDeduction, 0) as dormViolationDeduction,
|
||||
COALESCE(teaching_violation_stats.teachingViolationCount, 0) as teachingViolationCount,
|
||||
COALESCE(teaching_violation_stats.teachingViolationDeduction, 0) as teachingViolationDeduction,
|
||||
COALESCE(dorm_violation_stats.dormViolationDeduction, 0) + COALESCE(teaching_violation_stats.teachingViolationDeduction, 0) as totalDeduction
|
||||
FROM sys_dept d
|
||||
LEFT JOIN (
|
||||
-- 宿舍卫生检查扣分统计
|
||||
SELECT
|
||||
c.college_id,
|
||||
COUNT(h.id) as dormDeductionCount
|
||||
FROM xg_dorm_hygiene_check h
|
||||
INNER JOIN xg_class_msg c ON h.room_id IN (
|
||||
SELECT DISTINCT bs.room_id
|
||||
FROM xg_dorm_bed_student bs
|
||||
INNER JOIN xg_student_msg s ON bs.student_id = s.id
|
||||
WHERE s.class_id = c.id AND s.deleted = 0
|
||||
)
|
||||
WHERE h.deleted = 0
|
||||
AND h.check_date BETWEEN #{bo.startTime} AND #{bo.endTime}
|
||||
AND h.total_score > 0
|
||||
GROUP BY c.college_id
|
||||
) dorm_stats ON d.dept_id = dorm_stats.college_id
|
||||
LEFT JOIN (
|
||||
-- 宿舍区违纪记录统计
|
||||
SELECT
|
||||
dr.college_id,
|
||||
COUNT(dr.id) as dormViolationCount,
|
||||
COALESCE(SUM(dr.score_deduction), 0) as dormViolationDeduction
|
||||
FROM xskh_discipline_record dr
|
||||
WHERE dr.deleted = 0
|
||||
AND dr.violation_source = '1'
|
||||
AND dr.status = '1'
|
||||
AND dr.discipline_date BETWEEN #{bo.startTime} AND #{bo.endTime}
|
||||
GROUP BY dr.college_id
|
||||
) dorm_violation_stats ON d.dept_id = dorm_violation_stats.college_id
|
||||
LEFT JOIN (
|
||||
-- 教学区违纪记录统计
|
||||
SELECT
|
||||
dr.college_id,
|
||||
COUNT(dr.id) as teachingViolationCount,
|
||||
COALESCE(SUM(dr.score_deduction), 0) as teachingViolationDeduction
|
||||
FROM xskh_discipline_record dr
|
||||
WHERE dr.deleted = 0
|
||||
AND dr.violation_source = '2'
|
||||
AND dr.status = '1'
|
||||
AND dr.discipline_date BETWEEN #{bo.startTime} AND #{bo.endTime}
|
||||
GROUP BY dr.college_id
|
||||
) teaching_violation_stats ON d.dept_id = teaching_violation_stats.college_id
|
||||
WHERE d.parent_id = 101 AND d.del_flag = '0'
|
||||
ORDER BY d.order_num ASC, d.dept_name ASC
|
||||
</select>
|
||||
|
||||
<!-- 按专业维度统计图表数据 -->
|
||||
<select id="getMajorStatistics" resultType="org.dromara.xg.domain.vo.XgStudentStatisticsVo$StatisticsChartData">
|
||||
SELECT
|
||||
d.dept_name as name,
|
||||
COALESCE(dorm_stats.dormDeductionCount, 0) as dormDeductionCount,
|
||||
COALESCE(dorm_violation_stats.dormViolationCount, 0) as dormViolationCount,
|
||||
COALESCE(dorm_violation_stats.dormViolationDeduction, 0) as dormViolationDeduction,
|
||||
COALESCE(teaching_violation_stats.teachingViolationCount, 0) as teachingViolationCount,
|
||||
COALESCE(teaching_violation_stats.teachingViolationDeduction, 0) as teachingViolationDeduction
|
||||
FROM sys_dept d
|
||||
LEFT JOIN (
|
||||
-- 宿舍卫生检查扣分统计
|
||||
SELECT
|
||||
c.major_id,
|
||||
COUNT(h.id) as dormDeductionCount
|
||||
FROM xg_dorm_hygiene_check h
|
||||
INNER JOIN xg_class_msg c ON h.room_id IN (
|
||||
SELECT DISTINCT bs.room_id
|
||||
FROM xg_dorm_bed_student bs
|
||||
INNER JOIN xg_student_msg s ON bs.student_id = s.id
|
||||
WHERE s.class_id = c.id AND s.deleted = 0
|
||||
)
|
||||
WHERE h.deleted = 0
|
||||
AND h.check_date BETWEEN #{bo.startTime} AND #{bo.endTime}
|
||||
AND h.total_score > 0
|
||||
AND c.college_id = #{bo.collegeId}
|
||||
GROUP BY c.major_id
|
||||
) dorm_stats ON d.dept_id = dorm_stats.major_id
|
||||
LEFT JOIN (
|
||||
-- 宿舍区违纪记录统计
|
||||
SELECT
|
||||
dr.major_id,
|
||||
COUNT(dr.id) as dormViolationCount,
|
||||
COALESCE(SUM(dr.score_deduction), 0) as dormViolationDeduction
|
||||
FROM xskh_discipline_record dr
|
||||
WHERE dr.deleted = 0
|
||||
AND dr.violation_source = '1'
|
||||
AND dr.status = '1'
|
||||
AND dr.college_id = #{bo.collegeId}
|
||||
AND dr.discipline_date BETWEEN #{bo.startTime} AND #{bo.endTime}
|
||||
GROUP BY dr.major_id
|
||||
) dorm_violation_stats ON d.dept_id = dorm_violation_stats.major_id
|
||||
LEFT JOIN (
|
||||
-- 教学区违纪记录统计
|
||||
SELECT
|
||||
dr.major_id,
|
||||
COUNT(dr.id) as teachingViolationCount,
|
||||
COALESCE(SUM(dr.score_deduction), 0) as teachingViolationDeduction
|
||||
FROM xskh_discipline_record dr
|
||||
WHERE dr.deleted = 0
|
||||
AND dr.violation_source = '2'
|
||||
AND dr.status = '1'
|
||||
AND dr.college_id = #{bo.collegeId}
|
||||
AND dr.discipline_date BETWEEN #{bo.startTime} AND #{bo.endTime}
|
||||
GROUP BY dr.major_id
|
||||
) teaching_violation_stats ON d.dept_id = teaching_violation_stats.major_id
|
||||
WHERE d.parent_id = #{bo.collegeId} AND d.dept_category LIKE 'zy-%' AND d.del_flag = '0'
|
||||
ORDER BY d.order_num ASC, d.dept_name ASC
|
||||
</select>
|
||||
|
||||
<!-- 按专业维度统计明细数据 -->
|
||||
<select id="getMajorDetailStatistics" resultType="org.dromara.xg.domain.vo.XgStudentStatisticsVo$StatisticsDetailData">
|
||||
SELECT
|
||||
d.dept_id as id,
|
||||
d.dept_name as name,
|
||||
p.dept_name as parentName,
|
||||
COALESCE(dorm_stats.dormDeductionCount, 0) as dormDeductionCount,
|
||||
COALESCE(dorm_violation_stats.dormViolationCount, 0) as dormViolationCount,
|
||||
COALESCE(dorm_violation_stats.dormViolationDeduction, 0) as dormViolationDeduction,
|
||||
COALESCE(teaching_violation_stats.teachingViolationCount, 0) as teachingViolationCount,
|
||||
COALESCE(teaching_violation_stats.teachingViolationDeduction, 0) as teachingViolationDeduction,
|
||||
COALESCE(dorm_violation_stats.dormViolationDeduction, 0) + COALESCE(teaching_violation_stats.teachingViolationDeduction, 0) as totalDeduction
|
||||
FROM sys_dept d
|
||||
INNER JOIN sys_dept p ON d.parent_id = p.dept_id
|
||||
LEFT JOIN (
|
||||
-- 宿舍卫生检查扣分统计
|
||||
SELECT
|
||||
c.major_id,
|
||||
COUNT(h.id) as dormDeductionCount
|
||||
FROM xg_dorm_hygiene_check h
|
||||
INNER JOIN xg_class_msg c ON h.room_id IN (
|
||||
SELECT DISTINCT bs.room_id
|
||||
FROM xg_dorm_bed_student bs
|
||||
INNER JOIN xg_student_msg s ON bs.student_id = s.id
|
||||
WHERE s.class_id = c.id AND s.deleted = 0
|
||||
)
|
||||
WHERE h.deleted = 0
|
||||
AND h.check_date BETWEEN #{bo.startTime} AND #{bo.endTime}
|
||||
AND h.total_score > 0
|
||||
AND c.college_id = #{bo.collegeId}
|
||||
GROUP BY c.major_id
|
||||
) dorm_stats ON d.dept_id = dorm_stats.major_id
|
||||
LEFT JOIN (
|
||||
-- 宿舍区违纪记录统计
|
||||
SELECT
|
||||
dr.major_id,
|
||||
COUNT(dr.id) as dormViolationCount,
|
||||
COALESCE(SUM(dr.score_deduction), 0) as dormViolationDeduction
|
||||
FROM xskh_discipline_record dr
|
||||
WHERE dr.deleted = 0
|
||||
AND dr.violation_source = '1'
|
||||
AND dr.status = '1'
|
||||
AND dr.college_id = #{bo.collegeId}
|
||||
AND dr.discipline_date BETWEEN #{bo.startTime} AND #{bo.endTime}
|
||||
GROUP BY dr.major_id
|
||||
) dorm_violation_stats ON d.dept_id = dorm_violation_stats.major_id
|
||||
LEFT JOIN (
|
||||
-- 教学区违纪记录统计
|
||||
SELECT
|
||||
dr.major_id,
|
||||
COUNT(dr.id) as teachingViolationCount,
|
||||
COALESCE(SUM(dr.score_deduction), 0) as teachingViolationDeduction
|
||||
FROM xskh_discipline_record dr
|
||||
WHERE dr.deleted = 0
|
||||
AND dr.violation_source = '2'
|
||||
AND dr.status = '1'
|
||||
AND dr.college_id = #{bo.collegeId}
|
||||
AND dr.discipline_date BETWEEN #{bo.startTime} AND #{bo.endTime}
|
||||
GROUP BY dr.major_id
|
||||
) teaching_violation_stats ON d.dept_id = teaching_violation_stats.major_id
|
||||
WHERE d.parent_id = #{bo.collegeId} AND d.dept_category LIKE 'zy-%' AND d.del_flag = '0'
|
||||
ORDER BY d.order_num ASC, d.dept_name ASC
|
||||
</select>
|
||||
|
||||
<!-- 按班级维度统计图表数据 -->
|
||||
<select id="getClassStatistics" resultType="org.dromara.xg.domain.vo.XgStudentStatisticsVo$StatisticsChartData">
|
||||
SELECT
|
||||
c.class_name as name,
|
||||
(SELECT COUNT(h.id)
|
||||
FROM xg_dorm_hygiene_check h
|
||||
WHERE h.deleted = 0
|
||||
AND h.check_date BETWEEN #{bo.startTime} AND #{bo.endTime}
|
||||
AND h.total_score > 0
|
||||
AND h.room_id IN (
|
||||
SELECT DISTINCT bs.room_id
|
||||
FROM xg_dorm_bed_student bs
|
||||
INNER JOIN xg_student_msg s ON bs.student_id = s.id
|
||||
WHERE s.class_id = c.id AND s.deleted = 0
|
||||
)
|
||||
) as dormDeductionCount,
|
||||
(SELECT COUNT(dr.id)
|
||||
FROM xskh_discipline_record dr
|
||||
WHERE dr.deleted = 0
|
||||
AND dr.violation_source = '1'
|
||||
AND dr.status = '1'
|
||||
AND dr.class_id = c.id
|
||||
AND dr.college_id = #{bo.collegeId}
|
||||
AND dr.major_id = #{bo.majorId}
|
||||
AND dr.discipline_date BETWEEN #{bo.startTime} AND #{bo.endTime}
|
||||
) as dormViolationCount,
|
||||
(SELECT COALESCE(SUM(dr.score_deduction), 0)
|
||||
FROM xskh_discipline_record dr
|
||||
WHERE dr.deleted = 0
|
||||
AND dr.violation_source = '1'
|
||||
AND dr.status = '1'
|
||||
AND dr.class_id = c.id
|
||||
AND dr.college_id = #{bo.collegeId}
|
||||
AND dr.major_id = #{bo.majorId}
|
||||
AND dr.discipline_date BETWEEN #{bo.startTime} AND #{bo.endTime}
|
||||
) as dormViolationDeduction,
|
||||
(SELECT COUNT(dr.id)
|
||||
FROM xskh_discipline_record dr
|
||||
WHERE dr.deleted = 0
|
||||
AND dr.violation_source = '2'
|
||||
AND dr.status = '1'
|
||||
AND dr.class_id = c.id
|
||||
AND dr.college_id = #{bo.collegeId}
|
||||
AND dr.major_id = #{bo.majorId}
|
||||
AND dr.discipline_date BETWEEN #{bo.startTime} AND #{bo.endTime}
|
||||
) as teachingViolationCount,
|
||||
(SELECT COALESCE(SUM(dr.score_deduction), 0)
|
||||
FROM xskh_discipline_record dr
|
||||
WHERE dr.deleted = 0
|
||||
AND dr.violation_source = '2'
|
||||
AND dr.status = '1'
|
||||
AND dr.class_id = c.id
|
||||
AND dr.college_id = #{bo.collegeId}
|
||||
AND dr.major_id = #{bo.majorId}
|
||||
AND dr.discipline_date BETWEEN #{bo.startTime} AND #{bo.endTime}
|
||||
) as teachingViolationDeduction
|
||||
FROM xg_class_msg c
|
||||
WHERE c.college_id = #{bo.collegeId} AND c.major_id = #{bo.majorId} AND c.deleted = 0
|
||||
ORDER BY c.class_name ASC
|
||||
</select>
|
||||
|
||||
<!-- 按班级维度统计明细数据 -->
|
||||
<select id="getClassDetailStatistics" resultType="org.dromara.xg.domain.vo.XgStudentStatisticsVo$StatisticsDetailData">
|
||||
<choose>
|
||||
<when test="bo.classId != null">
|
||||
<!-- 班级详情统计 -->
|
||||
SELECT
|
||||
c.id as id,
|
||||
c.class_name as name,
|
||||
CONCAT(c.college_name, '-', c.major_name) as parentName,
|
||||
(SELECT COUNT(h.id)
|
||||
FROM xg_dorm_hygiene_check h
|
||||
WHERE h.deleted = 0
|
||||
AND h.check_date BETWEEN #{bo.startTime} AND #{bo.endTime}
|
||||
AND h.total_score > 0
|
||||
AND h.room_id IN (
|
||||
SELECT DISTINCT bs.room_id
|
||||
FROM xg_dorm_bed_student bs
|
||||
INNER JOIN xg_student_msg s ON bs.student_id = s.id
|
||||
WHERE s.class_id = c.id AND s.deleted = 0
|
||||
)
|
||||
) as dormDeductionCount,
|
||||
(SELECT COUNT(dr.id)
|
||||
FROM xskh_discipline_record dr
|
||||
WHERE dr.deleted = 0
|
||||
AND dr.violation_source = '1'
|
||||
AND dr.status = '1'
|
||||
AND dr.class_id = #{bo.classId}
|
||||
AND dr.discipline_date BETWEEN #{bo.startTime} AND #{bo.endTime}
|
||||
) as dormViolationCount,
|
||||
(SELECT COALESCE(SUM(dr.score_deduction), 0)
|
||||
FROM xskh_discipline_record dr
|
||||
WHERE dr.deleted = 0
|
||||
AND dr.violation_source = '1'
|
||||
AND dr.status = '1'
|
||||
AND dr.class_id = #{bo.classId}
|
||||
AND dr.discipline_date BETWEEN #{bo.startTime} AND #{bo.endTime}
|
||||
) as dormViolationDeduction,
|
||||
(SELECT COUNT(dr.id)
|
||||
FROM xskh_discipline_record dr
|
||||
WHERE dr.deleted = 0
|
||||
AND dr.violation_source = '2'
|
||||
AND dr.status = '1'
|
||||
AND dr.class_id = #{bo.classId}
|
||||
AND dr.discipline_date BETWEEN #{bo.startTime} AND #{bo.endTime}
|
||||
) as teachingViolationCount,
|
||||
(SELECT COALESCE(SUM(dr.score_deduction), 0)
|
||||
FROM xskh_discipline_record dr
|
||||
WHERE dr.deleted = 0
|
||||
AND dr.violation_source = '2'
|
||||
AND dr.status = '1'
|
||||
AND dr.class_id = #{bo.classId}
|
||||
AND dr.discipline_date BETWEEN #{bo.startTime} AND #{bo.endTime}
|
||||
) as teachingViolationDeduction,
|
||||
((SELECT COALESCE(SUM(dr.score_deduction), 0)
|
||||
FROM xskh_discipline_record dr
|
||||
WHERE dr.deleted = 0
|
||||
AND dr.violation_source = '1'
|
||||
AND dr.status = '1'
|
||||
AND dr.class_id = #{bo.classId}
|
||||
AND dr.discipline_date BETWEEN #{bo.startTime} AND #{bo.endTime}
|
||||
) +
|
||||
(SELECT COALESCE(SUM(dr.score_deduction), 0)
|
||||
FROM xskh_discipline_record dr
|
||||
WHERE dr.deleted = 0
|
||||
AND dr.violation_source = '2'
|
||||
AND dr.status = '1'
|
||||
AND dr.class_id = #{bo.classId}
|
||||
AND dr.discipline_date BETWEEN #{bo.startTime} AND #{bo.endTime}
|
||||
)) as totalDeduction
|
||||
FROM xg_class_msg c
|
||||
WHERE c.id = #{bo.classId} AND c.deleted = 0
|
||||
</when>
|
||||
<otherwise>
|
||||
<!-- 班级列表统计 -->
|
||||
SELECT
|
||||
c.id as id,
|
||||
c.class_name as name,
|
||||
c.major_name as parentName,
|
||||
(SELECT COUNT(h.id)
|
||||
FROM xg_dorm_hygiene_check h
|
||||
WHERE h.deleted = 0
|
||||
AND h.check_date BETWEEN #{bo.startTime} AND #{bo.endTime}
|
||||
AND h.total_score > 0
|
||||
AND h.room_id IN (
|
||||
SELECT DISTINCT bs.room_id
|
||||
FROM xg_dorm_bed_student bs
|
||||
INNER JOIN xg_student_msg s ON bs.student_id = s.id
|
||||
WHERE s.class_id = c.id AND s.deleted = 0
|
||||
)
|
||||
) as dormDeductionCount,
|
||||
(SELECT COUNT(dr.id)
|
||||
FROM xskh_discipline_record dr
|
||||
WHERE dr.deleted = 0
|
||||
AND dr.violation_source = '1'
|
||||
AND dr.status = '1'
|
||||
AND dr.class_id = c.id
|
||||
AND dr.college_id = #{bo.collegeId}
|
||||
AND dr.major_id = #{bo.majorId}
|
||||
AND dr.discipline_date BETWEEN #{bo.startTime} AND #{bo.endTime}
|
||||
) as dormViolationCount,
|
||||
(SELECT COALESCE(SUM(dr.score_deduction), 0)
|
||||
FROM xskh_discipline_record dr
|
||||
WHERE dr.deleted = 0
|
||||
AND dr.violation_source = '1'
|
||||
AND dr.status = '1'
|
||||
AND dr.class_id = c.id
|
||||
AND dr.college_id = #{bo.collegeId}
|
||||
AND dr.major_id = #{bo.majorId}
|
||||
AND dr.discipline_date BETWEEN #{bo.startTime} AND #{bo.endTime}
|
||||
) as dormViolationDeduction,
|
||||
(SELECT COUNT(dr.id)
|
||||
FROM xskh_discipline_record dr
|
||||
WHERE dr.deleted = 0
|
||||
AND dr.violation_source = '2'
|
||||
AND dr.status = '1'
|
||||
AND dr.class_id = c.id
|
||||
AND dr.college_id = #{bo.collegeId}
|
||||
AND dr.major_id = #{bo.majorId}
|
||||
AND dr.discipline_date BETWEEN #{bo.startTime} AND #{bo.endTime}
|
||||
) as teachingViolationCount,
|
||||
(SELECT COALESCE(SUM(dr.score_deduction), 0)
|
||||
FROM xskh_discipline_record dr
|
||||
WHERE dr.deleted = 0
|
||||
AND dr.violation_source = '2'
|
||||
AND dr.status = '1'
|
||||
AND dr.class_id = c.id
|
||||
AND dr.college_id = #{bo.collegeId}
|
||||
AND dr.major_id = #{bo.majorId}
|
||||
AND dr.discipline_date BETWEEN #{bo.startTime} AND #{bo.endTime}
|
||||
) as teachingViolationDeduction,
|
||||
((SELECT COALESCE(SUM(dr.score_deduction), 0)
|
||||
FROM xskh_discipline_record dr
|
||||
WHERE dr.deleted = 0
|
||||
AND dr.violation_source = '1'
|
||||
AND dr.status = '1'
|
||||
AND dr.class_id = c.id
|
||||
AND dr.college_id = #{bo.collegeId}
|
||||
AND dr.major_id = #{bo.majorId}
|
||||
AND dr.discipline_date BETWEEN #{bo.startTime} AND #{bo.endTime}
|
||||
) +
|
||||
(SELECT COALESCE(SUM(dr.score_deduction), 0)
|
||||
FROM xskh_discipline_record dr
|
||||
WHERE dr.deleted = 0
|
||||
AND dr.violation_source = '2'
|
||||
AND dr.status = '1'
|
||||
AND dr.class_id = c.id
|
||||
AND dr.college_id = #{bo.collegeId}
|
||||
AND dr.major_id = #{bo.majorId}
|
||||
AND dr.discipline_date BETWEEN #{bo.startTime} AND #{bo.endTime}
|
||||
)) as totalDeduction
|
||||
FROM xg_class_msg c
|
||||
WHERE c.college_id = #{bo.collegeId} AND c.major_id = #{bo.majorId} AND c.deleted = 0
|
||||
ORDER BY c.class_name ASC
|
||||
</otherwise>
|
||||
</choose>
|
||||
</select>
|
||||
|
||||
<!-- 获取二级学院列表 -->
|
||||
<select id="getColleges" resultType="org.dromara.xg.domain.vo.XgCascadeOptionVo">
|
||||
SELECT
|
||||
dept_id as id,
|
||||
dept_name as label,
|
||||
CAST(dept_id AS CHAR) as value,
|
||||
order_num as sort
|
||||
FROM sys_dept
|
||||
WHERE parent_id = 101 AND del_flag = '0'
|
||||
ORDER BY order_num ASC, dept_name ASC
|
||||
</select>
|
||||
|
||||
<!-- 根据学院ID获取专业列表 -->
|
||||
<select id="getMajorsByCollegeId" resultType="org.dromara.xg.domain.vo.XgCascadeOptionVo">
|
||||
SELECT
|
||||
dept_id as id,
|
||||
dept_name as label,
|
||||
CAST(dept_id AS CHAR) as value,
|
||||
order_num as sort
|
||||
FROM sys_dept
|
||||
WHERE parent_id = #{collegeId}
|
||||
AND dept_category LIKE 'zy-%'
|
||||
AND del_flag = '0'
|
||||
ORDER BY order_num ASC, dept_name ASC
|
||||
</select>
|
||||
|
||||
<!-- 根据专业ID获取班级列表 -->
|
||||
<select id="getClassesByMajorId" resultType="org.dromara.xg.domain.vo.XgCascadeOptionVo">
|
||||
SELECT
|
||||
id,
|
||||
class_name as label,
|
||||
CAST(id AS CHAR) as value,
|
||||
0 as sort
|
||||
FROM xg_class_msg
|
||||
WHERE major_id = #{majorId} AND deleted = 0
|
||||
ORDER BY class_name ASC
|
||||
</select>
|
||||
|
||||
</mapper>
|
||||
+1
-1
@@ -34,7 +34,7 @@
|
||||
"await-to-js": "3.0.0",
|
||||
"axios": "1.8.4",
|
||||
"crypto-js": "4.2.0",
|
||||
"echarts": "5.6.0",
|
||||
"echarts": "^5.6.0",
|
||||
"element-plus": "2.9.8",
|
||||
"file-saver": "2.0.5",
|
||||
"highlight.js": "11.9.0",
|
||||
|
||||
@@ -0,0 +1,86 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
export interface StudentStatisticsBo {
|
||||
startTime: string
|
||||
endTime: string
|
||||
collegeId?: number
|
||||
majorId?: number
|
||||
classId?: number
|
||||
}
|
||||
|
||||
export interface StatisticsChartData {
|
||||
name: string
|
||||
dormDeductionCount: number
|
||||
dormViolationCount: number
|
||||
dormViolationDeduction: number
|
||||
teachingViolationCount: number
|
||||
teachingViolationDeduction: number
|
||||
}
|
||||
|
||||
export interface StatisticsDetailData {
|
||||
id: number
|
||||
name: string
|
||||
parentName: string
|
||||
dormDeductionCount: number
|
||||
dormViolationCount: number
|
||||
dormViolationDeduction: number
|
||||
teachingViolationCount: number
|
||||
teachingViolationDeduction: number
|
||||
totalDeduction: number
|
||||
}
|
||||
|
||||
export interface StudentStatisticsVo {
|
||||
dimension: string
|
||||
chartData: StatisticsChartData[]
|
||||
detailData: StatisticsDetailData[]
|
||||
}
|
||||
|
||||
export interface CascadeOptionVo {
|
||||
id: number
|
||||
label: string
|
||||
value: string
|
||||
sort: number
|
||||
}
|
||||
|
||||
// 获取统计数据
|
||||
export function getStatistics(data: StudentStatisticsBo) {
|
||||
return request({
|
||||
url: '/xg/studentStatistics/statistics',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 导出统计数据
|
||||
export function exportStatistics(data: StudentStatisticsBo) {
|
||||
return request({
|
||||
url: '/xg/studentStatistics/export',
|
||||
method: 'post',
|
||||
data: data,
|
||||
responseType: 'blob'
|
||||
})
|
||||
}
|
||||
|
||||
// 获取二级学院列表
|
||||
export function getColleges() {
|
||||
return request({
|
||||
url: '/xg/studentStatistics/colleges',
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
// 根据学院ID获取专业列表
|
||||
export function getMajorsByCollegeId(collegeId: number) {
|
||||
return request({
|
||||
url: `/xg/studentStatistics/majors/${collegeId}`,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
// 根据专业ID获取班级列表
|
||||
export function getClassesByMajorId(majorId: number) {
|
||||
return request({
|
||||
url: `/xg/studentStatistics/classes/${majorId}`,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,426 @@
|
||||
<template>
|
||||
<div class="p-2 page-container">
|
||||
<transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
|
||||
<div v-show="showSearch" class="mb-[10px]">
|
||||
<el-card shadow="hover">
|
||||
<el-form ref="queryFormRef" :model="queryParams" label-width="120px">
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="6">
|
||||
<el-form-item label="统计开始时间" prop="startTime" required>
|
||||
<el-date-picker
|
||||
v-model="queryParams.startTime"
|
||||
type="datetime"
|
||||
placeholder="选择开始时间"
|
||||
value-format="YYYY-MM-DD HH:mm:ss"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item label="统计结束时间" prop="endTime" required>
|
||||
<el-date-picker
|
||||
v-model="queryParams.endTime"
|
||||
type="datetime"
|
||||
placeholder="选择结束时间"
|
||||
value-format="YYYY-MM-DD HH:mm:ss"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item label="二级学院" prop="collegeId">
|
||||
<el-select v-model="queryParams.collegeId" placeholder="请选择学院" clearable style="width: 100%" @change="onCollegeChange">
|
||||
<el-option v-for="item in collegeOptions" :key="item.id" :label="item.label" :value="item.id" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item label="专业" prop="majorId">
|
||||
<el-select
|
||||
v-model="queryParams.majorId"
|
||||
placeholder="请选择专业"
|
||||
clearable
|
||||
style="width: 100%"
|
||||
:disabled="!queryParams.collegeId"
|
||||
@change="onMajorChange"
|
||||
>
|
||||
<el-option v-for="item in majorOptions" :key="item.id" :label="item.label" :value="item.id" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="6">
|
||||
<el-form-item label="班级" prop="classId">
|
||||
<el-select v-model="queryParams.classId" placeholder="请选择班级" clearable style="width: 100%" :disabled="!queryParams.majorId">
|
||||
<el-option v-for="item in classOptions" :key="item.id" :label="item.label" :value="item.id" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="18">
|
||||
<el-form-item class="search-btn-container">
|
||||
<el-button type="primary" icon="Search" @click="handleQuery" :loading="loading">搜索</el-button>
|
||||
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
||||
<!-- <el-button type="success" icon="Download" @click="handleExport" :loading="exportLoading" v-if="statisticsData">导出</el-button> -->
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
</el-card>
|
||||
</div>
|
||||
</transition>
|
||||
|
||||
<!-- 无数据提示 -->
|
||||
<el-card shadow="never" v-if="!statisticsData && !loading">
|
||||
<el-empty description="暂无数据" style="padding: 60px 0">
|
||||
<template #description>
|
||||
<p style="color: #909399; font-size: 14px">请设置统计时间范围和筛选条件,然后点击【搜索】按钮查看统计数据</p>
|
||||
</template>
|
||||
</el-empty>
|
||||
</el-card>
|
||||
|
||||
<!-- 统计图表 -->
|
||||
<el-card shadow="never" v-if="statisticsData">
|
||||
<template #header>
|
||||
<el-row :gutter="10" class="mb8">
|
||||
<el-col :span="1.5">
|
||||
<div class="card-header">
|
||||
<span>{{ getChartTitle() }}</span>
|
||||
</div>
|
||||
</el-col>
|
||||
<right-toolbar :showSearch="showSearch" @update:showSearch="showSearch = $event" @queryTable="handleQuery"></right-toolbar>
|
||||
</el-row>
|
||||
</template>
|
||||
<div ref="chartRef" style="height: 400px"></div>
|
||||
</el-card>
|
||||
|
||||
<!-- 统计明细 -->
|
||||
<el-card shadow="never" v-if="statisticsData">
|
||||
<template #header>
|
||||
<div class="card-header">
|
||||
<span>明细数据</span>
|
||||
</div>
|
||||
</template>
|
||||
<el-table :data="statisticsData.detailData" style="width: 100%" border>
|
||||
<el-table-column prop="name" label="名称" width="200" />
|
||||
<el-table-column prop="parentName" label="上级" width="150" v-if="statisticsData.dimension !== 'college'" />
|
||||
<el-table-column prop="dormDeductionCount" label="宿舍扣分总数" min-width="120" align="center">
|
||||
<template #default="scope">
|
||||
{{ scope.row.dormDeductionCount && scope.row.dormDeductionCount !== 0 ? `-${scope.row.dormDeductionCount}` : '0' }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="dormViolationCount" label="宿舍违纪记录总数" min-width="140" align="center" />
|
||||
<el-table-column prop="dormViolationDeduction" label="宿舍违纪记录扣分总数" min-width="160" align="center">
|
||||
<template #default="scope">
|
||||
{{
|
||||
scope.row.dormViolationDeduction && scope.row.dormViolationDeduction !== 0 ? `-${scope.row.dormViolationDeduction.toFixed(2)}` : '0.00'
|
||||
}}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="teachingViolationCount" label="教学区违纪记录总数" min-width="160" align="center" />
|
||||
<el-table-column prop="teachingViolationDeduction" label="教学区违纪记录扣分总数" min-width="180" align="center">
|
||||
<template #default="scope">
|
||||
{{
|
||||
scope.row.teachingViolationDeduction && scope.row.teachingViolationDeduction !== 0
|
||||
? `-${scope.row.teachingViolationDeduction.toFixed(2)}`
|
||||
: '0.00'
|
||||
}}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="totalDeduction" label="违纪合计扣分" min-width="140" align="center">
|
||||
<template #default="scope">
|
||||
{{ scope.row.totalDeduction && scope.row.totalDeduction !== 0 ? `-${scope.row.totalDeduction.toFixed(2)}` : '0.00' }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive, onMounted, nextTick, getCurrentInstance, ComponentInternalInstance } from 'vue';
|
||||
import { ElMessage } from 'element-plus';
|
||||
import * as echarts from 'echarts';
|
||||
import {
|
||||
getStatistics,
|
||||
exportStatistics,
|
||||
getColleges,
|
||||
getMajorsByCollegeId,
|
||||
getClassesByMajorId,
|
||||
type StudentStatisticsBo,
|
||||
type StudentStatisticsVo,
|
||||
type CascadeOptionVo
|
||||
} from '@/api/xg/studentStatistics';
|
||||
|
||||
defineOptions({
|
||||
name: 'StudentStatistics'
|
||||
});
|
||||
|
||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||
|
||||
const queryFormRef = ref();
|
||||
const chartRef = ref<HTMLDivElement>();
|
||||
const loading = ref(false);
|
||||
const exportLoading = ref(false);
|
||||
const showSearch = ref(true);
|
||||
|
||||
// 查询参数
|
||||
const queryParams = reactive<StudentStatisticsBo>({
|
||||
startTime: '',
|
||||
endTime: '',
|
||||
collegeId: undefined,
|
||||
majorId: undefined,
|
||||
classId: undefined
|
||||
});
|
||||
|
||||
// 级联选择器选项
|
||||
const collegeOptions = ref<CascadeOptionVo[]>([]);
|
||||
const majorOptions = ref<CascadeOptionVo[]>([]);
|
||||
const classOptions = ref<CascadeOptionVo[]>([]);
|
||||
|
||||
// 统计数据
|
||||
const statisticsData = ref<StudentStatisticsVo>();
|
||||
|
||||
// 图表实例
|
||||
let chart: echarts.ECharts | null = null;
|
||||
|
||||
/** 设置默认时间范围(当前月第一天到最后一天) */
|
||||
const setDefaultTimeRange = () => {
|
||||
const now = new Date();
|
||||
const year = now.getFullYear();
|
||||
const month = now.getMonth();
|
||||
|
||||
// 当前月第一天 00:00:00
|
||||
const firstDay = new Date(year, month, 1);
|
||||
const startTime = `${firstDay.getFullYear()}-${String(firstDay.getMonth() + 1).padStart(2, '0')}-${String(firstDay.getDate()).padStart(2, '0')} 00:00:00`;
|
||||
|
||||
// 当前月最后一天 23:59:59
|
||||
const lastDay = new Date(year, month + 1, 0);
|
||||
const endTime = `${lastDay.getFullYear()}-${String(lastDay.getMonth() + 1).padStart(2, '0')}-${String(lastDay.getDate()).padStart(2, '0')} 23:59:59`;
|
||||
|
||||
queryParams.startTime = startTime;
|
||||
queryParams.endTime = endTime;
|
||||
};
|
||||
|
||||
/** 查询学院列表 */
|
||||
const getCollegeList = async () => {
|
||||
try {
|
||||
const res = await getColleges();
|
||||
collegeOptions.value = res.data || [];
|
||||
} catch (error) {
|
||||
console.error('获取学院列表失败:', error);
|
||||
}
|
||||
};
|
||||
|
||||
/** 学院变化事件 */
|
||||
const onCollegeChange = async (collegeId?: number) => {
|
||||
queryParams.majorId = undefined;
|
||||
queryParams.classId = undefined;
|
||||
majorOptions.value = [];
|
||||
classOptions.value = [];
|
||||
|
||||
if (collegeId) {
|
||||
try {
|
||||
const res = await getMajorsByCollegeId(collegeId);
|
||||
majorOptions.value = res.data || [];
|
||||
} catch (error) {
|
||||
console.error('获取专业列表失败:', error);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/** 专业变化事件 */
|
||||
const onMajorChange = async (majorId?: number) => {
|
||||
queryParams.classId = undefined;
|
||||
classOptions.value = [];
|
||||
|
||||
if (majorId) {
|
||||
try {
|
||||
const res = await getClassesByMajorId(majorId);
|
||||
classOptions.value = res.data || [];
|
||||
} catch (error) {
|
||||
console.error('获取班级列表失败:', error);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/** 搜索按钮操作 */
|
||||
const handleQuery = async () => {
|
||||
if (!queryParams.startTime || !queryParams.endTime) {
|
||||
ElMessage.warning('请填写统计开始时间和结束时间');
|
||||
return;
|
||||
}
|
||||
|
||||
loading.value = true;
|
||||
try {
|
||||
const res = await getStatistics(queryParams);
|
||||
statisticsData.value = res.data;
|
||||
|
||||
// 渲染图表
|
||||
await nextTick();
|
||||
renderChart();
|
||||
} catch (error) {
|
||||
console.error('获取统计数据失败:', error);
|
||||
ElMessage.error('获取统计数据失败');
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
/** 重置按钮操作 */
|
||||
const resetQuery = () => {
|
||||
queryFormRef.value?.resetFields();
|
||||
// 重置为默认时间范围
|
||||
setDefaultTimeRange();
|
||||
queryParams.collegeId = undefined;
|
||||
queryParams.majorId = undefined;
|
||||
queryParams.classId = undefined;
|
||||
majorOptions.value = [];
|
||||
classOptions.value = [];
|
||||
statisticsData.value = undefined;
|
||||
|
||||
if (chart) {
|
||||
chart.clear();
|
||||
}
|
||||
};
|
||||
|
||||
/** 导出按钮操作 */
|
||||
const handleExport = async () => {
|
||||
exportLoading.value = true;
|
||||
try {
|
||||
await exportStatistics(queryParams);
|
||||
ElMessage.success('导出成功');
|
||||
} catch (error) {
|
||||
console.error('导出失败:', error);
|
||||
ElMessage.error('导出失败');
|
||||
} finally {
|
||||
exportLoading.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
/** 获取图表标题 */
|
||||
const getChartTitle = () => {
|
||||
if (!statisticsData.value) return '';
|
||||
|
||||
const dimension = statisticsData.value.dimension;
|
||||
switch (dimension) {
|
||||
case 'college':
|
||||
return '二级学院统计';
|
||||
case 'major':
|
||||
return '专业统计';
|
||||
case 'class':
|
||||
return '班级统计';
|
||||
case 'classDetail':
|
||||
return '班级详情统计';
|
||||
default:
|
||||
return '统计图表';
|
||||
}
|
||||
};
|
||||
|
||||
/** 渲染图表 */
|
||||
const renderChart = () => {
|
||||
if (!chartRef.value || !statisticsData.value) return;
|
||||
|
||||
// 销毁现有图表
|
||||
if (chart) {
|
||||
chart.dispose();
|
||||
}
|
||||
|
||||
// 创建新图表
|
||||
chart = echarts.init(chartRef.value);
|
||||
|
||||
const chartData = statisticsData.value.chartData || [];
|
||||
const names = chartData.map((item) => item.name);
|
||||
|
||||
const option = {
|
||||
title: {
|
||||
text: getChartTitle(),
|
||||
left: 'center'
|
||||
},
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
axisPointer: {
|
||||
type: 'shadow'
|
||||
}
|
||||
},
|
||||
legend: {
|
||||
data: ['宿舍扣分总数', '宿舍违纪记录总数', '宿舍违纪记录扣分总数', '教学区违纪记录总数', '教学区违纪记录扣分总数'],
|
||||
top: 30
|
||||
},
|
||||
grid: {
|
||||
left: '3%',
|
||||
right: '4%',
|
||||
bottom: '3%',
|
||||
top: '15%',
|
||||
containLabel: true
|
||||
},
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
data: names,
|
||||
axisTick: {
|
||||
alignWithLabel: true
|
||||
}
|
||||
},
|
||||
yAxis: {
|
||||
type: 'value'
|
||||
},
|
||||
series: [
|
||||
{
|
||||
name: '宿舍扣分总数',
|
||||
type: 'bar',
|
||||
data: chartData.map((item) => item.dormDeductionCount)
|
||||
},
|
||||
{
|
||||
name: '宿舍违纪记录总数',
|
||||
type: 'bar',
|
||||
data: chartData.map((item) => item.dormViolationCount)
|
||||
},
|
||||
{
|
||||
name: '宿舍违纪记录扣分总数',
|
||||
type: 'bar',
|
||||
data: chartData.map((item) => item.dormViolationDeduction)
|
||||
},
|
||||
{
|
||||
name: '教学区违纪记录总数',
|
||||
type: 'bar',
|
||||
data: chartData.map((item) => item.teachingViolationCount)
|
||||
},
|
||||
{
|
||||
name: '教学区违纪记录扣分总数',
|
||||
type: 'bar',
|
||||
data: chartData.map((item) => item.teachingViolationDeduction)
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
chart.setOption(option);
|
||||
|
||||
// 监听窗口大小变化
|
||||
window.addEventListener('resize', () => {
|
||||
chart?.resize();
|
||||
});
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
// 设置默认时间范围
|
||||
setDefaultTimeRange();
|
||||
// 获取学院列表
|
||||
getCollegeList();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.page-container {
|
||||
background-color: #f5f5f5;
|
||||
}
|
||||
|
||||
.search-btn-container {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.card-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
</style>
|
||||
@@ -51,6 +51,12 @@
|
||||
<el-option v-for="type in disciplineTypeOptions" :key="type.id" :label="type.typeName" :value="type.id" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<!-- 违纪处分类型说明显示 -->
|
||||
<el-form-item label="类型说明" v-if="selectedDisciplineType && selectedDisciplineType.remark">
|
||||
<div class="discipline-type-remark">
|
||||
<el-text type="info" size="small">{{ selectedDisciplineType.remark }}</el-text>
|
||||
</div>
|
||||
</el-form-item>
|
||||
<el-form-item label="违纪处分日期" prop="disciplineDate">
|
||||
<el-date-picker
|
||||
v-model="form.disciplineDate"
|
||||
@@ -253,7 +259,7 @@
|
||||
<script setup name="DisciplineRecordForm" lang="ts">
|
||||
import { ref, reactive, computed, toRefs, getCurrentInstance } from 'vue';
|
||||
import { UploadFilled, Document, Loading, Download, Delete } from '@element-plus/icons-vue';
|
||||
import { ElMessage, ElMessageBox, ElLoading, FormInstance } from 'element-plus';
|
||||
import { ElMessage, ElMessageBox, ElLoading } from 'element-plus';
|
||||
import { getToken } from '@/utils/auth';
|
||||
import { globalHeaders } from '@/utils/request';
|
||||
import ImagePreview from '@/components/ImagePreview/index.vue';
|
||||
@@ -271,7 +277,7 @@ const emit = defineEmits(['success']);
|
||||
const { proxy } = getCurrentInstance() as any;
|
||||
const { student_discipline_status } = toRefs<any>(proxy?.useDict('student_discipline_status'));
|
||||
|
||||
const disciplineRecordFormRef = ref<FormInstance>();
|
||||
const disciplineRecordFormRef = ref<any>();
|
||||
const buttonLoading = ref(false);
|
||||
|
||||
// 学生选择器相关状态
|
||||
@@ -281,6 +287,9 @@ const studentLoading = ref(false);
|
||||
// 违纪处分类型选项
|
||||
const disciplineTypeOptions = ref<DisciplineTypeVO[]>([]);
|
||||
|
||||
// 选中的违纪处分类型信息
|
||||
const selectedDisciplineType = ref<DisciplineTypeVO | null>(null);
|
||||
|
||||
// 附件上传相关状态
|
||||
const attachmentList = ref<any[]>([]);
|
||||
|
||||
@@ -307,16 +316,12 @@ const initFormData: DisciplineRecordFormType = {
|
||||
disciplineContent: undefined,
|
||||
scoreDeduction: undefined,
|
||||
status: '1', // 默认生效
|
||||
approvalStatus: undefined,
|
||||
approvalBy: undefined,
|
||||
approvalTime: undefined,
|
||||
approvalRemark: undefined,
|
||||
attachmentOssIds: undefined
|
||||
};
|
||||
|
||||
const form = ref<DisciplineRecordFormType>({ ...initFormData });
|
||||
|
||||
const rules = reactive({
|
||||
const rules = reactive<any>({
|
||||
studentId: [{ required: true, message: '学生不能为空', trigger: 'change' }],
|
||||
disciplineTypeId: [{ required: true, message: '违纪处分类型不能为空', trigger: 'change' }],
|
||||
disciplineDate: [{ required: true, message: '违纪处分日期不能为空', trigger: 'blur' }],
|
||||
@@ -383,6 +388,14 @@ const openDialog = async (id?: string | number, title?: string) => {
|
||||
|
||||
// 处理附件数据
|
||||
await handleAttachmentData();
|
||||
|
||||
// 设置选中的违纪处分类型(用于显示类型说明)
|
||||
if (form.value.disciplineTypeId) {
|
||||
const selectedType = disciplineTypeOptions.value.find((type) => type.id === form.value.disciplineTypeId);
|
||||
if (selectedType) {
|
||||
selectedDisciplineType.value = selectedType;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -390,6 +403,7 @@ const openDialog = async (id?: string | number, title?: string) => {
|
||||
const resetForm = () => {
|
||||
form.value = { ...initFormData };
|
||||
attachmentList.value = [];
|
||||
selectedDisciplineType.value = null;
|
||||
disciplineRecordFormRef.value?.resetFields();
|
||||
};
|
||||
|
||||
@@ -478,12 +492,18 @@ const loadDisciplineTypes = async () => {
|
||||
const handleDisciplineTypeChange = (typeId: string | number) => {
|
||||
if (!typeId) {
|
||||
form.value.disciplineTypeName = undefined;
|
||||
selectedDisciplineType.value = null;
|
||||
return;
|
||||
}
|
||||
|
||||
const selectedType = disciplineTypeOptions.value.find((type) => type.id === typeId);
|
||||
if (selectedType) {
|
||||
form.value.disciplineTypeName = selectedType.typeName;
|
||||
selectedDisciplineType.value = selectedType;
|
||||
// 自动填充最低扣分(如果有的话)
|
||||
if (selectedType.minScore !== undefined && selectedType.minScore !== null) {
|
||||
form.value.scoreDeduction = Number(selectedType.minScore);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -972,6 +992,17 @@ defineExpose({
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
/* 违纪处分类型说明显示 */
|
||||
.discipline-type-remark {
|
||||
padding: 8px 12px;
|
||||
background: #f0f9ff;
|
||||
border: 1px solid #bfdbfe;
|
||||
border-radius: 4px;
|
||||
font-size: 13px;
|
||||
line-height: 1.5;
|
||||
color: #1e40af;
|
||||
}
|
||||
|
||||
.student-name-text {
|
||||
font-weight: 500;
|
||||
color: #303133;
|
||||
|
||||
Reference in new issue
Block a user