Quellcode durchsuchen

“班主任0820考核数据更新”

weizhong vor 1 Jahr
Ursprung
Commit
166c850356
33 geänderte Dateien mit 4001 neuen und 129 gelöschten Zeilen
  1. 146 0
      backend/ruoyi-modules/ruoyi-bzrkh/src/main/java/org/dromara/bzrkh/controller/AssessmentApprovalController.java
  2. 12 0
      backend/ruoyi-modules/ruoyi-bzrkh/src/main/java/org/dromara/bzrkh/controller/TeacherAssessmentController.java
  3. 35 0
      backend/ruoyi-modules/ruoyi-bzrkh/src/main/java/org/dromara/bzrkh/domain/bo/AssessmentApprovalIndicatorSubmitBo.java
  4. 56 0
      backend/ruoyi-modules/ruoyi-bzrkh/src/main/java/org/dromara/bzrkh/domain/bo/AssessmentApprovalQueryBo.java
  5. 35 0
      backend/ruoyi-modules/ruoyi-bzrkh/src/main/java/org/dromara/bzrkh/domain/bo/AssessmentApprovalSpecialWorkSubmitBo.java
  6. 70 0
      backend/ruoyi-modules/ruoyi-bzrkh/src/main/java/org/dromara/bzrkh/domain/bo/AssessmentApprovalSubmitBo.java
  7. 22 0
      backend/ruoyi-modules/ruoyi-bzrkh/src/main/java/org/dromara/bzrkh/domain/bo/BatchApprovalBo.java
  8. 111 0
      backend/ruoyi-modules/ruoyi-bzrkh/src/main/java/org/dromara/bzrkh/domain/vo/AssessmentApprovalDetailVo.java
  9. 82 0
      backend/ruoyi-modules/ruoyi-bzrkh/src/main/java/org/dromara/bzrkh/domain/vo/AssessmentApprovalIndicatorVo.java
  10. 62 0
      backend/ruoyi-modules/ruoyi-bzrkh/src/main/java/org/dromara/bzrkh/domain/vo/AssessmentApprovalSpecialWorkVo.java
  11. 163 0
      backend/ruoyi-modules/ruoyi-bzrkh/src/main/java/org/dromara/bzrkh/domain/vo/AssessmentApprovalVo.java
  12. 5 0
      backend/ruoyi-modules/ruoyi-bzrkh/src/main/java/org/dromara/bzrkh/domain/vo/AssessmentIndicatorScoreVo.java
  13. 17 0
      backend/ruoyi-modules/ruoyi-bzrkh/src/main/java/org/dromara/bzrkh/domain/vo/BmzrAssessmentPlanVo.java
  14. 39 0
      backend/ruoyi-modules/ruoyi-bzrkh/src/main/java/org/dromara/bzrkh/domain/vo/SchemeOptionVo.java
  15. 133 0
      backend/ruoyi-modules/ruoyi-bzrkh/src/main/java/org/dromara/bzrkh/mapper/AssessmentApprovalMapper.java
  16. 82 0
      backend/ruoyi-modules/ruoyi-bzrkh/src/main/java/org/dromara/bzrkh/service/IAssessmentApprovalService.java
  17. 10 0
      backend/ruoyi-modules/ruoyi-bzrkh/src/main/java/org/dromara/bzrkh/service/ITeacherAssessmentService.java
  18. 213 0
      backend/ruoyi-modules/ruoyi-bzrkh/src/main/java/org/dromara/bzrkh/service/impl/AssessmentApprovalServiceImpl.java
  19. 36 0
      backend/ruoyi-modules/ruoyi-bzrkh/src/main/java/org/dromara/bzrkh/service/impl/TeacherAssessmentServiceImpl.java
  20. 293 0
      backend/ruoyi-modules/ruoyi-bzrkh/src/main/resources/mapper/bzrkh/AssessmentApprovalMapper.xml
  21. 14 1
      backend/ruoyi-modules/ruoyi-bzrkh/src/main/resources/mapper/bzrkh/TeacherAssessmentMapper.xml
  22. 63 0
      backend/ruoyi-modules/ruoyi-bzrkh/班主任考核审核权限配置.sql
  23. 47 0
      backend/ruoyi-modules/ruoyi-bzrkh/班主任考核撤销功能权限配置.sql
  24. 0 14
      docs/开发文档/API/API文档总览.md
  25. 108 0
      web/src/api/bzrkh/assessmentApproval/index.ts
  26. 220 0
      web/src/api/bzrkh/assessmentApproval/types.ts
  27. 17 1
      web/src/api/bzrkh/teacherAssessment/index.ts
  28. 15 0
      web/src/api/bzrkh/teacherAssessment/types.ts
  29. 720 0
      web/src/views/bzrkh/assessmentApproval/approvalDialog.vue
  30. 273 0
      web/src/views/bzrkh/assessmentApproval/index.vue
  31. 577 0
      web/src/views/bzrkh/assessmentApproval/viewDialog.vue
  32. 91 40
      web/src/views/bzrkh/teacherAssessment/index.vue
  33. 234 73
      web/src/views/bzrkh/teacherAssessment/submitDialog.vue

+ 146 - 0
backend/ruoyi-modules/ruoyi-bzrkh/src/main/java/org/dromara/bzrkh/controller/AssessmentApprovalController.java

@@ -0,0 +1,146 @@
+package org.dromara.bzrkh.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.mybatis.core.page.PageQuery;
+import org.dromara.common.core.domain.R;
+import org.dromara.common.log.enums.BusinessType;
+import org.dromara.bzrkh.domain.vo.AssessmentApprovalVo;
+import org.dromara.bzrkh.domain.vo.AssessmentApprovalDetailVo;
+import org.dromara.bzrkh.domain.vo.SchemeOptionVo;
+import org.dromara.bzrkh.domain.bo.AssessmentApprovalQueryBo;
+import org.dromara.bzrkh.domain.bo.AssessmentApprovalSubmitBo;
+import org.dromara.bzrkh.domain.bo.BatchApprovalBo;
+import org.dromara.bzrkh.service.IAssessmentApprovalService;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.common.satoken.utils.LoginHelper;
+import org.dromara.common.excel.utils.ExcelUtil;
+import jakarta.servlet.http.HttpServletResponse;
+
+/**
+ * 班主任考核审核Controller
+ *
+ * @author ruoyi
+ * @date 2025-01-28
+ */
+@Validated
+@RequiredArgsConstructor
+@RestController
+@RequestMapping("/bzrkh/assessmentApproval")
+public class AssessmentApprovalController extends BaseController {
+
+    private final IAssessmentApprovalService assessmentApprovalService;
+
+    /**
+     * 查询班主任考核审核列表
+     */
+    @SaCheckPermission("bzrkh:assessmentApproval:list")
+    @GetMapping("/list")
+    public TableDataInfo<AssessmentApprovalVo> list(AssessmentApprovalQueryBo bo, PageQuery pageQuery) {
+        return assessmentApprovalService.queryPageList(bo, pageQuery);
+    }
+
+    /**
+     * 获取考核审核详情
+     */
+    @SaCheckPermission("bzrkh:assessmentApproval:query")
+    @GetMapping("/detail")
+    public R<AssessmentApprovalDetailVo> getApprovalDetail(
+            @RequestParam @NotNull(message = "计划ID不能为空") Long planId,
+            @RequestParam @NotNull(message = "班级ID不能为空") Long classId,
+            @RequestParam @NotNull(message = "被评价用户ID不能为空") Long evaluatedUserId) {
+        AssessmentApprovalDetailVo detail = assessmentApprovalService.getApprovalDetail(planId, classId, evaluatedUserId);
+        return R.ok(detail);
+    }
+
+    /**
+     * 提交考核审核
+     */
+    @SaCheckPermission("bzrkh:assessmentApproval:approve")
+    @Log(title = "班主任考核审核", businessType = BusinessType.UPDATE)
+    @PostMapping("/submit")
+    public R<Void> submitApproval(@RequestBody @Validated AssessmentApprovalSubmitBo bo) {
+        Long approverUserId = LoginHelper.getUserId();
+        boolean result = assessmentApprovalService.submitApproval(bo, approverUserId);
+        return toAjax(result);
+    }
+
+    /**
+     * 批量审核通过
+     */
+    @SaCheckPermission("bzrkh:assessmentApproval:approve")
+    @Log(title = "班主任考核审核", businessType = BusinessType.UPDATE)
+    @PostMapping("/batchApprove")
+    public R<Void> batchApprove(@RequestBody BatchApprovalBo bo) {
+        Long approverUserId = LoginHelper.getUserId();
+        boolean result = assessmentApprovalService.batchApprove(bo.getIds(), approverUserId);
+        return toAjax(result);
+    }
+
+    /**
+     * 批量审核拒绝
+     */
+    @SaCheckPermission("bzrkh:assessmentApproval:approve")
+    @Log(title = "班主任考核审核", businessType = BusinessType.UPDATE)
+    @PostMapping("/batchReject")
+    public R<Void> batchReject(@RequestBody BatchRejectBo bo) {
+        Long approverUserId = LoginHelper.getUserId();
+        boolean result = assessmentApprovalService.batchReject(bo.getIds(), bo.getRejectReason(), approverUserId);
+        return toAjax(result);
+    }
+
+    /**
+     * 获取考核方案下拉选项
+     */
+    @SaCheckPermission("bzrkh:assessmentApproval:list")
+    @GetMapping("/schemeOptions")
+    public R<List<SchemeOptionVo>> getSchemeOptions() {
+        List<SchemeOptionVo> options = assessmentApprovalService.getSchemeOptions();
+        return R.ok(options);
+    }
+
+    /**
+     * 导出班主任考核审核数据
+     */
+    @SaCheckPermission("bzrkh:assessmentApproval:export")
+    @Log(title = "班主任考核审核", businessType = BusinessType.EXPORT)
+    @PostMapping("/export")
+    public void export(AssessmentApprovalQueryBo bo, HttpServletResponse response) {
+        List<AssessmentApprovalVo> list = assessmentApprovalService.queryList(bo);
+        ExcelUtil.exportExcel(list, "班主任考核审核数据", AssessmentApprovalVo.class, response);
+    }
+
+    /**
+     * 批量拒绝请求对象
+     */
+    public static class BatchRejectBo {
+        @NotEmpty(message = "审核ID列表不能为空")
+        private List<Long> ids;
+        
+        @NotBlank(message = "拒绝原因不能为空")
+        private String rejectReason;
+
+        public List<Long> getIds() {
+            return ids;
+        }
+
+        public void setIds(List<Long> ids) {
+            this.ids = ids;
+        }
+
+        public String getRejectReason() {
+            return rejectReason;
+        }
+
+        public void setRejectReason(String rejectReason) {
+            this.rejectReason = rejectReason;
+        }
+    }
+} 

+ 12 - 0
backend/ruoyi-modules/ruoyi-bzrkh/src/main/java/org/dromara/bzrkh/controller/TeacherAssessmentController.java

@@ -73,6 +73,18 @@ public class TeacherAssessmentController extends BaseController {
         return toAjax(result);
     }
 
+    /**
+     * 撤销考核提交
+     */
+    @SaCheckPermission("bzrkh:teacherAssessment:withdraw")
+    @Log(title = "班主任考核管理", businessType = BusinessType.UPDATE)
+    @PostMapping("/withdraw")
+    public R<Void> withdrawAssessment(@RequestBody TeacherAssessmentSubmitRequest request) {
+        Long teacherId = LoginHelper.getUserId();
+        boolean result = teacherAssessmentService.withdrawAssessment(request.getPlanId(), request.getClassId(), teacherId);
+        return toAjax(result);
+    }
+
     /**
      * 查看考核详情
      */

+ 35 - 0
backend/ruoyi-modules/ruoyi-bzrkh/src/main/java/org/dromara/bzrkh/domain/bo/AssessmentApprovalIndicatorSubmitBo.java

@@ -0,0 +1,35 @@
+package org.dromara.bzrkh.domain.bo;
+
+import lombok.Data;
+
+import java.math.BigDecimal;
+
+/**
+ * 指标审核提交业务对象
+ *
+ * @author ruoyi
+ * @date 2025-01-28
+ */
+@Data
+public class AssessmentApprovalIndicatorSubmitBo {
+
+    /**
+     * 主键ID
+     */
+    private Long id;
+
+    /**
+     * 指标ID
+     */
+    private Long indicatorId;
+
+    /**
+     * 上级评分数
+     */
+    private BigDecimal superiorScore;
+
+    /**
+     * 上级评意见
+     */
+    private String superiorComment;
+} 

+ 56 - 0
backend/ruoyi-modules/ruoyi-bzrkh/src/main/java/org/dromara/bzrkh/domain/bo/AssessmentApprovalQueryBo.java

@@ -0,0 +1,56 @@
+package org.dromara.bzrkh.domain.bo;
+
+import org.dromara.common.mybatis.core.domain.BaseEntity;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * 班主任考核审核查询对象
+ *
+ * @author ruoyi
+ * @date 2025-01-28
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class AssessmentApprovalQueryBo extends BaseEntity {
+
+    /**
+     * 计划名称
+     */
+    private String planName;
+
+    /**
+     * 考核方案名称
+     */
+    private String schemeName;
+
+    /**
+     * 审核状态(0=待审核 1=审核通过 2=审核不通过)
+     */
+    private String auditStatus;
+
+    /**
+     * 班级名称
+     */
+    private String className;
+
+    /**
+     * 班主任姓名
+     */
+    private String teacherName;
+
+    /**
+     * 被评价用户姓名
+     */
+    private String evaluatedUserName;
+
+    /**
+     * 学年
+     */
+    private String academicYear;
+
+    /**
+     * 学期
+     */
+    private String semester;
+} 

+ 35 - 0
backend/ruoyi-modules/ruoyi-bzrkh/src/main/java/org/dromara/bzrkh/domain/bo/AssessmentApprovalSpecialWorkSubmitBo.java

@@ -0,0 +1,35 @@
+package org.dromara.bzrkh.domain.bo;
+
+import lombok.Data;
+
+import java.math.BigDecimal;
+
+/**
+ * 特色工作审核提交业务对象
+ *
+ * @author ruoyi
+ * @date 2025-01-28
+ */
+@Data
+public class AssessmentApprovalSpecialWorkSubmitBo {
+
+    /**
+     * 主键ID
+     */
+    private Long id;
+
+    /**
+     * 指标编码
+     */
+    private String indicatorCode;
+
+    /**
+     * 上级评分数
+     */
+    private BigDecimal superiorScore;
+
+    /**
+     * 上级评意见
+     */
+    private String superiorComment;
+} 

+ 70 - 0
backend/ruoyi-modules/ruoyi-bzrkh/src/main/java/org/dromara/bzrkh/domain/bo/AssessmentApprovalSubmitBo.java

@@ -0,0 +1,70 @@
+package org.dromara.bzrkh.domain.bo;
+
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+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.NotNull;
+import java.util.List;
+
+/**
+ * 考核审核提交业务对象
+ *
+ * @author ruoyi
+ * @date 2025-01-28
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class AssessmentApprovalSubmitBo extends BaseEntity {
+
+    /**
+     * 考核计划ID
+     */
+    @NotNull(message = "考核计划ID不能为空", groups = { AddGroup.class, EditGroup.class })
+    private Long planId;
+
+    /**
+     * 班级ID
+     */
+    @NotNull(message = "班级ID不能为空", groups = { AddGroup.class, EditGroup.class })
+    private Long classId;
+
+    /**
+     * 被评价用户ID
+     */
+    @NotNull(message = "被评价用户ID不能为空", groups = { AddGroup.class, EditGroup.class })
+    private Long evaluatedUserId;
+
+    /**
+     * 班主任常规工作审核数据
+     */
+    private List<AssessmentApprovalIndicatorSubmitBo> routineWorkApproval;
+
+    /**
+     * 班级管理实效审核数据
+     */
+    private AssessmentApprovalIndicatorSubmitBo classDeductionApproval;
+
+    /**
+     * 特色工作审核数据
+     */
+    private List<AssessmentApprovalSpecialWorkSubmitBo> specialWorkApproval;
+
+    /**
+     * 上级总体评价
+     */
+    private String superiorOverallComment;
+
+    /**
+     * 审核状态 0=待审核 1=审核通过 2=审核不通过
+     */
+    @NotNull(message = "审核状态不能为空", groups = { AddGroup.class, EditGroup.class })
+    private String auditStatus;
+
+    /**
+     * 审核意见
+     */
+    private String auditComment;
+} 

+ 22 - 0
backend/ruoyi-modules/ruoyi-bzrkh/src/main/java/org/dromara/bzrkh/domain/bo/BatchApprovalBo.java

@@ -0,0 +1,22 @@
+package org.dromara.bzrkh.domain.bo;
+
+import lombok.Data;
+import jakarta.validation.constraints.NotEmpty;
+
+import java.util.List;
+
+/**
+ * 批量审核业务对象
+ *
+ * @author ruoyi
+ * @date 2025-01-28
+ */
+@Data
+public class BatchApprovalBo {
+
+    /**
+     * 审核ID列表
+     */
+    @NotEmpty(message = "审核ID列表不能为空")
+    private List<Long> ids;
+} 

+ 111 - 0
backend/ruoyi-modules/ruoyi-bzrkh/src/main/java/org/dromara/bzrkh/domain/vo/AssessmentApprovalDetailVo.java

@@ -0,0 +1,111 @@
+package org.dromara.bzrkh.domain.vo;
+
+import lombok.Data;
+import com.fasterxml.jackson.annotation.JsonFormat;
+
+import java.io.Serial;
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * 考核审核详情视图对象
+ *
+ * @author ruoyi
+ * @date 2025-01-28
+ */
+@Data
+public class AssessmentApprovalDetailVo implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 主键ID
+     */
+    private Long id;
+
+    /**
+     * 考核计划ID
+     */
+    private Long planId;
+
+    /**
+     * 班级ID
+     */
+    private Long classId;
+
+    /**
+     * 班级详细信息
+     */
+    private ClassDetailVo classDetail;
+
+    /**
+     * 系数信息
+     */
+    private CoefficientVo coefficient;
+
+    /**
+     * 班主任常规工作指标列表 - 包含自评和上级评分
+     */
+    private List<AssessmentApprovalIndicatorVo> routineWorkIndicators;
+
+    /**
+     * 班级扣分指标 - 班级管理实效
+     */
+    private AssessmentApprovalIndicatorVo classDeductionIndicator;
+
+    /**
+     * 特色工作指标列表
+     */
+    private List<AssessmentApprovalSpecialWorkVo> specialWorkIndicators;
+
+    /**
+     * 自我总体评价
+     */
+    private String selfOverallComment;
+
+    /**
+     * 上级总体评价
+     */
+    private String superiorOverallComment;
+
+    /**
+     * 月考核得分
+     */
+    private BigDecimal monthlyScore;
+
+    /**
+     * 审核状态
+     */
+    private String auditStatus;
+
+    /**
+     * 提交时间
+     */
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date submitTime;
+
+    /**
+     * 创建者
+     */
+    private Long createBy;
+
+    /**
+     * 创建时间
+     */
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date createTime;
+
+    /**
+     * 更新者
+     */
+    private Long updateBy;
+
+    /**
+     * 更新时间
+     */
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date updateTime;
+} 

+ 82 - 0
backend/ruoyi-modules/ruoyi-bzrkh/src/main/java/org/dromara/bzrkh/domain/vo/AssessmentApprovalIndicatorVo.java

