+
已选择的奖励类型:
-
{{ type.typeCode }} - {{ type.typeName }}
+
{{ selectedRewardType.typeCode }} - {{ selectedRewardType.typeName }}
@@ -158,11 +153,11 @@ const initFormData: XskhAssessmentIndicatorForm = {
indicatorName: undefined,
description: undefined,
indicatorTypeId: undefined,
- maxScore: undefined,
+ maxScore: 100, // 默认值设为100
status: '0',
sortOrder: 0,
- disciplineTypeIds: [],
- rewardTypeIds: []
+ disciplineTypeId: undefined, // 改为单个值
+ rewardTypeId: undefined // 改为单个值
};
const data = reactive({
@@ -181,22 +176,38 @@ const rules = reactive({
{ min: 1, max: 100, message: '指标名称长度必须介于 1 和 100 之间', trigger: 'blur' }
],
indicatorTypeId: [{ required: true, message: '指标类型不能为空', trigger: 'change' }],
- maxScore: [{ required: true, message: '最高分值不能为空', trigger: 'blur' }],
+ // maxScore: [{ required: true, message: '最高分值不能为空', trigger: 'blur' }],
status: [{ required: true, message: '状态不能为空', trigger: 'change' }],
sortOrder: [{ required: true, message: '排序号不能为空', trigger: 'blur' }],
description: [{ max: 500, message: '指标说明长度不能超过 500 个字符', trigger: 'blur' }]
} as any);
-// 计算属性:已选择的违纪处分类型
-const selectedDisciplineTypes = computed(() => {
- return disciplineTypeOptions.value.filter((type) => form.value.disciplineTypeIds?.includes(type.id.toString()));
+// 计算属性:已选择的违纪处分类型(改为单个)
+const selectedDisciplineType = computed(() => {
+ return disciplineTypeOptions.value.find((type) => type.id.toString() === form.value.disciplineTypeId?.toString());
});
-// 计算属性:已选择的奖励类型
-const selectedRewardTypes = computed(() => {
- return rewardTypeOptions.value.filter((type) => form.value.rewardTypeIds?.includes(type.id.toString()));
+// 计算属性:已选择的奖励类型(改为单个)
+const selectedRewardType = computed(() => {
+ return rewardTypeOptions.value.find((type) => type.id.toString() === form.value.rewardTypeId?.toString());
});
+// 违纪处分类型选择变化时的处理(实现互斥逻辑)
+const onDisciplineTypeChange = (value: any) => {
+ if (value) {
+ // 如果选择了违纪处分类型,清空奖励类型
+ form.value.rewardTypeId = undefined;
+ }
+};
+
+// 奖励类型选择变化时的处理(实现互斥逻辑)
+const onRewardTypeChange = (value: any) => {
+ if (value) {
+ // 如果选择了奖励类型,清空违纪处分类型
+ form.value.disciplineTypeId = undefined;
+ }
+};
+
/** 获取指标类型选项 */
const getIndicatorTypeOptions = async () => {
try {
@@ -270,7 +281,41 @@ const openDialog = async (id?: string | number, title?: string) => {
if (id) {
try {
const res = await getAssessmentIndicator(id);
- Object.assign(form.value, res.data);
+ console.log('API响应数据:', res);
+ console.log('res.data:', res.data);
+
+ // 处理后端返回的数据,将数组格式转换为单个值格式
+ const responseData = res.data;
+ console.log('处理后的数据:', responseData);
+
+ // 创建表单数据对象,只包含表单需要的字段
+ const formData: any = {
+ id: responseData.id,
+ indicatorCode: responseData.indicatorCode,
+ indicatorName: responseData.indicatorName,
+ description: responseData.description,
+ indicatorTypeId: responseData.indicatorTypeId,
+ maxScore: responseData.maxScore,
+ status: responseData.status,
+ sortOrder: responseData.sortOrder
+ };
+
+ // 转换违纪处分类型ID(取第一个,因为前端现在只支持单选)
+ if (responseData.disciplineTypeIds && responseData.disciplineTypeIds.length > 0) {
+ formData.disciplineTypeId = responseData.disciplineTypeIds[0];
+ }
+
+ // 转换奖励类型ID(取第一个,因为前端现在只支持单选)
+ if (responseData.rewardTypeIds && responseData.rewardTypeIds.length > 0) {
+ formData.rewardTypeId = responseData.rewardTypeIds[0];
+ }
+
+ console.log('表单数据:', formData);
+ console.log('赋值前的form.value:', form.value);
+
+ Object.assign(form.value, formData);
+
+ console.log('赋值后的form.value:', form.value);
} catch (error) {
console.error('获取数据失败:', error);
}
@@ -282,11 +327,27 @@ const submitForm = async () => {
assessmentIndicatorFormRef.value?.validate(async (valid) => {
if (valid) {
try {
+ // 按照XskhAssessmentIndicatorForm接口定义,只提取需要的字段
+ const submitData: any = {
+ indicatorCode: form.value.indicatorCode,
+ indicatorName: form.value.indicatorName,
+ description: form.value.description,
+ indicatorTypeId: form.value.indicatorTypeId,
+ maxScore: Number(form.value.maxScore) || 100,
+ status: form.value.status,
+ sortOrder: form.value.sortOrder,
+ // 将单个ID转换为数组格式以兼容后端
+ disciplineTypeIds: form.value.disciplineTypeId ? [form.value.disciplineTypeId] : [],
+ rewardTypeIds: form.value.rewardTypeId ? [form.value.rewardTypeId] : []
+ };
+
+ // 如果是编辑,添加ID字段
if (form.value.id) {
- await updateAssessmentIndicator(form.value);
+ submitData.id = form.value.id;
+ await updateAssessmentIndicator(submitData);
proxy?.$modal.msgSuccess('修改成功');
} else {
- await addAssessmentIndicator(form.value);
+ await addAssessmentIndicator(submitData);
proxy?.$modal.msgSuccess('新增成功');
}
dialog.visible = false;
@@ -331,34 +392,4 @@ defineExpose({
color: #409eff;
font-size: 14px;
}
-
-/* 固定多选框高度,防止动态变化 */
-.fixed-height-select :deep(.el-select__tags) {
- max-height: 32px;
- overflow: hidden;
-}
-
-.fixed-height-select :deep(.el-select__tags-text) {
- max-width: 120px;
- overflow: hidden;
- text-overflow: ellipsis;
- white-space: nowrap;
-}
-
-.fixed-height-select :deep(.el-select__collapse-tags) {
- max-width: 100%;
-}
-
-/* 确保多选框输入框高度固定 */
-.fixed-height-select :deep(.el-input__wrapper) {
- min-height: 32px;
- max-height: 32px;
- overflow: hidden;
-}
-
-/* 多选框下拉选项的最大高度 */
-.fixed-height-select :deep(.el-select-dropdown__list) {
- max-height: 200px;
- overflow-y: auto;
-}
diff --git a/web/src/views/xskh/assessmentIndicator/index.vue b/web/src/views/xskh/assessmentIndicator/index.vue
index 080cad46..e060429e 100644
--- a/web/src/views/xskh/assessmentIndicator/index.vue
+++ b/web/src/views/xskh/assessmentIndicator/index.vue
@@ -62,7 +62,7 @@
-
+
{{ scope.row.maxScore ? parseFloat(scope.row.maxScore).toFixed(2) : '0.00' }}
diff --git a/web/src/views/xskh/assessmentPlan/AssessmentPlanForm.vue b/web/src/views/xskh/assessmentPlan/AssessmentPlanForm.vue
index a4ed1fe5..1cb77c0d 100644
--- a/web/src/views/xskh/assessmentPlan/AssessmentPlanForm.vue
+++ b/web/src/views/xskh/assessmentPlan/AssessmentPlanForm.vue
@@ -69,12 +69,12 @@
-
+
-
+
{
dialog.visible = true;
dialog.title = title || '新增';
- // 重置表单
- Object.assign(form.value, initFormData);
+ // 重置表单数据
+ form.value = { ...initFormData };
indicatorList.value = [];
// 获取选项数据
@@ -304,8 +304,13 @@ const submitForm = async () => {
}
try {
+ // 准备提交数据,排除自动填充字段
const submitData = {
- ...form.value,
+ id: form.value.id,
+ planCode: form.value.planCode,
+ planName: form.value.planName,
+ description: form.value.description,
+ status: form.value.status,
indicatorList: indicatorList.value
};
diff --git a/web/src/views/xskh/assessmentSchedule/index.vue b/web/src/views/xskh/assessmentSchedule/index.vue
index 2dc01874..248615f1 100644
--- a/web/src/views/xskh/assessmentSchedule/index.vue
+++ b/web/src/views/xskh/assessmentSchedule/index.vue
@@ -182,6 +182,8 @@ const data = reactive
Date: Tue, 9 Sep 2025 15:42:51 +0800
Subject: [PATCH 2/3] =?UTF-8?q?=E6=8F=90=E4=BA=A4=E4=BB=A3=E7=A0=81?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../XskhDisciplineRecordController.java | 15 +-
.../XskhRewardRecordController.java | 12 +
.../mapper/XskhDisciplineRecordMapper.java | 12 +
.../xskh/mapper/XskhRewardRecordMapper.java | 12 +
.../service/IXskhDisciplineRecordService.java | 10 +
.../service/IXskhRewardRecordService.java | 10 +
.../impl/XskhDisciplineRecordServiceImpl.java | 19 +
.../impl/XskhRewardRecordServiceImpl.java | 21 +
.../mapper/XskhDisciplineRecordMapper.xml | 17 +
.../mapper/xskh/XskhRewardRecordMapper.xml | 17 +
docs/开发文档/API/API文档总览.md | 1 +
.../AssessmentApplicationForm.vue | 478 +++++++++++++-----
12 files changed, 507 insertions(+), 117 deletions(-)
diff --git a/backend/ruoyi-modules/ruoyi-xskh/src/main/java/org/dromara/xskh/controller/XskhDisciplineRecordController.java b/backend/ruoyi-modules/ruoyi-xskh/src/main/java/org/dromara/xskh/controller/XskhDisciplineRecordController.java
index 58daab72..be7e95fc 100644
--- a/backend/ruoyi-modules/ruoyi-xskh/src/main/java/org/dromara/xskh/controller/XskhDisciplineRecordController.java
+++ b/backend/ruoyi-modules/ruoyi-xskh/src/main/java/org/dromara/xskh/controller/XskhDisciplineRecordController.java
@@ -151,6 +151,19 @@ public class XskhDisciplineRecordController extends BaseController {
@RequestParam String disciplineTypeIds,
@RequestParam String startTime,
@RequestParam String endTime) {
- return R.ok(xskhDisciplineRecordService.getStudentDisciplineRecords(studentId, disciplineTypeIds, startTime, endTime));
+ return R.ok(xskhDisciplineRecordService.getStudentDisciplineRecords(studentId, disciplineTypeIds, startTime,
+ endTime));
+ }
+
+ /**
+ * 获取指定违纪类型在指定时间范围内所有学生的最高总扣分
+ */
+ @SaCheckPermission("disciplineRecord:disciplineRecord:query")
+ @GetMapping("/getMaxScoreByTypeAndPeriod/{typeId}")
+ public R getMaxScoreByTypeAndPeriod(
+ @NotNull(message = "违纪类型ID不能为空") @PathVariable Long typeId,
+ @RequestParam String startTime,
+ @RequestParam String endTime) {
+ return R.ok(xskhDisciplineRecordService.getMaxScoreByTypeAndPeriod(typeId, startTime, endTime));
}
}
diff --git a/backend/ruoyi-modules/ruoyi-xskh/src/main/java/org/dromara/xskh/controller/XskhRewardRecordController.java b/backend/ruoyi-modules/ruoyi-xskh/src/main/java/org/dromara/xskh/controller/XskhRewardRecordController.java
index c6375b5c..a8e2a19b 100644
--- a/backend/ruoyi-modules/ruoyi-xskh/src/main/java/org/dromara/xskh/controller/XskhRewardRecordController.java
+++ b/backend/ruoyi-modules/ruoyi-xskh/src/main/java/org/dromara/xskh/controller/XskhRewardRecordController.java
@@ -143,4 +143,16 @@ public class XskhRewardRecordController extends BaseController {
@RequestParam String endTime) {
return R.ok(xskhRewardRecordService.getStudentRewardRecords(studentId, rewardTypeIds, startTime, endTime));
}
+
+ /**
+ * 获取指定奖励类型在指定时间范围内所有学生的最高总加分
+ */
+ @SaCheckPermission("rewardRecord:rewardRecord:query")
+ @GetMapping("/getMaxScoreByTypeAndPeriod/{typeId}")
+ public R getMaxScoreByTypeAndPeriod(
+ @NotNull(message = "奖励类型ID不能为空") @PathVariable Long typeId,
+ @RequestParam String startTime,
+ @RequestParam String endTime) {
+ return R.ok(xskhRewardRecordService.getMaxScoreByTypeAndPeriod(typeId, startTime, endTime));
+ }
}
diff --git a/backend/ruoyi-modules/ruoyi-xskh/src/main/java/org/dromara/xskh/mapper/XskhDisciplineRecordMapper.java b/backend/ruoyi-modules/ruoyi-xskh/src/main/java/org/dromara/xskh/mapper/XskhDisciplineRecordMapper.java
index 3557020d..75db4990 100644
--- a/backend/ruoyi-modules/ruoyi-xskh/src/main/java/org/dromara/xskh/mapper/XskhDisciplineRecordMapper.java
+++ b/backend/ruoyi-modules/ruoyi-xskh/src/main/java/org/dromara/xskh/mapper/XskhDisciplineRecordMapper.java
@@ -69,4 +69,16 @@ public interface XskhDisciplineRecordMapper extends BaseMapperPlus rewardTypeIds,
@Param("startTime") String startTime,
@Param("endTime") String endTime);
+
+ /**
+ * 获取指定奖励类型在指定时间范围内所有学生的最高总加分
+ *
+ * @param typeId 奖励类型ID
+ * @param startTime 开始时间
+ * @param endTime 结束时间
+ * @return 最高总加分
+ */
+ java.math.BigDecimal selectMaxScoreByTypeAndPeriod(@Param("typeId") Long typeId,
+ @Param("startTime") String startTime,
+ @Param("endTime") String endTime);
}
diff --git a/backend/ruoyi-modules/ruoyi-xskh/src/main/java/org/dromara/xskh/service/IXskhDisciplineRecordService.java b/backend/ruoyi-modules/ruoyi-xskh/src/main/java/org/dromara/xskh/service/IXskhDisciplineRecordService.java
index f6a5ad67..4f061dce 100644
--- a/backend/ruoyi-modules/ruoyi-xskh/src/main/java/org/dromara/xskh/service/IXskhDisciplineRecordService.java
+++ b/backend/ruoyi-modules/ruoyi-xskh/src/main/java/org/dromara/xskh/service/IXskhDisciplineRecordService.java
@@ -91,4 +91,14 @@ public interface IXskhDisciplineRecordService {
*/
List getStudentDisciplineRecords(Long studentId, String disciplineTypeIds, String startTime,
String endTime);
+
+ /**
+ * 获取指定违纪类型在指定时间范围内所有学生的最高总扣分
+ *
+ * @param typeId 违纪类型ID
+ * @param startTime 开始时间
+ * @param endTime 结束时间
+ * @return 最高总扣分
+ */
+ java.math.BigDecimal getMaxScoreByTypeAndPeriod(Long typeId, String startTime, String endTime);
}
diff --git a/backend/ruoyi-modules/ruoyi-xskh/src/main/java/org/dromara/xskh/service/IXskhRewardRecordService.java b/backend/ruoyi-modules/ruoyi-xskh/src/main/java/org/dromara/xskh/service/IXskhRewardRecordService.java
index 4112809f..dd68d0c3 100644
--- a/backend/ruoyi-modules/ruoyi-xskh/src/main/java/org/dromara/xskh/service/IXskhRewardRecordService.java
+++ b/backend/ruoyi-modules/ruoyi-xskh/src/main/java/org/dromara/xskh/service/IXskhRewardRecordService.java
@@ -104,4 +104,14 @@ public interface IXskhRewardRecordService {
*/
List getStudentRewardRecords(Long studentId, String rewardTypeIds, String startTime,
String endTime);
+
+ /**
+ * 获取指定奖励类型在指定时间范围内所有学生的最高总加分
+ *
+ * @param typeId 奖励类型ID
+ * @param startTime 开始时间
+ * @param endTime 结束时间
+ * @return 最高总加分
+ */
+ java.math.BigDecimal getMaxScoreByTypeAndPeriod(Long typeId, String startTime, String endTime);
}
diff --git a/backend/ruoyi-modules/ruoyi-xskh/src/main/java/org/dromara/xskh/service/impl/XskhDisciplineRecordServiceImpl.java b/backend/ruoyi-modules/ruoyi-xskh/src/main/java/org/dromara/xskh/service/impl/XskhDisciplineRecordServiceImpl.java
index 9f12aaf5..97a73cbf 100644
--- a/backend/ruoyi-modules/ruoyi-xskh/src/main/java/org/dromara/xskh/service/impl/XskhDisciplineRecordServiceImpl.java
+++ b/backend/ruoyi-modules/ruoyi-xskh/src/main/java/org/dromara/xskh/service/impl/XskhDisciplineRecordServiceImpl.java
@@ -267,4 +267,23 @@ public class XskhDisciplineRecordServiceImpl implements IXskhDisciplineRecordSer
return baseMapper.selectStudentDisciplineRecords(studentId, typeIds, startTime, endTime);
}
+
+ /**
+ * 获取指定违纪类型在指定时间范围内所有学生的最高总扣分
+ */
+ @Override
+ public java.math.BigDecimal getMaxScoreByTypeAndPeriod(Long typeId, String startTime, String endTime) {
+ log.info("获取违纪类型 {} 在时间范围 {} - {} 内的最高总扣分", typeId, startTime, endTime);
+
+ java.math.BigDecimal maxScore = baseMapper.selectMaxScoreByTypeAndPeriod(typeId, startTime, endTime);
+
+ // 如果查询结果为null,返回0
+ if (maxScore == null) {
+ log.info("违纪类型 {} 在指定时间范围内无数据,返回0", typeId);
+ return java.math.BigDecimal.ZERO;
+ }
+
+ log.info("违纪类型 {} 的最高总扣分为: {}", typeId, maxScore);
+ return maxScore;
+ }
}
diff --git a/backend/ruoyi-modules/ruoyi-xskh/src/main/java/org/dromara/xskh/service/impl/XskhRewardRecordServiceImpl.java b/backend/ruoyi-modules/ruoyi-xskh/src/main/java/org/dromara/xskh/service/impl/XskhRewardRecordServiceImpl.java
index ecbd0688..e637eb82 100644
--- a/backend/ruoyi-modules/ruoyi-xskh/src/main/java/org/dromara/xskh/service/impl/XskhRewardRecordServiceImpl.java
+++ b/backend/ruoyi-modules/ruoyi-xskh/src/main/java/org/dromara/xskh/service/impl/XskhRewardRecordServiceImpl.java
@@ -24,6 +24,7 @@ import java.util.List;
import java.util.Arrays;
import java.util.stream.Collectors;
import java.util.Map;
+import lombok.extern.slf4j.Slf4j;
/**
* 学生奖励记录Service业务层处理
@@ -31,6 +32,7 @@ import java.util.Map;
* @author ruoyi
* @date 2025-01-03
*/
+@Slf4j
@RequiredArgsConstructor
@Service
public class XskhRewardRecordServiceImpl implements IXskhRewardRecordService {
@@ -249,4 +251,23 @@ public class XskhRewardRecordServiceImpl implements IXskhRewardRecordService {
return baseMapper.selectStudentRewardRecords(studentId, typeIds, startTime, endTime);
}
+
+ /**
+ * 获取指定奖励类型在指定时间范围内所有学生的最高总加分
+ */
+ @Override
+ public java.math.BigDecimal getMaxScoreByTypeAndPeriod(Long typeId, String startTime, String endTime) {
+ log.info("获取奖励类型 {} 在时间范围 {} - {} 内的最高总加分", typeId, startTime, endTime);
+
+ java.math.BigDecimal maxScore = baseMapper.selectMaxScoreByTypeAndPeriod(typeId, startTime, endTime);
+
+ // 如果查询结果为null,返回0
+ if (maxScore == null) {
+ log.info("奖励类型 {} 在指定时间范围内无数据,返回0", typeId);
+ return java.math.BigDecimal.ZERO;
+ }
+
+ log.info("奖励类型 {} 的最高总加分为: {}", typeId, maxScore);
+ return maxScore;
+ }
}
diff --git a/backend/ruoyi-modules/ruoyi-xskh/src/main/resources/mapper/XskhDisciplineRecordMapper.xml b/backend/ruoyi-modules/ruoyi-xskh/src/main/resources/mapper/XskhDisciplineRecordMapper.xml
index 9713a923..ac51253f 100644
--- a/backend/ruoyi-modules/ruoyi-xskh/src/main/resources/mapper/XskhDisciplineRecordMapper.xml
+++ b/backend/ruoyi-modules/ruoyi-xskh/src/main/resources/mapper/XskhDisciplineRecordMapper.xml
@@ -134,4 +134,21 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
and deleted = 0
+
+
+
diff --git a/backend/ruoyi-modules/ruoyi-xskh/src/main/resources/mapper/xskh/XskhRewardRecordMapper.xml b/backend/ruoyi-modules/ruoyi-xskh/src/main/resources/mapper/xskh/XskhRewardRecordMapper.xml
index 2b4783b5..1d78d650 100644
--- a/backend/ruoyi-modules/ruoyi-xskh/src/main/resources/mapper/xskh/XskhRewardRecordMapper.xml
+++ b/backend/ruoyi-modules/ruoyi-xskh/src/main/resources/mapper/xskh/XskhRewardRecordMapper.xml
@@ -151,4 +151,21 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
order by create_time desc
+
+
+
diff --git a/docs/开发文档/API/API文档总览.md b/docs/开发文档/API/API文档总览.md
index 5d93d987..06e458c5 100644
--- a/docs/开发文档/API/API文档总览.md
+++ b/docs/开发文档/API/API文档总览.md
@@ -20,6 +20,7 @@
- [学生管理员授权关系API](./学生管理员授权关系API.md)
- [学生销假管理API](./学生销假管理API.md)
- [假期留宿管理API](./假期留宿管理API.md) - **重要修复:单人留宿计算逻辑**(2025-01-03)
+- [均化处理最高分值API](./均化处理最高分值API.md) - **新增**:支持考核申请均化处理功能(2025-01-03)
### 1. 用户认证登录
diff --git a/web/src/views/xskh/assessmentApplication/AssessmentApplicationForm.vue b/web/src/views/xskh/assessmentApplication/AssessmentApplicationForm.vue
index b4768de0..dac5e5c1 100644
--- a/web/src/views/xskh/assessmentApplication/AssessmentApplicationForm.vue
+++ b/web/src/views/xskh/assessmentApplication/AssessmentApplicationForm.vue
@@ -65,7 +65,7 @@
@@ -92,27 +92,18 @@
自评得分
-
+
-
- {{ scope.row.selfScore || '-' }}
+
+ {{ scope.row.selfScore || '0' }}
-
handleSelfScoreInput(value, scope.row)"
- @blur="(event) => handleSelfScoreBlur(event, scope.row)"
- :class="{ 'score-input-warning': isScoreExceeded(scope.row) }"
- style="width: 100%"
- />
@@ -401,6 +392,7 @@ import {
getApplicationByStudentAndSchedule,
getIndicatorsByScheduleId
} from '@/api/xskh/assessmentApplication/assessmentApplication';
+// 注意:暂时使用request直接调用API,避免导入路径问题
// 类型定义
interface XskhAssessmentApplicationApprovalForm {
@@ -446,6 +438,9 @@ interface XskhAssessmentSelfScoreForm {
selfRemark?: string;
teacherScore?: number;
teacherRemark?: string;
+ // 新增字段:用于新算分规则
+ deductionScore?: number; // 扣分
+ additionScore?: number; // 加分
}
interface XskhAssessmentBonusApprovalForm {
@@ -600,6 +595,210 @@ const getCurrentUserStudentInfo = async () => {
}
};
+/** 计算单个指标的自评得分(新算分规则) */
+const calculateIndicatorSelfScore = async (indicatorId: string | number): Promise<{ deduction: number; addition: number }> => {
+ try {
+ // 获取指标关联的违纪处分类型和奖励类型
+ const indicatorTypesResponse = await request({
+ url: `/disciplineRecord/disciplineRecord/getIndicatorTypes/${indicatorId}`,
+ method: 'get'
+ });
+
+ if (indicatorTypesResponse.code !== 200 || !indicatorTypesResponse.data) {
+ console.warn(`获取指标 ${indicatorId} 的类型信息失败`);
+ return { deduction: 0, addition: 0 };
+ }
+
+ // 修复字段名映射:后端返回下划线格式,前端使用驼峰格式
+ const disciplineTypeIds = indicatorTypesResponse.data.discipline_type_ids || indicatorTypesResponse.data.disciplineTypeIds;
+ const rewardTypeIds = indicatorTypesResponse.data.reward_type_ids || indicatorTypesResponse.data.rewardTypeIds;
+
+ // 并行获取违纪处分记录和奖励记录
+ const [disciplineRecords, rewardRecords] = await Promise.all([getDisciplineRecords(disciplineTypeIds), getRewardRecords(rewardTypeIds)]);
+
+ // 计算违纪扣分(正数,表示扣分金额)
+ let disciplineDeduction = 0;
+ if (disciplineRecords && disciplineRecords.length > 0) {
+ disciplineDeduction = disciplineRecords.reduce((sum: number, record: any) => {
+ const deduction = parseFloat(String(record.scoreDeduction || 0)) || 0;
+ return sum + deduction;
+ }, 0);
+
+ // 检查违纪类型是否需要均化处理
+ if (disciplineTypeIds) {
+ disciplineDeduction = await applyEqualizationIfNeeded(disciplineTypeIds, disciplineDeduction, 'discipline');
+ }
+ }
+
+ // 计算奖励加分(正数,表示加分金额)
+ let rewardAddition = 0;
+ if (rewardRecords && rewardRecords.length > 0) {
+ rewardAddition = rewardRecords.reduce((sum: number, record: any) => {
+ const addition = parseFloat(String(record.scoreAddition || 0)) || 0;
+ return sum + addition;
+ }, 0);
+
+ // 检查奖励类型是否需要均化处理
+ if (rewardTypeIds) {
+ rewardAddition = await applyEqualizationIfNeeded(rewardTypeIds, rewardAddition, 'reward');
+ }
+ }
+
+ console.log(
+ `指标 ${indicatorId} 自评得分计算完成: 扣分=${disciplineDeduction}, 加分=${rewardAddition} (违纪扣分: ${disciplineRecords?.length || 0}条, 奖励加分: ${rewardRecords?.length || 0}条)`
+ );
+
+ return {
+ deduction: Math.round(disciplineDeduction * 10) / 10,
+ addition: Math.round(rewardAddition * 10) / 10
+ };
+ } catch (error) {
+ console.error(`计算指标 ${indicatorId} 自评得分失败:`, error);
+ return { deduction: 0, addition: 0 };
+ }
+};
+
+/** 获取学生违纪处分记录 */
+const getDisciplineRecords = async (disciplineTypeIds: string): Promise => {
+ if (!disciplineTypeIds || !form.value.studentId) {
+ return [];
+ }
+
+ try {
+ const response = await request({
+ url: '/disciplineRecord/disciplineRecord/getStudentDisciplineRecords',
+ method: 'get',
+ params: {
+ studentId: form.value.studentId,
+ disciplineTypeIds: disciplineTypeIds,
+ startTime: form.value.dataStartTime,
+ endTime: form.value.dataEndTime,
+ status: 1 // 只查询状态为1的记录
+ }
+ });
+
+ if (response.code === 200) {
+ return response.data || [];
+ } else {
+ console.warn('获取违纪处分记录失败:', response.msg);
+ return [];
+ }
+ } catch (error) {
+ console.error('获取违纪处分记录失败:', error);
+ return [];
+ }
+};
+
+/** 获取学生奖励记录 */
+const getRewardRecords = async (rewardTypeIds: string): Promise => {
+ if (!rewardTypeIds || !form.value.studentId) {
+ return [];
+ }
+
+ try {
+ const response = await request({
+ url: '/rewardRecord/rewardRecord/getStudentRewardRecords',
+ method: 'get',
+ params: {
+ studentId: form.value.studentId,
+ rewardTypeIds: rewardTypeIds,
+ startTime: form.value.dataStartTime,
+ endTime: form.value.dataEndTime,
+ status: 1 // 只查询状态为1的记录
+ }
+ });
+
+ if (response.code === 200) {
+ return response.data || [];
+ } else {
+ console.warn('获取奖励记录失败:', response.msg);
+ return [];
+ }
+ } catch (error) {
+ console.error('获取奖励记录失败:', error);
+ return [];
+ }
+};
+
+/** 应用均化处理(如果需要) */
+const applyEqualizationIfNeeded = async (typeIds: string, studentScore: number, scoreType: 'discipline' | 'reward'): Promise => {
+ if (!typeIds || studentScore === 0) {
+ return studentScore;
+ }
+
+ try {
+ // 将逗号分隔的类型ID字符串转换为数组
+ const typeIdArray = typeIds
+ .split(',')
+ .map((id) => id.trim())
+ .filter((id) => id);
+
+ console.log('typeIdArray:', typeIdArray);
+
+ // 遍历每个类型,检查是否需要均化
+ for (const typeId of typeIdArray) {
+ console.log('typeId:', typeId);
+
+ // 获取类型的均化设置
+ const typeDetailsResponse = await request({
+ url: scoreType === 'discipline' ? `/disciplineType/disciplineType/${typeId}` : `/rewardType/rewardType/${typeId}`,
+ method: 'get'
+ });
+
+ console.log('typeDetailsResponse:', typeDetailsResponse);
+
+ if (typeDetailsResponse.code === 200 && typeDetailsResponse.data) {
+ const typeInfo = typeDetailsResponse.data;
+
+ // 检查是否启用均化 (isEqualized: '1' 表示启用)
+ const isEqualized = typeInfo.isEqualized === '1';
+ const equalizedThreshold = parseFloat(String(typeInfo.equalizedThreshold || 0)) || 0;
+
+ if (isEqualized && equalizedThreshold > 0) {
+ console.log(`类型 ${typeId} 启用了均化处理,均化阈值: ${equalizedThreshold}`);
+
+ // 调用专门的接口获取统计周期内该类型下所有学生的最高总分值
+ const maxScoreResponse = await request({
+ url:
+ scoreType === 'discipline'
+ ? `/disciplineRecord/disciplineRecord/getMaxScoreByTypeAndPeriod/${typeId}`
+ : `/rewardRecord/rewardRecord/getMaxScoreByTypeAndPeriod/${typeId}`,
+ method: 'get',
+ params: {
+ startTime: form.value.dataStartTime,
+ endTime: form.value.dataEndTime
+ }
+ });
+
+ if (maxScoreResponse.code === 200 && maxScoreResponse.data !== null && maxScoreResponse.data !== undefined) {
+ const maxScore = parseFloat(String(maxScoreResponse.data)) || 0;
+
+ console.log(`类型 ${typeId} 统计周期内学生最高总分值: ${maxScore}, 当前学生得分: ${studentScore}, 均化阈值: ${equalizedThreshold}`);
+
+ // 如果最高分值超过了均化阈值,应用均化公式
+ if (maxScore > equalizedThreshold) {
+ const equalizedScore = (studentScore * equalizedThreshold) / maxScore;
+ console.log(`应用均化公式: ${studentScore} * ${equalizedThreshold} / ${maxScore} = ${equalizedScore}`);
+ return Math.round(equalizedScore * 10) / 10; // 保留一位小数
+ } else {
+ console.log(`最高分值 ${maxScore} 未超过均化阈值 ${equalizedThreshold},不需要均化处理`);
+ }
+ } else {
+ console.warn(`获取类型 ${typeId} 的最高分值失败:`, maxScoreResponse.msg);
+ }
+ }
+ }
+ }
+
+ // 如果没有需要均化的类型,返回原始分值
+ return studentScore;
+ } catch (error) {
+ console.error(`均化处理失败 (类型: ${scoreType}, typeIds: ${typeIds}):`, error);
+ // 均化失败时返回原始分值,不影响正常计算
+ return studentScore;
+ }
+};
+
/** 根据考核计划ID获取关联的指标数据 */
const loadIndicatorsByScheduleId = async (scheduleId: string | number) => {
try {
@@ -607,7 +806,7 @@ const loadIndicatorsByScheduleId = async (scheduleId: string | number) => {
if (response.code === 200 && response.data) {
// 将指标数据转换为自评得分列表格式
- form.value.selfScoreList = response.data.map((item: any) => ({
+ const indicatorList = response.data.map((item: any) => ({
id: undefined,
applicationId: undefined,
indicatorId: item.indicatorId,
@@ -618,12 +817,19 @@ const loadIndicatorsByScheduleId = async (scheduleId: string | number) => {
maxScore: item.maxScore, // 修改:使用maxScore字段名,匹配后端期望
planMaxScore: item.maxScore, // 保留planMaxScore用于前端显示
sortOrder: item.sortOrder,
- selfScore: 0,
+ selfScore: 0, // 初始化为0,稍后计算
selfRemark: '',
teacherScore: 0,
teacherRemark: ''
}));
+ form.value.selfScoreList = indicatorList;
+
+ // 自动计算每个指标的自评得分
+ if (form.value.studentId && form.value.dataStartTime && form.value.dataEndTime) {
+ await calculateAllIndicatorScores();
+ }
+
console.log('获取到考核计划关联的指标数据:', response.data);
} else {
ElMessage.warning(response.msg || '获取指标数据失败');
@@ -638,115 +844,133 @@ const loadIndicatorsByScheduleId = async (scheduleId: string | number) => {
}
};
-/** 计算总得分 */
-const calculateTotalScore = () => {
- // 计算自评得分
- let selfScore = 0;
- if (form.value.selfScoreList && form.value.selfScoreList.length > 0) {
- selfScore += form.value.selfScoreList.reduce((sum, item) => {
- const score = parseFloat(String(item.selfScore || 0)) || 0;
- return sum + score;
- }, 0);
+/** 计算所有指标的自评得分(新算分规则) */
+const calculateAllIndicatorScores = async () => {
+ if (!form.value.selfScoreList || form.value.selfScoreList.length === 0) {
+ return;
}
+ console.log('开始计算所有指标的自评得分(新算分规则)...');
+
+ // 并行计算所有指标的得分
+ const scorePromises = form.value.selfScoreList.map(async (indicator) => {
+ const { deduction, addition } = await calculateIndicatorSelfScore(indicator.indicatorId);
+
+ // 设置扣分和加分
+ indicator.deductionScore = deduction;
+ indicator.additionScore = addition;
+
+ // 为了兼容现有显示,selfScore设置为净得分(加分-扣分)
+ indicator.selfScore = addition - deduction;
+
+ return {
+ indicatorId: indicator.indicatorId,
+ deduction,
+ addition,
+ netScore: indicator.selfScore
+ };
+ });
+
+ try {
+ const results = await Promise.all(scorePromises);
+ console.log('所有指标自评得分计算完成(新算分规则):', results);
+
+ // 重新计算总得分
+ calculateTotalScore();
+ } catch (error) {
+ console.error('计算指标自评得分失败:', error);
+ ElMessage.error('计算指标自评得分失败,请稍后重试');
+ }
+};
+
+/** 计算总得分(新算分规则) */
+const calculateTotalScore = () => {
+ // 第1步:基础分100分 - 指标模块的扣分,最小为0
+ const baseScore = 100;
+ let totalIndicatorDeduction = 0;
+ let totalIndicatorAddition = 0;
+
+ // 计算指标模块的总扣分和总加分
+ if (form.value.selfScoreList && form.value.selfScoreList.length > 0) {
+ form.value.selfScoreList.forEach((item) => {
+ const deduction = parseFloat(String(item.deductionScore || 0)) || 0;
+ const addition = parseFloat(String(item.additionScore || 0)) || 0;
+ totalIndicatorDeduction += deduction;
+ totalIndicatorAddition += addition;
+ });
+ }
+
+ // 第1步:基础分 - 扣分,结果不能小于0
+ let step1Score = baseScore - totalIndicatorDeduction;
+ if (step1Score < 0) {
+ step1Score = 0;
+ }
+
+ // 第2步:加上指标模块的加分
+ const step2Score = step1Score + totalIndicatorAddition;
+
+ // 第3步:加上附加分模块的分值(可正可负)
+ let totalBonusScore = 0;
if (form.value.bonusApprovalList && form.value.bonusApprovalList.length > 0) {
- selfScore += form.value.bonusApprovalList.reduce((sum, item) => {
+ totalBonusScore = form.value.bonusApprovalList.reduce((sum, item) => {
const score = parseFloat(String(item.bonusScore || 0)) || 0;
return sum + score;
}, 0);
}
- form.value.selfScore = parseFloat(selfScore.toFixed(1));
+ // 最终自评得分
+ const finalSelfScore = step2Score + totalBonusScore;
+ form.value.selfScore = parseFloat(finalSelfScore.toFixed(1));
- // 计算班主任评分
- let teacherScore = 0;
+ console.log(
+ `自评得分计算详情: 基础分=${baseScore}, 指标扣分=${totalIndicatorDeduction}, 第1步结果=${step1Score}, 指标加分=${totalIndicatorAddition}, 第2步结果=${step2Score}, 附加分=${totalBonusScore}, 最终得分=${form.value.selfScore}`
+ );
+
+ // 班主任评分采用相同逻辑,但使用班主任的评分数据
+ let teacherTotalIndicatorDeduction = 0;
+ let teacherTotalIndicatorAddition = 0;
+
+ // 计算班主任对指标模块的评分
if (form.value.selfScoreList && form.value.selfScoreList.length > 0) {
- teacherScore += form.value.selfScoreList.reduce((sum, item) => {
- const score = parseFloat(String(item.teacherScore || 0)) || 0;
- return sum + score;
- }, 0);
+ form.value.selfScoreList.forEach((item) => {
+ const teacherScore = parseFloat(String(item.teacherScore || 0)) || 0;
+ // 班主任评分可能是综合评分,这里需要根据实际情况调整
+ if (teacherScore < 0) {
+ teacherTotalIndicatorDeduction += Math.abs(teacherScore);
+ } else {
+ teacherTotalIndicatorAddition += teacherScore;
+ }
+ });
}
+ // 第1步:基础分 - 班主任评定的扣分
+ let teacherStep1Score = baseScore - teacherTotalIndicatorDeduction;
+ if (teacherStep1Score < 0) {
+ teacherStep1Score = 0;
+ }
+
+ // 第2步:加上班主任评定的加分
+ const teacherStep2Score = teacherStep1Score + teacherTotalIndicatorAddition;
+
+ // 第3步:加上附加分模块的审核得分
+ let totalApprovalScore = 0;
if (form.value.bonusApprovalList && form.value.bonusApprovalList.length > 0) {
- teacherScore += form.value.bonusApprovalList.reduce((sum, item) => {
+ totalApprovalScore = form.value.bonusApprovalList.reduce((sum, item) => {
const score = parseFloat(String(item.approvalScore || 0)) || 0;
return sum + score;
}, 0);
}
- form.value.teacherScore = parseFloat(teacherScore.toFixed(1));
+ // 最终班主任评分
+ const finalTeacherScore = teacherStep2Score + totalApprovalScore;
+ form.value.teacherScore = parseFloat(finalTeacherScore.toFixed(1));
// 总得分等于班主任评分
- form.value.totalScore = parseFloat(teacherScore.toFixed(1));
-};
+ form.value.totalScore = parseFloat(finalTeacherScore.toFixed(1));
-/** 处理自评得分输入验证 */
-const handleSelfScoreInput = (value: string | number, row: XskhAssessmentSelfScoreForm) => {
- const numValue = parseFloat(String(value)) || 0;
- const maxScore = parseFloat(String(row.planMaxScore)) || 0;
-
- // 如果输入值超过最高分值,自动限制为最高分值
- if (numValue > maxScore) {
- row.selfScore = maxScore;
- ElMessage.warning(`自评得分不能超过最高分值 ${maxScore}`);
- } else {
- row.selfScore = numValue;
- }
-
- // 重新计算总得分
- calculateTotalScore();
-};
-
-/** 处理自评得分失焦验证 */
-const handleSelfScoreBlur = (event: Event, row: XskhAssessmentSelfScoreForm) => {
- const target = event.target as HTMLInputElement;
- const value = parseFloat(target.value) || 0;
- const maxScore = parseFloat(String(row.planMaxScore)) || 0;
-
- // 失焦时再次验证,确保不超过最高分值
- if (value > maxScore) {
- row.selfScore = maxScore;
- target.value = maxScore.toString();
- ElMessage.warning(`自评得分已自动调整为最高分值 ${maxScore}`);
- }
-
- // 确保值为非负数
- if (value < 0) {
- row.selfScore = 0;
- target.value = '0';
- }
-};
-
-/** 验证所有自评得分是否超过最高分值 */
-const validateSelfScores = (): boolean => {
- if (!form.value.selfScoreList || form.value.selfScoreList.length === 0) {
- return true;
- }
-
- for (let i = 0; i < form.value.selfScoreList.length; i++) {
- const item = form.value.selfScoreList[i];
- const selfScore = parseFloat(String(item.selfScore || 0)) || 0;
- const maxScore = parseFloat(String(item.planMaxScore || 0)) || 0;
-
- if (selfScore > maxScore) {
- ElMessage.error(`第${i + 1}项指标"${item.indicatorName}"的自评得分(${selfScore})不能超过最高分值(${maxScore})`);
- return false;
- }
-
- if (selfScore < 0) {
- ElMessage.error(`第${i + 1}项指标"${item.indicatorName}"的自评得分不能为负数`);
- return false;
- }
- }
-
- return true;
-};
-
-/** 检查单个指标的自评得分是否超过最高分值 */
-const isScoreExceeded = (row: XskhAssessmentSelfScoreForm): boolean => {
- const selfScore = parseFloat(String(row.selfScore || 0)) || 0;
- const maxScore = parseFloat(String(row.planMaxScore || 0)) || 0;
- return selfScore > maxScore;
+ console.log(
+ `班主任评分计算详情: 基础分=${baseScore}, 指标扣分=${teacherTotalIndicatorDeduction}, 第1步结果=${teacherStep1Score}, 指标加分=${teacherTotalIndicatorAddition}, 第2步结果=${teacherStep2Score}, 附加审核分=${totalApprovalScore}, 最终得分=${form.value.teacherScore}`
+ );
};
/** 添加附加分项目 */
@@ -1096,6 +1320,11 @@ const openDialog = async (id?: string | number, title?: string, schedule?: Asses
teacherScore: item.teacherScore || 0,
teacherRemark: item.teacherRemark || ''
}));
+
+ // 重新计算自评得分(确保数据是最新的)
+ if (form.value.studentId && form.value.dataStartTime && form.value.dataEndTime) {
+ await calculateAllIndicatorScores();
+ }
}
// 确保附加分列表正确回显
@@ -1164,6 +1393,11 @@ const openDialog = async (id?: string | number, title?: string, schedule?: Asses
teacherScore: item.teacherScore || 0,
teacherRemark: item.teacherRemark || ''
}));
+
+ // 重新计算自评得分(确保数据是最新的)
+ if (form.value.studentId && form.value.dataStartTime && form.value.dataEndTime) {
+ await calculateAllIndicatorScores();
+ }
}
// 确保附加分列表正确回显
@@ -1258,11 +1492,6 @@ const safeConvertId = (id: string | number | undefined): string | undefined => {
const handleSave = async () => {
assessmentApplicationFormRef.value?.validate(async (valid) => {
if (valid) {
- // 验证自评得分是否超过最高分值
- if (!validateSelfScores()) {
- return;
- }
-
try {
// 处理附件数据,将fileList中的ossId合并为evidenceFile字段
if (form.value.bonusApprovalList && form.value.bonusApprovalList.length > 0) {
@@ -1310,11 +1539,6 @@ const handleSave = async () => {
const handleSubmit = async () => {
assessmentApplicationFormRef.value?.validate(async (valid) => {
if (valid) {
- // 验证自评得分是否超过最高分值
- if (!validateSelfScores()) {
- return;
- }
-
try {
// 处理附件数据,将fileList中的ossId合并为evidenceFile字段
if (form.value.bonusApprovalList && form.value.bonusApprovalList.length > 0) {
@@ -1764,6 +1988,28 @@ defineExpose({
justify-content: center;
}
+/* 自动计算得分样式 */
+.score-display.auto-calculated {
+ /* background: #f0f9ff; */
+ /* order: 1px solid #38bdf8; */
+ /* color: #0369a1; */
+ font-weight: 600;
+ position: relative;
+}
+
+.score-display.auto-calculated::after {
+ /* content: '自动计算'; */
+ position: absolute;
+ top: -8px;
+ right: -8px;
+ background: #38bdf8;
+ color: white;
+ font-size: 10px;
+ padding: 1px 4px;
+ border-radius: 2px;
+ font-weight: normal;
+}
+
/* 备注展示样式 */
.remark-display {
padding: 8px 12px;
From 9f4668df938bb1b6ac96c4cfe2db8fdf071993ac Mon Sep 17 00:00:00 2001
From: zlwu <704541015@qq.com>
Date: Tue, 9 Sep 2025 16:07:28 +0800
Subject: [PATCH 3/3] =?UTF-8?q?=E6=8F=90=E4=BA=A4=E5=AE=A1=E6=A0=B8?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../IndicatorDataDialog.vue | 17 ++-
.../AssessmentApprovalForm.vue | 143 +++++++++++++++---
2 files changed, 129 insertions(+), 31 deletions(-)
diff --git a/web/src/views/xskh/assessmentApplication/IndicatorDataDialog.vue b/web/src/views/xskh/assessmentApplication/IndicatorDataDialog.vue
index ec7e90ff..772c781a 100644
--- a/web/src/views/xskh/assessmentApplication/IndicatorDataDialog.vue
+++ b/web/src/views/xskh/assessmentApplication/IndicatorDataDialog.vue
@@ -1,15 +1,15 @@
-
-
+
+
-
+
{{ formatDate(scope.row.disciplineDate) }}
@@ -24,18 +24,17 @@
-
-
-
+
+
-
+
{{ formatDate(scope.row.rewardDate) }}
@@ -49,8 +48,10 @@
-
+
+
+
diff --git a/web/src/views/xskh/assessmentApproval/AssessmentApprovalForm.vue b/web/src/views/xskh/assessmentApproval/AssessmentApprovalForm.vue
index 427102ab..abbb4e9c 100644
--- a/web/src/views/xskh/assessmentApproval/AssessmentApprovalForm.vue
+++ b/web/src/views/xskh/assessmentApproval/AssessmentApprovalForm.vue
@@ -67,10 +67,10 @@
-
+
@@ -484,46 +484,130 @@ const isViewMode = computed(() => {
return dialog.title === '查看考核申请' || form.value.status === '6';
});
-/** 计算总得分 */
-const calculateTotalScore = () => {
- // 计算自评得分
- let selfScore = 0;
- if (form.value.selfScoreList && form.value.selfScoreList.length > 0) {
- selfScore += form.value.selfScoreList.reduce((sum, item) => {
- const score = parseFloat(String(item.selfScore || 0)) || 0;
- return sum + score;
- }, 0);
+// 计算排序后的指标列表
+const sortedSelfScoreList = computed(() => {
+ if (!form.value.selfScoreList || form.value.selfScoreList.length === 0) {
+ return [];
}
+ // 创建副本进行排序,避免修改原数据
+ const list = [...form.value.selfScoreList];
+
+ return list.sort((a, b) => {
+ const scoreA = parseFloat(String(a.selfScore || 0)) || 0;
+ const scoreB = parseFloat(String(b.selfScore || 0)) || 0;
+
+ // 如果A不为0,B为0,A排前面
+ if (scoreA !== 0 && scoreB === 0) return -1;
+ // 如果A为0,B不为0,B排前面
+ if (scoreA === 0 && scoreB !== 0) return 1;
+ // 如果都不为0,按分值倒序排列(高分在前)
+ if (scoreA !== 0 && scoreB !== 0) return scoreB - scoreA;
+ // 如果都为0,保持原顺序
+ return 0;
+ });
+});
+
+/** 计算总得分(新算分规则) */
+const calculateTotalScore = () => {
+ // 第1步:基础分100分 - 指标模块的扣分,最小为0
+ const baseScore = 100;
+ let totalIndicatorDeduction = 0;
+ let totalIndicatorAddition = 0;
+
+ // 计算指标模块的总扣分和总加分
+ if (form.value.selfScoreList && form.value.selfScoreList.length > 0) {
+ form.value.selfScoreList.forEach((item) => {
+ // 兼容性处理:如果存在 deductionScore 和 additionScore 字段,使用新算分规则
+ const itemWithNewFields = item as any; // 类型断言以访问可能的新字段
+ if (itemWithNewFields.deductionScore !== undefined || itemWithNewFields.additionScore !== undefined) {
+ const deduction = parseFloat(String(itemWithNewFields.deductionScore || 0)) || 0;
+ const addition = parseFloat(String(itemWithNewFields.additionScore || 0)) || 0;
+ totalIndicatorDeduction += deduction;
+ totalIndicatorAddition += addition;
+ } else {
+ // 兼容性处理:如果没有新字段,从 selfScore 推算(假设都是加分)
+ const score = parseFloat(String(item.selfScore || 0)) || 0;
+ if (score >= 0) {
+ totalIndicatorAddition += score;
+ } else {
+ totalIndicatorDeduction += Math.abs(score);
+ }
+ }
+ });
+ }
+
+ // 第1步:基础分 - 扣分,结果不能小于0
+ let step1Score = baseScore - totalIndicatorDeduction;
+ if (step1Score < 0) {
+ step1Score = 0;
+ }
+
+ // 第2步:加上指标模块的加分
+ const step2Score = step1Score + totalIndicatorAddition;
+
+ // 第3步:加上附加分模块的分值(可正可负)
+ let totalBonusScore = 0;
if (form.value.bonusApprovalList && form.value.bonusApprovalList.length > 0) {
- selfScore += form.value.bonusApprovalList.reduce((sum, item) => {
+ totalBonusScore = form.value.bonusApprovalList.reduce((sum, item) => {
const score = parseFloat(String(item.bonusScore || 0)) || 0;
return sum + score;
}, 0);
}
- form.value.selfScore = parseFloat(selfScore.toFixed(1));
+ // 最终自评得分
+ const finalSelfScore = step2Score + totalBonusScore;
+ form.value.selfScore = parseFloat(finalSelfScore.toFixed(1));
- // 计算班主任评分
- let teacherScore = 0;
+ console.log(
+ `自评得分计算详情: 基础分=${baseScore}, 指标扣分=${totalIndicatorDeduction}, 第1步结果=${step1Score}, 指标加分=${totalIndicatorAddition}, 第2步结果=${step2Score}, 附加分=${totalBonusScore}, 最终得分=${form.value.selfScore}`
+ );
+
+ // 班主任评分采用相同逻辑,但使用班主任的评分数据
+ let teacherTotalIndicatorDeduction = 0;
+ let teacherTotalIndicatorAddition = 0;
+
+ // 计算班主任对指标模块的评分
if (form.value.selfScoreList && form.value.selfScoreList.length > 0) {
- teacherScore += form.value.selfScoreList.reduce((sum, item) => {
- const score = parseFloat(String(item.teacherScore || 0)) || 0;
- return sum + score;
- }, 0);
+ form.value.selfScoreList.forEach((item) => {
+ const teacherScore = parseFloat(String(item.teacherScore || 0)) || 0;
+ // 班主任评分:负数视为扣分,正数视为加分
+ if (teacherScore < 0) {
+ teacherTotalIndicatorDeduction += Math.abs(teacherScore);
+ } else {
+ teacherTotalIndicatorAddition += teacherScore;
+ }
+ });
}
+ // 第1步:基础分 - 班主任评定的扣分
+ let teacherStep1Score = baseScore - teacherTotalIndicatorDeduction;
+ if (teacherStep1Score < 0) {
+ teacherStep1Score = 0;
+ }
+
+ // 第2步:加上班主任评定的加分
+ const teacherStep2Score = teacherStep1Score + teacherTotalIndicatorAddition;
+
+ // 第3步:加上附加分模块的审核得分
+ let totalApprovalScore = 0;
if (form.value.bonusApprovalList && form.value.bonusApprovalList.length > 0) {
- teacherScore += form.value.bonusApprovalList.reduce((sum, item) => {
+ totalApprovalScore = form.value.bonusApprovalList.reduce((sum, item) => {
const score = parseFloat(String(item.approvalScore || 0)) || 0;
return sum + score;
}, 0);
}
- form.value.teacherScore = parseFloat(teacherScore.toFixed(1));
+ // 最终班主任评分
+ const finalTeacherScore = teacherStep2Score + totalApprovalScore;
+ form.value.teacherScore = parseFloat(finalTeacherScore.toFixed(1));
// 总得分等于班主任评分
- form.value.totalScore = parseFloat(teacherScore.toFixed(1));
+ form.value.totalScore = parseFloat(finalTeacherScore.toFixed(1));
+
+ console.log(
+ `班主任评分计算详情: 基础分=${baseScore}, 指标扣分=${teacherTotalIndicatorDeduction}, 第1步结果=${teacherStep1Score}, 指标加分=${teacherTotalIndicatorAddition}, 第2步结果=${teacherStep2Score}, 附加审核分=${totalApprovalScore}, 最终得分=${form.value.teacherScore}`
+ );
};
/** 获取状态标签类型 */
@@ -1465,11 +1549,24 @@ defineExpose({
.indicator-name-cell {
display: flex;
align-items: center;
- gap: 8px;
+ gap: 6px;
+}
+
+.indicator-name-cell span {
+ flex: 1;
+ font-size: inherit;
}
.indicator-data-btn {
flex-shrink: 0;
margin-left: 4px;
+ transform: scale(0.7);
+ opacity: 0.7;
+}
+
+.indicator-data-btn:hover {
+ transform: scale(0.8);
+ opacity: 1;
+ transition: all 0.2s ease;
}