@@ -0,0 +1,82 @@
+package org.dromara.bzrkh.domain.vo;
+
+import lombok.Data;
+
+import java.io.Serial;
+import java.io.Serializable;
+import java.math.BigDecimal;
+
+/**
+ * 审核指标视图对象 - 包含自评和上级评分
+ *
+ * @author ruoyi
+ * @date 2025-01-28
+ */
+@Data
+public class AssessmentApprovalIndicatorVo implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 主键ID
+     */
+    private Long id;
+
+    /**
+     * 指标ID
+     */
+    private Long indicatorId;
+
+    /**
+     * 指标名称
+     */
+    private String indicatorName;
+
+    /**
+     * 指标编码
+     */
+    private String indicatorCode;
+
+    /**
+     * 指标描述
+     */
+    private String description;
+
+    /**
+     * 指标分值
+     */
+    private BigDecimal score;
+
+    /**
+     * 最高分值
+     */
+    private BigDecimal maxScore;
+
+    // 自评相关
+    /**
+     * 自评分数
+     */
+    private BigDecimal selfScore;
+
+    /**
+     * 自评意见
+     */
+    private String selfComment;
+
+    // 上级评相关
+    /**
+     * 上级评分数
+     */
+    private BigDecimal superiorScore;
+
+    /**
+     * 上级评意见
+     */
+    private String superiorComment;
+
+    /**
+     * 审核状态
+     */
+    private String auditStatus;
+} 

+ 62 - 0
backend/ruoyi-modules/ruoyi-bzrkh/src/main/java/org/dromara/bzrkh/domain/vo/AssessmentApprovalSpecialWorkVo.java

@@ -0,0 +1,62 @@
+package org.dromara.bzrkh.domain.vo;
+
+import lombok.Data;
+
+import java.io.Serial;
+import java.io.Serializable;
+import java.math.BigDecimal;
+
+/**
+ * 特色工作审核视图对象
+ *
+ * @author ruoyi
+ * @date 2025-01-28
+ */
+@Data
+public class AssessmentApprovalSpecialWorkVo implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 主键ID
+     */
+    private Long id;
+
+    /**
+     * 指标编码
+     */
+    private String indicatorCode;
+
+    /**
+     * 指标名称
+     */
+    private String indicatorName;
+
+    // 自评相关
+    /**
+     * 自评分数
+     */
+    private BigDecimal score;
+
+    /**
+     * 自评意见
+     */
+    private String selfComment;
+
+    // 上级评相关
+    /**
+     * 上级评分数
+     */
+    private BigDecimal superiorScore;
+
+    /**
+     * 上级评意见
+     */
+    private String superiorComment;
+
+    /**
+     * 审核状态
+     */
+    private String auditStatus;
+} 

+ 163 - 0
backend/ruoyi-modules/ruoyi-bzrkh/src/main/java/org/dromara/bzrkh/domain/vo/AssessmentApprovalVo.java

@@ -0,0 +1,163 @@
+package org.dromara.bzrkh.domain.vo;
+
+import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
+import cn.idev.excel.annotation.ExcelProperty;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+
+import java.io.Serial;
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.util.Date;
+
+/**
+ * 班主任考核审核视图对象
+ *
+ * @author ruoyi
+ * @date 2025-01-28
+ */
+@Data
+@ExcelIgnoreUnannotated
+public class AssessmentApprovalVo implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 主键ID
+     */
+    @ExcelProperty(value = "主键ID")
+    private Long id;
+
+    /**
+     * 考核计划ID
+     */
+    private Long planId;
+
+    /**
+     * 考核计划名称
+     */
+    @ExcelProperty(value = "计划名称")
+    private String planName;
+
+    /**
+     * 考核计划编码
+     */
+    @ExcelProperty(value = "计划编码")
+    private String planCode;
+
+    /**
+     * 考核方案ID
+     */
+    private Long schemeId;
+
+    /**
+     * 考核方案名称
+     */
+    @ExcelProperty(value = "考核方案")
+    private String schemeName;
+
+    /**
+     * 学年
+     */
+    @ExcelProperty(value = "学年")
+    private String academicYear;
+
+    /**
+     * 学期
+     */
+    @ExcelProperty(value = "学期")
+    private String semester;
+
+    /**
+     * 班级ID
+     */
+    private Long classId;
+
+    /**
+     * 班级名称
+     */
+    @ExcelProperty(value = "班级名称")
+    private String className;
+
+    /**
+     * 班主任用户ID
+     */
+    private Long teacherId;
+
+    /**
+     * 班主任姓名
+     */
+    @ExcelProperty(value = "班主任姓名")
+    private String teacherName;
+
+    /**
+     * 被评价用户ID
+     */
+    private Long evaluatedUserId;
+
+    /**
+     * 被评价用户姓名
+     */
+    @ExcelProperty(value = "被评价用户姓名")
+    private String evaluatedUserName;
+
+    /**
+     * 提交时间
+     */
+    @ExcelProperty(value = "提交时间")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date submitTime;
+
+    /**
+     * 审核状态(0=待审核 1=审核通过 2=审核不通过)
+     */
+    @ExcelProperty(value = "审核状态")
+    private String auditStatus;
+
+    /**
+     * 审核状态文本
+     */
+    private String auditStatusText;
+
+    /**
+     * 自评总分
+     */
+    @ExcelProperty(value = "自评总分")
+    private BigDecimal selfScore;
+
+    /**
+     * 上级评总分
+     */
+    @ExcelProperty(value = "上级评总分")
+    private BigDecimal superiorScore;
+
+    /**
+     * 最终得分
+     */
+    @ExcelProperty(value = "最终得分")
+    private BigDecimal finalScore;
+
+    /**
+     * 创建时间
+     */
+    @ExcelProperty(value = "创建时间")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date createTime;
+
+    /**
+     * 创建者
+     */
+    private Long createBy;
+
+    /**
+     * 更新时间
+     */
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date updateTime;
+
+    /**
+     * 更新者
+     */
+    private Long updateBy;
+} 

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

@@ -65,6 +65,11 @@ public class AssessmentIndicatorScoreVo implements Serializable {
      */
     private Integer sortOrder;
 
+    /**
+     * 审核状态(0=待审核,1=审核通过,2=审核不通过)
+     */
+    private String auditStatus;
+
     /**
      * 创建者
      */

+ 17 - 0
backend/ruoyi-modules/ruoyi-bzrkh/src/main/java/org/dromara/bzrkh/domain/vo/BmzrAssessmentPlanVo.java

@@ -150,4 +150,21 @@ public class BmzrAssessmentPlanVo implements Serializable {
      * 删除标志(0代表存在 1代表删除)
      */
     private String deleted;
+
+    /**
+     * 审核状态(null=未提交,0=已提交待审核,1=审核通过,2=审核不通过)
+     */
+    @ExcelProperty(value = "审核状态")
+    private String auditStatus;
+
+    /**
+     * 提交时间
+     */
+    @ExcelProperty(value = "提交时间")
+    private Date submitTime;
+
+    /**
+     * 是否已提交(用于前端按钮状态控制)
+     */
+    private Boolean submitted;
 } 

+ 39 - 0
backend/ruoyi-modules/ruoyi-bzrkh/src/main/java/org/dromara/bzrkh/domain/vo/SchemeOptionVo.java

@@ -0,0 +1,39 @@
+package org.dromara.bzrkh.domain.vo;
+
+import lombok.Data;
+
+import java.io.Serial;
+import java.io.Serializable;
+
+/**
+ * 考核方案选项视图对象
+ *
+ * @author ruoyi
+ * @date 2025-01-28
+ */
+@Data
+public class SchemeOptionVo implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 选项值
+     */
+    private String value;
+
+    /**
+     * 选项标签
+     */
+    private String label;
+
+    /**
+     * 方案ID
+     */
+    private Long schemeId;
+
+    /**
+     * 方案编码
+     */
+    private String schemeCode;
+} 

+ 133 - 0
backend/ruoyi-modules/ruoyi-bzrkh/src/main/java/org/dromara/bzrkh/mapper/AssessmentApprovalMapper.java

@@ -0,0 +1,133 @@
+package org.dromara.bzrkh.mapper;
+
+import org.dromara.bzrkh.domain.vo.AssessmentApprovalVo;
+import org.dromara.bzrkh.domain.vo.AssessmentApprovalDetailVo;
+import org.dromara.bzrkh.domain.vo.AssessmentApprovalIndicatorVo;
+import org.dromara.bzrkh.domain.vo.AssessmentApprovalSpecialWorkVo;
+import org.dromara.bzrkh.domain.vo.SchemeOptionVo;
+import org.dromara.bzrkh.domain.bo.AssessmentApprovalQueryBo;
+import org.dromara.bzrkh.domain.BmzrAssessmentScore;
+import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+/**
+ * 班主任考核审核Mapper接口
+ *
+ * @author ruoyi
+ * @date 2025-01-28
+ */
+public interface AssessmentApprovalMapper extends BaseMapperPlus<BmzrAssessmentScore, AssessmentApprovalVo> {
+
+    /**
+     * 查询班主任考核审核列表
+     *
+     * @param bo 查询条件
+     * @return 班主任考核审核列表
+     */
+    List<AssessmentApprovalVo> queryList(AssessmentApprovalQueryBo bo);
+
+    /**
+     * 获取考核审核基本信息
+     *
+     * @param planId          计划ID
+     * @param classId         班级ID
+     * @param evaluatedUserId 被评价用户ID
+     * @return 审核基本信息
+     */
+    AssessmentApprovalDetailVo getApprovalBasicInfo(@Param("planId") Long planId, 
+                                                    @Param("classId") Long classId, 
+                                                    @Param("evaluatedUserId") Long evaluatedUserId);
+
+    /**
+     * 获取班主任常规工作指标列表
+     *
+     * @param planId          计划ID
+     * @param classId         班级ID
+     * @param evaluatedUserId 被评价用户ID
+     * @return 常规工作指标列表
+     */
+    List<AssessmentApprovalIndicatorVo> getRoutineWorkIndicators(@Param("planId") Long planId, 
+                                                                 @Param("classId") Long classId, 
+                                                                 @Param("evaluatedUserId") Long evaluatedUserId);
+
+    /**
+     * 获取班级扣分指标(班级管理实效)
+     *
+     * @param planId          计划ID
+     * @param classId         班级ID
+     * @param evaluatedUserId 被评价用户ID
+     * @return 班级扣分指标
+     */
+    AssessmentApprovalIndicatorVo getClassDeductionIndicator(@Param("planId") Long planId, 
+                                                             @Param("classId") Long classId, 
+                                                             @Param("evaluatedUserId") Long evaluatedUserId);
+
+    /**
+     * 获取特色工作指标列表
+     *
+     * @param planId          计划ID
+     * @param classId         班级ID
+     * @param evaluatedUserId 被评价用户ID
+     * @return 特色工作指标列表
+     */
+    List<AssessmentApprovalSpecialWorkVo> getSpecialWorkIndicators(@Param("planId") Long planId, 
+                                                                   @Param("classId") Long classId, 
+                                                                   @Param("evaluatedUserId") Long evaluatedUserId);
+
+    /**
+     * 更新上级评分和意见
+     *
+     * @param id              分数记录ID
+     * @param superiorScore   上级评分
+     * @param superiorComment 上级评意见
+     * @param approverUserId  审核人用户ID
+     * @return 更新条数
+     */
+    int updateSuperiorScore(@Param("id") Long id, 
+                           @Param("superiorScore") String superiorScore, 
+                           @Param("superiorComment") String superiorComment,
+                           @Param("approverUserId") Long approverUserId);
+
+    /**
+     * 更新审核状态和意见
+     *
+     * @param planId                    计划ID
+     * @param classId                   班级ID
+     * @param evaluatedUserId           被评价用户ID
+     * @param auditStatus               审核状态
+     * @param auditComment              审核意见
+     * @param superiorOverallComment    上级总体评价
+     * @param approverUserId            审核人用户ID
+     * @return 更新条数
+     */
+    int updateAuditStatus(@Param("planId") Long planId, 
+                         @Param("classId") Long classId, 
+                         @Param("evaluatedUserId") Long evaluatedUserId,
+                         @Param("auditStatus") String auditStatus, 
+                         @Param("auditComment") String auditComment,
+                         @Param("superiorOverallComment") String superiorOverallComment,
+                         @Param("approverUserId") Long approverUserId);
+
+    /**
+     * 批量更新审核状态
+     *
+     * @param ids            审核ID列表
+     * @param auditStatus    审核状态
+     * @param auditComment   审核意见
+     * @param approverUserId 审核人用户ID
+     * @return 更新条数
+     */
+    int batchUpdateAuditStatus(@Param("ids") List<Long> ids, 
+                              @Param("auditStatus") String auditStatus, 
+                              @Param("auditComment") String auditComment,
+                              @Param("approverUserId") Long approverUserId);
+
+    /**
+     * 获取考核方案下拉选项
+     *
+     * @return 方案选项列表
+     */
+    List<SchemeOptionVo> getSchemeOptions();
+} 

+ 82 - 0
backend/ruoyi-modules/ruoyi-bzrkh/src/main/java/org/dromara/bzrkh/service/IAssessmentApprovalService.java

@@ -0,0 +1,82 @@
+package org.dromara.bzrkh.service;
+
+import org.dromara.bzrkh.domain.vo.AssessmentApprovalVo;
+import org.dromara.bzrkh.domain.vo.AssessmentApprovalDetailVo;
+import org.dromara.bzrkh.domain.vo.SchemeOptionVo;
+import org.dromara.bzrkh.domain.bo.AssessmentApprovalQueryBo;
+import org.dromara.bzrkh.domain.bo.AssessmentApprovalSubmitBo;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.common.mybatis.core.page.PageQuery;
+
+import java.util.List;
+
+/**
+ * 班主任考核审核Service接口
+ *
+ * @author ruoyi
+ * @date 2025-01-28
+ */
+public interface IAssessmentApprovalService {
+
+    /**
+     * 查询班主任考核审核列表
+     *
+     * @param bo        查询条件
+     * @param pageQuery 分页参数
+     * @return 班主任考核审核列表
+     */
+    TableDataInfo<AssessmentApprovalVo> queryPageList(AssessmentApprovalQueryBo bo, PageQuery pageQuery);
+
+    /**
+     * 查询班主任考核审核列表
+     *
+     * @param bo 查询条件
+     * @return 班主任考核审核列表
+     */
+    List<AssessmentApprovalVo> queryList(AssessmentApprovalQueryBo bo);
+
+    /**
+     * 获取考核审核详情
+     *
+     * @param planId           计划ID
+     * @param classId          班级ID
+     * @param evaluatedUserId  被评价用户ID
+     * @return 审核详情
+     */
+    AssessmentApprovalDetailVo getApprovalDetail(Long planId, Long classId, Long evaluatedUserId);
+
+    /**
+     * 提交考核审核
+     *
+     * @param bo             审核数据
+     * @param approverUserId 审核人用户ID
+     * @return 是否成功
+     */
+    boolean submitApproval(AssessmentApprovalSubmitBo bo, Long approverUserId);
+
+    /**
+     * 批量审核通过
+     *
+     * @param ids            审核ID列表
+     * @param approverUserId 审核人用户ID
+     * @return 是否成功
+     */
+    boolean batchApprove(List<Long> ids, Long approverUserId);
+
+    /**
+     * 批量审核拒绝
+     *
+     * @param ids            审核ID列表
+     * @param rejectReason   拒绝原因
+     * @param approverUserId 审核人用户ID
+     * @return 是否成功
+     */
+    boolean batchReject(List<Long> ids, String rejectReason, Long approverUserId);
+
+    /**
+     * 获取考核方案下拉选项
+     *
+     * @return 方案选项列表
+     */
+    List<SchemeOptionVo> getSchemeOptions();
+} 

+ 10 - 0
backend/ruoyi-modules/ruoyi-bzrkh/src/main/java/org/dromara/bzrkh/service/ITeacherAssessmentService.java

@@ -75,6 +75,16 @@ public interface ITeacherAssessmentService {
      */
     boolean submitAssessmentScore(AssessmentSubmitBo bo, Long teacherId);
 
+    /**
+     * 撤销考核提交
+     *
+     * @param planId    计划ID
+     * @param classId   班级ID
+     * @param teacherId 班主任ID
+     * @return 是否成功
+     */
+    boolean withdrawAssessment(Long planId, Long classId, Long teacherId);
+
     /**
      * 测试人数系数计算(临时调试方法)
      * 用于验证特定人数的系数计算是否正确

+ 213 - 0
backend/ruoyi-modules/ruoyi-bzrkh/src/main/java/org/dromara/bzrkh/service/impl/AssessmentApprovalServiceImpl.java

@@ -0,0 +1,213 @@
+package org.dromara.bzrkh.service.impl;
+
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.common.mybatis.core.page.PageQuery;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import org.dromara.common.core.utils.MapstructUtils;
+import org.dromara.bzrkh.domain.vo.AssessmentApprovalVo;
+import org.dromara.bzrkh.domain.vo.AssessmentApprovalDetailVo;
+import org.dromara.bzrkh.domain.vo.AssessmentApprovalIndicatorVo;
+import org.dromara.bzrkh.domain.vo.AssessmentApprovalSpecialWorkVo;
+import org.dromara.bzrkh.domain.vo.SchemeOptionVo;
+import org.dromara.bzrkh.domain.vo.ClassDetailVo;
+import org.dromara.bzrkh.domain.vo.CoefficientVo;
+import org.dromara.bzrkh.domain.bo.AssessmentApprovalQueryBo;
+import org.dromara.bzrkh.domain.bo.AssessmentApprovalSubmitBo;
+import org.dromara.bzrkh.domain.bo.AssessmentApprovalIndicatorSubmitBo;
+import org.dromara.bzrkh.domain.bo.AssessmentApprovalSpecialWorkSubmitBo;
+import org.dromara.bzrkh.mapper.AssessmentApprovalMapper;
+import org.dromara.bzrkh.service.IAssessmentApprovalService;
+import org.dromara.bzrkh.service.ITeacherAssessmentService;
+
+import java.util.List;
+import java.util.Date;
+
+/**
+ * 班主任考核审核Service业务层处理
+ *
+ * @author ruoyi
+ * @date 2025-01-28
+ */
+@RequiredArgsConstructor
+@Service
+public class AssessmentApprovalServiceImpl implements IAssessmentApprovalService {
+
+    private final AssessmentApprovalMapper assessmentApprovalMapper;
+    private final ITeacherAssessmentService teacherAssessmentService;
+
+    @Override
+    public TableDataInfo<AssessmentApprovalVo> queryPageList(AssessmentApprovalQueryBo bo, PageQuery pageQuery) {
+        Page<AssessmentApprovalVo> page = pageQuery.build();
+        List<AssessmentApprovalVo> list = assessmentApprovalMapper.queryList(bo);
+        
+        // 手动分页处理
+        int total = list.size();
+        int start = (int) ((page.getCurrent() - 1) * page.getSize());
+        int end = Math.min(start + (int) page.getSize(), total);
+        
+        List<AssessmentApprovalVo> pageList = list.subList(start, end);
+        
+        page.setRecords(pageList);
+        page.setTotal(total);
+        
+        return TableDataInfo.build(page);
+    }
+
+    @Override
+    public List<AssessmentApprovalVo> queryList(AssessmentApprovalQueryBo bo) {
+        return assessmentApprovalMapper.queryList(bo);
+    }
+
+    @Override
+    public AssessmentApprovalDetailVo getApprovalDetail(Long planId, Long classId, Long evaluatedUserId) {
+        // 1. 获取基本信息
+        AssessmentApprovalDetailVo detail = assessmentApprovalMapper.getApprovalBasicInfo(planId, classId, evaluatedUserId);
+        if (detail == null) {
+            throw new RuntimeException("未找到考核审核数据");
+        }
+
+        // 2. 获取班级详细信息和系数信息(复用现有service)
+        try {
+            // 使用现有的获取考核详情方法来获取班级信息和系数
+            var assessmentDetail = teacherAssessmentService.getAssessmentSubmitDetail(planId, classId, evaluatedUserId);
+            
+            ClassDetailVo classDetail = new ClassDetailVo();
+            classDetail.setId(assessmentDetail.getClassDetail().getId());
+            classDetail.setClassName(assessmentDetail.getClassDetail().getClassName());
+            classDetail.setCollegeName(assessmentDetail.getClassDetail().getCollegeName());
+            classDetail.setMajorName(assessmentDetail.getClassDetail().getMajorName());
+            classDetail.setClassType(assessmentDetail.getClassDetail().getClassType());
+            classDetail.setTotalStudentCount(assessmentDetail.getClassDetail().getTotalStudentCount());
+            classDetail.setBoardingStudentCount(assessmentDetail.getClassDetail().getBoardingStudentCount());
+            detail.setClassDetail(classDetail);
+
+            CoefficientVo coefficient = new CoefficientVo();
+            coefficient.setTotalCoefficient(assessmentDetail.getCoefficient().getTotalCoefficient());
+            coefficient.setLevelCoefficient(assessmentDetail.getCoefficient().getLevelCoefficient());
+            coefficient.setStudentCountCoefficient(assessmentDetail.getCoefficient().getStudentCountCoefficient());
+            coefficient.setBoardingCoefficient(assessmentDetail.getCoefficient().getBoardingCoefficient());
+            detail.setCoefficient(coefficient);
+        } catch (Exception e) {
+            // 如果获取失败,使用默认值
+            detail.setClassDetail(new ClassDetailVo());
+            detail.setCoefficient(new CoefficientVo());
+        }
+
+        // 3. 获取班主任常规工作指标列表
+        List<AssessmentApprovalIndicatorVo> routineWorkIndicators = 
+            assessmentApprovalMapper.getRoutineWorkIndicators(planId, classId, evaluatedUserId);
+        detail.setRoutineWorkIndicators(routineWorkIndicators);
+
+        // 4. 获取班级扣分指标(班级管理实效)
+        AssessmentApprovalIndicatorVo classDeductionIndicator = 
+            assessmentApprovalMapper.getClassDeductionIndicator(planId, classId, evaluatedUserId);
+        detail.setClassDeductionIndicator(classDeductionIndicator);
+
+        // 5. 获取特色工作指标列表
+        List<AssessmentApprovalSpecialWorkVo> specialWorkIndicators = 
+            assessmentApprovalMapper.getSpecialWorkIndicators(planId, classId, evaluatedUserId);
+        detail.setSpecialWorkIndicators(specialWorkIndicators);
+
+        return detail;
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean submitApproval(AssessmentApprovalSubmitBo bo, Long approverUserId) {
+        try {
+            // 1. 更新班主任常规工作指标的上级评分和意见
+            if (bo.getRoutineWorkApproval() != null) {
+                for (AssessmentApprovalIndicatorSubmitBo indicator : bo.getRoutineWorkApproval()) {
+                    if (indicator.getId() != null) {
+                        assessmentApprovalMapper.updateSuperiorScore(
+                            indicator.getId(),
+                            indicator.getSuperiorScore() != null ? indicator.getSuperiorScore().toString() : null,
+                            indicator.getSuperiorComment(),
+                            approverUserId
+                        );
+                    }
+                }
+            }
+
+            // 2. 更新班级管理实效的上级评分和意见
+            if (bo.getClassDeductionApproval() != null && bo.getClassDeductionApproval().getId() != null) {
+                assessmentApprovalMapper.updateSuperiorScore(
+                    bo.getClassDeductionApproval().getId(),
+                    bo.getClassDeductionApproval().getSuperiorScore() != null ? 
+                        bo.getClassDeductionApproval().getSuperiorScore().toString() : null,
+                    bo.getClassDeductionApproval().getSuperiorComment(),
+                    approverUserId
+                );
+            }
+
+            // 3. 更新特色工作指标的上级评分和意见
+            if (bo.getSpecialWorkApproval() != null) {
+                for (AssessmentApprovalSpecialWorkSubmitBo specialWork : bo.getSpecialWorkApproval()) {
+                    if (specialWork.getId() != null) {
+                        assessmentApprovalMapper.updateSuperiorScore(
+                            specialWork.getId(),
+                            specialWork.getSuperiorScore() != null ? specialWork.getSuperiorScore().toString() : null,
+                            specialWork.getSuperiorComment(),
+                            approverUserId
+                        );
+                    }
+                }
+            }
+
+            // 4. 更新审核状态和总体评价
+            int result = assessmentApprovalMapper.updateAuditStatus(
+                bo.getPlanId(),
+                bo.getClassId(),
+                bo.getEvaluatedUserId(),
+                bo.getAuditStatus(),
+                bo.getAuditComment(),
+                bo.getSuperiorOverallComment(),
+                approverUserId
+            );
+
+            return result > 0;
+        } catch (Exception e) {
+            throw new RuntimeException("提交审核失败: " + e.getMessage(), e);
+        }
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean batchApprove(List<Long> ids, Long approverUserId) {
+        try {
+            int result = assessmentApprovalMapper.batchUpdateAuditStatus(
+                ids, 
+                "1", // 审核通过
+                "批量审核通过",
+                approverUserId
+            );
+            return result > 0;
+        } catch (Exception e) {
+            throw new RuntimeException("批量审核通过失败: " + e.getMessage(), e);
+        }
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean batchReject(List<Long> ids, String rejectReason, Long approverUserId) {
+        try {
+            int result = assessmentApprovalMapper.batchUpdateAuditStatus(
+                ids, 
+                "2", // 审核不通过
+                rejectReason,
+                approverUserId
+            );
+            return result > 0;
+        } catch (Exception e) {
+            throw new RuntimeException("批量审核拒绝失败: " + e.getMessage(), e);
+        }
+    }
+
+    @Override
+    public List<SchemeOptionVo> getSchemeOptions() {
+        return assessmentApprovalMapper.getSchemeOptions();
+    }
+} 

+ 36 - 0
backend/ruoyi-modules/ruoyi-bzrkh/src/main/java/org/dromara/bzrkh/service/impl/TeacherAssessmentServiceImpl.java

@@ -379,6 +379,42 @@ public class TeacherAssessmentServiceImpl implements ITeacherAssessmentService {
         return result;
     }
 
+    /**
+     * 撤销考核提交
+     *
+     * @param planId    计划ID
+     * @param classId   班级ID
+     * @param teacherId 班主任ID
+     * @return 是否成功
+     */
+    @Override
+    public boolean withdrawAssessment(Long planId, Long classId, Long teacherId) {
+        try {
+            // 验证是否有权限撤销(只能撤销自己提交的且状态为待审核的考核)
+            List<AssessmentIndicatorScoreVo> savedScores = teacherAssessmentMapper.selectSavedAssessmentScores(planId, teacherId);
+            if (savedScores == null || savedScores.isEmpty()) {
+                log.warn("未找到可撤销的考核提交记录,计划ID: {}, 教师ID: {}", planId, teacherId);
+                return false;
+            }
+            
+            // 检查审核状态,只有待审核状态("0")的才能撤销
+            boolean canWithdraw = savedScores.stream().anyMatch(score -> "0".equals(score.getAuditStatus()));
+            if (!canWithdraw) {
+                log.warn("考核已审核,无法撤销,计划ID: {}, 教师ID: {}", planId, teacherId);
+                return false;
+            }
+            
+            // 逻辑删除该计划下该教师的所有评分数据
+            teacherAssessmentMapper.deleteAssessmentScoresByPlanAndTeacher(planId, teacherId);
+            
+            log.info("成功撤销考核提交,计划ID: {}, 教师ID: {}", planId, teacherId);
+            return true;
+        } catch (Exception e) {
+            log.error("撤销考核提交失败,计划ID: {}, 教师ID: {}", planId, teacherId, e);
+            return false;
+        }
+    }
+
     /**
      * 测试人数系数计算(临时调试方法)
      * 可以通过调用这个方法来验证具体人数的系数计算

+ 293 - 0
backend/ruoyi-modules/ruoyi-bzrkh/src/main/resources/mapper/bzrkh/AssessmentApprovalMapper.xml

@@ -0,0 +1,293 @@
+<?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.bzrkh.mapper.AssessmentApprovalMapper">
+
+    <!-- 审核列表结果映射 -->
+    <resultMap type="org.dromara.bzrkh.domain.vo.AssessmentApprovalVo" id="AssessmentApprovalVoResult">
+        <result property="id" column="id"/>
+        <result property="planId" column="plan_id"/>
+        <result property="planName" column="plan_name"/>
+        <result property="planCode" column="plan_code"/>
+        <result property="schemeId" column="scheme_id"/>
+        <result property="schemeName" column="scheme_name"/>
+        <result property="academicYear" column="academic_year"/>
+        <result property="semester" column="semester"/>
+        <result property="classId" column="class_id"/>
+        <result property="className" column="class_name"/>
+        <result property="teacherId" column="teacher_id"/>
+        <result property="teacherName" column="teacher_name"/>
+        <result property="evaluatedUserId" column="evaluated_user_id"/>
+        <result property="evaluatedUserName" column="evaluated_user_name"/>
+        <result property="submitTime" column="submit_time"/>
+        <result property="auditStatus" column="audit_status"/>
+        <result property="selfScore" column="self_score"/>
+        <result property="superiorScore" column="superior_score"/>
+        <result property="finalScore" column="final_score"/>
+        <result property="createTime" column="create_time"/>
+        <result property="createBy" column="create_by"/>
+        <result property="updateTime" column="update_time"/>
+        <result property="updateBy" column="update_by"/>
+    </resultMap>
+
+    <!-- 审核详情结果映射 -->
+    <resultMap type="org.dromara.bzrkh.domain.vo.AssessmentApprovalDetailVo" id="AssessmentApprovalDetailVoResult">
+        <result property="id" column="id"/>
+        <result property="planId" column="plan_id"/>
+        <result property="classId" column="class_id"/>
+        <result property="selfOverallComment" column="self_overall_comment"/>
+        <result property="superiorOverallComment" column="superior_overall_comment"/>
+        <result property="auditStatus" column="audit_status"/>
+        <result property="submitTime" column="submit_time"/>
+        <result property="createBy" column="create_by"/>
+        <result property="createTime" column="create_time"/>
+        <result property="updateBy" column="update_by"/>
+        <result property="updateTime" column="update_time"/>
+    </resultMap>
+
+    <!-- 审核指标结果映射 -->
+    <resultMap type="org.dromara.bzrkh.domain.vo.AssessmentApprovalIndicatorVo" id="AssessmentApprovalIndicatorVoResult">
+        <result property="id" column="id"/>
+        <result property="indicatorId" column="indicator_id"/>
+        <result property="indicatorName" column="indicator_name"/>
+        <result property="indicatorCode" column="indicator_code"/>
+        <result property="description" column="description"/>
+        <result property="score" column="score"/>
+        <result property="maxScore" column="max_score"/>
+        <result property="selfScore" column="self_score"/>
+        <result property="selfComment" column="self_comment"/>
+        <result property="superiorScore" column="superior_score"/>
+        <result property="superiorComment" column="superior_comment"/>
+        <result property="auditStatus" column="audit_status"/>
+    </resultMap>
+
+    <!-- 特色工作审核结果映射 -->
+    <resultMap type="org.dromara.bzrkh.domain.vo.AssessmentApprovalSpecialWorkVo" id="AssessmentApprovalSpecialWorkVoResult">
+        <result property="id" column="id"/>
+        <result property="indicatorCode" column="indicator_code"/>
+        <result property="indicatorName" column="indicator_name"/>
+        <result property="score" column="score"/>
+        <result property="selfComment" column="self_comment"/>
+        <result property="superiorScore" column="superior_score"/>
+        <result property="superiorComment" column="superior_comment"/>
+        <result property="auditStatus" column="audit_status"/>
+    </resultMap>
+
+    <!-- 方案选项结果映射 -->
+    <resultMap type="org.dromara.bzrkh.domain.vo.SchemeOptionVo" id="SchemeOptionVoResult">
+        <result property="value" column="scheme_name"/>
+        <result property="label" column="scheme_name"/>
+        <result property="schemeId" column="id"/>
+        <result property="schemeCode" column="scheme_code"/>
+    </resultMap>
+
+    <!-- 查询班主任考核审核列表 -->
+    <select id="queryList" parameterType="org.dromara.bzrkh.domain.bo.AssessmentApprovalQueryBo" resultMap="AssessmentApprovalVoResult">
+        SELECT 
+            MIN(s.id) as id,
+            s.plan_id,
+            p.plan_name,
+            p.plan_code,
+            s.scheme_id,
+            sch.scheme_name,
+            p.academic_year,
+            p.semester,
+            s.class_id,
+            c.class_name,
+            c.class_teacher_id as teacher_id,
+            c.class_teacher_name as teacher_name,
+            s.evaluated_user_id,
+            s.evaluated_user_name,
+            MAX(s.submit_time) as submit_time,
+            MAX(s.audit_status) as audit_status,
+            SUM(s.self_score) as self_score,
+            SUM(s.superior_score) as superior_score,
+            SUM(s.final_score) as final_score,
+            MAX(s.create_time) as create_time,
+            MAX(s.create_by) as create_by,
+            MAX(s.update_time) as update_time,
+            MAX(s.update_by) as update_by
+        FROM bmzr_assessment_score s
+        LEFT JOIN bmzr_assessment_plan p ON s.plan_id = p.id AND p.deleted = 0
+        LEFT JOIN bmzr_assessment_scheme sch ON s.scheme_id = sch.id AND sch.deleted = 0
+        LEFT JOIN xg_class_msg c ON s.class_id = c.id AND c.deleted = 0
+        WHERE s.deleted = 0
+          AND s.self_submit_time IS NOT NULL
+        <if test="planName != null and planName != ''">
+            AND p.plan_name LIKE CONCAT('%', #{planName}, '%')
+        </if>
+        <if test="schemeName != null and schemeName != ''">
+            AND sch.scheme_name LIKE CONCAT('%', #{schemeName}, '%')
+        </if>
+        <if test="auditStatus != null and auditStatus != ''">
+            AND s.audit_status = #{auditStatus}
+        </if>
+        <if test="className != null and className != ''">
+            AND c.class_name LIKE CONCAT('%', #{className}, '%')
+        </if>
+        <if test="teacherName != null and teacherName != ''">
+            AND c.class_teacher_name LIKE CONCAT('%', #{teacherName}, '%')
+        </if>
+        <if test="evaluatedUserName != null and evaluatedUserName != ''">
+            AND s.evaluated_user_name LIKE CONCAT('%', #{evaluatedUserName}, '%')
+        </if>
+        <if test="academicYear != null and academicYear != ''">
+            AND p.academic_year = #{academicYear}
+        </if>
+        <if test="semester != null and semester != ''">
+            AND p.semester = #{semester}
+        </if>
+        GROUP BY s.plan_id, s.class_id, s.evaluated_user_id, s.scheme_id, s.audit_status, s.evaluated_user_name,
+                 p.plan_name, p.plan_code, p.academic_year, p.semester,
+                 c.class_name, c.class_teacher_id, c.class_teacher_name,
+                 sch.scheme_name
+        ORDER BY MAX(s.create_time) DESC
+    </select>
+
+    <!-- 获取考核审核基本信息 -->
+    <select id="getApprovalBasicInfo" resultMap="AssessmentApprovalDetailVoResult">
+        SELECT 
+            s.id,
+            s.plan_id,
+            s.class_id,
+            s.self_overall_comment,
+            s.superior_overall_comment,
+            s.audit_status,
+            s.submit_time,
+            s.create_by,
+            s.create_time,
+            s.update_by,
+            s.update_time
+        FROM bmzr_assessment_score s
+        WHERE s.plan_id = #{planId}
+          AND s.class_id = #{classId}
+          AND s.evaluated_user_id = #{evaluatedUserId}
+          AND s.deleted = 0
+        LIMIT 1
+    </select>
+
+    <!-- 获取班主任常规工作指标列表 -->
+    <select id="getRoutineWorkIndicators" resultMap="AssessmentApprovalIndicatorVoResult">
+        SELECT 
+            s.id,
+            s.indicator_id,
+            i.indicator_name,
+            i.indicator_code,
+            CONCAT(i.indicator_name, '(', i.remark, ')') as description,
+            i.score,
+            i.max_score,
+            s.self_score,
+            s.self_comment,
+            s.superior_score,
+            s.superior_comment,
+            s.audit_status
+        FROM bmzr_assessment_score s
+        LEFT JOIN bmzr_assessment_indicator i ON s.indicator_id = i.id AND i.deleted = 0
+        WHERE s.plan_id = #{planId}
+          AND s.class_id = #{classId}
+          AND s.evaluated_user_id = #{evaluatedUserId}
+          AND s.deleted = 0
+          AND i.indicator_type = 'routine_work'
+        ORDER BY i.sort_order ASC
+    </select>
+
+    <!-- 获取班级扣分指标(班级管理实效) -->
+    <select id="getClassDeductionIndicator" resultMap="AssessmentApprovalIndicatorVoResult">
+        SELECT 
+            s.id,
+            s.indicator_id,
+            i.indicator_name,
+            i.indicator_code,
+            CONCAT(i.indicator_name, '(', i.remark, ')') as description,
+            i.score,
+            i.max_score,
+            s.self_score,
+            s.self_comment,
+            s.superior_score,
+            s.superior_comment,
+            s.audit_status
+        FROM bmzr_assessment_score s
+        LEFT JOIN bmzr_assessment_indicator i ON s.indicator_id = i.id AND i.deleted = 0
+        WHERE s.plan_id = #{planId}
+          AND s.class_id = #{classId}
+          AND s.evaluated_user_id = #{evaluatedUserId}
+          AND s.deleted = 0
+          AND i.indicator_type = 'class_deduction'
+        LIMIT 1
+    </select>
+
+    <!-- 获取特色工作指标列表 -->
+    <select id="getSpecialWorkIndicators" resultMap="AssessmentApprovalSpecialWorkVoResult">
+        SELECT 
+            s.id,
+            i.indicator_code,
+            i.indicator_name,
+            s.self_score as score,
+            s.self_comment,
+            s.superior_score,
+            s.superior_comment,
+            s.audit_status
+        FROM bmzr_assessment_score s
+        LEFT JOIN bmzr_assessment_indicator i ON s.indicator_id = i.id AND i.deleted = 0
+        WHERE s.plan_id = #{planId}
+          AND s.class_id = #{classId}
+          AND s.evaluated_user_id = #{evaluatedUserId}
+          AND s.deleted = 0
+          AND i.indicator_type = 'special_work'
+        ORDER BY i.sort_order ASC
+    </select>
+
+    <!-- 更新上级评分和意见 -->
+    <update id="updateSuperiorScore">
+        UPDATE bmzr_assessment_score 
+        SET superior_score = #{superiorScore},
+            superior_comment = #{superiorComment},
+            superior_evaluator_id = #{approverUserId},
+            superior_submit_time = NOW(),
+            update_by = #{approverUserId},
+            update_time = NOW()
+        WHERE id = #{id}
+          AND deleted = 0
+    </update>
+
+    <!-- 更新审核状态和意见 -->
+    <update id="updateAuditStatus">
+        UPDATE bmzr_assessment_score 
+        SET audit_status = #{auditStatus},
+            superior_overall_comment = #{superiorOverallComment},
+            update_by = #{approverUserId},
+            update_time = NOW()
+        WHERE plan_id = #{planId}
+          AND class_id = #{classId}
+          AND evaluated_user_id = #{evaluatedUserId}
+          AND deleted = 0
+    </update>
+
+    <!-- 批量更新审核状态 -->
+    <update id="batchUpdateAuditStatus">
+        UPDATE bmzr_assessment_score 
+        SET audit_status = #{auditStatus},
+            superior_overall_comment = #{auditComment},
+            update_by = #{approverUserId},
+            update_time = NOW()
+        WHERE id IN
+        <foreach collection="ids" item="id" open="(" separator="," close=")">
+            #{id}
+        </foreach>
+        AND deleted = 0
+    </update>
+
+    <!-- 获取考核方案下拉选项 -->
+    <select id="getSchemeOptions" resultMap="SchemeOptionVoResult">
+        SELECT 
+            id,
+            scheme_code,
+            scheme_name
+        FROM bmzr_assessment_scheme
+        WHERE status = '0'
+          AND deleted = 0
+        ORDER BY create_time DESC
+    </select>
+
+</mapper> 

+ 14 - 1
backend/ruoyi-modules/ruoyi-bzrkh/src/main/resources/mapper/bzrkh/TeacherAssessmentMapper.xml

@@ -43,6 +43,9 @@
         <result property="updateBy" column="update_by"/>
         <result property="updateTime" column="update_time"/>
         <result property="deleted" column="deleted"/>
+        <result property="auditStatus" column="audit_status"/>
+        <result property="submitTime" column="submit_time"/>
+        <result property="submitted" column="submitted"/>
     </resultMap>
 
     <!-- 班级详细信息结果映射 -->
@@ -71,6 +74,7 @@
         <result property="selfComment" column="self_comment"/>
         <result property="selfOverallComment" column="self_overall_comment"/>
         <result property="sortOrder" column="sort_order"/>
+        <result property="auditStatus" column="audit_status"/>
         <result property="createBy" column="create_by"/>
         <result property="createTime" column="create_time"/>
         <result property="updateBy" column="update_by"/>
@@ -134,9 +138,17 @@
             p.create_time,
             p.update_by,
             p.update_time,
-            p.deleted
+            p.deleted,
+            score.audit_status as audit_status,
+            score.self_submit_time as submit_time,
+            CASE WHEN score.plan_id IS NOT NULL THEN 1 ELSE 0 END as submitted
         FROM bmzr_assessment_plan p
         LEFT JOIN bmzr_assessment_scheme s ON p.scheme_id = s.id AND s.deleted = 0
+        LEFT JOIN (
+            SELECT DISTINCT plan_id, audit_status, self_submit_time
+            FROM bmzr_assessment_score
+            WHERE evaluated_user_id = #{teacherId} AND deleted = 0
+        ) score ON p.id = score.plan_id
         WHERE p.deleted = 0
         <if test="planStatus != null and planStatus != ''">
             AND p.plan_status = #{planStatus}
@@ -256,6 +268,7 @@
             s.self_comment,
             s.self_overall_comment,
             i.sort_order,
+            s.audit_status,
             s.create_by,
             s.create_time,
             s.update_by,

+ 63 - 0
backend/ruoyi-modules/ruoyi-bzrkh/班主任考核审核权限配置.sql

@@ -0,0 +1,63 @@
+-- ==========================================
+-- 班主任考核审核权限配置SQL
+-- 版本:V1.0.0
+-- 功能:班主任考核审核相关权限配置
+-- 作者:系统设计
+-- 时间:2025-01-28
+-- 模块:学工管理-班主任考核审核权限配置
+-- ==========================================
+
+-- 1. 菜单配置
+-- 班主任考核审核菜单
+INSERT INTO sys_menu (menu_name, parent_id, order_num, path, component, query_param, route_name, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark) VALUES 
+('班主任考核审核', (SELECT menu_id FROM sys_menu WHERE menu_name = '班主任考核系统' LIMIT 1), 6, 'assessmentApproval', 'bzrkh/assessmentApproval/index', '', '', 1, 0, 'C', '0', '0', 'bzrkh:assessmentApproval:list', 'edit', 103, 1, now(), 1, now(), '班主任考核审核菜单');
+
+-- 2. 按钮权限配置
+-- 获取刚插入的菜单ID
+SET @assessment_approval_menu_id = LAST_INSERT_ID();
+
+-- 班主任考核审核按钮权限
+INSERT INTO sys_menu (menu_name, parent_id, order_num, path, component, query_param, route_name, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark) VALUES
+('考核审核查询', @assessment_approval_menu_id, 1, '', '', '', '', 1, 0, 'F', '0', '0', 'bzrkh:assessmentApproval:list', '#', 103, 1, now(), 1, now(), ''),
+('考核审核详情', @assessment_approval_menu_id, 2, '', '', '', '', 1, 0, 'F', '0', '0', 'bzrkh:assessmentApproval:query', '#', 103, 1, now(), 1, now(), ''),
+('考核审核操作', @assessment_approval_menu_id, 3, '', '', '', '', 1, 0, 'F', '0', '0', 'bzrkh:assessmentApproval:approve', '#', 103, 1, now(), 1, now(), ''),
+('考核审核导出', @assessment_approval_menu_id, 4, '', '', '', '', 1, 0, 'F', '0', '0', 'bzrkh:assessmentApproval:export', '#', 103, 1, now(), 1, now(), '');
+
+-- 3. 字典配置
+-- 审核状态字典
+INSERT INTO sys_dict_type (dict_name, dict_type, status, create_dept, create_by, create_time, update_by, update_time, remark) VALUES 
+('班主任考核审核状态', 'bmzr_audit_status', '0', 103, 1, now(), 1, now(), '班主任考核审核状态字典');
+
+-- 获取字典类型ID
+SET @dict_type_id = LAST_INSERT_ID();
+
+-- 审核状态字典数据
+INSERT INTO sys_dict_data (dict_sort, dict_label, dict_value, dict_type, css_class, list_class, is_default, status, create_dept, create_by, create_time, update_by, update_time, remark) VALUES
+(1, '待审核', '0', 'bmzr_audit_status', '', 'warning', 'Y', '0', 103, 1, now(), 1, now(), '待审核状态'),
+(2, '审核通过', '1', 'bmzr_audit_status', '', 'success', 'N', '0', 103, 1, now(), 1, now(), '审核通过状态'),
+(3, '审核不通过', '2', 'bmzr_audit_status', '', 'danger', 'N', '0', 103, 1, now(), 1, now(), '审核不通过状态');
+
+-- ==========================================
+-- 权限字符说明
+-- ==========================================
+/*
+权限字符列表:
+1. bzrkh:assessmentApproval:list - 班主任考核审核查询权限(查看审核列表)
+2. bzrkh:assessmentApproval:query - 班主任考核审核详情权限(查看审核详情)
+3. bzrkh:assessmentApproval:approve - 班主任考核审核操作权限(审批、批量审批、批量拒绝)
+4. bzrkh:assessmentApproval:export - 班主任考核审核导出权限(导出审核数据)
+
+API接口与权限字符对应关系:
+- GET /bzrkh/assessmentApproval/list → bzrkh:assessmentApproval:list
+- GET /bzrkh/assessmentApproval/detail → bzrkh:assessmentApproval:query
+- POST /bzrkh/assessmentApproval/submit → bzrkh:assessmentApproval:approve
+- POST /bzrkh/assessmentApproval/batchApprove → bzrkh:assessmentApproval:approve
+- POST /bzrkh/assessmentApproval/batchReject → bzrkh:assessmentApproval:approve
+- GET /bzrkh/assessmentApproval/schemeOptions → bzrkh:assessmentApproval:list
+- POST /bzrkh/assessmentApproval/export → bzrkh:assessmentApproval:export
+
+用户角色分配建议:
+1. 学工处管理员:拥有所有权限(list、query、approve、export)
+2. 学院管理员:拥有查询和审核权限(list、query、approve)
+3. 普通审核员:拥有查询权限(list、query)
+*/ 

+ 47 - 0
backend/ruoyi-modules/ruoyi-bzrkh/班主任考核撤销功能权限配置.sql

@@ -0,0 +1,47 @@
+-- ==========================================
+-- 班主任考核撤销功能权限配置
+-- 功能说明:为班主任考核管理新增撤销提交功能的权限配置
+-- 创建时间:2025-01-28
+-- ==========================================
+
+-- 1. 插入撤销考核权限
+INSERT INTO sys_menu (
+    menu_name, parent_id, order_num, path, component, query_param, route_name, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark
+) VALUES (
+    '撤销考核提交', 
+    (SELECT menu_id FROM sys_menu WHERE perms = 'bzrkh:teacherAssessment:list' LIMIT 1),
+    4, 
+    '', 
+    '', 
+    '', 
+    '', 
+    1, 
+    0, 
+    'F', 
+    '0', 
+    '0', 
+    'bzrkh:teacherAssessment:withdraw', 
+    '#',
+    103,
+    1,
+    NOW(),
+    1,
+    NOW(),
+    '班主任考核撤销提交权限'
+);
+
+-- ==========================================
+-- 权限字符说明
+-- ==========================================
+/*
+新增权限字符:
+- bzrkh:teacherAssessment:withdraw - 班主任考核撤销权限
+
+使用的API接口及对应权限:
+- POST /bzrkh/teacherAssessment/withdraw - bzrkh:teacherAssessment:withdraw
+
+说明:
+- 撤销功能只对待审核状态(audit_status='0')的考核有效
+- 撤销后会逻辑删除评分数据,允许重新提交
+- 已审核通过或驳回的考核无法撤销
+*/ 

+ 0 - 14
docs/开发文档/API/API文档总览.md

@@ -17,7 +17,6 @@
 - [宿舍管理员授权API](./宿舍管理员授权API.md)
 - [学生管理员授权关系API](./学生管理员授权关系API.md)
 - [学生销假管理API](./学生销假管理API.md)
-- [逆地理编码API](./逆地理编码API.md) - **新增逆地理编码功能**(2025-01-03)
 
 ### 1. 用户认证登录
 
@@ -83,14 +82,11 @@
 | 处理预约申请 | POST | /api/xljk/consultation/appointment/process | 预约管理 | xljk:consultation:appointment:process |
 | **获取房间床位详细信息** | GET | /dormbed/dormBed/details/room/{roomId} | 宿舍管理 | dormbed:dormBed:query |
 | **获取宿舍楼床位详细信息** | GET | /dormbed/dormBed/details/building/{buildingId} | 宿舍管理 | dormbed:dormBed:query |
-| 获取当前班主任的班级列表 | GET | /classMsg/classMsg/myClassListAsTeacher | 班级信息 | classMsg:classMsg:list |
 | 记录咨询结果 | POST | /api/xljk/consultation/appointment/record | 预约管理 | xljk:consultation:appointment:record |
 | 查询未到访记录列表 | GET | /api/xljk/consultation/no-show/list | 预约限制 | xljk:consultation:noshow:list |
 | 获取未到访记录详情 | GET | /api/xljk/consultation/no-show/{id} | 预约限制 | xljk:consultation:noshow:query |
 | 解除预约限制 | PUT | /api/xljk/consultation/no-show/{id}/release | 预约限制 | xljk:consultation:noshow:release |
 | 检查学生是否被限制预约 | GET | /api/xljk/consultation/no-show/check-limitation | 预约限制 | - |
-| 逆地理编码 | POST | /system/SysRegion/reverse-geocode | 行政区划 | system:SysRegion:geocode |
-| **根据学生ID查询卫生检查信息** | GET | /dormHygieneCheck/dormHygieneCheck/student/{studentId} | 宿舍卫生检查 | dormHygieneCheck:dormHygieneCheck:query |
 
 ## 更新历史
 
@@ -100,8 +96,6 @@
 | 2025-07-01 | 1.0 | 初始版本 | 系统管理员 |
 | 2025-07-15 | 1.1 | 添加心理健康测评API | 张工 |
 | 2025-07-30 | 1.2 | 添加预约限制功能API | Cursor |
-| 2025-01-03 | 1.3 | 添加逆地理编码API | zlwu |
-| 2025-01-03 | 1.4 | 添加宿舍卫生检查-根据学生ID查询API | zlwu |
 
 **详细文档**: [企业信息管理API.md](./企业信息管理API.md)
 
@@ -141,13 +135,6 @@
 
 ## 🔗 API文档导航
 
-### 🏠 宿舍管理模块
-
-| API文档 | 描述 | 状态 | 更新时间 |
-|---------|------|------|----------|
-| [宿舍卫生检查API-根据学生ID查询](./宿舍卫生检查API-根据学生ID查询.md) | 根据学生ID查询宿舍卫生检查信息 | ✅ 完成 | 2025-01-03 |
-| [宿舍卫生检查API-根据学生ID查询-使用说明](./宿舍卫生检查API-根据学生ID查询-使用说明.md) | 宿舍卫生检查API使用说明 | ✅ 完成 | 2025-01-03 |
-
 ### 👥 学工管理模块
 
 | API文档 | 描述 | 状态 | 更新时间 |
@@ -161,5 +148,4 @@
 | **[学生考核管理系统API](./学生考核管理系统API.md)** | **学生综合素质测评、违纪处分、奖励加分管理** | **✅ 完成** | **2025-01-27** |
 | **[学生考核管理系统修改方案](./学生考核管理系统API修改方案.md)** | **基于标准化违纪处分等级的系统升级方案** | **📋 方案** | **2025-01-27** |
 | **[学生考核管理系统数据库修改影响分析](./学生考核管理系统数据库修改影响分析.md)** | **数据库升级脚本执行的详细影响分析** | **📊 分析** | **2025-01-27** |
-- 指标体系管理API.md(新增:支持Excel批量导入、导入模板下载;新增字段:具体指标名称)
 

+ 108 - 0
web/src/api/bzrkh/assessmentApproval/index.ts

@@ -0,0 +1,108 @@
+import request from '@/utils/request';
+import { AxiosPromise } from 'axios';
+import { 
+  AssessmentApprovalQuery,
+  AssessmentApprovalVO,
+  AssessmentApprovalDetailVO,
+  AssessmentApprovalSubmitBO
+} from './types';
+
+/**
+ * 查询班主任考核审核列表
+ * @param query
+ * @returns {*}
+ */
+export const listAssessmentApproval = (query?: AssessmentApprovalQuery): AxiosPromise<AssessmentApprovalVO[]> => {
+  return request({
+    url: '/bzrkh/assessmentApproval/list',
+    method: 'get',
+    params: query
+  });
+};
+
+/**
+ * 获取考核审核详情
+ * @param planId 计划ID
+ * @param classId 班级ID
+ * @param evaluatedUserId 被评价用户ID
+ * @returns {*}
+ */
+export const getAssessmentApprovalDetail = (planId: string | number, classId: string | number, evaluatedUserId: string | number): AxiosPromise<AssessmentApprovalDetailVO> => {
+  return request({
+    url: '/bzrkh/assessmentApproval/detail',
+    method: 'get',
+    params: {
+      planId,
+      classId,
+      evaluatedUserId
+    }
+  });
+};
+
+/**
+ * 提交考核审核
+ * @param data 审核数据
+ * @returns {*}
+ */
+export const submitAssessmentApproval = (data: AssessmentApprovalSubmitBO): AxiosPromise<void> => {
+  return request({
+    url: '/bzrkh/assessmentApproval/submit',
+    method: 'post',
+    data: data
+  });
+};
+
+/**
+ * 批量审核通过
+ * @param ids 审核ID列表
+ * @returns {*}
+ */
+export const batchApproveAssessment = (ids: (string | number)[]): AxiosPromise<void> => {
+  return request({
+    url: '/bzrkh/assessmentApproval/batchApprove',
+    method: 'post',
+    data: { ids }
+  });
+};
+
+/**
+ * 批量审核拒绝
+ * @param ids 审核ID列表
+ * @param rejectReason 拒绝原因
+ * @returns {*}
+ */
+export const batchRejectAssessment = (ids: (string | number)[], rejectReason: string): AxiosPromise<void> => {
+  return request({
+    url: '/bzrkh/assessmentApproval/batchReject',
+    method: 'post',
+    data: { 
+      ids,
+      rejectReason
+    }
+  });
+};
+
+/**
+ * 获取考核方案下拉选项
+ * @returns {*}
+ */
+export const getAssessmentSchemeOptions = (): AxiosPromise<any[]> => {
+  return request({
+    url: '/bzrkh/assessmentApproval/schemeOptions',
+    method: 'get'
+  });
+};
+
+/**
+ * 导出考核审核数据
+ * @param query 查询条件
+ * @returns {*}
+ */
+export const exportAssessmentApproval = (query?: AssessmentApprovalQuery): AxiosPromise<void> => {
+  return request({
+    url: '/bzrkh/assessmentApproval/export',
+    method: 'post',
+    data: query,
+    responseType: 'blob'
+  });
+}; 

+ 220 - 0
web/src/api/bzrkh/assessmentApproval/types.ts

@@ -0,0 +1,220 @@
+/**
+ * 班主任考核审核相关类型定义
+ */
+
+/**
+ * 审核列表查询参数
+ */
+export interface AssessmentApprovalQuery {
+  pageNum?: number;
+  pageSize?: number;
+  planName?: string;
+  schemeName?: string;
+  auditStatus?: string;
+  className?: string;
+  teacherName?: string;
+  orderByColumn?: string;
+  isAsc?: string;
+}
+
+/**
+ * 审核列表VO
+ */
+export interface AssessmentApprovalVO {
+  id?: string | number;
+  planId?: string | number;
+  planName?: string;
+  planCode?: string;
+  schemeId?: string | number;
+  schemeName?: string;
+  academicYear?: string;
+  semester?: string;
+  classId?: string | number;
+  className?: string;
+  teacherId?: string | number;
+  teacherName?: string;
+  evaluatedUserId?: string | number;
+  evaluatedUserName?: string;
+  submitTime?: string;
+  auditStatus?: string;
+  auditStatusText?: string;
+  selfScore?: number;
+  superiorScore?: number;
+  finalScore?: number;
+  createTime?: string;
+}
+
+/**
+ * 审核详情VO - 继承自班主任提交的详情数据
+ */
+export interface AssessmentApprovalDetailVO {
+  id?: string | number;
+  planId?: string | number;
+  classId?: string | number;
+  
+  /**
+   * 班级详细信息
+   */
+  classDetail?: {
+    id?: string | number;
+    className?: string;
+    collegeName?: string;
+    majorName?: string;
+    classType?: string;
+    totalStudentCount?: number;
+    boardingStudentCount?: number;
+  };
+  
+  /**
+   * 系数信息
+   */
+  coefficient?: {
+    totalCoefficient?: number;
+    levelCoefficient?: number;
+    studentCountCoefficient?: number;
+    boardingCoefficient?: number;
+  };
+  
+  /**
+   * 班主任常规工作指标列表 - 包含自评和上级评分
+   */
+  routineWorkIndicators?: AssessmentApprovalIndicatorVO[];
+  
+  /**
+   * 班级扣分指标 - 班级管理实效
+   */
+  classDeductionIndicator?: AssessmentApprovalIndicatorVO;
+  
+  /**
+   * 特色工作指标列表
+   */
+  specialWorkIndicators?: AssessmentApprovalSpecialWorkVO[];
+  
+  /**
+   * 自我总体评价
+   */
+  selfOverallComment?: string;
+  
+  /**
+   * 上级总体评价
+   */
+  superiorOverallComment?: string;
+  
+  /**
+   * 月考核得分
+   */
+  monthlyScore?: number;
+  
+  /**
+   * 审核状态
+   */
+  auditStatus?: string;
+  
+  /**
+   * 提交时间
+   */
+  submitTime?: string;
+}
+
+/**
+ * 审核指标VO - 包含自评和上级评分
+ */
+export interface AssessmentApprovalIndicatorVO {
+  id?: string | number;
+  indicatorId?: string | number;
+  indicatorName?: string;
+  indicatorCode?: string;
+  description?: string;
+  score?: number;  // 指标分值
+  maxScore?: number;
+  
+  // 自评相关
+  selfScore?: number;
+  selfComment?: string;
+  
+  // 上级评相关
+  superiorScore?: number;
+  superiorComment?: string;
+  
+  // 审核状态
+  auditStatus?: string;
+}
+
+/**
+ * 特色工作审核VO
+ */
+export interface AssessmentApprovalSpecialWorkVO {
+  id?: string | number;
+  indicatorCode?: string;
+  indicatorName?: string;
+  
+  // 自评相关
+  score?: number;  // 自评分数
+  selfComment?: string;
+  
+  // 上级评相关
+  superiorScore?: number;
+  superiorComment?: string;
+  
+  // 审核状态
+  auditStatus?: string;
+}
+
+/**
+ * 审核提交BO
+ */
+export interface AssessmentApprovalSubmitBO {
+  planId?: string | number;
+  classId?: string | number;
+  evaluatedUserId?: string | number;
+  
+  /**
+   * 班主任常规工作审核数据
+   */
+  routineWorkApproval?: AssessmentApprovalIndicatorSubmitVO[];
+  
+  /**
+   * 班级管理实效审核数据
+   */
+  classDeductionApproval?: AssessmentApprovalIndicatorSubmitVO;
+  
+  /**
+   * 特色工作审核数据
+   */
+  specialWorkApproval?: AssessmentApprovalSpecialWorkSubmitVO[];
+  
+  /**
+   * 上级总体评价
+   */
+  superiorOverallComment?: string;
+  
+  /**
+   * 审核状态 0=待审核 1=审核通过 2=审核不通过
+   */
+  auditStatus?: string;
+  
+  /**
+   * 审核意见
+   */
+  auditComment?: string;
+}
+
+/**
+ * 指标审核提交VO
+ */
+export interface AssessmentApprovalIndicatorSubmitVO {
+  id?: string | number;
+  indicatorId?: string | number;
+  superiorScore?: number;
+  superiorComment?: string;
+}
+
+/**
+ * 特色工作审核提交VO
+ */
+export interface AssessmentApprovalSpecialWorkSubmitVO {
+  id?: string | number;
+  indicatorCode?: string;
+  superiorScore?: number;
+  superiorComment?: string;
+} 

+ 17 - 1
web/src/api/bzrkh/teacherAssessment/index.ts

@@ -29,7 +29,7 @@ export const listTeacherClasses = (query?: TeacherClassQuery): AxiosPromise<Teac
  */
 export const listTeacherAssessmentPlans = (query?: TeacherAssessmentPlanQuery): AxiosPromise<TeacherAssessmentPlanVO[]> => {
   return request({
-    url: '/bzrkh/assessmentPlan/list',
+    url: '/bzrkh/teacherAssessment/plans',
     method: 'get',
     params: query
   });
@@ -93,4 +93,20 @@ export const submitAssessmentScore = (data: AssessmentSubmitVO): AxiosPromise<vo
     method: 'post',
     data
   });
+};
+
+/**
+ * 撤销考核提交
+ * @param planId 计划ID
+ * @param classId 班级ID
+ */
+export const withdrawAssessment = (planId: string | number, classId: string | number): AxiosPromise<void> => {
+  return request({
+    url: '/bzrkh/teacherAssessment/withdraw',
+    method: 'post',
+    data: {
+      planId,
+      classId
+    }
+  });
 }; 

+ 15 - 0
web/src/api/bzrkh/teacherAssessment/types.ts

@@ -135,6 +135,21 @@ export interface TeacherAssessmentPlanVO {
    * 备注
    */
   remark?: string;
+
+  /**
+   * 审核状态(null=未提交,0=已提交待审核,1=审核通过,2=审核不通过)
+   */
+  auditStatus?: string;
+
+  /**
+   * 提交时间
+   */
+  submitTime?: string;
+
+  /**
+   * 是否已提交(用于前端按钮状态控制)
+   */
+  submitted?: boolean;
 }
 
 export interface TeacherAssessmentPlanQuery {

+ 720 - 0
web/src/views/bzrkh/assessmentApproval/approvalDialog.vue

@@ -0,0 +1,720 @@
+<template>
+  <el-dialog
+    :title="dialogTitle"
+    v-model="visible"
+    width="1200px"
+    :close-on-click-modal="false"
+    append-to-body
+    @close="handleClose"
+  >
+    <div v-loading="loading" class="approval-dialog-content">
+      <!-- 1. 班级信息卡片 -->
+      <el-card shadow="never" class="info-card">
+        <template #header>
+          <div class="card-header">
+            <span>班级信息</span>
+          </div>
+        </template>
+        <el-descriptions :column="3" border>
+          <el-descriptions-item label="学院名称">{{ approvalDetail?.classDetail?.collegeName || '-' }}</el-descriptions-item>
+          <el-descriptions-item label="专业名称">{{ approvalDetail?.classDetail?.majorName || '-' }}</el-descriptions-item>
+          <el-descriptions-item label="班级名称">{{ approvalDetail?.classDetail?.className || '-' }}</el-descriptions-item>
+        </el-descriptions>
+      </el-card>
+
+      <!-- 2. 总系数(K)与层次系数(K1)并排 -->
+      <el-row :gutter="20" class="info-card">
+        <el-col :span="12">
+          <el-card shadow="never">
+            <template #header>
+              <div class="card-header">
+                <span>总系数(K)</span>
+              </div>
+            </template>
+            <el-descriptions :column="1" border>
+              <el-descriptions-item label="总系数">{{ formatNumber(approvalDetail?.coefficient?.totalCoefficient, 3) }}</el-descriptions-item>
+            </el-descriptions>
+          </el-card>
+        </el-col>
+        <el-col :span="12">
+          <el-card shadow="never">
+            <template #header>
+              <div class="card-header">
+                <span>层次系数(K1)</span>
+              </div>
+            </template>
+            <el-descriptions :column="2" border>
+              <el-descriptions-item label="班级学历层级">{{ getClassTypeText(approvalDetail?.classDetail?.classType) }}</el-descriptions-item>
+              <el-descriptions-item label="层次系数">{{ formatNumber(approvalDetail?.coefficient?.levelCoefficient, 3) }}</el-descriptions-item>
+            </el-descriptions>
+          </el-card>
+        </el-col>
+      </el-row>
+
+      <!-- 3. 人数系数(K2)与住校生系数(K3)并排 -->
+      <el-row :gutter="20" class="info-card">
+        <el-col :span="12">
+          <el-card shadow="never">
+            <template #header>
+              <div class="card-header">
+                <span>人数系数(K2)</span>
+              </div>
+            </template>
+            <el-descriptions :column="2" border>
+              <el-descriptions-item label="班级总人数">{{ approvalDetail?.classDetail?.totalStudentCount || 0 }}人</el-descriptions-item>
+              <el-descriptions-item label="人数系数">{{ formatNumber(approvalDetail?.coefficient?.studentCountCoefficient, 3) }}</el-descriptions-item>
+            </el-descriptions>
+          </el-card>
+        </el-col>
+        <el-col :span="12">
+          <el-card shadow="never">
+            <template #header>
+              <div class="card-header">
+                <span>住校生系数(K3)</span>
+              </div>
+            </template>
+            <el-descriptions :column="2" border>
+              <el-descriptions-item label="住校生人数">{{ approvalDetail?.classDetail?.boardingStudentCount || 0 }}人</el-descriptions-item>
+              <el-descriptions-item label="住校生系数">{{ formatNumber(approvalDetail?.coefficient?.boardingCoefficient, 3) }}</el-descriptions-item>
+            </el-descriptions>
+          </el-card>
+        </el-col>
+      </el-row>
+
+      <!-- 4. 班主任常规工作(50分)卡片 -->
+      <el-card shadow="never" class="info-card">
+        <template #header>
+          <div class="card-header">
+            <span>班主任常规工作(50分)</span>
+          </div>
+        </template>
+        <el-table border :data="routineWorkScores" style="width: 100%" max-height="400" class="routine-work-table">
+          <el-table-column type="index" label="序号" width="60" align="center" />
+          <el-table-column prop="indicatorName" label="指标名称" min-width="150" align="center" :show-overflow-tooltip="true" />
+          <el-table-column prop="description" label="指标描述" min-width="180" align="center" :show-overflow-tooltip="true" />
+          <el-table-column prop="score" label="指标分值" width="80" align="center">
+            <template #default="scope">
+              <span>{{ scope.row.score || 0 }}</span>
+            </template>
+          </el-table-column>
+          <el-table-column label="自评分数" width="80" align="center">
+            <template #default="scope">
+              <span>{{ scope.row.selfScore || 0 }}</span>
+            </template>
+          </el-table-column>
+          <el-table-column label="自评意见" width="180" align="center">
+            <template #default="scope">
+              <el-tooltip :content="scope.row.selfComment || '无'" placement="top" :disabled="!scope.row.selfComment">
+                <span class="text-ellipsis">{{ scope.row.selfComment || '无' }}</span>
+              </el-tooltip>
+            </template>
+          </el-table-column>
+          <el-table-column label="上级评分" width="100" align="center">
+            <template #default="scope">
+              <el-input-number
+                v-model="scope.row.superiorScore"
+                :min="0"
+                :max="scope.row.score || 100"
+                :precision="2"
+                controls-position="right"
+                style="width: 100%"
+                placeholder="请输入分数"
+                size="small"
+              />
+            </template>
+          </el-table-column>
+          <el-table-column label="审批意见" width="200" align="center">
+            <template #default="scope">
+              <el-input
+                v-model="scope.row.superiorComment"
+                type="textarea"
+                :rows="2"
+                placeholder="请输入审批意见"
+                maxlength="200"
+                show-word-limit
+                size="small"
+              />
+            </template>
+          </el-table-column>
+        </el-table>
+      </el-card>
+
+      <!-- 5. 班级管理实效(50分)卡片 -->
+      <el-card shadow="never" class="info-card">
+        <template #header>
+          <div class="card-header">
+            <span>班级管理实效(50分)</span>
+          </div>
+        </template>
+        <el-form :model="managementEffectivenessForm" label-width="150px" class="management-effectiveness-form">
+          <el-row :gutter="20">
+            <el-col :span="8">
+              <el-form-item label="班级扣分">
+                <el-input
+                  :value="managementEffectivenessForm.classDeduction?.toFixed(2) || '0.00'"
+                  readonly
+                  style="width: 100%; text-align: center;"
+                />
+              </el-form-item>
+            </el-col>
+            <el-col :span="8">
+              <el-form-item label="按班级扣分50%计">
+                <el-input
+                  :value="managementEffectivenessForm.classDeductionHalf?.toFixed(2) || '0.00'"
+                  readonly
+                  style="width: 100%; text-align: center;"
+                />
+              </el-form-item>
+            </el-col>
+            <el-col :span="8">
+              <el-form-item label="上级评分">
+                <el-input-number
+                  v-model="managementEffectivenessForm.superiorScore"
+                  :min="0"
+                  :max="50"
+                  :precision="2"
+                  controls-position="right"
+                  style="width: 100%"
+                  placeholder="请输入分数"
+                />
+              </el-form-item>
+            </el-col>
+          </el-row>
+          <el-row>
+            <el-col :span="12">
+              <el-form-item label="自评意见">
+                <el-input
+                  :value="managementEffectivenessForm.selfComment"
+                  type="textarea"
+                  :rows="3"
+                  readonly
+                />
+              </el-form-item>
+            </el-col>
+            <el-col :span="12">
+              <el-form-item label="审批意见">
+                <el-input
+                  v-model="managementEffectivenessForm.superiorComment"
+                  type="textarea"
+                  :rows="3"
+                  placeholder="请输入审批意见"
+                  maxlength="500"
+                  show-word-limit
+                />
+              </el-form-item>
+            </el-col>
+          </el-row>
+        </el-form>
+      </el-card>
+
+      <!-- 6. 特色工作(加20分)卡片 -->
+      <el-card shadow="never" class="info-card">
+        <template #header>
+          <div class="card-header">
+            <span>特色工作(加20分)</span>
+          </div>
+        </template>
+        <el-table border :data="specialWorkScores" style="width: 100%" class="special-work-table">
+          <el-table-column type="index" label="序号" width="60" align="center" />
+          <el-table-column prop="indicatorName" label="特色工作项目" min-width="180" align="center" :show-overflow-tooltip="true" />
+          <el-table-column label="自评分数" width="80" align="center">
+            <template #default="scope">
+              <span>{{ scope.row.score || 0 }}</span>
+            </template>
+          </el-table-column>
+          <el-table-column label="自评意见" width="180" align="center">
+            <template #default="scope">
+              <el-tooltip :content="scope.row.selfComment || '无'" placement="top" :disabled="!scope.row.selfComment">
+                <span class="text-ellipsis">{{ scope.row.selfComment || '无' }}</span>
+              </el-tooltip>
+            </template>
+          </el-table-column>
+          <el-table-column label="上级评分" width="100" align="center">
+            <template #default="scope">
+              <el-input-number
+                v-model="scope.row.superiorScore"
+                :min="0"
+                :max="20"
+                :precision="2"
+                controls-position="right"
+                style="width: 100%"
+                placeholder="请输入分数"
+                size="small"
+              />
+            </template>
+          </el-table-column>
+          <el-table-column label="审批意见" width="200" align="center">
+            <template #default="scope">
+              <el-input
+                v-model="scope.row.superiorComment"
+                type="textarea"
+                :rows="2"
+                placeholder="请输入审批意见"
+                maxlength="200"
+                show-word-limit
+                size="small"
+              />
+            </template>
+          </el-table-column>
+        </el-table>
+      </el-card>
+
+      <!-- 7. 月考核得分卡片 -->
+      <el-card shadow="never" class="info-card">
+        <template #header>
+          <div class="card-header">
+            <span>月考核得分</span>
+          </div>
+        </template>
+        <el-form :model="monthlyScoreForm" label-width="100px" class="monthly-score-form">
+          <el-row :gutter="20">
+            <el-col :span="12">
+              <el-form-item label="月考核得分">
+                <el-input
+                  :value="calculateMonthlyScore().toFixed(2)"
+                  readonly
+                  style="width: 100%; text-align: center;"
+                />
+              </el-form-item>
+            </el-col>
+          </el-row>
+          <el-row>
+            <el-col :span="12">
+              <el-form-item label="自我总体评价">
+                <el-input
+                  :value="monthlyScoreForm.selfOverallComment"
+                  type="textarea"
+                  :rows="4"
+                  readonly
+                />
+              </el-form-item>
+            </el-col>
+            <el-col :span="12">
+              <el-form-item label="上级总体评价">
+                <el-input
+                  v-model="monthlyScoreForm.superiorOverallComment"
+                  type="textarea"
+                  :rows="4"
+                  placeholder="请输入上级总体评价"
+                  maxlength="500"
+                  show-word-limit
+                />
+              </el-form-item>
+            </el-col>
+          </el-row>
+        </el-form>
+      </el-card>
+
+      <!-- 8. 审批结果卡片 -->
+      <el-card shadow="never" class="info-card">
+        <template #header>
+          <div class="card-header">
+            <span>审批结果</span>
+          </div>
+        </template>
+        <el-form :model="approvalForm" label-width="100px" class="approval-form">
+          <el-row :gutter="20">
+            <el-col :span="12">
+              <el-form-item label="审批状态" required>
+                <el-radio-group v-model="approvalForm.auditStatus">
+                  <el-radio value="1">通过</el-radio>
+                  <el-radio value="2">拒绝</el-radio>
+                </el-radio-group>
+              </el-form-item>
+            </el-col>
+          </el-row>
+          <el-row>
+            <el-col :span="24">
+              <el-form-item label="审批意见">
+                <el-input
+                  v-model="approvalForm.auditComment"
+                  type="textarea"
+                  :rows="3"
+                  placeholder="请输入审批意见"
+                  maxlength="500"
+                  show-word-limit
+                />
+              </el-form-item>
+            </el-col>
+          </el-row>
+        </el-form>
+      </el-card>
+    </div>
+
+    <template #footer>
+      <div class="dialog-footer">
+        <el-button :loading="submitLoading" type="primary" @click="handleSubmit">保存审批</el-button>
+        <el-button @click="handleClose">取消</el-button>
+      </div>
+    </template>
+  </el-dialog>
+</template>
+
+<script setup name="ApprovalDialog" lang="ts">
+import { 
+  getAssessmentApprovalDetail, 
+  submitAssessmentApproval 
+} from '@/api/bzrkh/assessmentApproval';
+import {
+  AssessmentApprovalVO,
+  AssessmentApprovalDetailVO,
+  AssessmentApprovalIndicatorVO,
+  AssessmentApprovalSpecialWorkVO,
+  AssessmentApprovalSubmitBO
+} from '@/api/bzrkh/assessmentApproval/types';
+
+const emit = defineEmits(['success']);
+
+const { proxy } = getCurrentInstance() as ComponentInternalInstance;
+
+const visible = ref(false);
+const loading = ref(false);
+const submitLoading = ref(false);
+
+const currentRow = ref<AssessmentApprovalVO>();
+const approvalDetail = ref<AssessmentApprovalDetailVO>();
+const routineWorkScores = ref<AssessmentApprovalIndicatorVO[]>([]);
+const specialWorkScores = ref<AssessmentApprovalSpecialWorkVO[]>([]);
+
+// 班级管理实效表单
+const managementEffectivenessForm = reactive({
+  classDeduction: 0,
+  classDeductionHalf: 0,
+  selfComment: '',
+  superiorScore: 0,
+  superiorComment: ''
+});
+
+// 月考核得分表单
+const monthlyScoreForm = reactive({
+  selfOverallComment: '',
+  superiorOverallComment: ''
+});
+
+// 审批表单
+const approvalForm = reactive({
+  auditStatus: '1', // 默认通过
+  auditComment: ''
+});
+
+const dialogTitle = computed(() => {
+  const className = approvalDetail.value?.classDetail?.className || '';
+  return `${className} - 班主任考核审批`;
+});
+
+/** 获取班级层次文本 */
+const getClassTypeText = (classType?: string) => {
+  const typeMap: Record<string, string> = {
+    '1': '中级工班',
+    '2': '高级工班',
+    '3': '预备技师班',
+    '4': '技师班',
+    '5': '中高职一体'
+  };
+  return typeMap[classType || ''] || '未知';
+};
+
+/** 格式化数字显示 */
+const formatNumber = (value?: number | string, precision = 4) => {
+  if (value === undefined || value === null || value === '') {
+    return '0.' + '0'.repeat(precision);
+  }
+  
+  const numValue = typeof value === 'string' ? parseFloat(value) : value;
+  
+  if (isNaN(numValue)) {
+    return '0.' + '0'.repeat(precision);
+  }
+  
+  return numValue.toFixed(precision);
+};
+
+/** 计算月考核得分 */
+const calculateMonthlyScore = () => {
+  // 总系数(K)
+  const totalCoefficient = approvalDetail.value?.coefficient?.totalCoefficient || 0;
+  
+  // 班主任常规工作自评分之和
+  const routineWorkTotal = routineWorkScores.value.reduce((sum, item) => sum + (item.selfScore || 0), 0);
+  
+  // 按班级扣分50%计的分值
+  const deductionHalf = managementEffectivenessForm.classDeductionHalf || 0;
+  
+  // 特色工作总分值
+  const specialWorkTotal = specialWorkScores.value.reduce((sum, item) => sum + (item.score || 0), 0);
+  
+  // 月考核得分 = 总系数(K)* (班主任常规工作自评分之和 - 按班级扣分50%计的分值 + 特色工作总分值)
+  return totalCoefficient * (routineWorkTotal - deductionHalf + specialWorkTotal);
+};
+
+/** 打开弹窗 */
+const open = async (row: AssessmentApprovalVO) => {
+  if (!row.planId || !row.classId || !row.evaluatedUserId) {
+    proxy?.$modal.msgError('参数错误:缺少必要的ID信息');
+    return;
+  }
+  
+  currentRow.value = row;
+  visible.value = true;
+  await loadApprovalDetail();
+};
+
+/** 加载审批详情数据 */
+const loadApprovalDetail = async () => {
+  if (!currentRow.value?.planId || !currentRow.value?.classId || !currentRow.value?.evaluatedUserId) {
+    return;
+  }
+
+  loading.value = true;
+  try {
+    const res = await getAssessmentApprovalDetail(
+      currentRow.value.planId,
+      currentRow.value.classId,
+      currentRow.value.evaluatedUserId
+    );
+    approvalDetail.value = res.data;
+    
+    // 初始化班主任常规工作数据
+    routineWorkScores.value = (approvalDetail.value?.routineWorkIndicators || []).map(item => ({
+      ...item,
+      superiorScore: item.superiorScore || 0,
+      superiorComment: item.superiorComment || ''
+    }));
+    
+    // 初始化班级管理实效数据
+    if (approvalDetail.value?.classDeductionIndicator) {
+      const indicator = approvalDetail.value.classDeductionIndicator;
+      managementEffectivenessForm.classDeduction = indicator.selfScore || 0;
+      managementEffectivenessForm.classDeductionHalf = (indicator.selfScore || 0) * 0.5;
+      managementEffectivenessForm.selfComment = indicator.selfComment || '';
+      managementEffectivenessForm.superiorScore = indicator.superiorScore || 0;
+      managementEffectivenessForm.superiorComment = indicator.superiorComment || '';
+    }
+    
+    // 初始化特色工作数据
+    specialWorkScores.value = (approvalDetail.value?.specialWorkIndicators || []).map(item => ({
+      ...item,
+      superiorScore: item.superiorScore || 0,
+      superiorComment: item.superiorComment || ''
+    }));
+    
+    // 初始化月考核得分数据
+    monthlyScoreForm.selfOverallComment = approvalDetail.value?.selfOverallComment || '';
+    monthlyScoreForm.superiorOverallComment = approvalDetail.value?.superiorOverallComment || '';
+    
+    // 初始化审批状态
+    approvalForm.auditStatus = approvalDetail.value?.auditStatus || '1';
+    
+  } catch (error) {
+    console.error('加载审批详情失败:', error);
+    proxy?.$modal.msgError('加载审批详情失败');
+  } finally {
+    loading.value = false;
+  }
+};
+
+/** 提交审批 */
+const handleSubmit = async () => {
+  try {
+    // 验证必填项
+    if (!approvalForm.auditStatus) {
+      proxy?.$modal.msgWarning('请选择审批状态');
+      return;
+    }
+
+    if (approvalForm.auditStatus === '2' && !approvalForm.auditComment.trim()) {
+      proxy?.$modal.msgWarning('拒绝审批时必须填写审批意见');
+      return;
+    }
+
+    submitLoading.value = true;
+
+    // 构造提交数据
+    const submitData: AssessmentApprovalSubmitBO = {
+      planId: currentRow.value?.planId,
+      classId: currentRow.value?.classId,
+      evaluatedUserId: currentRow.value?.evaluatedUserId,
+      routineWorkApproval: routineWorkScores.value.map(item => ({
+        id: item.id,
+        indicatorId: item.indicatorId,
+        superiorScore: item.superiorScore,
+        superiorComment: item.superiorComment
+      })),
+      classDeductionApproval: {
+        id: approvalDetail.value?.classDeductionIndicator?.id,
+        indicatorId: approvalDetail.value?.classDeductionIndicator?.indicatorId,
+        superiorScore: managementEffectivenessForm.superiorScore,
+        superiorComment: managementEffectivenessForm.superiorComment
+      },
+      specialWorkApproval: specialWorkScores.value.map(item => ({
+        id: item.id,
+        indicatorCode: item.indicatorCode,
+        superiorScore: item.superiorScore,
+        superiorComment: item.superiorComment
+      })),
+      superiorOverallComment: monthlyScoreForm.superiorOverallComment,
+      auditStatus: approvalForm.auditStatus,
+      auditComment: approvalForm.auditComment
+    };
+
+    await submitAssessmentApproval(submitData);
+    proxy?.$modal.msgSuccess('审批提交成功');
+    emit('success');
+    handleClose();
+    
+  } catch (error) {
+    console.error('提交审批失败:', error);
+    proxy?.$modal.msgError('提交审批失败');
+  } finally {
+    submitLoading.value = false;
+  }
+};
+
+/** 关闭弹窗 */
+const handleClose = () => {
+  visible.value = false;
+  
+  // 重置表单数据
+  routineWorkScores.value = [];
+  specialWorkScores.value = [];
+  Object.assign(managementEffectivenessForm, {
+    classDeduction: 0,
+    classDeductionHalf: 0,
+    selfComment: '',
+    superiorScore: 0,
+    superiorComment: ''
+  });
+  Object.assign(monthlyScoreForm, {
+    selfOverallComment: '',
+    superiorOverallComment: ''
+  });
+  Object.assign(approvalForm, {
+    auditStatus: '1',
+    auditComment: ''
+  });
+};
+
+// 暴露给父组件的方法
+defineExpose({
+  open
+});
+</script>
+
+<style scoped>
+.approval-dialog-content {
+  max-height: 70vh;
+  overflow-y: auto;
+}
+
+.info-card {
+  margin-bottom: 16px;
+}
+
+.info-card:last-child {
+  margin-bottom: 0;
+}
+
+.card-header {
+  font-weight: 600;
+  color: #303133;
+  text-align: center;
+}
+
+/* 表格样式 */
+:deep(.el-table) {
+  border-radius: 4px;
+}
+
+:deep(.el-table th) {
+  background-color: #f5f7fa;
+  color: #606266;
+  font-weight: 600;
+}
+
+/* 班主任常规工作表格样式优化 */
+:deep(.routine-work-table) {
+  .el-table__body-wrapper {
+    max-height: 350px;
+    overflow-y: auto;
+  }
+  
+  .el-table__row {
+    height: auto;
+  }
+  
+  .el-table__cell {
+    padding: 8px 0;
+    vertical-align: middle;
+  }
+  
+  /* 优化输入框在表格中的显示 */
+  .el-input-number {
+    width: 100% !important;
+  }
+  
+  .el-textarea__inner {
+    resize: none;
+    min-height: 60px !important;
+  }
+}
+
+/* 特色工作表格样式优化 */
+:deep(.special-work-table) {
+  .el-table__row {
+    height: auto;
+  }
+  
+  .el-table__cell {
+    padding: 8px 0;
+    vertical-align: middle;
+  }
+  
+  .el-input-number {
+    width: 100% !important;
+  }
+  
+  .el-textarea__inner {
+    resize: none;
+    min-height: 60px !important;
+  }
+}
+
+/* 文本省略样式 */
+.text-ellipsis {
+  display: block;
+  white-space: nowrap;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  max-width: 160px;
+}
+
+/* 表单样式优化 */
+:deep(.el-form-item__label) {
+  font-weight: 500;
+  text-align: center;
+}
+
+/* 描述列表居中样式 */
+:deep(.el-descriptions) {
+  .el-descriptions__label {
+    text-align: center;
+    font-weight: 500;
+  }
+  
+  .el-descriptions__content {
+    text-align: center;
+  }
+}
+
+/* 只读输入框样式 */
+:deep(.el-input.is-disabled .el-input__wrapper) {
+  background-color: #f5f7fa;
+}
+
+/* 审批表单样式 */
+.approval-form :deep(.el-radio-group) {
+  .el-radio {
+    margin-right: 30px;
+  }
+}
+</style> 

+ 273 - 0
web/src/views/bzrkh/assessmentApproval/index.vue

@@ -0,0 +1,273 @@
+<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 :model="queryParams" ref="queryFormRef" label-width="100px">
+            <el-row :gutter="20">
+              <el-col :lg="6" :md="12" :sm="24">
+                <el-form-item label="计划名称" prop="planName">
+                  <el-input v-model="queryParams.planName" placeholder="请输入计划名称" clearable @keyup.enter="handleQuery" />
+                </el-form-item>
+              </el-col>
+              <el-col :lg="6" :md="12" :sm="24">
+                <el-form-item label="考核方案" prop="schemeName">
+                  <el-select v-model="queryParams.schemeName" placeholder="请选择考核方案" clearable style="width: 100%">
+                    <el-option
+                      v-for="item in schemeOptions"
+                      :key="item.value"
+                      :label="item.label"
+                      :value="item.value"
+                    />
+                  </el-select>
+                </el-form-item>
+              </el-col>
+              <el-col :lg="6" :md="12" :sm="24">
+                <el-form-item label="审批状态" prop="auditStatus">
+                  <el-select v-model="queryParams.auditStatus" placeholder="请选择审批状态" clearable style="width: 100%">
+                    <el-option label="待审核" value="0" />
+                    <el-option label="审核通过" value="1" />
+                    <el-option label="审核不通过" value="2" />
+                  </el-select>
+                </el-form-item>
+              </el-col>
+              <el-col :lg="6" :md="12" :sm="24">
+                <el-form-item label="班级名称" prop="className">
+                  <el-input v-model="queryParams.className" placeholder="请输入班级名称" clearable @keyup.enter="handleQuery" />
+                </el-form-item>
+              </el-col>
+              <el-col :lg="6" :md="12" :sm="24">
+                <el-form-item label="班主任姓名" prop="teacherName">
+                  <el-input v-model="queryParams.teacherName" placeholder="请输入班主任姓名" clearable @keyup.enter="handleQuery" />
+                </el-form-item>
+              </el-col>
+              <el-col :lg="6" :md="24" :sm="24" style="text-align: right">
+                <el-form-item>
+                  <el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
+                  <el-button icon="Refresh" @click="resetQuery">重置</el-button>
+                </el-form-item>
+              </el-col>
+            </el-row>
+          </el-form>
+        </el-card>
+      </div>
+    </transition>
+
+    <!-- 表格区域 -->
+    <el-card shadow="never" class="button-card table-card">
+      <template #header>
+        <el-row :gutter="10" class="mb8">
+          <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
+        </el-row>
+      </template>
+
+      <div class="table-container">
+        <el-table v-loading="loading" border :data="approvalList" @sort-change="sortChange">
+          <el-table-column label="计划名称" align="center" prop="planName" :show-overflow-tooltip="true" />
+          <el-table-column label="考核方案" align="center" prop="schemeName" :show-overflow-tooltip="true" />
+          <el-table-column label="学年学期" align="center" width="120">
+            <template #default="scope">
+              <span>{{ scope.row.academicYear }}{{ scope.row.semester === '1' ? '上' : '下' }}学期</span>
+            </template>
+          </el-table-column>
+          <el-table-column label="班级名称" align="center" prop="className" :show-overflow-tooltip="true" />
+          <el-table-column label="班主任姓名" align="center" prop="evaluatedUserName" :show-overflow-tooltip="true" />
+          <el-table-column label="申请时间" align="center" width="180" sortable="custom" prop="submitTime">
+            <template #default="scope">
+              <span>{{ parseTime(scope.row.submitTime, '{y}-{m}-{d} {h}:{i}:{s}') }}</span>
+            </template>
+          </el-table-column>
+          <el-table-column label="审批状态" align="center" width="120">
+            <template #default="scope">
+              <el-tag v-if="!scope.row.auditStatus || scope.row.auditStatus === '0'" type="warning" effect="plain">待审核</el-tag>
+              <el-tag v-else-if="scope.row.auditStatus === '1'" type="success" effect="plain">审核通过</el-tag>
+              <el-tag v-else-if="scope.row.auditStatus === '2'" type="danger" effect="plain">审核不通过</el-tag>
+              <el-tag v-else type="info" effect="plain">未知状态</el-tag>
+            </template>
+          </el-table-column>
+          <el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="180">
+            <template #default="scope">
+              <el-tooltip content="审批" placement="top">
+                <el-button 
+                  link 
+                  type="primary" 
+                  icon="Edit" 
+                  :disabled="loading || scope.row.auditStatus !== '0'"
+                  @click="handleApproval(scope.row)"
+                ></el-button>
+              </el-tooltip>
+              <el-tooltip content="查看" placement="top">
+                <el-button 
+                  link 
+                  type="success" 
+                  icon="View" 
+                  :disabled="loading"
+                  @click="handleView(scope.row)"
+                ></el-button>
+              </el-tooltip>
+            </template>
+          </el-table-column>
+        </el-table>
+      </div>
+
+      <div class="pagination-container">
+        <pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
+      </div>
+    </el-card>
+
+    <!-- 审批弹窗 -->
+    <ApprovalDialog 
+      ref="approvalDialogRef" 
+      @success="handleApprovalSuccess" 
+    />
+
+    <!-- 查看弹窗 -->
+    <ViewDialog 
+      ref="viewDialogRef" 
+    />
+  </div>
+</template>
+
+<script setup name="AssessmentApproval" lang="ts">
+import { 
+  listAssessmentApproval,
+  getAssessmentSchemeOptions
+} from '@/api/bzrkh/assessmentApproval';
+import {
+  AssessmentApprovalVO,
+  AssessmentApprovalQuery
+} from '@/api/bzrkh/assessmentApproval/types';
+import ApprovalDialog from './approvalDialog.vue';
+import ViewDialog from './viewDialog.vue';
+
+const { proxy } = getCurrentInstance() as ComponentInternalInstance;
+
+const approvalList = ref<AssessmentApprovalVO[]>([]);
+const loading = ref(true);
+const showSearch = ref(true);
+const total = ref(0);
+const schemeOptions = ref<any[]>([]);
+
+// 弹窗引用
+const approvalDialogRef = ref();
+const viewDialogRef = ref();
+const queryFormRef = ref<ElFormInstance>();
+
+const data = reactive<PageData<any, AssessmentApprovalQuery>>({
+  form: {},
+  queryParams: {
+    pageNum: 1,
+    pageSize: 10,
+    planName: undefined,
+    schemeName: undefined,
+    auditStatus: undefined,
+    className: undefined,
+    teacherName: undefined
+  },
+  rules: {}
+});
+
+const { queryParams } = toRefs(data);
+
+/** 获取考核方案选项 */
+const getSchemeOptions = async () => {
+  try {
+    const res = await getAssessmentSchemeOptions();
+    schemeOptions.value = res.data || [];
+  } catch (error) {
+    console.error('获取考核方案选项失败:', error);
+  }
+};
+
+/** 查询审核列表 */
+const getList = async () => {
+  loading.value = true;
+  try {
+    const res = await listAssessmentApproval(queryParams.value);
+    approvalList.value = res.rows || [];
+    total.value = res.total || 0;
+  } catch (error) {
+    console.error('获取审核列表失败:', error);
+  } finally {
+    loading.value = false;
+  }
+};
+
+/** 搜索按钮操作 */
+const handleQuery = () => {
+  queryParams.value.pageNum = 1;
+  getList();
+};
+
+/** 重置按钮操作 */
+const resetQuery = () => {
+  queryFormRef.value?.resetFields();
+  handleQuery();
+};
+
+/** 排序触发事件 */
+const sortChange = (column: any) => {
+  const { prop, order } = column;
+  if (prop === 'submitTime') {
+    queryParams.value.orderByColumn = prop;
+    queryParams.value.isAsc = order === 'ascending' ? 'asc' : 'desc';
+    getList();
+  }
+};
+
+/** 审批操作 */
+const handleApproval = (row: AssessmentApprovalVO) => {
+  approvalDialogRef.value?.open(row);
+};
+
+/** 查看操作 */
+const handleView = (row: AssessmentApprovalVO) => {
+  viewDialogRef.value?.open(row);
+};
+
+/** 审批成功回调 */
+const handleApprovalSuccess = () => {
+  getList();
+};
+
+onMounted(() => {
+  getSchemeOptions();
+  getList();
+});
+</script>
+
+<style scoped>
+/* 页面容器样式 */
+.page-container {
+  padding: 8px;
+}
+
+/* 表格卡片布局 */
+.table-card {
+  margin-top: 0;
+}
+
+.table-card :deep(.el-card__body) {
+  padding: 0px 20px 20px 20px !important;
+}
+
+/* 表格主体 */
+.table-container {
+  margin-bottom: 0;
+}
+
+/* 移除按钮栏底部边框 */
+.button-card :deep(.el-card__header) {
+  border-bottom: none !important;
+}
+
+/* 分页容器样式 */
+.pagination-container {
+  display: flex;
+  justify-content: flex-end;
+  padding: 16px 20px 0 0 !important;
+  background-color: #fff;
+  margin-top: 0px !important;
+}
+</style> 

+ 577 - 0
web/src/views/bzrkh/assessmentApproval/viewDialog.vue

@@ -0,0 +1,577 @@
+<template>
+  <el-dialog
+    :title="dialogTitle"
+    v-model="visible"
+    width="1200px"
+    :close-on-click-modal="false"
+    append-to-body
+    @close="handleClose"
+  >
+    <div v-loading="loading" class="view-dialog-content">
+      <!-- 1. 班级信息卡片 -->
+      <el-card shadow="never" class="info-card">
+        <template #header>
+          <div class="card-header">
+            <span>班级信息</span>
+          </div>
+        </template>
+        <el-descriptions :column="3" border>
+          <el-descriptions-item label="学院名称">{{ viewDetail?.classDetail?.collegeName || '-' }}</el-descriptions-item>
+          <el-descriptions-item label="专业名称">{{ viewDetail?.classDetail?.majorName || '-' }}</el-descriptions-item>
+          <el-descriptions-item label="班级名称">{{ viewDetail?.classDetail?.className || '-' }}</el-descriptions-item>
+        </el-descriptions>
+      </el-card>
+
+      <!-- 2. 总系数(K)与层次系数(K1)并排 -->
+      <el-row :gutter="20" class="info-card">
+        <el-col :span="12">
+          <el-card shadow="never">
+            <template #header>
+              <div class="card-header">
+                <span>总系数(K)</span>
+              </div>
+            </template>
+            <el-descriptions :column="1" border>
+              <el-descriptions-item label="总系数">{{ formatNumber(viewDetail?.coefficient?.totalCoefficient, 3) }}</el-descriptions-item>
+            </el-descriptions>
+          </el-card>
+        </el-col>
+        <el-col :span="12">
+          <el-card shadow="never">
+            <template #header>
+              <div class="card-header">
+                <span>层次系数(K1)</span>
+              </div>
+            </template>
+            <el-descriptions :column="2" border>
+              <el-descriptions-item label="班级学历层级">{{ getClassTypeText(viewDetail?.classDetail?.classType) }}</el-descriptions-item>
+              <el-descriptions-item label="层次系数">{{ formatNumber(viewDetail?.coefficient?.levelCoefficient, 3) }}</el-descriptions-item>
+            </el-descriptions>
+          </el-card>
+        </el-col>
+      </el-row>
+
+      <!-- 3. 人数系数(K2)与住校生系数(K3)并排 -->
+      <el-row :gutter="20" class="info-card">
+        <el-col :span="12">
+          <el-card shadow="never">
+            <template #header>
+              <div class="card-header">
+                <span>人数系数(K2)</span>
+              </div>
+            </template>
+            <el-descriptions :column="2" border>
+              <el-descriptions-item label="班级总人数">{{ viewDetail?.classDetail?.totalStudentCount || 0 }}人</el-descriptions-item>
+              <el-descriptions-item label="人数系数">{{ formatNumber(viewDetail?.coefficient?.studentCountCoefficient, 3) }}</el-descriptions-item>
+            </el-descriptions>
+          </el-card>
+        </el-col>
+        <el-col :span="12">
+          <el-card shadow="never">
+            <template #header>
+              <div class="card-header">
+                <span>住校生系数(K3)</span>
+              </div>
+            </template>
+            <el-descriptions :column="2" border>
+              <el-descriptions-item label="住校生人数">{{ viewDetail?.classDetail?.boardingStudentCount || 0 }}人</el-descriptions-item>
+              <el-descriptions-item label="住校生系数">{{ formatNumber(viewDetail?.coefficient?.boardingCoefficient, 3) }}</el-descriptions-item>
+            </el-descriptions>
+          </el-card>
+        </el-col>
+      </el-row>
+
+      <!-- 4. 班主任常规工作(50分)卡片 -->
+      <el-card shadow="never" class="info-card">
+        <template #header>
+          <div class="card-header">
+            <span>班主任常规工作(50分)</span>
+          </div>
+        </template>
+        <el-table border :data="routineWorkScores" style="width: 100%" max-height="400" class="routine-work-table">
+          <el-table-column type="index" label="序号" width="60" align="center" />
+          <el-table-column prop="indicatorName" label="指标名称" min-width="150" align="center" :show-overflow-tooltip="true" />
+          <el-table-column prop="description" label="指标描述" min-width="180" align="center" :show-overflow-tooltip="true" />
+          <el-table-column prop="score" label="指标分值" width="80" align="center">
+            <template #default="scope">
+              <span>{{ scope.row.score || 0 }}</span>
+            </template>
+          </el-table-column>
+          <el-table-column label="自评分数" width="80" align="center">
+            <template #default="scope">
+              <span>{{ scope.row.selfScore || 0 }}</span>
+            </template>
+          </el-table-column>
+          <el-table-column label="自评意见" width="180" align="center">
+            <template #default="scope">
+              <el-tooltip :content="scope.row.selfComment || '无'" placement="top" :disabled="!scope.row.selfComment">
+                <span class="text-ellipsis">{{ scope.row.selfComment || '无' }}</span>
+              </el-tooltip>
+            </template>
+          </el-table-column>
+          <el-table-column label="上级评分" width="80" align="center">
+            <template #default="scope">
+              <span>{{ scope.row.superiorScore || '-' }}</span>
+            </template>
+          </el-table-column>
+          <el-table-column label="审批意见" width="180" align="center">
+            <template #default="scope">
+              <el-tooltip :content="scope.row.superiorComment || '无'" placement="top" :disabled="!scope.row.superiorComment">
+                <span class="text-ellipsis">{{ scope.row.superiorComment || '无' }}</span>
+              </el-tooltip>
+            </template>
+          </el-table-column>
+        </el-table>
+      </el-card>
+
+      <!-- 5. 班级管理实效(50分)卡片 -->
+      <el-card shadow="never" class="info-card">
+        <template #header>
+          <div class="card-header">
+            <span>班级管理实效(50分)</span>
+          </div>
+        </template>
+        <el-form label-width="150px" class="management-effectiveness-form">
+          <el-row :gutter="20">
+            <el-col :span="8">
+              <el-form-item label="班级扣分">
+                <el-input
+                  :value="managementEffectivenessData.classDeduction?.toFixed(2) || '0.00'"
+                  readonly
+                  style="width: 100%; text-align: center;"
+                />
+              </el-form-item>
+            </el-col>
+            <el-col :span="8">
+              <el-form-item label="按班级扣分50%计">
+                <el-input
+                  :value="managementEffectivenessData.classDeductionHalf?.toFixed(2) || '0.00'"
+                  readonly
+                  style="width: 100%; text-align: center;"
+                />
+              </el-form-item>
+            </el-col>
+            <el-col :span="8">
+              <el-form-item label="上级评分">
+                <el-input
+                  :value="managementEffectivenessData.superiorScore?.toFixed(2) || '-'"
+                  readonly
+                  style="width: 100%; text-align: center;"
+                />
+              </el-form-item>
+            </el-col>
+          </el-row>
+          <el-row>
+            <el-col :span="12">
+              <el-form-item label="自评意见">
+                <el-input
+                  :value="managementEffectivenessData.selfComment"
+                  type="textarea"
+                  :rows="3"
+                  readonly
+                />
+              </el-form-item>
+            </el-col>
+            <el-col :span="12">
+              <el-form-item label="审批意见">
+                <el-input
+                  :value="managementEffectivenessData.superiorComment"
+                  type="textarea"
+                  :rows="3"
+                  readonly
+                />
+              </el-form-item>
+            </el-col>
+          </el-row>
+        </el-form>
+      </el-card>
+
+      <!-- 6. 特色工作(加20分)卡片 -->
+      <el-card shadow="never" class="info-card">
+        <template #header>
+          <div class="card-header">
+            <span>特色工作(加20分)</span>
+          </div>
+        </template>
+        <el-table border :data="specialWorkScores" style="width: 100%" class="special-work-table">
+          <el-table-column type="index" label="序号" width="60" align="center" />
+          <el-table-column prop="indicatorName" label="特色工作项目" min-width="180" align="center" :show-overflow-tooltip="true" />
+          <el-table-column label="自评分数" width="80" align="center">
+            <template #default="scope">
+              <span>{{ scope.row.score || 0 }}</span>
+            </template>
+          </el-table-column>
+          <el-table-column label="自评意见" width="180" align="center">
+            <template #default="scope">
+              <el-tooltip :content="scope.row.selfComment || '无'" placement="top" :disabled="!scope.row.selfComment">
+                <span class="text-ellipsis">{{ scope.row.selfComment || '无' }}</span>
+              </el-tooltip>
+            </template>
+          </el-table-column>
+          <el-table-column label="上级评分" width="80" align="center">
+            <template #default="scope">
+              <span>{{ scope.row.superiorScore || '-' }}</span>
+            </template>
+          </el-table-column>
+          <el-table-column label="审批意见" width="180" align="center">
+            <template #default="scope">
+              <el-tooltip :content="scope.row.superiorComment || '无'" placement="top" :disabled="!scope.row.superiorComment">
+                <span class="text-ellipsis">{{ scope.row.superiorComment || '无' }}</span>
+              </el-tooltip>
+            </template>
+          </el-table-column>
+        </el-table>
+      </el-card>
+
+      <!-- 7. 月考核得分卡片 -->
+      <el-card shadow="never" class="info-card">
+        <template #header>
+          <div class="card-header">
+            <span>月考核得分</span>
+          </div>
+        </template>
+        <el-form label-width="100px" class="monthly-score-form">
+          <el-row :gutter="20">
+            <el-col :span="12">
+              <el-form-item label="月考核得分">
+                <el-input
+                  :value="calculateMonthlyScore().toFixed(2)"
+                  readonly
+                  style="width: 100%; text-align: center;"
+                />
+              </el-form-item>
+            </el-col>
+          </el-row>
+          <el-row>
+            <el-col :span="12">
+              <el-form-item label="自我总体评价">
+                <el-input
+                  :value="monthlyScoreData.selfOverallComment"
+                  type="textarea"
+                  :rows="4"
+                  readonly
+                />
+              </el-form-item>
+            </el-col>
+            <el-col :span="12">
+              <el-form-item label="上级总体评价">
+                <el-input
+                  :value="monthlyScoreData.superiorOverallComment"
+                  type="textarea"
+                  :rows="4"
+                  readonly
+                />
+              </el-form-item>
+            </el-col>
+          </el-row>
+        </el-form>
+      </el-card>
+
+      <!-- 8. 审批结果卡片 -->
+      <el-card shadow="never" class="info-card" v-if="viewDetail?.auditStatus">
+        <template #header>
+          <div class="card-header">
+            <span>审批结果</span>
+          </div>
+        </template>
+        <el-descriptions :column="2" border>
+          <el-descriptions-item label="审批状态">
+            <dict-tag :options="bmzr_audit_status" :value="viewDetail?.auditStatus"/>
+          </el-descriptions-item>
+          <el-descriptions-item label="审批时间">
+            {{ parseTime(currentRow?.createTime, '{y}-{m}-{d} {h}:{i}:{s}') || '-' }}
+          </el-descriptions-item>
+        </el-descriptions>
+        <el-form label-width="100px" style="margin-top: 20px;" v-if="approvalData.auditComment">
+          <el-form-item label="审批意见">
+            <el-input
+              :value="approvalData.auditComment"
+              type="textarea"
+              :rows="3"
+              readonly
+            />
+          </el-form-item>
+        </el-form>
+      </el-card>
+    </div>
+
+    <template #footer>
+      <div class="dialog-footer">
+        <el-button @click="handleClose">关闭</el-button>
+      </div>
+    </template>
+  </el-dialog>
+</template>
+
+<script setup name="ViewDialog" lang="ts">
+import { 
+  getAssessmentApprovalDetail
+} from '@/api/bzrkh/assessmentApproval';
+import {
+  AssessmentApprovalVO,
+  AssessmentApprovalDetailVO,
+  AssessmentApprovalIndicatorVO,
+  AssessmentApprovalSpecialWorkVO
+} from '@/api/bzrkh/assessmentApproval/types';
+
+const { proxy } = getCurrentInstance() as ComponentInternalInstance;
+const { bmzr_audit_status } = proxy?.useDict('bmzr_audit_status');
+
+const visible = ref(false);
+const loading = ref(false);
+
+const currentRow = ref<AssessmentApprovalVO>();
+const viewDetail = ref<AssessmentApprovalDetailVO>();
+const routineWorkScores = ref<AssessmentApprovalIndicatorVO[]>([]);
+const specialWorkScores = ref<AssessmentApprovalSpecialWorkVO[]>([]);
+
+// 班级管理实效数据
+const managementEffectivenessData = reactive({
+  classDeduction: 0,
+  classDeductionHalf: 0,
+  selfComment: '',
+  superiorScore: 0,
+  superiorComment: ''
+});
+
+// 月考核得分数据
+const monthlyScoreData = reactive({
+  selfOverallComment: '',
+  superiorOverallComment: ''
+});
+
+// 审批数据
+const approvalData = reactive({
+  auditComment: ''
+});
+
+const dialogTitle = computed(() => {
+  const className = viewDetail.value?.classDetail?.className || '';
+  return `${className} - 班主任考核查看`;
+});
+
+/** 获取班级层次文本 */
+const getClassTypeText = (classType?: string) => {
+  const typeMap: Record<string, string> = {
+    '1': '中级工班',
+    '2': '高级工班',
+    '3': '预备技师班',
+    '4': '技师班',
+    '5': '中高职一体'
+  };
+  return typeMap[classType || ''] || '未知';
+};
+
+/** 格式化数字显示 */
+const formatNumber = (value?: number | string, precision = 4) => {
+  if (value === undefined || value === null || value === '') {
+    return '0.' + '0'.repeat(precision);
+  }
+  
+  const numValue = typeof value === 'string' ? parseFloat(value) : value;
+  
+  if (isNaN(numValue)) {
+    return '0.' + '0'.repeat(precision);
+  }
+  
+  return numValue.toFixed(precision);
+};
+
+/** 计算月考核得分 */
+const calculateMonthlyScore = () => {
+  // 总系数(K)
+  const totalCoefficient = viewDetail.value?.coefficient?.totalCoefficient || 0;
+  
+  // 班主任常规工作自评分之和
+  const routineWorkTotal = routineWorkScores.value.reduce((sum, item) => sum + (item.selfScore || 0), 0);
+  
+  // 按班级扣分50%计的分值
+  const deductionHalf = managementEffectivenessData.classDeductionHalf || 0;
+  
+  // 特色工作总分值
+  const specialWorkTotal = specialWorkScores.value.reduce((sum, item) => sum + (item.score || 0), 0);
+  
+  // 月考核得分 = 总系数(K)* (班主任常规工作自评分之和 - 按班级扣分50%计的分值 + 特色工作总分值)
+  return totalCoefficient * (routineWorkTotal - deductionHalf + specialWorkTotal);
+};
+
+/** 打开弹窗 */
+const open = async (row: AssessmentApprovalVO) => {
+  if (!row.planId || !row.classId || !row.evaluatedUserId) {
+    proxy?.$modal.msgError('参数错误:缺少必要的ID信息');
+    return;
+  }
+  
+  currentRow.value = row;
+  visible.value = true;
+  await loadViewDetail();
+};
+
+/** 加载查看详情数据 */
+const loadViewDetail = async () => {
+  if (!currentRow.value?.planId || !currentRow.value?.classId || !currentRow.value?.evaluatedUserId) {
+    return;
+  }
+
+  loading.value = true;
+  try {
+    const res = await getAssessmentApprovalDetail(
+      currentRow.value.planId,
+      currentRow.value.classId,
+      currentRow.value.evaluatedUserId
+    );
+    viewDetail.value = res.data;
+    
+    // 初始化班主任常规工作数据
+    routineWorkScores.value = viewDetail.value?.routineWorkIndicators || [];
+    
+    // 初始化班级管理实效数据
+    if (viewDetail.value?.classDeductionIndicator) {
+      const indicator = viewDetail.value.classDeductionIndicator;
+      managementEffectivenessData.classDeduction = indicator.selfScore || 0;
+      managementEffectivenessData.classDeductionHalf = (indicator.selfScore || 0) * 0.5;
+      managementEffectivenessData.selfComment = indicator.selfComment || '';
+      managementEffectivenessData.superiorScore = indicator.superiorScore || 0;
+      managementEffectivenessData.superiorComment = indicator.superiorComment || '';
+    }
+    
+    // 初始化特色工作数据
+    specialWorkScores.value = viewDetail.value?.specialWorkIndicators || [];
+    
+    // 初始化月考核得分数据
+    monthlyScoreData.selfOverallComment = viewDetail.value?.selfOverallComment || '';
+    monthlyScoreData.superiorOverallComment = viewDetail.value?.superiorOverallComment || '';
+    
+    // 初始化审批数据
+    // 这里需要根据实际的后端字段调整
+    approvalData.auditComment = '';
+    
+  } catch (error) {
+    console.error('加载查看详情失败:', error);
+    proxy?.$modal.msgError('加载查看详情失败');
+  } finally {
+    loading.value = false;
+  }
+};
+
+/** 关闭弹窗 */
+const handleClose = () => {
+  visible.value = false;
+  
+  // 重置数据
+  routineWorkScores.value = [];
+  specialWorkScores.value = [];
+  Object.assign(managementEffectivenessData, {
+    classDeduction: 0,
+    classDeductionHalf: 0,
+    selfComment: '',
+    superiorScore: 0,
+    superiorComment: ''
+  });
+  Object.assign(monthlyScoreData, {
+    selfOverallComment: '',
+    superiorOverallComment: ''
+  });
+  Object.assign(approvalData, {
+    auditComment: ''
+  });
+};
+
+// 暴露给父组件的方法
+defineExpose({
+  open
+});
+</script>
+
+<style scoped>
+.view-dialog-content {
+  max-height: 70vh;
+  overflow-y: auto;
+}
+
+.info-card {
+  margin-bottom: 16px;
+}
+
+.info-card:last-child {
+  margin-bottom: 0;
+}
+
+.card-header {
+  font-weight: 600;
+  color: #303133;
+  text-align: center;
+}
+
+/* 表格样式 */
+:deep(.el-table) {
+  border-radius: 4px;
+}
+
+:deep(.el-table th) {
+  background-color: #f5f7fa;
+  color: #606266;
+  font-weight: 600;
+}
+
+/* 班主任常规工作表格样式优化 */
+:deep(.routine-work-table) {
+  .el-table__body-wrapper {
+    max-height: 350px;
+    overflow-y: auto;
+  }
+  
+  .el-table__row {
+    height: auto;
+  }
+  
+  .el-table__cell {
+    padding: 8px 0;
+    vertical-align: middle;
+  }
+}
+
+/* 特色工作表格样式优化 */
+:deep(.special-work-table) {
+  .el-table__row {
+    height: auto;
+  }
+  
+  .el-table__cell {
+    padding: 8px 0;
+    vertical-align: middle;
+  }
+}
+
+/* 文本省略样式 */
+.text-ellipsis {
+  display: block;
+  white-space: nowrap;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  max-width: 160px;
+}
+
+/* 表单样式优化 */
+:deep(.el-form-item__label) {
+  font-weight: 500;
+  text-align: center;
+}
+
+/* 描述列表居中样式 */
+:deep(.el-descriptions) {
+  .el-descriptions__label {
+    text-align: center;
+    font-weight: 500;
+  }
+  
+  .el-descriptions__content {
+    text-align: center;
+  }
+}
+
+/* 只读输入框样式 */
+:deep(.el-input.is-disabled .el-input__wrapper) {
+  background-color: #f5f7fa;
+}
+</style> 

+ 91 - 40
web/src/views/bzrkh/teacherAssessment/index.vue

@@ -35,15 +35,9 @@
           <!-- 表格区域 -->
           <el-card shadow="never" class="button-card table-card">
             <template #header>
-              <!-- <el-row :gutter="10" class="mb8">
-                <el-col :span="1.5">
-                  <el-button type="primary" plain icon="Edit" @click="() => handleSubmitAssessment()" :disabled="!hasSelectedPlan"></el-button>
-                </el-col>
-                <el-col :span="1.5">
-                  <el-button type="success" plain icon="View" @click="() => handleViewAssessment()" :disabled="!hasSelectedPlan"></el-button>
-                </el-col>
+              <el-row :gutter="10" class="mb8">
                 <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
-              </el-row> -->
+              </el-row>
             </template>
 
             <div class="table-container">
@@ -70,6 +64,15 @@
                     <span v-else class="text-gray-400">未设置</span>
                   </template>
                 </el-table-column>
+                <el-table-column label="审核状态" align="center" width="120">
+                  <template #default="scope">
+                    <el-tag v-if="!scope.row.submitted" type="info" effect="plain">未提交</el-tag>
+                    <el-tag v-else-if="scope.row.auditStatus === '0'" type="warning" effect="plain">待审核</el-tag>
+                    <el-tag v-else-if="scope.row.auditStatus === '1'" type="success" effect="plain">审核通过</el-tag>
+                    <el-tag v-else-if="scope.row.auditStatus === '2'" type="danger" effect="plain">审核不通过</el-tag>
+                    <el-tag v-else type="info" effect="plain">未知状态</el-tag>
+                  </template>
+                </el-table-column>
                 <el-table-column label="创建时间" align="center" prop="createTime" width="180">
                   <template #default="scope">
                     <span>{{ parseTime(scope.row.createTime, '{y}-{m}-{d} {h}:{i}:{s}') }}</span>
@@ -77,15 +80,30 @@
                 </el-table-column>
                 <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
                   <template #default="scope">
-                    <el-tooltip content="提交考核" placement="top">
-                      <el-button 
-                        link 
-                        type="primary" 
-                        icon="Edit" 
-                        :disabled="loading || !isDataReady"
-                        @click="handleSubmitAssessment(scope.row)"
-                      ></el-button>
-                    </el-tooltip>
+                    <!-- 未提交状态:显示提交考核按钮 -->
+                    <template v-if="!scope.row.submitted">
+                      <el-tooltip content="提交考核" placement="top">
+                        <el-button 
+                          link 
+                          type="primary" 
+                          icon="Edit" 
+                          :disabled="loading || !isDataReady"
+                          @click="handleSubmitAssessment(scope.row)"
+                        ></el-button>
+                      </el-tooltip>
+                    </template>
+                    <!-- 已提交状态:显示撤销按钮 -->
+                    <template v-else>
+                      <el-tooltip content="撤销提交" placement="top">
+                        <el-button 
+                          link 
+                          type="warning" 
+                          icon="RefreshLeft" 
+                          :disabled="loading || !isDataReady || scope.row.auditStatus !== '0'"
+                          @click="handleWithdrawAssessment(scope.row)"
+                        ></el-button>
+                      </el-tooltip>
+                    </template>
                     <el-tooltip content="查看考核" placement="top">
                       <el-button 
                         link 
@@ -129,7 +147,8 @@ import {
   listTeacherClasses,
   listTeacherAssessmentPlans,
   submitAssessment,
-  getAssessmentDetail
+  getAssessmentDetail,
+  withdrawAssessment
 } from '@/api/bzrkh/teacherAssessment';
 import {
   TeacherClassVO,
@@ -147,8 +166,7 @@ const assessmentPlanList = ref<TeacherAssessmentPlanVO[]>([]);
 const loading = ref(true);
 const showSearch = ref(true);
 const activeTab = ref<string>('');
-const selectedPlans = ref<TeacherAssessmentPlanVO[]>([]);
-const hasSelectedPlan = ref(false);
+
 const total = ref(0);
 
 // 考核提交相关状态
@@ -235,8 +253,7 @@ const resetQuery = () => {
 
 /** 多选框选中数据 */
 const handleSelectionChange = (selection: TeacherAssessmentPlanVO[]) => {
-  selectedPlans.value = selection;
-  hasSelectedPlan.value = selection.length > 0;
+  // 不再需要处理批量选择逻辑
 };
 
 /** 排序触发事件 */
@@ -250,25 +267,19 @@ const sortChange = (column: any) => {
 };
 
 /** 提交考核 */
-const handleSubmitAssessment = async (row?: TeacherAssessmentPlanVO) => {
-  const plans = row ? [row] : selectedPlans.value;
-  if (plans.length === 0) {
+const handleSubmitAssessment = async (row: TeacherAssessmentPlanVO) => {
+  if (!row) {
     proxy?.$modal.msgWarning('请选择要提交考核的计划');
     return;
   }
 
-  if (plans.length > 1) {
-    proxy?.$modal.msgWarning('每次只能提交一个考核计划');
-    return;
-  }
-
   // 验证数据是否已准备就绪
   if (!isDataReady.value) {
     proxy?.$modal.msgWarning('数据加载中,请稍后再试');
     return;
   }
 
-  const plan = plans[0];
+  const plan = row;
   
   // 确保计划ID存在
   if (!plan.id) {
@@ -295,9 +306,8 @@ const handleSubmitAssessment = async (row?: TeacherAssessmentPlanVO) => {
 };
 
 /** 查看考核 */
-const handleViewAssessment = async (row?: TeacherAssessmentPlanVO) => {
-  const plans = row ? [row] : selectedPlans.value;
-  if (plans.length === 0) {
+const handleViewAssessment = async (row: TeacherAssessmentPlanVO) => {
+  if (!row) {
     proxy?.$modal.msgWarning('请选择要查看考核的计划');
     return;
   }
@@ -307,11 +317,9 @@ const handleViewAssessment = async (row?: TeacherAssessmentPlanVO) => {
     proxy?.$modal.msgWarning('数据加载中,请稍后再试');
     return;
   }
-
-  const plan = plans[0];
   
   // 确保计划ID存在
-  if (!plan.id) {
+  if (!row.id) {
     proxy?.$modal.msgError('考核计划ID无效');
     return;
   }
@@ -327,13 +335,56 @@ const handleViewAssessment = async (row?: TeacherAssessmentPlanVO) => {
   proxy?.$modal.msg('查看考核功能待实现');
 };
 
+/** 撤销考核提交 */
+const handleWithdrawAssessment = async (row: TeacherAssessmentPlanVO) => {
+  // 验证数据是否已准备就绪
+  if (!isDataReady.value) {
+    proxy?.$modal.msgWarning('数据加载中,请稍后再试');
+    return;
+  }
+
+  // 确保计划ID存在
+  if (!row.id) {
+    proxy?.$modal.msgError('考核计划ID无效');
+    return;
+  }
+
+  // 检查提交状态,只有待审核状态才能撤销
+          if (row.auditStatus !== '0') {
+    proxy?.$modal.msgWarning('只有待审核状态的考核才能撤销');
+    return;
+  }
+  
+  const currentClass = teacherClasses.value.find(c => c.id?.toString() === activeTab.value);
+  
+  if (!currentClass || !currentClass.id) {
+    proxy?.$modal.msgError('获取班级信息失败,请刷新页面后重试');
+    return;
+  }
+
+  try {
+    // 确认撤销操作
+    await proxy?.$modal.confirm('确定要撤销该考核提交吗?撤销后可以重新修改和提交。');
+    
+    // 调用撤销API
+    await withdrawAssessment(row.id, currentClass.id);
+    
+    proxy?.$modal.msgSuccess('撤销成功');
+    
+    // 刷新列表
+    await getList();
+  } catch (error) {
+    if (error !== 'cancel') {
+      console.error('撤销考核提交失败:', error);
+      proxy?.$modal.msgError('撤销失败,请重试');
+    }
+  }
+};
+
 /** 考核提交成功回调 */
 const handleSubmitSuccess = () => {
   // 刷新考核计划列表
   getList();
-  // 清空选择
-  selectedPlans.value = [];
-  hasSelectedPlan.value = false;
 };
 
 onMounted(() => {

+ 234 - 73
web/src/views/bzrkh/teacherAssessment/submitDialog.vue

@@ -22,74 +22,82 @@
         </el-descriptions>
       </el-card>
 
-      <!-- 2. 人数系数卡片 -->
-      <el-card shadow="never" class="info-card">
-        <template #header>
-          <div class="card-header">
-            <span>人数系数(K2)</span>
-          </div>
-        </template>
-        <el-descriptions :column="2" border>
-          <el-descriptions-item label="班级总人数">{{ assessmentDetail?.classDetail?.totalStudentCount || 0 }}人</el-descriptions-item>
-          <el-descriptions-item label="人数系数">{{ formatNumber(assessmentDetail?.coefficient?.studentCountCoefficient, 4) }}</el-descriptions-item>
-        </el-descriptions>
-      </el-card>
-
-      <!-- 3. 住校生系数卡片 -->
-      <el-card shadow="never" class="info-card">
-        <template #header>
-          <div class="card-header">
-            <span>住校生系数(K3)</span>
-          </div>
-        </template>
-        <el-descriptions :column="2" border>
-          <el-descriptions-item label="住校生人数">{{ assessmentDetail?.classDetail?.boardingStudentCount || 0 }}人</el-descriptions-item>
-          <el-descriptions-item label="住校生系数">{{ formatNumber(assessmentDetail?.coefficient?.boardingCoefficient, 4) }}</el-descriptions-item>
-        </el-descriptions>
-      </el-card>
-
-      <!-- 4. 层次系数卡片 -->
-      <el-card shadow="never" class="info-card">
-        <template #header>
-          <div class="card-header">
-            <span>层次系数(K1)</span>
-          </div>
-        </template>
-        <el-descriptions :column="2" border>
-          <el-descriptions-item label="班级学历层级">{{ getClassTypeText(assessmentDetail?.classDetail?.classType) }}</el-descriptions-item>
-          <el-descriptions-item label="层次系数">{{ formatNumber(assessmentDetail?.coefficient?.levelCoefficient, 4) }}</el-descriptions-item>
-        </el-descriptions>
-      </el-card>
-
-      <!-- 5. 总系数卡片 -->
-      <el-card shadow="never" class="info-card">
-        <template #header>
-          <div class="card-header">
-            <span>总系数(K)</span>
-          </div>
-        </template>
-        <el-descriptions :column="1" border>
-          <el-descriptions-item label="总系数">{{ formatNumber(assessmentDetail?.coefficient?.totalCoefficient, 6) }}</el-descriptions-item>
-        </el-descriptions>
-      </el-card>
-
-      <!-- 6. 班主任常规工作(50分)卡片 -->
+      <!-- 2. 总系数(K)与层次系数(K1)并排 -->
+      <el-row :gutter="20" class="info-card">
+        <el-col :span="12">
+          <el-card shadow="never">
+            <template #header>
+              <div class="card-header">
+                <span>总系数(K)</span>
+              </div>
+            </template>
+            <el-descriptions :column="1" border>
+              <el-descriptions-item label="总系数">{{ formatNumber(assessmentDetail?.coefficient?.totalCoefficient, 3) }}</el-descriptions-item>
+            </el-descriptions>
+          </el-card>
+        </el-col>
+        <el-col :span="12">
+          <el-card shadow="never">
+            <template #header>
+              <div class="card-header">
+                <span>层次系数(K1)</span>
+              </div>
+            </template>
+            <el-descriptions :column="2" border>
+              <el-descriptions-item label="班级学历层级">{{ getClassTypeText(assessmentDetail?.classDetail?.classType) }}</el-descriptions-item>
+              <el-descriptions-item label="层次系数">{{ formatNumber(assessmentDetail?.coefficient?.levelCoefficient, 3) }}</el-descriptions-item>
+            </el-descriptions>
+          </el-card>
+        </el-col>
+      </el-row>
+
+      <!-- 3. 人数系数(K2)与住校生系数(K3)并排 -->
+      <el-row :gutter="20" class="info-card">
+        <el-col :span="12">
+          <el-card shadow="never">
+            <template #header>
+              <div class="card-header">
+                <span>人数系数(K2)</span>
+              </div>
+            </template>
+            <el-descriptions :column="2" border>
+              <el-descriptions-item label="班级总人数">{{ assessmentDetail?.classDetail?.totalStudentCount || 0 }}人</el-descriptions-item>
+              <el-descriptions-item label="人数系数">{{ formatNumber(assessmentDetail?.coefficient?.studentCountCoefficient, 3) }}</el-descriptions-item>
+            </el-descriptions>
+          </el-card>
+        </el-col>
+        <el-col :span="12">
+          <el-card shadow="never">
+            <template #header>
+              <div class="card-header">
+                <span>住校生系数(K3)</span>
+              </div>
+            </template>
+            <el-descriptions :column="2" border>
+              <el-descriptions-item label="住校生人数">{{ assessmentDetail?.classDetail?.boardingStudentCount || 0 }}人</el-descriptions-item>
+              <el-descriptions-item label="住校生系数">{{ formatNumber(assessmentDetail?.coefficient?.boardingCoefficient, 3) }}</el-descriptions-item>
+            </el-descriptions>
+          </el-card>
+        </el-col>
+      </el-row>
+
+      <!-- 4. 班主任常规工作(50分)卡片 -->
       <el-card shadow="never" class="info-card">
         <template #header>
           <div class="card-header">
             <span>班主任常规工作(50分)</span>
           </div>
         </template>
-        <el-table border :data="routineWorkScores" style="width: 100%">
+        <el-table border :data="routineWorkScores" style="width: 100%" max-height="400" class="routine-work-table">
           <el-table-column type="index" label="序号" width="60" align="center" />
-          <el-table-column prop="indicatorName" label="指标名称" align="center" :show-overflow-tooltip="true" />
-          <el-table-column prop="description" label="指标描述" align="center" :show-overflow-tooltip="true" />
+          <el-table-column prop="indicatorName" label="指标名称" min-width="180" align="center" :show-overflow-tooltip="true" />
+          <el-table-column prop="description" label="指标描述" min-width="200" align="center" :show-overflow-tooltip="true" />
           <el-table-column prop="score" label="指标分值" width="100" align="center">
             <template #default="scope">
               <span>{{ scope.row.score || 0 }}</span>
             </template>
           </el-table-column>
-          <el-table-column label="自评分数" width="120" align="center">
+          <el-table-column label="自评分数" width="130" align="center">
             <template #default="scope">
               <el-input-number
                 v-model="scope.row.selfScore"
@@ -99,10 +107,11 @@
                 controls-position="right"
                 style="width: 100%"
                 placeholder="请输入分数"
+                size="small"
               />
             </template>
           </el-table-column>
-          <el-table-column label="自评意见" width="200" align="center">
+          <el-table-column label="自评意见" width="220" align="center">
             <template #default="scope">
               <el-input
                 v-model="scope.row.selfComment"
@@ -111,20 +120,21 @@
                 placeholder="请输入自评意见"
                 maxlength="200"
                 show-word-limit
+                size="small"
               />
             </template>
           </el-table-column>
         </el-table>
       </el-card>
 
-      <!-- 7. 班级管理实效(50分)卡片 -->
+      <!-- 5. 班级管理实效(50分)卡片 -->
       <el-card shadow="never" class="info-card">
         <template #header>
           <div class="card-header">
             <span>班级管理实效(50分)</span>
           </div>
         </template>
-        <el-form :model="managementEffectivenessForm" label-width="150px">
+        <el-form :model="managementEffectivenessForm" label-width="150px" class="management-effectiveness-form">
           <el-row :gutter="20">
             <el-col :span="8">
               <el-form-item label="班级扣分">
@@ -144,7 +154,7 @@
                 <el-input
                   :value="managementEffectivenessForm.classDeductionHalf?.toFixed(2) || '0.00'"
                   readonly
-                  style="width: 100%"
+                  style="width: 100%; text-align: center;"
                 />
               </el-form-item>
             </el-col>
@@ -171,17 +181,17 @@
         </el-form>
       </el-card>
 
-      <!-- 8. 特色工作(加20分)卡片 -->
+      <!-- 6. 特色工作(加20分)卡片 -->
       <el-card shadow="never" class="info-card">
         <template #header>
           <div class="card-header">
             <span>特色工作(加20分)</span>
           </div>
         </template>
-        <el-form :model="specialWorkForm" label-width="200px">
+        <el-form :model="specialWorkForm" label-width="240px" class="special-work-form">
           <el-row :gutter="20">
             <el-col :span="12">
-              <el-form-item label="及时并妥善处理好学生违纪事件">
+              <el-form-item label="及时并妥善处理好学生违纪事件" class="no-wrap-label">
                 <el-input-number
                   v-model="specialWorkForm.score1"
                   :min="0"
@@ -237,7 +247,7 @@
           </el-row>
           <el-row :gutter="20">
             <el-col :span="12">
-              <el-form-item label="班级宣传工作有特色">
+              <el-form-item label="班级宣传工作有特色" class="no-wrap-label">
                 <el-input-number
                   v-model="specialWorkForm.score3"
                   :min="0"
@@ -297,7 +307,7 @@
                 <el-input
                   :value="specialWorkForm.totalScore?.toFixed(2) || '0.00'"
                   readonly
-                  style="width: 100%"
+                  style="width: 100%; text-align: center;"
                 />
               </el-form-item>
             </el-col>
@@ -305,21 +315,21 @@
         </el-form>
       </el-card>
 
-      <!-- 9. 月考核得分卡片 -->
+      <!-- 7. 月考核得分卡片 -->
       <el-card shadow="never" class="info-card">
         <template #header>
           <div class="card-header">
             <span>月考核得分</span>
           </div>
         </template>
-        <el-form :model="monthlyScoreForm" label-width="100px">
+        <el-form :model="monthlyScoreForm" label-width="100px" class="monthly-score-form">
           <el-row :gutter="20">
             <el-col :span="12">
               <el-form-item label="月考核得分">
                 <el-input
                   :value="calculateMonthlyScore().toFixed(2)"
                   readonly
-                  style="width: 100%"
+                  style="width: 100%; text-align: center;"
                 />
               </el-form-item>
             </el-col>
@@ -345,6 +355,7 @@
     <template #footer>
       <div class="dialog-footer">
         <el-button :loading="submitLoading" type="primary" @click="handleSubmit">保存</el-button>
+        <el-button :loading="submitLoading" type="success" @click="handleSubmitForApproval">提交</el-button>
         <el-button @click="handleClose">取消</el-button>
       </div>
     </template>
@@ -354,7 +365,8 @@
 <script setup name="SubmitDialog" lang="ts">
 import { 
   getAssessmentSubmitDetail, 
-  submitAssessmentScore 
+  submitAssessmentScore,
+  submitAssessment
 } from '@/api/bzrkh/teacherAssessment';
 import {
   AssessmentDetailVO,
@@ -548,7 +560,7 @@ const handleViewStudentViolations = () => {
   proxy?.$modal.msg('学生违规处分信息查看功能暂未实现');
 };
 
-/** 提交考核 */
+/** 保存考核数据 */
 const handleSubmit = async () => {
   try {
     // 验证必填项
@@ -602,13 +614,83 @@ const handleSubmit = async () => {
     };
 
     await submitAssessmentScore(submitData);
-    proxy?.$modal.msgSuccess('考核提交成功');
+    proxy?.$modal.msgSuccess('考核保存成功');
+    emit('success');
+    
+  } catch (error) {
+    console.error('保存考核失败:', error);
+    proxy?.$modal.msgError('保存考核失败');
+  } finally {
+    submitLoading.value = false;
+  }
+};
+
+/** 提交到审批流程 */
+const handleSubmitForApproval = async () => {
+  try {
+    // 验证必填项
+    if (routineWorkScores.value.some(item => item.selfScore === undefined || item.selfScore === null)) {
+      proxy?.$modal.msgWarning('请完善班主任常规工作的自评分数');
+      return;
+    }
+    
+    // 验证必要参数
+    if (!props.planId || !props.classId) {
+      proxy?.$modal.msgError('缺少必要参数:计划ID或班级ID');
+      return;
+    }
+
+    submitLoading.value = true;
+
+    // 构造提交数据
+    const submitData: AssessmentSubmitVO = {
+      planId: props.planId,
+      classId: props.classId,
+      routineWorkScores: routineWorkScores.value,
+      classDeduction: managementEffectivenessForm.classDeduction,
+      classDeductionComment: managementEffectivenessForm.selfComment,
+      specialWorkScores: [
+        {
+          indicatorCode: 'bzrtsgz001',
+          indicatorName: '及时并妥善处理好学生违纪事件',
+          score: specialWorkForm.score1,
+          selfComment: specialWorkForm.comment1
+        },
+        {
+          indicatorCode: 'bzrtsgz002',
+          indicatorName: '班级活动获奖情况',
+          score: specialWorkForm.score2,
+          selfComment: specialWorkForm.comment2
+        },
+        {
+          indicatorCode: 'bzrtsgz003',
+          indicatorName: '班级宣传工作有特色',
+          score: specialWorkForm.score3,
+          selfComment: specialWorkForm.comment3
+        },
+        {
+          indicatorCode: 'bzrtsgz004',
+          indicatorName: '其他',
+          score: specialWorkForm.score4,
+          selfComment: specialWorkForm.comment4
+        }
+      ],
+      overallComment: monthlyScoreForm.overallComment
+    };
+
+    // 第一步:保存考核评分数据
+    await submitAssessmentScore(submitData);
+    
+    // 第二步:提交到审批流程
+    await submitAssessment(props.planId, props.classId);
+    
+    proxy?.$modal.msgSuccess('考核提交成功,已进入审批流程');
     emit('success');
     handleClose();
     
   } catch (error) {
-    console.error('提交考核失败:', error);
-    proxy?.$modal.msgError('提交考核失败');
+    console.error('提交审批失败:', error);
+    proxy?.$modal.msgError('提交审批失败');
   } finally {
     submitLoading.value = false;
   }
@@ -617,6 +699,7 @@ const handleSubmit = async () => {
 /** 关闭弹窗 */
 const handleClose = () => {
   visible.value = false;
+  
   // 重置表单数据
   routineWorkScores.value = [];
   Object.assign(managementEffectivenessForm, {
@@ -663,6 +746,7 @@ defineExpose({
 .card-header {
   font-weight: 600;
   color: #303133;
+  text-align: center;
 }
 
 /* 表格样式 */
@@ -676,11 +760,88 @@ defineExpose({
   font-weight: 600;
 }
 
+/* 班主任常规工作表格样式优化 */
+:deep(.routine-work-table) {
+  .el-table__body-wrapper {
+    max-height: 350px;
+    overflow-y: auto;
+  }
+  
+  .el-table__row {
+    height: auto;
+  }
+  
+  .el-table__cell {
+    padding: 8px 0;
+    vertical-align: middle;
+  }
+  
+  /* 优化输入框在表格中的显示 */
+  .el-input-number {
+    width: 100% !important;
+  }
+  
+  .el-textarea__inner {
+    resize: none;
+    min-height: 60px !important;
+  }
+  
+  /* 响应式调整 */
+  @media (max-width: 1400px) {
+    .el-table__cell {
+      padding: 6px 4px;
+    }
+  }
+}
+
+/* 特色工作表单样式优化 */
+:deep(.special-work-form) {
+  .no-wrap-label .el-form-item__label {
+    white-space: nowrap;
+    overflow: hidden;
+    text-overflow: ellipsis;
+    line-height: 1.4;
+  }
+  
+  .el-form-item__label {
+    font-weight: 500;
+    text-align: center;
+  }
+}
+
+/* 月考核得分表单样式优化 */
+:deep(.monthly-score-form) {
+  .el-form-item__label {
+    text-align: center;
+    font-weight: 500;
+  }
+}
+
+/* 班级管理实效表单样式优化 */
+:deep(.management-effectiveness-form) {
+  .el-form-item__label {
+    text-align: center;
+    font-weight: 500;
+  }
+}
+
 /* 表单样式 */
 :deep(.el-form-item__label) {
   font-weight: 500;
 }
 
+/* 描述列表居中样式 */
+:deep(.el-descriptions) {
+  .el-descriptions__label {
+    text-align: center;
+    font-weight: 500;
+  }
+  
+  .el-descriptions__content {
+    text-align: center;
+  }
+}
+
 /* 只读输入框样式 */
 :deep(.el-input.is-disabled .el-input__wrapper) {
   background-color: #f5f7fa;