“班主任考核更新8.22”
This commit is contained in:
1 parent
64a0c9e81a
commit
35aa48f0fb
59 files changed
+4761
-788
No files matched your search
@@ -1,11 +1,6 @@
|
||||
import request from '@/utils/request';
|
||||
import { AxiosPromise } from 'axios';
|
||||
import {
|
||||
AssessmentApprovalQuery,
|
||||
AssessmentApprovalVO,
|
||||
AssessmentApprovalDetailVO,
|
||||
AssessmentApprovalSubmitBO
|
||||
} from './types';
|
||||
import { AssessmentApprovalQuery, AssessmentApprovalVO, AssessmentApprovalDetailVO, AssessmentApprovalSubmitBO, EvaluationLevelStatsVO } from './types';
|
||||
|
||||
/**
|
||||
* 查询班主任考核审核列表
|
||||
@@ -27,7 +22,11 @@ export const listAssessmentApproval = (query?: AssessmentApprovalQuery): AxiosPr
|
||||
* @param evaluatedUserId 被评价用户ID
|
||||
* @returns {*}
|
||||
*/
|
||||
export const getAssessmentApprovalDetail = (planId: string | number, classId: string | number, evaluatedUserId: string | number): AxiosPromise<AssessmentApprovalDetailVO> => {
|
||||
export const getAssessmentApprovalDetail = (
|
||||
planId: string | number,
|
||||
classId: string | number,
|
||||
evaluatedUserId: string | number
|
||||
): AxiosPromise<AssessmentApprovalDetailVO> => {
|
||||
return request({
|
||||
url: '/bzrkh/assessmentApproval/detail',
|
||||
method: 'get',
|
||||
@@ -75,7 +74,7 @@ export const batchRejectAssessment = (ids: (string | number)[], rejectReason: st
|
||||
return request({
|
||||
url: '/bzrkh/assessmentApproval/batchReject',
|
||||
method: 'post',
|
||||
data: {
|
||||
data: {
|
||||
ids,
|
||||
rejectReason
|
||||
}
|
||||
@@ -105,4 +104,17 @@ export const exportAssessmentApproval = (query?: AssessmentApprovalQuery): Axios
|
||||
data: query,
|
||||
responseType: 'blob'
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* 获取评价等级统计数据
|
||||
* @param planId 计划ID
|
||||
* @returns {*}
|
||||
*/
|
||||
export const getEvaluationLevelStats = (planId: string | number): AxiosPromise<EvaluationLevelStatsVO> => {
|
||||
return request({
|
||||
url: '/bzrkh/assessmentApproval/evaluationStats',
|
||||
method: 'get',
|
||||
params: { planId }
|
||||
});
|
||||
};
|
||||
@@ -51,7 +51,7 @@ export interface AssessmentApprovalDetailVO {
|
||||
id?: string | number;
|
||||
planId?: string | number;
|
||||
classId?: string | number;
|
||||
|
||||
|
||||
/**
|
||||
* 班级详细信息
|
||||
*/
|
||||
@@ -64,7 +64,7 @@ export interface AssessmentApprovalDetailVO {
|
||||
totalStudentCount?: number;
|
||||
boardingStudentCount?: number;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* 系数信息
|
||||
*/
|
||||
@@ -74,42 +74,42 @@ export interface AssessmentApprovalDetailVO {
|
||||
studentCountCoefficient?: number;
|
||||
boardingCoefficient?: number;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* 班主任常规工作指标列表 - 包含自评和上级评分
|
||||
*/
|
||||
routineWorkIndicators?: AssessmentApprovalIndicatorVO[];
|
||||
|
||||
|
||||
/**
|
||||
* 班级扣分指标 - 班级管理实效
|
||||
*/
|
||||
classDeductionIndicator?: AssessmentApprovalIndicatorVO;
|
||||
|
||||
|
||||
/**
|
||||
* 特色工作指标列表
|
||||
*/
|
||||
specialWorkIndicators?: AssessmentApprovalSpecialWorkVO[];
|
||||
|
||||
|
||||
/**
|
||||
* 自我总体评价
|
||||
*/
|
||||
selfOverallComment?: string;
|
||||
|
||||
|
||||
/**
|
||||
* 上级总体评价
|
||||
*/
|
||||
superiorOverallComment?: string;
|
||||
|
||||
|
||||
/**
|
||||
* 月考核得分
|
||||
*/
|
||||
monthlyScore?: number;
|
||||
|
||||
|
||||
/**
|
||||
* 审核状态
|
||||
*/
|
||||
auditStatus?: string;
|
||||
|
||||
|
||||
/**
|
||||
* 提交时间
|
||||
*/
|
||||
@@ -125,17 +125,17 @@ export interface AssessmentApprovalIndicatorVO {
|
||||
indicatorName?: string;
|
||||
indicatorCode?: string;
|
||||
description?: string;
|
||||
score?: number; // 指标分值
|
||||
score?: number; // 指标分值
|
||||
maxScore?: number;
|
||||
|
||||
|
||||
// 自评相关
|
||||
selfScore?: number;
|
||||
selfComment?: string;
|
||||
|
||||
|
||||
// 上级评相关
|
||||
superiorScore?: number;
|
||||
superiorComment?: string;
|
||||
|
||||
|
||||
// 审核状态
|
||||
auditStatus?: string;
|
||||
}
|
||||
@@ -147,15 +147,16 @@ export interface AssessmentApprovalSpecialWorkVO {
|
||||
id?: string | number;
|
||||
indicatorCode?: string;
|
||||
indicatorName?: string;
|
||||
|
||||
|
||||
// 自评相关
|
||||
score?: number; // 自评分数
|
||||
score?: number; // 自评分数 (兼容原有字段)
|
||||
selfScore?: number; // 自评分数 (标准字段名)
|
||||
selfComment?: string;
|
||||
|
||||
|
||||
// 上级评相关
|
||||
superiorScore?: number;
|
||||
superiorComment?: string;
|
||||
|
||||
|
||||
// 审核状态
|
||||
auditStatus?: string;
|
||||
}
|
||||
@@ -167,32 +168,32 @@ 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;
|
||||
|
||||
|
||||
/**
|
||||
* 审核意见
|
||||
*/
|
||||
@@ -217,4 +218,26 @@ export interface AssessmentApprovalSpecialWorkSubmitVO {
|
||||
indicatorCode?: string;
|
||||
superiorScore?: number;
|
||||
superiorComment?: string;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 评价等级统计数据
|
||||
*/
|
||||
export interface EvaluationLevelStatsVO {
|
||||
totalTeachers: number; // 总班主任数量
|
||||
scoreRankings: ScoreRankingVO[]; // 分数排名列表
|
||||
evaluationLevelRules: { // 评价等级规则
|
||||
aLevelMaxPercentage: number; // A等最大占比(如20%)
|
||||
passScore: number; // 及格分数(如60分)
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 分数排名VO
|
||||
*/
|
||||
export interface ScoreRankingVO {
|
||||
score: number; // 考核得分
|
||||
ranking: number; // 排名(从1开始)
|
||||
percentage: number; // 百分比排名(前X%)
|
||||
evaluatedUserId?: string | number; // 被评价用户ID(可选,用于标识当前用户)
|
||||
}
|
||||
@@ -4,7 +4,7 @@ import { AssessmentIndicatorVO, AssessmentIndicatorQuery, AssessmentIndicatorFor
|
||||
/**
|
||||
* 查询班主任考核指标体系列表
|
||||
* @param query 查询条件
|
||||
* @returns
|
||||
* @returns
|
||||
*/
|
||||
export function listBmzrAssessmentIndicator(query?: AssessmentIndicatorQuery) {
|
||||
return request({
|
||||
@@ -17,7 +17,7 @@ export function listBmzrAssessmentIndicator(query?: AssessmentIndicatorQuery) {
|
||||
/**
|
||||
* 查询班主任考核指标体系详细
|
||||
* @param id 主键
|
||||
* @returns
|
||||
* @returns
|
||||
*/
|
||||
export function getBmzrAssessmentIndicator(id: string | number) {
|
||||
return request({
|
||||
@@ -29,7 +29,7 @@ export function getBmzrAssessmentIndicator(id: string | number) {
|
||||
/**
|
||||
* 新增班主任考核指标体系
|
||||
* @param data 表单数据
|
||||
* @returns
|
||||
* @returns
|
||||
*/
|
||||
export function addBmzrAssessmentIndicator(data: AssessmentIndicatorForm) {
|
||||
return request({
|
||||
@@ -42,7 +42,7 @@ export function addBmzrAssessmentIndicator(data: AssessmentIndicatorForm) {
|
||||
/**
|
||||
* 修改班主任考核指标体系
|
||||
* @param data 表单数据
|
||||
* @returns
|
||||
* @returns
|
||||
*/
|
||||
export function updateBmzrAssessmentIndicator(data: AssessmentIndicatorForm) {
|
||||
return request({
|
||||
@@ -55,7 +55,7 @@ export function updateBmzrAssessmentIndicator(data: AssessmentIndicatorForm) {
|
||||
/**
|
||||
* 删除班主任考核指标体系
|
||||
* @param ids 主键串
|
||||
* @returns
|
||||
* @returns
|
||||
*/
|
||||
export function delBmzrAssessmentIndicator(ids: string | number | Array<string | number>) {
|
||||
return request({
|
||||
@@ -66,7 +66,7 @@ export function delBmzrAssessmentIndicator(ids: string | number | Array<string |
|
||||
|
||||
/**
|
||||
* 获取指标类型选项
|
||||
* @returns
|
||||
* @returns
|
||||
*/
|
||||
export function getIndicatorTypeOptions() {
|
||||
return request({
|
||||
@@ -77,11 +77,11 @@ export function getIndicatorTypeOptions() {
|
||||
|
||||
/**
|
||||
* 获取父级指标选项
|
||||
* @returns
|
||||
* @returns
|
||||
*/
|
||||
export function getParentIndicatorOptions() {
|
||||
return request({
|
||||
url: '/bzrkh/assessmentIndicator/treeselect',
|
||||
method: 'get'
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -234,4 +234,4 @@ export interface AssessmentIndicatorTypeOption {
|
||||
* 状态(0正常 1停用)
|
||||
*/
|
||||
status?: string;
|
||||
}
|
||||
}
|
||||
@@ -72,4 +72,4 @@ export const delAssessmentIndicatorType = (id: string | number | Array<string |
|
||||
url: '/bzrkh/assessmentIndicatorType/' + id,
|
||||
method: 'delete'
|
||||
});
|
||||
};
|
||||
};
|
||||
@@ -107,4 +107,4 @@ export interface AssessmentIndicatorTypeQuery extends PageQuery {
|
||||
* 日期范围参数
|
||||
*/
|
||||
params?: any;
|
||||
}
|
||||
}
|
||||
@@ -97,4 +97,4 @@ export const changeAssessmentPlanStatus = (id: string | number, status: string)
|
||||
planStatus: status
|
||||
}
|
||||
});
|
||||
};
|
||||
};
|
||||
@@ -237,4 +237,4 @@ export interface AssessmentSchemeOption {
|
||||
* 状态
|
||||
*/
|
||||
status?: string;
|
||||
}
|
||||
}
|
||||
@@ -71,4 +71,4 @@ export const exportBmzrAssessmentScheme = (query?: BmzrAssessmentSchemeQuery): A
|
||||
method: 'post',
|
||||
data: query
|
||||
});
|
||||
};
|
||||
};
|
||||
@@ -182,4 +182,4 @@ export interface BmzrAssessmentSchemeQuery extends PageQuery {
|
||||
* 参数
|
||||
*/
|
||||
params?: any;
|
||||
}
|
||||
}
|
||||
@@ -4,7 +4,7 @@ import { BmzrAssessmentSchemeIndicatorVO, BmzrAssessmentSchemeIndicatorQuery, Bm
|
||||
/**
|
||||
* 查询班主任考核方案指标关联列表
|
||||
* @param query 查询条件
|
||||
* @returns
|
||||
* @returns
|
||||
*/
|
||||
export function listBmzrAssessmentSchemeIndicator(query?: BmzrAssessmentSchemeIndicatorQuery) {
|
||||
return request({
|
||||
@@ -17,7 +17,7 @@ export function listBmzrAssessmentSchemeIndicator(query?: BmzrAssessmentSchemeIn
|
||||
/**
|
||||
* 根据方案ID查询指标关联列表
|
||||
* @param schemeId 方案ID
|
||||
* @returns
|
||||
* @returns
|
||||
*/
|
||||
export function listBySchemeId(schemeId: string | number) {
|
||||
return request({
|
||||
@@ -29,7 +29,7 @@ export function listBySchemeId(schemeId: string | number) {
|
||||
/**
|
||||
* 查询班主任考核方案指标关联详细
|
||||
* @param id 主键
|
||||
* @returns
|
||||
* @returns
|
||||
*/
|
||||
export function getBmzrAssessmentSchemeIndicator(id: string | number) {
|
||||
return request({
|
||||
@@ -41,7 +41,7 @@ export function getBmzrAssessmentSchemeIndicator(id: string | number) {
|
||||
/**
|
||||
* 新增班主任考核方案指标关联
|
||||
* @param data 表单数据
|
||||
* @returns
|
||||
* @returns
|
||||
*/
|
||||
export function addBmzrAssessmentSchemeIndicator(data: BmzrAssessmentSchemeIndicatorForm) {
|
||||
return request({
|
||||
@@ -54,7 +54,7 @@ export function addBmzrAssessmentSchemeIndicator(data: BmzrAssessmentSchemeIndic
|
||||
/**
|
||||
* 修改班主任考核方案指标关联
|
||||
* @param data 表单数据
|
||||
* @returns
|
||||
* @returns
|
||||
*/
|
||||
export function updateBmzrAssessmentSchemeIndicator(data: BmzrAssessmentSchemeIndicatorForm) {
|
||||
return request({
|
||||
@@ -67,7 +67,7 @@ export function updateBmzrAssessmentSchemeIndicator(data: BmzrAssessmentSchemeIn
|
||||
/**
|
||||
* 删除班主任考核方案指标关联
|
||||
* @param ids 主键串
|
||||
* @returns
|
||||
* @returns
|
||||
*/
|
||||
export function delBmzrAssessmentSchemeIndicator(ids: string | number | Array<string | number>) {
|
||||
return request({
|
||||
@@ -80,7 +80,7 @@ export function delBmzrAssessmentSchemeIndicator(ids: string | number | Array<st
|
||||
* 批量保存方案指标关联
|
||||
* @param schemeId 方案ID
|
||||
* @param indicatorList 指标列表
|
||||
* @returns
|
||||
* @returns
|
||||
*/
|
||||
export function batchSaveSchemeIndicators(schemeId: string | number, indicatorList: BmzrAssessmentSchemeIndicatorForm[]) {
|
||||
return request({
|
||||
@@ -88,4 +88,4 @@ export function batchSaveSchemeIndicators(schemeId: string | number, indicatorLi
|
||||
method: 'post',
|
||||
data: indicatorList
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -147,4 +147,4 @@ export interface BmzrAssessmentSchemeIndicatorQuery extends PageQuery {
|
||||
* 参数
|
||||
*/
|
||||
params?: any;
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,9 @@
|
||||
import request from '@/utils/request';
|
||||
import { AxiosPromise } from 'axios';
|
||||
import {
|
||||
TeacherClassVO,
|
||||
TeacherAssessmentPlanVO,
|
||||
TeacherAssessmentPlanQuery,
|
||||
import {
|
||||
TeacherClassVO,
|
||||
TeacherAssessmentPlanVO,
|
||||
TeacherAssessmentPlanQuery,
|
||||
TeacherClassQuery,
|
||||
AssessmentDetailVO,
|
||||
AssessmentSubmitVO
|
||||
@@ -95,6 +95,18 @@ export const submitAssessmentScore = (data: AssessmentSubmitVO): AxiosPromise<vo
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 查询班级学生违纪记录和奖励记录
|
||||
* @param classId 班级ID
|
||||
*/
|
||||
export const getClassStudentRecords = (classId: string | number): AxiosPromise<any> => {
|
||||
return request({
|
||||
url: '/bzrkh/teacherAssessment/classStudentRecords',
|
||||
method: 'get',
|
||||
params: { classId }
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 撤销考核提交
|
||||
* @param planId 计划ID
|
||||
@@ -109,4 +121,4 @@ export const withdrawAssessment = (planId: string | number, classId: string | nu
|
||||
classId
|
||||
}
|
||||
});
|
||||
};
|
||||
};
|
||||
@@ -231,32 +231,32 @@ export interface ClassDetailVO {
|
||||
* 班级ID
|
||||
*/
|
||||
id?: string | number;
|
||||
|
||||
|
||||
/**
|
||||
* 学院名称
|
||||
*/
|
||||
collegeName?: string;
|
||||
|
||||
|
||||
/**
|
||||
* 专业名称
|
||||
*/
|
||||
majorName?: string;
|
||||
|
||||
|
||||
/**
|
||||
* 班级名称
|
||||
*/
|
||||
className?: string;
|
||||
|
||||
|
||||
/**
|
||||
* 班级层次:1-中级工 2-高级工 3-预备技师 4-技师 5-中高职一体
|
||||
*/
|
||||
classType?: string;
|
||||
|
||||
|
||||
/**
|
||||
* 班级总人数
|
||||
*/
|
||||
totalStudentCount?: number;
|
||||
|
||||
|
||||
/**
|
||||
* 住校生人数
|
||||
*/
|
||||
@@ -271,17 +271,17 @@ export interface CoefficientVO {
|
||||
* 人数系数(K2)
|
||||
*/
|
||||
studentCountCoefficient?: number;
|
||||
|
||||
|
||||
/**
|
||||
* 住校生系数(K3)
|
||||
*/
|
||||
boardingCoefficient?: number;
|
||||
|
||||
|
||||
/**
|
||||
* 层次系数(K1)
|
||||
*/
|
||||
levelCoefficient?: number;
|
||||
|
||||
|
||||
/**
|
||||
* 总系数(K = K1 * (K2 + K3))
|
||||
*/
|
||||
@@ -296,37 +296,37 @@ export interface AssessmentIndicatorVO {
|
||||
* 指标ID
|
||||
*/
|
||||
id?: string | number;
|
||||
|
||||
|
||||
/**
|
||||
* 指标名称
|
||||
*/
|
||||
indicatorName?: string;
|
||||
|
||||
|
||||
/**
|
||||
* 指标编码
|
||||
*/
|
||||
indicatorCode?: string;
|
||||
|
||||
|
||||
/**
|
||||
* 指标描述
|
||||
*/
|
||||
description?: string;
|
||||
|
||||
|
||||
/**
|
||||
* 指标分值
|
||||
*/
|
||||
score?: number;
|
||||
|
||||
|
||||
/**
|
||||
* 自评分数
|
||||
*/
|
||||
selfScore?: number;
|
||||
|
||||
|
||||
/**
|
||||
* 自评意见
|
||||
*/
|
||||
selfComment?: string;
|
||||
|
||||
|
||||
/**
|
||||
* 排序
|
||||
*/
|
||||
@@ -341,17 +341,17 @@ export interface SpecialWorkIndicatorVO {
|
||||
* 指标编码
|
||||
*/
|
||||
indicatorCode?: string;
|
||||
|
||||
|
||||
/**
|
||||
* 指标名称
|
||||
*/
|
||||
indicatorName?: string;
|
||||
|
||||
|
||||
/**
|
||||
* 分值
|
||||
*/
|
||||
score?: number;
|
||||
|
||||
|
||||
/**
|
||||
* 自评意见
|
||||
*/
|
||||
@@ -366,32 +366,32 @@ export interface AssessmentSubmitVO {
|
||||
* 考核计划ID
|
||||
*/
|
||||
planId?: string | number;
|
||||
|
||||
|
||||
/**
|
||||
* 班级ID
|
||||
*/
|
||||
classId?: string | number;
|
||||
|
||||
|
||||
/**
|
||||
* 班主任常规工作指标评分
|
||||
*/
|
||||
routineWorkScores?: AssessmentIndicatorVO[];
|
||||
|
||||
|
||||
/**
|
||||
* 班级扣分
|
||||
*/
|
||||
classDeduction?: number;
|
||||
|
||||
|
||||
/**
|
||||
* 班级扣分意见
|
||||
*/
|
||||
classDeductionComment?: string;
|
||||
|
||||
|
||||
/**
|
||||
* 特色工作指标评分
|
||||
*/
|
||||
specialWorkScores?: SpecialWorkIndicatorVO[];
|
||||
|
||||
|
||||
/**
|
||||
* 总体评价
|
||||
*/
|
||||
@@ -406,34 +406,179 @@ export interface AssessmentDetailVO {
|
||||
* 班级详细信息
|
||||
*/
|
||||
classDetail?: ClassDetailVO;
|
||||
|
||||
|
||||
/**
|
||||
* 系数信息
|
||||
*/
|
||||
coefficient?: CoefficientVO;
|
||||
|
||||
|
||||
/**
|
||||
* 班主任常规工作指标列表
|
||||
*/
|
||||
routineWorkIndicators?: AssessmentIndicatorVO[];
|
||||
|
||||
|
||||
/**
|
||||
* 班级扣分指标
|
||||
*/
|
||||
classDeductionIndicator?: AssessmentIndicatorVO;
|
||||
|
||||
|
||||
/**
|
||||
* 特色工作指标列表
|
||||
*/
|
||||
specialWorkIndicators?: SpecialWorkIndicatorVO[];
|
||||
|
||||
|
||||
/**
|
||||
* 月考核得分
|
||||
*/
|
||||
monthlyScore?: number;
|
||||
|
||||
|
||||
/**
|
||||
* 总体评价
|
||||
*/
|
||||
overallComment?: string;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 班级学生违纪奖励记录
|
||||
*/
|
||||
export interface ClassStudentRecordsVO {
|
||||
/**
|
||||
* 班级名称
|
||||
*/
|
||||
className?: string;
|
||||
|
||||
/**
|
||||
* 违纪记录数量
|
||||
*/
|
||||
disciplineCount?: number;
|
||||
|
||||
/**
|
||||
* 奖励记录数量
|
||||
*/
|
||||
rewardCount?: number;
|
||||
|
||||
/**
|
||||
* 违纪记录列表
|
||||
*/
|
||||
disciplineRecords?: StudentDisciplineRecordVO[];
|
||||
|
||||
/**
|
||||
* 奖励记录列表
|
||||
*/
|
||||
rewardRecords?: StudentRewardRecordVO[];
|
||||
}
|
||||
|
||||
/**
|
||||
* 学生违纪记录
|
||||
*/
|
||||
export interface StudentDisciplineRecordVO {
|
||||
/**
|
||||
* 记录ID
|
||||
*/
|
||||
id?: string | number;
|
||||
|
||||
/**
|
||||
* 学生ID
|
||||
*/
|
||||
studentId?: string | number;
|
||||
|
||||
/**
|
||||
* 学号
|
||||
*/
|
||||
studentNo?: string;
|
||||
|
||||
/**
|
||||
* 学生姓名
|
||||
*/
|
||||
studentName?: string;
|
||||
|
||||
/**
|
||||
* 违纪类型ID
|
||||
*/
|
||||
disciplineTypeId?: string | number;
|
||||
|
||||
/**
|
||||
* 违纪类型名称
|
||||
*/
|
||||
disciplineTypeName?: string;
|
||||
|
||||
/**
|
||||
* 违纪日期
|
||||
*/
|
||||
disciplineDate?: string;
|
||||
|
||||
/**
|
||||
* 违纪原因
|
||||
*/
|
||||
disciplineReason?: string;
|
||||
|
||||
/**
|
||||
* 处分内容
|
||||
*/
|
||||
disciplineContent?: string;
|
||||
|
||||
/**
|
||||
* 扣分分值
|
||||
*/
|
||||
scoreDeduction?: number;
|
||||
|
||||
/**
|
||||
* 状态(1=生效 0=已撤销)
|
||||
*/
|
||||
status?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* 学生奖励记录
|
||||
*/
|
||||
export interface StudentRewardRecordVO {
|
||||
/**
|
||||
* 记录ID
|
||||
*/
|
||||
id?: string | number;
|
||||
|
||||
/**
|
||||
* 学生ID
|
||||
*/
|
||||
studentId?: string | number;
|
||||
|
||||
/**
|
||||
* 学号
|
||||
*/
|
||||
studentNo?: string;
|
||||
|
||||
/**
|
||||
* 学生姓名
|
||||
*/
|
||||
studentName?: string;
|
||||
|
||||
/**
|
||||
* 奖励类型ID
|
||||
*/
|
||||
rewardTypeId?: string | number;
|
||||
|
||||
/**
|
||||
* 奖励类型名称
|
||||
*/
|
||||
rewardTypeName?: string;
|
||||
|
||||
/**
|
||||
* 奖励日期
|
||||
*/
|
||||
rewardDate?: string;
|
||||
|
||||
/**
|
||||
* 奖励内容
|
||||
*/
|
||||
rewardContent?: string;
|
||||
|
||||
/**
|
||||
* 加分分值
|
||||
*/
|
||||
scoreAddition?: number;
|
||||
|
||||
/**
|
||||
* 状态(1=生效 0=撤销)
|
||||
*/
|
||||
status?: string;
|
||||
}
|
||||
@@ -1,12 +1,5 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
:title="dialogTitle"
|
||||
v-model="visible"
|
||||
width="1200px"
|
||||
:close-on-click-modal="false"
|
||||
append-to-body
|
||||
@close="handleClose"
|
||||
>
|
||||
<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">
|
||||
@@ -62,7 +55,9 @@
|
||||
</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-item label="人数系数">{{
|
||||
formatNumber(approvalDetail?.coefficient?.studentCountCoefficient, 3)
|
||||
}}</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
</el-card>
|
||||
</el-col>
|
||||
@@ -153,7 +148,7 @@
|
||||
<el-input
|
||||
:value="managementEffectivenessForm.classDeduction?.toFixed(2) || '0.00'"
|
||||
readonly
|
||||
style="width: 100%; text-align: center;"
|
||||
style="width: 100%; text-align: center"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
@@ -162,7 +157,7 @@
|
||||
<el-input
|
||||
:value="managementEffectivenessForm.classDeductionHalf?.toFixed(2) || '0.00'"
|
||||
readonly
|
||||
style="width: 100%; text-align: center;"
|
||||
style="width: 100%; text-align: center"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
@@ -183,12 +178,7 @@
|
||||
<el-row>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="自评意见">
|
||||
<el-input
|
||||
:value="managementEffectivenessForm.selfComment"
|
||||
type="textarea"
|
||||
:rows="3"
|
||||
readonly
|
||||
/>
|
||||
<el-input :value="managementEffectivenessForm.selfComment" type="textarea" :rows="3" readonly />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
@@ -219,7 +209,7 @@
|
||||
<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>
|
||||
<span>{{ scope.row.score || scope.row.selfScore || 0 }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="自评意见" width="180" align="center">
|
||||
@@ -270,22 +260,19 @@
|
||||
<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-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-input
|
||||
:value="monthlyScoreForm.selfOverallComment || '暂无自我总体评价'"
|
||||
type="textarea"
|
||||
:rows="4"
|
||||
readonly
|
||||
placeholder="暂无自我总体评价内容"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
@@ -313,16 +300,6 @@
|
||||
</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="审批意见">
|
||||
@@ -343,7 +320,8 @@
|
||||
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button :loading="submitLoading" type="primary" @click="handleSubmit">保存审批</el-button>
|
||||
<el-button :loading="submitLoading" type="success" @click="() => handleApprovalSubmit('1')"> 通过 </el-button>
|
||||
<el-button :loading="submitLoading" type="danger" @click="() => handleApprovalSubmit('2')"> 拒绝 </el-button>
|
||||
<el-button @click="handleClose">取消</el-button>
|
||||
</div>
|
||||
</template>
|
||||
@@ -351,10 +329,7 @@
|
||||
</template>
|
||||
|
||||
<script setup name="ApprovalDialog" lang="ts">
|
||||
import {
|
||||
getAssessmentApprovalDetail,
|
||||
submitAssessmentApproval
|
||||
} from '@/api/bzrkh/assessmentApproval';
|
||||
import { getAssessmentApprovalDetail, submitAssessmentApproval } from '@/api/bzrkh/assessmentApproval';
|
||||
import {
|
||||
AssessmentApprovalVO,
|
||||
AssessmentApprovalDetailVO,
|
||||
@@ -419,13 +394,13 @@ 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);
|
||||
};
|
||||
|
||||
@@ -433,18 +408,18 @@ const formatNumber = (value?: number | string, precision = 4) => {
|
||||
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 routineWorkTotal = routineWorkScores.value.reduce((sum, item) => sum + (item.superiorScore || 0), 0);
|
||||
|
||||
// 班级管理实效上级评分(使用上级评分,而非扣分逻辑)
|
||||
const managementEffectivenessScore = managementEffectivenessForm.superiorScore || 0;
|
||||
|
||||
// 特色工作上级评分之和(使用上级评分,而非自评分)
|
||||
const specialWorkTotal = specialWorkScores.value.reduce((sum, item) => sum + (item.superiorScore || 0), 0);
|
||||
|
||||
// 月考核得分 = 总系数(K)* (班主任常规工作上级评分之和 + 班级管理实效上级评分 + 特色工作上级评分之和)
|
||||
return totalCoefficient * (routineWorkTotal + managementEffectivenessScore + specialWorkTotal);
|
||||
};
|
||||
|
||||
/** 打开弹窗 */
|
||||
@@ -453,7 +428,7 @@ const open = async (row: AssessmentApprovalVO) => {
|
||||
proxy?.$modal.msgError('参数错误:缺少必要的ID信息');
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
currentRow.value = row;
|
||||
visible.value = true;
|
||||
await loadApprovalDetail();
|
||||
@@ -467,44 +442,131 @@ const loadApprovalDetail = async () => {
|
||||
|
||||
loading.value = true;
|
||||
try {
|
||||
const res = await getAssessmentApprovalDetail(
|
||||
currentRow.value.planId,
|
||||
currentRow.value.classId,
|
||||
currentRow.value.evaluatedUserId
|
||||
);
|
||||
const res = await getAssessmentApprovalDetail(currentRow.value.planId, currentRow.value.classId, currentRow.value.evaluatedUserId);
|
||||
approvalDetail.value = res.data;
|
||||
|
||||
// 初始化班主任常规工作数据
|
||||
routineWorkScores.value = (approvalDetail.value?.routineWorkIndicators || []).map(item => ({
|
||||
|
||||
// 详细的调试日志 - 用于排查数据显示问题
|
||||
console.log('=== 审批详情数据加载开始 ===');
|
||||
console.log('完整审批详情数据:', approvalDetail.value);
|
||||
console.log('班主任常规工作原始数据:', approvalDetail.value?.routineWorkIndicators);
|
||||
console.log('特色工作原始数据:', approvalDetail.value?.specialWorkIndicators);
|
||||
console.log('班级管理实效原始数据:', approvalDetail.value?.classDeductionIndicator);
|
||||
console.log('自我总体评价:', approvalDetail.value?.selfOverallComment);
|
||||
|
||||
// 初始化班主任常规工作数据 - 确保包含所有必要字段
|
||||
if (approvalDetail.value?.routineWorkIndicators && Array.isArray(approvalDetail.value.routineWorkIndicators)) {
|
||||
routineWorkScores.value = approvalDetail.value.routineWorkIndicators.map((item) => {
|
||||
const mappedItem = {
|
||||
...item,
|
||||
superiorScore: item.superiorScore || 0,
|
||||
superiorComment: item.superiorComment || ''
|
||||
}));
|
||||
|
||||
// 确保数值字段不为空
|
||||
selfScore: Number(item.selfScore) || 0,
|
||||
superiorScore: Number(item.superiorScore) || Number(item.selfScore) || 0, // 默认使用自评分数
|
||||
score: Number(item.score) || 0,
|
||||
maxScore: Number(item.maxScore) || 0,
|
||||
// 确保字符串字段不为空
|
||||
selfComment: item.selfComment || '',
|
||||
superiorComment: item.superiorComment || '',
|
||||
indicatorName: item.indicatorName || '',
|
||||
description: item.description || '',
|
||||
indicatorCode: item.indicatorCode || ''
|
||||
};
|
||||
console.log(`常规工作指标 [${item.indicatorName}]:`, {
|
||||
自评分数: mappedItem.selfScore,
|
||||
自评意见: mappedItem.selfComment,
|
||||
上级评分: mappedItem.superiorScore,
|
||||
上级意见: mappedItem.superiorComment
|
||||
});
|
||||
return mappedItem;
|
||||
});
|
||||
console.log('班主任常规工作数据初始化完成,条目数量:', routineWorkScores.value.length);
|
||||
} else {
|
||||
routineWorkScores.value = [];
|
||||
console.warn('班主任常规工作数据为空或格式错误');
|
||||
}
|
||||
|
||||
// 初始化班级管理实效数据
|
||||
if (approvalDetail.value?.classDeductionIndicator) {
|
||||
const indicator = approvalDetail.value.classDeductionIndicator;
|
||||
managementEffectivenessForm.classDeduction = indicator.selfScore || 0;
|
||||
managementEffectivenessForm.classDeductionHalf = (indicator.selfScore || 0) * 0.5;
|
||||
managementEffectivenessForm.classDeduction = Number(indicator.selfScore) || 0;
|
||||
managementEffectivenessForm.classDeductionHalf = (Number(indicator.selfScore) || 0) * 0.5;
|
||||
managementEffectivenessForm.selfComment = indicator.selfComment || '';
|
||||
managementEffectivenessForm.superiorScore = indicator.superiorScore || 0;
|
||||
// 上级评分默认使用按班级扣分50%计的分值
|
||||
const classDeductionHalf = (Number(indicator.selfScore) || 0) * 0.5;
|
||||
managementEffectivenessForm.superiorScore = Number(indicator.superiorScore) || classDeductionHalf;
|
||||
managementEffectivenessForm.superiorComment = indicator.superiorComment || '';
|
||||
console.log('班级管理实效数据初始化:', {
|
||||
班级扣分: managementEffectivenessForm.classDeduction,
|
||||
扣分50计: managementEffectivenessForm.classDeductionHalf,
|
||||
自评意见: managementEffectivenessForm.selfComment,
|
||||
上级评分: managementEffectivenessForm.superiorScore,
|
||||
上级意见: managementEffectivenessForm.superiorComment
|
||||
});
|
||||
} else {
|
||||
// 如果没有找到班级扣分指标,设置默认值
|
||||
managementEffectivenessForm.classDeduction = 0;
|
||||
managementEffectivenessForm.classDeductionHalf = 0;
|
||||
managementEffectivenessForm.selfComment = '';
|
||||
managementEffectivenessForm.superiorScore = 0; // 默认为0
|
||||
managementEffectivenessForm.superiorComment = '';
|
||||
console.warn('班级管理实效数据为空,使用默认值');
|
||||
}
|
||||
|
||||
// 初始化特色工作数据
|
||||
specialWorkScores.value = (approvalDetail.value?.specialWorkIndicators || []).map(item => ({
|
||||
|
||||
// 初始化特色工作数据 - 确保包含所有必要字段
|
||||
if (approvalDetail.value?.specialWorkIndicators && Array.isArray(approvalDetail.value.specialWorkIndicators)) {
|
||||
specialWorkScores.value = approvalDetail.value.specialWorkIndicators.map((item) => {
|
||||
const mappedItem = {
|
||||
...item,
|
||||
superiorScore: item.superiorScore || 0,
|
||||
superiorComment: item.superiorComment || ''
|
||||
}));
|
||||
|
||||
// 自评分数字段处理 - 兼容不同字段名,确保数值类型
|
||||
score: Number(item.score || item.selfScore) || 0,
|
||||
selfScore: Number(item.selfScore || item.score) || 0,
|
||||
superiorScore: Number(item.superiorScore) || Number(item.selfScore || item.score) || 0, // 默认使用自评分数
|
||||
// 确保字符串字段不为空
|
||||
selfComment: item.selfComment || '',
|
||||
superiorComment: item.superiorComment || '',
|
||||
indicatorName: item.indicatorName || '',
|
||||
indicatorCode: item.indicatorCode || ''
|
||||
};
|
||||
console.log(`特色工作指标 [${item.indicatorCode} - ${item.indicatorName}]:`, {
|
||||
自评分数: mappedItem.selfScore,
|
||||
兼容分数: mappedItem.score,
|
||||
自评意见: mappedItem.selfComment,
|
||||
上级评分: mappedItem.superiorScore,
|
||||
上级意见: mappedItem.superiorComment
|
||||
});
|
||||
return mappedItem;
|
||||
});
|
||||
console.log('特色工作数据初始化完成,条目数量:', specialWorkScores.value.length);
|
||||
} else {
|
||||
specialWorkScores.value = [];
|
||||
console.warn('特色工作数据为空或格式错误');
|
||||
}
|
||||
|
||||
// 初始化月考核得分数据
|
||||
monthlyScoreForm.selfOverallComment = approvalDetail.value?.selfOverallComment || '';
|
||||
monthlyScoreForm.superiorOverallComment = approvalDetail.value?.superiorOverallComment || '';
|
||||
|
||||
console.log('月考核得分数据初始化:', {
|
||||
自我总体评价: monthlyScoreForm.selfOverallComment,
|
||||
上级总体评价: monthlyScoreForm.superiorOverallComment,
|
||||
计算得分: calculateMonthlyScore().toFixed(2)
|
||||
});
|
||||
|
||||
// 初始化审批状态
|
||||
approvalForm.auditStatus = approvalDetail.value?.auditStatus || '1';
|
||||
approvalForm.auditComment = '';
|
||||
|
||||
console.log('=== 审批详情数据加载完成 ===');
|
||||
|
||||
// 验证数据完整性
|
||||
if (routineWorkScores.value.length === 0) {
|
||||
console.warn('⚠️ 警告:班主任常规工作数据为空,可能存在数据问题');
|
||||
proxy?.$modal.msgWarning('班主任常规工作数据为空,请检查数据是否正确');
|
||||
}
|
||||
|
||||
if (specialWorkScores.value.length === 0) {
|
||||
console.warn('⚠️ 警告:特色工作数据为空,可能存在数据问题');
|
||||
proxy?.$modal.msgWarning('特色工作数据为空,请检查数据是否正确');
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
console.error('加载审批详情失败:', error);
|
||||
proxy?.$modal.msgError('加载审批详情失败');
|
||||
@@ -514,15 +576,13 @@ const loadApprovalDetail = async () => {
|
||||
};
|
||||
|
||||
/** 提交审批 */
|
||||
const handleSubmit = async () => {
|
||||
const handleApprovalSubmit = async (auditStatus: string) => {
|
||||
try {
|
||||
// 验证必填项
|
||||
if (!approvalForm.auditStatus) {
|
||||
proxy?.$modal.msgWarning('请选择审批状态');
|
||||
return;
|
||||
}
|
||||
// 设置审批状态
|
||||
approvalForm.auditStatus = auditStatus;
|
||||
|
||||
if (approvalForm.auditStatus === '2' && !approvalForm.auditComment.trim()) {
|
||||
// 验证必填项
|
||||
if (auditStatus === '2' && !approvalForm.auditComment.trim()) {
|
||||
proxy?.$modal.msgWarning('拒绝审批时必须填写审批意见');
|
||||
return;
|
||||
}
|
||||
@@ -534,7 +594,7 @@ const handleSubmit = async () => {
|
||||
planId: currentRow.value?.planId,
|
||||
classId: currentRow.value?.classId,
|
||||
evaluatedUserId: currentRow.value?.evaluatedUserId,
|
||||
routineWorkApproval: routineWorkScores.value.map(item => ({
|
||||
routineWorkApproval: routineWorkScores.value.map((item) => ({
|
||||
id: item.id,
|
||||
indicatorId: item.indicatorId,
|
||||
superiorScore: item.superiorScore,
|
||||
@@ -546,7 +606,7 @@ const handleSubmit = async () => {
|
||||
superiorScore: managementEffectivenessForm.superiorScore,
|
||||
superiorComment: managementEffectivenessForm.superiorComment
|
||||
},
|
||||
specialWorkApproval: specialWorkScores.value.map(item => ({
|
||||
specialWorkApproval: specialWorkScores.value.map((item) => ({
|
||||
id: item.id,
|
||||
indicatorCode: item.indicatorCode,
|
||||
superiorScore: item.superiorScore,
|
||||
@@ -561,7 +621,6 @@ const handleSubmit = async () => {
|
||||
proxy?.$modal.msgSuccess('审批提交成功');
|
||||
emit('success');
|
||||
handleClose();
|
||||
|
||||
} catch (error) {
|
||||
console.error('提交审批失败:', error);
|
||||
proxy?.$modal.msgError('提交审批失败');
|
||||
@@ -573,7 +632,7 @@ const handleSubmit = async () => {
|
||||
/** 关闭弹窗 */
|
||||
const handleClose = () => {
|
||||
visible.value = false;
|
||||
|
||||
|
||||
// 重置表单数据
|
||||
routineWorkScores.value = [];
|
||||
specialWorkScores.value = [];
|
||||
@@ -596,7 +655,8 @@ const handleClose = () => {
|
||||
|
||||
// 暴露给父组件的方法
|
||||
defineExpose({
|
||||
open
|
||||
open,
|
||||
handleApprovalSubmit
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -637,21 +697,21 @@ defineExpose({
|
||||
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;
|
||||
@@ -663,16 +723,16 @@ defineExpose({
|
||||
.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;
|
||||
@@ -700,7 +760,7 @@ defineExpose({
|
||||
text-align: center;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
|
||||
.el-descriptions__content {
|
||||
text-align: center;
|
||||
}
|
||||
@@ -717,4 +777,4 @@ defineExpose({
|
||||
margin-right: 30px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
@@ -14,12 +14,7 @@
|
||||
<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-option v-for="item in schemeOptions" :key="item.value" :label="item.label" :value="item.value" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
@@ -89,22 +84,16 @@
|
||||
<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"
|
||||
<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-button link type="success" icon="View" :disabled="loading" @click="handleView(scope.row)"></el-button>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
</el-table-column>
|
||||
@@ -117,27 +106,16 @@
|
||||
</el-card>
|
||||
|
||||
<!-- 审批弹窗 -->
|
||||
<ApprovalDialog
|
||||
ref="approvalDialogRef"
|
||||
@success="handleApprovalSuccess"
|
||||
/>
|
||||
<ApprovalDialog ref="approvalDialogRef" @success="handleApprovalSuccess" />
|
||||
|
||||
<!-- 查看弹窗 -->
|
||||
<ViewDialog
|
||||
ref="viewDialogRef"
|
||||
/>
|
||||
<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 { listAssessmentApproval, getAssessmentSchemeOptions } from '@/api/bzrkh/assessmentApproval';
|
||||
import { AssessmentApprovalVO, AssessmentApprovalQuery } from '@/api/bzrkh/assessmentApproval/types';
|
||||
import ApprovalDialog from './approvalDialog.vue';
|
||||
import ViewDialog from './viewDialog.vue';
|
||||
|
||||
@@ -270,4 +248,4 @@ onMounted(() => {
|
||||
background-color: #fff;
|
||||
margin-top: 0px !important;
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
@@ -1,12 +1,5 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
:title="dialogTitle"
|
||||
v-model="visible"
|
||||
width="1200px"
|
||||
:close-on-click-modal="false"
|
||||
append-to-body
|
||||
@close="handleClose"
|
||||
>
|
||||
<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">
|
||||
@@ -88,7 +81,7 @@
|
||||
<span>班主任常规工作(50分)</span>
|
||||
</div>
|
||||
</template>
|
||||
<el-table border :data="routineWorkScores" style="width: 100%" max-height="400" class="routine-work-table">
|
||||
<el-table border :data="routineWorkScores" style="width: 100%" max-height="250" 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" />
|
||||
@@ -138,7 +131,7 @@
|
||||
<el-input
|
||||
:value="managementEffectivenessData.classDeduction?.toFixed(2) || '0.00'"
|
||||
readonly
|
||||
style="width: 100%; text-align: center;"
|
||||
style="width: 100%; text-align: center"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
@@ -147,39 +140,25 @@
|
||||
<el-input
|
||||
:value="managementEffectivenessData.classDeductionHalf?.toFixed(2) || '0.00'"
|
||||
readonly
|
||||
style="width: 100%; text-align: center;"
|
||||
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-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-input :value="managementEffectivenessData.selfComment" type="textarea" :autosize="{ minRows: 2, maxRows: 6 }" 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-input :value="managementEffectivenessData.superiorComment" type="textarea" :autosize="{ minRows: 2, maxRows: 6 }" readonly />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
@@ -193,12 +172,12 @@
|
||||
<span>特色工作(加20分)</span>
|
||||
</div>
|
||||
</template>
|
||||
<el-table border :data="specialWorkScores" style="width: 100%" class="special-work-table">
|
||||
<el-table border :data="specialWorkScores" style="width: 100%" max-height="200" 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>
|
||||
<span>{{ scope.row.selfScore || 0 }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="自评意见" width="180" align="center">
|
||||
@@ -234,33 +213,19 @@
|
||||
<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-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-input :value="monthlyScoreData.selfOverallComment" type="textarea" :autosize="{ minRows: 2, maxRows: 8 }" 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-input :value="monthlyScoreData.superiorOverallComment" type="textarea" :autosize="{ minRows: 2, maxRows: 8 }" readonly />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
@@ -274,22 +239,36 @@
|
||||
<span>审批结果</span>
|
||||
</div>
|
||||
</template>
|
||||
<el-descriptions :column="2" border>
|
||||
<el-descriptions-item label="审批状态">
|
||||
<dict-tag :options="bmzr_audit_status" :value="viewDetail?.auditStatus"/>
|
||||
<el-descriptions :column="3" border>
|
||||
<el-descriptions-item label="评价等级">
|
||||
<div style="display: flex; align-items: center; gap: 8px;">
|
||||
<dict-tag :options="getEvaluationLevelOptions()" :value="calculateEvaluationLevel()" />
|
||||
<el-tooltip placement="top">
|
||||
<template #content>
|
||||
<div>
|
||||
<div>{{ evaluationStats ? '基于占比规则的精准评级' : '基于分数阈值的简化评级' }}</div>
|
||||
<div v-if="isDictDataMissing" style="color: #f56c6c; margin-top: 4px;">
|
||||
⚠️ 字典数据缺失,使用默认数据
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<el-icon :color="evaluationStats ? '#67c23a' : '#e6a23c'" size="16">
|
||||
<InfoFilled v-if="evaluationStats" />
|
||||
<WarningFilled v-else />
|
||||
</el-icon>
|
||||
</el-tooltip>
|
||||
</div>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="月考核得分">
|
||||
{{ calculateMonthlyScore().toFixed(2) }}分
|
||||
</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 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-input :value="approvalData.auditComment" type="textarea" :autosize="{ minRows: 2, maxRows: 6 }" readonly />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
@@ -304,18 +283,47 @@
|
||||
</template>
|
||||
|
||||
<script setup name="ViewDialog" lang="ts">
|
||||
import {
|
||||
getAssessmentApprovalDetail
|
||||
} from '@/api/bzrkh/assessmentApproval';
|
||||
import { InfoFilled, WarningFilled } from '@element-plus/icons-vue';
|
||||
import { getAssessmentApprovalDetail, getEvaluationLevelStats } from '@/api/bzrkh/assessmentApproval';
|
||||
import {
|
||||
AssessmentApprovalVO,
|
||||
AssessmentApprovalDetailVO,
|
||||
AssessmentApprovalIndicatorVO,
|
||||
AssessmentApprovalSpecialWorkVO
|
||||
AssessmentApprovalSpecialWorkVO,
|
||||
EvaluationLevelStatsVO
|
||||
} from '@/api/bzrkh/assessmentApproval/types';
|
||||
|
||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||
const { bmzr_audit_status } = proxy?.useDict('bmzr_audit_status');
|
||||
const { bmzr_evaluation_level } = toRefs<any>(proxy?.useDict('bmzr_evaluation_level'));
|
||||
|
||||
// 字典数据备用方案 - 如果字典加载失败,使用默认数据
|
||||
const fallbackEvaluationLevelOptions = ref<DictDataOption[]>([
|
||||
{ label: 'A等(优秀)', value: 'A', elTagType: 'success' },
|
||||
{ label: 'B等(合格)', value: 'B', elTagType: 'primary' },
|
||||
{ label: 'C等(不合格)', value: 'C', elTagType: 'danger' }
|
||||
]);
|
||||
|
||||
// 获取有效的字典数据
|
||||
const getEvaluationLevelOptions = (): DictDataOption[] => {
|
||||
// 检查字典数据是否已加载
|
||||
if (bmzr_evaluation_level.value && bmzr_evaluation_level.value.length > 0) {
|
||||
console.log('✅ 使用数据库字典数据:', bmzr_evaluation_level.value);
|
||||
return bmzr_evaluation_level.value;
|
||||
}
|
||||
|
||||
// 字典数据未加载或为空时的处理
|
||||
if (visible.value) { // 只在弹窗打开时输出警告
|
||||
console.warn('⚠️ 字典数据为空,使用备用数据,当前状态:', {
|
||||
弹窗是否打开: visible.value,
|
||||
字典对象存在: !!bmzr_evaluation_level.value,
|
||||
字典数据长度: bmzr_evaluation_level.value?.length || 0,
|
||||
字典加载状态: isDictLoaded.value,
|
||||
字典数据内容: bmzr_evaluation_level.value
|
||||
});
|
||||
}
|
||||
|
||||
return fallbackEvaluationLevelOptions.value;
|
||||
};
|
||||
|
||||
const visible = ref(false);
|
||||
const loading = ref(false);
|
||||
@@ -324,6 +332,7 @@ const currentRow = ref<AssessmentApprovalVO>();
|
||||
const viewDetail = ref<AssessmentApprovalDetailVO>();
|
||||
const routineWorkScores = ref<AssessmentApprovalIndicatorVO[]>([]);
|
||||
const specialWorkScores = ref<AssessmentApprovalSpecialWorkVO[]>([]);
|
||||
const evaluationStats = ref<EvaluationLevelStatsVO>();
|
||||
|
||||
// 班级管理实效数据
|
||||
const managementEffectivenessData = reactive({
|
||||
@@ -350,6 +359,29 @@ const dialogTitle = computed(() => {
|
||||
return `${className} - 班主任考核查看`;
|
||||
});
|
||||
|
||||
// 检查字典数据是否缺失 - 只有在组件已挂载且字典确实为空时才认为缺失
|
||||
const isDictDataMissing = computed(() => {
|
||||
// 如果还没有尝试加载字典数据,不显示警告
|
||||
if (!visible.value) return false;
|
||||
|
||||
// 如果字典数据已经加载成功,不显示警告
|
||||
if (isDictLoaded.value) return false;
|
||||
|
||||
// 只有在弹窗打开且字典数据为空时才显示警告
|
||||
return !bmzr_evaluation_level.value || bmzr_evaluation_level.value.length === 0;
|
||||
});
|
||||
|
||||
// 字典数据加载状态
|
||||
const isDictLoaded = ref(false);
|
||||
|
||||
// 监听字典数据变化
|
||||
watchEffect(() => {
|
||||
if (bmzr_evaluation_level.value && bmzr_evaluation_level.value.length > 0) {
|
||||
console.log('字典数据已加载:', bmzr_evaluation_level.value);
|
||||
isDictLoaded.value = true;
|
||||
}
|
||||
});
|
||||
|
||||
/** 获取班级层次文本 */
|
||||
const getClassTypeText = (classType?: string) => {
|
||||
const typeMap: Record<string, string> = {
|
||||
@@ -367,13 +399,13 @@ 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);
|
||||
};
|
||||
|
||||
@@ -381,18 +413,107 @@ const formatNumber = (value?: number | string, precision = 4) => {
|
||||
const calculateMonthlyScore = () => {
|
||||
// 总系数(K)
|
||||
const totalCoefficient = viewDetail.value?.coefficient?.totalCoefficient || 0;
|
||||
|
||||
// 班主任常规工作上级评分之和(查看界面显示最终审批结果,使用上级评分)
|
||||
const routineWorkTotal = routineWorkScores.value.reduce((sum, item) => sum + (item.superiorScore || 0), 0);
|
||||
|
||||
// 班级管理实效上级评分(查看界面显示最终审批结果,使用上级评分)
|
||||
const managementEffectivenessScore = managementEffectivenessData.superiorScore || 0;
|
||||
|
||||
// 特色工作上级评分之和(查看界面显示最终审批结果,使用上级评分)
|
||||
const specialWorkTotal = specialWorkScores.value.reduce((sum, item) => sum + (item.superiorScore || 0), 0);
|
||||
|
||||
// 月考核得分 = 总系数(K)* (班主任常规工作上级评分之和 + 班级管理实效上级评分 + 特色工作上级评分之和)
|
||||
return totalCoefficient * (routineWorkTotal + managementEffectivenessScore + specialWorkTotal);
|
||||
};
|
||||
|
||||
/** 计算评价等级(基于占比规则) */
|
||||
const calculateEvaluationLevel = () => {
|
||||
const score = calculateMonthlyScore();
|
||||
console.log('=== 📊 评价等级计算调试 ===');
|
||||
console.log('💯 月考核得分:', score);
|
||||
console.log('📈 是否有统计数据:', !!evaluationStats.value);
|
||||
console.log('👤 当前用户ID:', currentRow.value?.evaluatedUserId);
|
||||
|
||||
// 班主任常规工作自评分之和
|
||||
const routineWorkTotal = routineWorkScores.value.reduce((sum, item) => sum + (item.selfScore || 0), 0);
|
||||
if (evaluationStats.value) {
|
||||
console.log('📊 统计数据详情:', {
|
||||
总教师数: evaluationStats.value.totalTeachers,
|
||||
排名数据: evaluationStats.value.scoreRankings?.length || 0,
|
||||
A等最大占比: evaluationStats.value.evaluationLevelRules?.aLevelMaxPercentage,
|
||||
及格分数: evaluationStats.value.evaluationLevelRules?.passScore
|
||||
});
|
||||
}
|
||||
|
||||
// 按班级扣分50%计的分值
|
||||
const deductionHalf = managementEffectivenessData.classDeductionHalf || 0;
|
||||
let level = '';
|
||||
let calculationMethod = '';
|
||||
|
||||
// 特色工作总分值
|
||||
const specialWorkTotal = specialWorkScores.value.reduce((sum, item) => sum + (item.score || 0), 0);
|
||||
// 如果有统计数据且用户ID存在,使用严格的占比规则
|
||||
if (evaluationStats.value &&
|
||||
evaluationStats.value.totalTeachers > 0 &&
|
||||
evaluationStats.value.scoreRankings.length > 0 &&
|
||||
currentRow.value?.evaluatedUserId) {
|
||||
level = calculateEvaluationLevelByStats(score, currentRow.value.evaluatedUserId);
|
||||
calculationMethod = '📈 严格占比规则评级';
|
||||
} else {
|
||||
// 降级方案:基于分数的简单评级
|
||||
if (score < 60) {
|
||||
level = 'C'; // C等(不合格):60分以下
|
||||
} else if (score >= 85) {
|
||||
level = 'A'; // A等(优秀):85分以上(暂定)
|
||||
} else {
|
||||
level = 'B'; // B等(合格):60-85分
|
||||
}
|
||||
calculationMethod = '🔢 简化分数评级';
|
||||
|
||||
// 输出使用简化评级的原因
|
||||
const reasons = [];
|
||||
if (!evaluationStats.value) reasons.push('统计数据为空');
|
||||
if (evaluationStats.value?.totalTeachers === 0) reasons.push('总教师数为0');
|
||||
if (evaluationStats.value?.scoreRankings?.length === 0) reasons.push('排名数据为空');
|
||||
if (!currentRow.value?.evaluatedUserId) reasons.push('用户ID缺失');
|
||||
|
||||
console.warn('⚠️ 使用简化评级的原因:', reasons.join('、'));
|
||||
}
|
||||
|
||||
// 月考核得分 = 总系数(K)* (班主任常规工作自评分之和 - 按班级扣分50%计的分值 + 特色工作总分值)
|
||||
return totalCoefficient * (routineWorkTotal - deductionHalf + specialWorkTotal);
|
||||
console.log('🎯 计算方法:', calculationMethod);
|
||||
console.log('📋 最终评价等级:', level);
|
||||
console.log('=== 📊 评价等级计算调试结束 ===');
|
||||
return level;
|
||||
};
|
||||
|
||||
/** 基于统计数据计算评价等级(严格占比规则) */
|
||||
const calculateEvaluationLevelByStats = (score: number, evaluatedUserId: string | number) => {
|
||||
const stats = evaluationStats.value;
|
||||
if (!stats) {
|
||||
console.warn('统计数据不可用,使用简单评级');
|
||||
return score < 60 ? 'C' : (score >= 85 ? 'A' : 'B');
|
||||
}
|
||||
|
||||
const { totalTeachers, scoreRankings, evaluationLevelRules } = stats;
|
||||
const { aLevelMaxPercentage, passScore } = evaluationLevelRules;
|
||||
|
||||
// C等:不及格
|
||||
if (score < passScore) {
|
||||
return 'C';
|
||||
}
|
||||
|
||||
// 查找当前用户的排名
|
||||
const currentRanking = scoreRankings.find(item =>
|
||||
item.evaluatedUserId === evaluatedUserId || item.score === score
|
||||
);
|
||||
|
||||
if (!currentRanking) {
|
||||
console.warn('找不到当前用户的排名信息,使用简单评级');
|
||||
return score < 60 ? 'C' : (score >= 85 ? 'A' : 'B');
|
||||
}
|
||||
|
||||
// A等:及格且排名在前20%内
|
||||
if (score >= passScore && currentRanking.percentage <= aLevelMaxPercentage) {
|
||||
return 'A';
|
||||
}
|
||||
|
||||
// B等:其余及格的
|
||||
return 'B';
|
||||
};
|
||||
|
||||
/** 打开弹窗 */
|
||||
@@ -401,9 +522,31 @@ const open = async (row: AssessmentApprovalVO) => {
|
||||
proxy?.$modal.msgError('参数错误:缺少必要的ID信息');
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
currentRow.value = row;
|
||||
visible.value = true;
|
||||
|
||||
// 检查字典数据加载状态
|
||||
console.log('🔍 打开弹窗时字典数据状态:', {
|
||||
字典对象存在: !!bmzr_evaluation_level.value,
|
||||
字典数据长度: bmzr_evaluation_level.value?.length || 0,
|
||||
字典数据内容: bmzr_evaluation_level.value
|
||||
});
|
||||
|
||||
// 等待字典数据加载完成(最多等待2秒)
|
||||
let waitCount = 0;
|
||||
while ((!bmzr_evaluation_level.value || bmzr_evaluation_level.value.length === 0) && waitCount < 20) {
|
||||
await new Promise(resolve => setTimeout(resolve, 100));
|
||||
waitCount++;
|
||||
}
|
||||
|
||||
if (bmzr_evaluation_level.value && bmzr_evaluation_level.value.length > 0) {
|
||||
console.log('✅ 字典数据加载完成:', bmzr_evaluation_level.value);
|
||||
isDictLoaded.value = true;
|
||||
} else {
|
||||
console.warn('⚠️ 字典数据加载超时,使用备用数据');
|
||||
}
|
||||
|
||||
await loadViewDetail();
|
||||
};
|
||||
|
||||
@@ -415,37 +558,156 @@ const loadViewDetail = async () => {
|
||||
|
||||
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 || [];
|
||||
|
||||
// 并行加载详情数据和统计数据
|
||||
const [detailRes, statsRes] = await Promise.allSettled([
|
||||
getAssessmentApprovalDetail(currentRow.value.planId, currentRow.value.classId, currentRow.value.evaluatedUserId),
|
||||
getEvaluationLevelStats(currentRow.value.planId)
|
||||
]);
|
||||
|
||||
// 处理详情数据
|
||||
if (detailRes.status === 'fulfilled') {
|
||||
viewDetail.value = detailRes.value.data;
|
||||
} else {
|
||||
console.error('加载详情数据失败:', detailRes.reason);
|
||||
proxy?.$modal.msgError('加载详情数据失败');
|
||||
return;
|
||||
}
|
||||
|
||||
// 处理统计数据(非必需,失败时使用简单评级)
|
||||
if (statsRes.status === 'fulfilled') {
|
||||
evaluationStats.value = statsRes.value.data;
|
||||
console.log('✅ 评价等级统计数据加载成功:', evaluationStats.value);
|
||||
|
||||
// 检查统计数据的完整性
|
||||
if (!evaluationStats.value.totalTeachers || evaluationStats.value.scoreRankings.length === 0) {
|
||||
console.warn('⚠️ 统计数据不完整,总教师数:', evaluationStats.value.totalTeachers,
|
||||
'排名数据条数:', evaluationStats.value.scoreRankings.length);
|
||||
proxy?.$modal.msgWarning('统计数据不完整,可能影响等级评定准确性');
|
||||
}
|
||||
} else {
|
||||
console.error('❌ 评价等级统计数据加载失败,使用简单评级:', statsRes.reason);
|
||||
proxy?.$modal.msgWarning('无法加载等级统计数据,将使用简化评级规则');
|
||||
evaluationStats.value = undefined;
|
||||
}
|
||||
|
||||
// 详细的调试日志 - 用于排查数据显示问题
|
||||
console.log('=== 查看详情数据加载开始 ===');
|
||||
console.log('完整查看详情数据:', viewDetail.value);
|
||||
console.log('班主任常规工作原始数据:', viewDetail.value?.routineWorkIndicators);
|
||||
console.log('特色工作原始数据:', viewDetail.value?.specialWorkIndicators);
|
||||
console.log('班级管理实效原始数据:', viewDetail.value?.classDeductionIndicator);
|
||||
console.log('自我总体评价:', viewDetail.value?.selfOverallComment);
|
||||
|
||||
// 初始化班主任常规工作数据 - 确保包含所有必要字段
|
||||
if (viewDetail.value?.routineWorkIndicators && Array.isArray(viewDetail.value.routineWorkIndicators)) {
|
||||
routineWorkScores.value = viewDetail.value.routineWorkIndicators.map((item) => {
|
||||
const mappedItem = {
|
||||
...item,
|
||||
// 确保数值字段不为空
|
||||
selfScore: Number(item.selfScore) || 0,
|
||||
superiorScore: Number(item.superiorScore) || 0,
|
||||
score: Number(item.score) || 0,
|
||||
maxScore: Number(item.maxScore) || 0,
|
||||
// 确保字符串字段不为空
|
||||
selfComment: item.selfComment || '',
|
||||
superiorComment: item.superiorComment || '',
|
||||
indicatorName: item.indicatorName || '',
|
||||
description: item.description || '',
|
||||
indicatorCode: item.indicatorCode || ''
|
||||
};
|
||||
console.log(`常规工作指标 [${item.indicatorName}]:`, {
|
||||
自评分数: mappedItem.selfScore,
|
||||
自评意见: mappedItem.selfComment,
|
||||
上级评分: mappedItem.superiorScore,
|
||||
上级意见: mappedItem.superiorComment
|
||||
});
|
||||
return mappedItem;
|
||||
});
|
||||
console.log('班主任常规工作数据初始化完成,条目数量:', routineWorkScores.value.length);
|
||||
} else {
|
||||
routineWorkScores.value = [];
|
||||
console.warn('班主任常规工作数据为空或格式错误');
|
||||
}
|
||||
|
||||
// 初始化班级管理实效数据
|
||||
if (viewDetail.value?.classDeductionIndicator) {
|
||||
const indicator = viewDetail.value.classDeductionIndicator;
|
||||
managementEffectivenessData.classDeduction = indicator.selfScore || 0;
|
||||
managementEffectivenessData.classDeductionHalf = (indicator.selfScore || 0) * 0.5;
|
||||
managementEffectivenessData.classDeduction = Number(indicator.selfScore) || 0;
|
||||
managementEffectivenessData.classDeductionHalf = (Number(indicator.selfScore) || 0) * 0.5;
|
||||
managementEffectivenessData.selfComment = indicator.selfComment || '';
|
||||
managementEffectivenessData.superiorScore = indicator.superiorScore || 0;
|
||||
managementEffectivenessData.superiorScore = Number(indicator.superiorScore) || 0;
|
||||
managementEffectivenessData.superiorComment = indicator.superiorComment || '';
|
||||
console.log('班级管理实效数据初始化:', {
|
||||
班级扣分: managementEffectivenessData.classDeduction,
|
||||
扣分50计: managementEffectivenessData.classDeductionHalf,
|
||||
自评意见: managementEffectivenessData.selfComment,
|
||||
上级评分: managementEffectivenessData.superiorScore,
|
||||
上级意见: managementEffectivenessData.superiorComment
|
||||
});
|
||||
} else {
|
||||
// 如果没有找到班级扣分指标,设置默认值
|
||||
managementEffectivenessData.classDeduction = 0;
|
||||
managementEffectivenessData.classDeductionHalf = 0;
|
||||
managementEffectivenessData.selfComment = '';
|
||||
managementEffectivenessData.superiorScore = 0;
|
||||
managementEffectivenessData.superiorComment = '';
|
||||
console.warn('班级管理实效数据为空,使用默认值');
|
||||
}
|
||||
|
||||
// 初始化特色工作数据
|
||||
specialWorkScores.value = viewDetail.value?.specialWorkIndicators || [];
|
||||
|
||||
|
||||
// 初始化特色工作数据 - 确保包含所有必要字段
|
||||
if (viewDetail.value?.specialWorkIndicators && Array.isArray(viewDetail.value.specialWorkIndicators)) {
|
||||
specialWorkScores.value = viewDetail.value.specialWorkIndicators.map((item) => {
|
||||
const mappedItem = {
|
||||
...item,
|
||||
// 确保数值字段不为空
|
||||
selfScore: Number(item.selfScore) || 0,
|
||||
superiorScore: Number(item.superiorScore) || 0,
|
||||
score: Number(item.score) || 0,
|
||||
// 确保字符串字段不为空
|
||||
selfComment: item.selfComment || '',
|
||||
superiorComment: item.superiorComment || '',
|
||||
indicatorName: item.indicatorName || '',
|
||||
indicatorCode: item.indicatorCode || ''
|
||||
};
|
||||
console.log(`特色工作指标 [${item.indicatorCode} - ${item.indicatorName}]:`, {
|
||||
自评分数: mappedItem.selfScore,
|
||||
自评意见: mappedItem.selfComment,
|
||||
上级评分: mappedItem.superiorScore,
|
||||
上级意见: mappedItem.superiorComment
|
||||
});
|
||||
return mappedItem;
|
||||
});
|
||||
console.log('特色工作数据初始化完成,条目数量:', specialWorkScores.value.length);
|
||||
} else {
|
||||
specialWorkScores.value = [];
|
||||
console.warn('特色工作数据为空或格式错误');
|
||||
}
|
||||
|
||||
// 初始化月考核得分数据
|
||||
monthlyScoreData.selfOverallComment = viewDetail.value?.selfOverallComment || '';
|
||||
monthlyScoreData.superiorOverallComment = viewDetail.value?.superiorOverallComment || '';
|
||||
|
||||
console.log('月考核得分数据初始化:', {
|
||||
自我总体评价: monthlyScoreData.selfOverallComment,
|
||||
上级总体评价: monthlyScoreData.superiorOverallComment,
|
||||
计算得分: calculateMonthlyScore().toFixed(2)
|
||||
});
|
||||
|
||||
// 初始化审批数据
|
||||
// 这里需要根据实际的后端字段调整
|
||||
approvalData.auditComment = '';
|
||||
|
||||
console.log('=== 查看详情数据加载完成 ===');
|
||||
|
||||
// 验证数据完整性
|
||||
if (routineWorkScores.value.length === 0) {
|
||||
console.warn('⚠️ 警告:班主任常规工作数据为空,可能存在数据问题');
|
||||
proxy?.$modal.msgWarning('班主任常规工作数据为空,请检查数据是否正确');
|
||||
}
|
||||
|
||||
if (specialWorkScores.value.length === 0) {
|
||||
console.warn('⚠️ 警告:特色工作数据为空,可能存在数据问题');
|
||||
proxy?.$modal.msgWarning('特色工作数据为空,请检查数据是否正确');
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
console.error('加载查看详情失败:', error);
|
||||
proxy?.$modal.msgError('加载查看详情失败');
|
||||
@@ -457,10 +719,13 @@ const loadViewDetail = async () => {
|
||||
/** 关闭弹窗 */
|
||||
const handleClose = () => {
|
||||
visible.value = false;
|
||||
|
||||
|
||||
// 重置数据
|
||||
routineWorkScores.value = [];
|
||||
specialWorkScores.value = [];
|
||||
evaluationStats.value = undefined;
|
||||
isDictLoaded.value = false; // 重置字典加载状态
|
||||
|
||||
Object.assign(managementEffectivenessData, {
|
||||
classDeduction: 0,
|
||||
classDeductionHalf: 0,
|
||||
@@ -485,7 +750,7 @@ defineExpose({
|
||||
|
||||
<style scoped>
|
||||
.view-dialog-content {
|
||||
max-height: 70vh;
|
||||
max-height: 65vh;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
@@ -517,14 +782,14 @@ defineExpose({
|
||||
/* 班主任常规工作表格样式优化 */
|
||||
:deep(.routine-work-table) {
|
||||
.el-table__body-wrapper {
|
||||
max-height: 350px;
|
||||
max-height: 200px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
|
||||
.el-table__row {
|
||||
height: auto;
|
||||
}
|
||||
|
||||
|
||||
.el-table__cell {
|
||||
padding: 8px 0;
|
||||
vertical-align: middle;
|
||||
@@ -533,10 +798,15 @@ defineExpose({
|
||||
|
||||
/* 特色工作表格样式优化 */
|
||||
:deep(.special-work-table) {
|
||||
.el-table__body-wrapper {
|
||||
max-height: 150px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.el-table__row {
|
||||
height: auto;
|
||||
}
|
||||
|
||||
|
||||
.el-table__cell {
|
||||
padding: 8px 0;
|
||||
vertical-align: middle;
|
||||
@@ -564,7 +834,7 @@ defineExpose({
|
||||
text-align: center;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
|
||||
.el-descriptions__content {
|
||||
text-align: center;
|
||||
}
|
||||
@@ -574,4 +844,4 @@ defineExpose({
|
||||
:deep(.el-input.is-disabled .el-input__wrapper) {
|
||||
background-color: #f5f7fa;
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
@@ -41,24 +41,10 @@
|
||||
<el-button type="primary" icon="Plus" @click="handleAdd" v-hasPermi="['bzrkh:assessmentIndicator:add']">新增</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button
|
||||
icon="Edit"
|
||||
:disabled="single"
|
||||
@click="handleUpdate()"
|
||||
v-hasPermi="['bzrkh:assessmentIndicator:edit']"
|
||||
>
|
||||
修改
|
||||
</el-button>
|
||||
<el-button icon="Edit" :disabled="single" @click="handleUpdate()" v-hasPermi="['bzrkh:assessmentIndicator:edit']"> 修改 </el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button
|
||||
icon="Delete"
|
||||
:disabled="multiple"
|
||||
@click="handleDelete()"
|
||||
v-hasPermi="['bzrkh:assessmentIndicator:remove']"
|
||||
>
|
||||
删除
|
||||
</el-button>
|
||||
<el-button icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['bzrkh:assessmentIndicator:remove']"> 删除 </el-button>
|
||||
</el-col>
|
||||
|
||||
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
|
||||
@@ -66,12 +52,7 @@
|
||||
</template>
|
||||
|
||||
<div class="table-container">
|
||||
<el-table
|
||||
v-loading="loading"
|
||||
border
|
||||
:data="assessmentIndicatorList"
|
||||
@selection-change="handleSelectionChange"
|
||||
>
|
||||
<el-table v-loading="loading" border :data="assessmentIndicatorList" @selection-change="handleSelectionChange">
|
||||
<el-table-column type="selection" width="55" align="center" />
|
||||
<el-table-column label="指标编码" align="center" prop="indicatorCode" width="140" show-overflow-tooltip />
|
||||
<el-table-column label="指标名称" align="center" prop="indicatorName" min-width="180" show-overflow-tooltip />
|
||||
@@ -91,10 +72,22 @@
|
||||
<el-table-column label="操作" align="center" width="120" class-name="small-padding fixed-width">
|
||||
<template #default="scope">
|
||||
<el-tooltip content="修改" placement="top">
|
||||
<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['bzrkh:assessmentIndicator:edit']"></el-button>
|
||||
<el-button
|
||||
link
|
||||
type="primary"
|
||||
icon="Edit"
|
||||
@click="handleUpdate(scope.row)"
|
||||
v-hasPermi="['bzrkh:assessmentIndicator:edit']"
|
||||
></el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip content="删除" placement="top">
|
||||
<el-button link type="danger" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['bzrkh:assessmentIndicator:remove']"></el-button>
|
||||
<el-button
|
||||
link
|
||||
type="danger"
|
||||
icon="Delete"
|
||||
@click="handleDelete(scope.row)"
|
||||
v-hasPermi="['bzrkh:assessmentIndicator:remove']"
|
||||
></el-button>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
</el-table-column>
|
||||
@@ -170,8 +163,21 @@
|
||||
</template>
|
||||
|
||||
<script setup name="AssessmentIndicator" lang="ts">
|
||||
import { listBmzrAssessmentIndicator, getBmzrAssessmentIndicator, delBmzrAssessmentIndicator, addBmzrAssessmentIndicator, updateBmzrAssessmentIndicator, getIndicatorTypeOptions, getParentIndicatorOptions } from '@/api/bzrkh/assessmentIndicator';
|
||||
import { AssessmentIndicatorVO, AssessmentIndicatorQuery, AssessmentIndicatorForm, AssessmentIndicatorTypeOption } from '@/api/bzrkh/assessmentIndicator/types';
|
||||
import {
|
||||
listBmzrAssessmentIndicator,
|
||||
getBmzrAssessmentIndicator,
|
||||
delBmzrAssessmentIndicator,
|
||||
addBmzrAssessmentIndicator,
|
||||
updateBmzrAssessmentIndicator,
|
||||
getIndicatorTypeOptions,
|
||||
getParentIndicatorOptions
|
||||
} from '@/api/bzrkh/assessmentIndicator';
|
||||
import {
|
||||
AssessmentIndicatorVO,
|
||||
AssessmentIndicatorQuery,
|
||||
AssessmentIndicatorForm,
|
||||
AssessmentIndicatorTypeOption
|
||||
} from '@/api/bzrkh/assessmentIndicator/types';
|
||||
|
||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||
const { sys_item_enable, sys_yes_no } = toRefs<any>(proxy?.useDict('sys_item_enable', 'sys_yes_no'));
|
||||
@@ -234,7 +240,7 @@ const { queryParams, form, rules } = toRefs(data);
|
||||
|
||||
/** 获取指标类型名称 */
|
||||
const getIndicatorTypeName = (code: string) => {
|
||||
const option = indicatorTypeOptions.value.find(item => item.indicatorTypeCode === code);
|
||||
const option = indicatorTypeOptions.value.find((item) => item.indicatorTypeCode === code);
|
||||
return option ? option.indicatorTypeName : code;
|
||||
};
|
||||
|
||||
@@ -359,8 +365,6 @@ const handleDelete = async (row?: AssessmentIndicatorVO) => {
|
||||
await getList();
|
||||
};
|
||||
|
||||
|
||||
|
||||
onMounted(() => {
|
||||
getList();
|
||||
getIndicatorTypeOptionsList();
|
||||
@@ -400,4 +404,4 @@ onMounted(() => {
|
||||
background-color: #fff;
|
||||
margin-top: 0px !important;
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
@@ -44,7 +44,9 @@
|
||||
<el-button icon="Edit" :disabled="single" @click="handleUpdate()" v-hasPermi="['bzrkh:assessmentIndicatorType:edit']">修改</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['bzrkh:assessmentIndicatorType:remove']">删除</el-button>
|
||||
<el-button icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['bzrkh:assessmentIndicatorType:remove']"
|
||||
>删除</el-button
|
||||
>
|
||||
</el-col>
|
||||
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
|
||||
</el-row>
|
||||
@@ -69,10 +71,22 @@
|
||||
<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" @click="handleUpdate(scope.row)" v-hasPermi="['bzrkh:assessmentIndicatorType:edit']"></el-button>
|
||||
<el-button
|
||||
link
|
||||
type="primary"
|
||||
icon="Edit"
|
||||
@click="handleUpdate(scope.row)"
|
||||
v-hasPermi="['bzrkh:assessmentIndicatorType:edit']"
|
||||
></el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip content="删除" placement="top">
|
||||
<el-button link type="danger" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['bzrkh:assessmentIndicatorType:remove']"></el-button>
|
||||
<el-button
|
||||
link
|
||||
type="danger"
|
||||
icon="Delete"
|
||||
@click="handleDelete(scope.row)"
|
||||
v-hasPermi="['bzrkh:assessmentIndicatorType:remove']"
|
||||
></el-button>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
</el-table-column>
|
||||
@@ -112,7 +126,13 @@
|
||||
</template>
|
||||
|
||||
<script setup name="AssessmentIndicatorType" lang="ts">
|
||||
import { listAssessmentIndicatorType, getAssessmentIndicatorType, delAssessmentIndicatorType, addAssessmentIndicatorType, updateAssessmentIndicatorType } from '@/api/bzrkh/assessmentIndicatorType';
|
||||
import {
|
||||
listAssessmentIndicatorType,
|
||||
getAssessmentIndicatorType,
|
||||
delAssessmentIndicatorType,
|
||||
addAssessmentIndicatorType,
|
||||
updateAssessmentIndicatorType
|
||||
} from '@/api/bzrkh/assessmentIndicatorType';
|
||||
import { AssessmentIndicatorTypeVO, AssessmentIndicatorTypeQuery, AssessmentIndicatorTypeForm } from '@/api/bzrkh/assessmentIndicatorType/types';
|
||||
|
||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||
@@ -300,4 +320,4 @@ onMounted(() => {
|
||||
background-color: #fff;
|
||||
margin-top: 0px !important;
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
@@ -91,7 +91,7 @@
|
||||
<el-table-column label="计划编码" align="center" prop="planCode" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="考核方案" align="center" :show-overflow-tooltip="true">
|
||||
<template #default="scope">
|
||||
<span>{{ schemeOptions.find(item => item.id === scope.row.schemeId)?.schemeName || '' }}</span>
|
||||
<span>{{ schemeOptions.find((item) => item.id === scope.row.schemeId)?.schemeName || '' }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="学年学期" align="center" width="120">
|
||||
@@ -165,7 +165,12 @@
|
||||
<el-col :span="24">
|
||||
<el-form-item label="考核方案" prop="schemeId">
|
||||
<el-select v-model="form.schemeId" placeholder="请选择考核方案" style="width: 100%">
|
||||
<el-option v-for="item in schemeOptions" :key="item.id" :label="`${item.schemeName}(${item.academicYear}${item.semester === '1' ? '上' : '下'}学期)`" :value="item.id" />
|
||||
<el-option
|
||||
v-for="item in schemeOptions"
|
||||
:key="item.id"
|
||||
:label="`${item.schemeName}(${item.academicYear}${item.semester === '1' ? '上' : '下'}学期)`"
|
||||
:value="item.id"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
@@ -277,11 +282,7 @@ import {
|
||||
changeAssessmentPlanStatus
|
||||
} from '@/api/bzrkh/assessmentPlan';
|
||||
import { listBmzrAssessmentScheme } from '@/api/bzrkh/assessmentScheme';
|
||||
import {
|
||||
AssessmentPlanVO,
|
||||
AssessmentPlanQuery,
|
||||
AssessmentPlanForm
|
||||
} from '@/api/bzrkh/assessmentPlan/types';
|
||||
import { AssessmentPlanVO, AssessmentPlanQuery, AssessmentPlanForm } from '@/api/bzrkh/assessmentPlan/types';
|
||||
import { BmzrAssessmentSchemeVO } from '@/api/bzrkh/assessmentScheme/types';
|
||||
|
||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||
@@ -371,7 +372,7 @@ const getList = async () => {
|
||||
|
||||
/** 获取考核方案选项 */
|
||||
const getSchemeOptions = async () => {
|
||||
const res = await listBmzrAssessmentScheme({
|
||||
const res = await listBmzrAssessmentScheme({
|
||||
status: '0', // 只获取正常状态的方案
|
||||
pageNum: 1,
|
||||
pageSize: 1000 // 设置较大的pageSize以获取所有可用方案
|
||||
@@ -479,18 +480,19 @@ const handleDelete = async (row?: AssessmentPlanVO) => {
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
|
||||
/** 状态修改 */
|
||||
const handleStatusChange = async (row: AssessmentPlanVO) => {
|
||||
const text = row.planStatus === '1' ? '启用' : '禁用';
|
||||
await proxy?.$modal.confirm('确认要"' + text + '""' + row.planName + '"考核计划吗?').then(async () => {
|
||||
await changeAssessmentPlanStatus(row.id!, row.planStatus!).then(() => {
|
||||
proxy?.$modal.msgSuccess(text + '成功');
|
||||
await proxy?.$modal
|
||||
.confirm('确认要"' + text + '""' + row.planName + '"考核计划吗?')
|
||||
.then(async () => {
|
||||
await changeAssessmentPlanStatus(row.id!, row.planStatus!).then(() => {
|
||||
proxy?.$modal.msgSuccess(text + '成功');
|
||||
});
|
||||
})
|
||||
.catch(() => {
|
||||
row.planStatus = row.planStatus === '1' ? '0' : '1';
|
||||
});
|
||||
}).catch(() => {
|
||||
row.planStatus = row.planStatus === '1' ? '0' : '1';
|
||||
});
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
@@ -532,4 +534,4 @@ onMounted(() => {
|
||||
background-color: #fff;
|
||||
margin-top: 0px !important;
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
@@ -1,12 +1,5 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
title="指标体系管理"
|
||||
v-model="dialogVisible"
|
||||
width="1200px"
|
||||
append-to-body
|
||||
:close-on-click-modal="false"
|
||||
@close="handleClose"
|
||||
>
|
||||
<el-dialog title="指标体系管理" v-model="dialogVisible" width="1200px" append-to-body :close-on-click-modal="false" @close="handleClose">
|
||||
<div class="indicator-management-container">
|
||||
<!-- 检索区域 -->
|
||||
<div class="search-container">
|
||||
@@ -15,12 +8,7 @@
|
||||
<el-row :gutter="20">
|
||||
<el-col :lg="8" :md="12" :sm="24">
|
||||
<el-form-item label="指标名称" prop="indicatorName">
|
||||
<el-input
|
||||
v-model="searchParams.indicatorName"
|
||||
placeholder="请输入指标名称"
|
||||
clearable
|
||||
@keyup.enter="handleSearchIndicators"
|
||||
/>
|
||||
<el-input v-model="searchParams.indicatorName" placeholder="请输入指标名称" clearable @keyup.enter="handleSearchIndicators" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :lg="16" :md="12" :sm="24">
|
||||
@@ -31,15 +19,10 @@
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
|
||||
|
||||
<!-- 搜索结果提示 -->
|
||||
<div v-if="searchResultInfo" class="search-result-info">
|
||||
<el-alert
|
||||
:title="searchResultInfo"
|
||||
type="info"
|
||||
:closable="false"
|
||||
show-icon
|
||||
/>
|
||||
<el-alert :title="searchResultInfo" type="info" :closable="false" show-icon />
|
||||
</div>
|
||||
</el-card>
|
||||
</div>
|
||||
@@ -54,8 +37,8 @@
|
||||
|
||||
<!-- 没有搜索结果时显示提示 -->
|
||||
<div v-else-if="filteredIndicatorList.length === 0" class="empty-state">
|
||||
<div style="text-align: center; color: #909399;">
|
||||
<el-icon size="48" style="margin-bottom: 16px;"><Search /></el-icon>
|
||||
<div style="text-align: center; color: #909399">
|
||||
<el-icon size="48" style="margin-bottom: 16px"><Search /></el-icon>
|
||||
<p>未找到匹配"{{ searchParams.indicatorName }}"的指标</p>
|
||||
<el-button type="text" @click="resetSearch">清除搜索条件</el-button>
|
||||
</div>
|
||||
@@ -71,19 +54,14 @@
|
||||
</div>
|
||||
<div class="row-item">
|
||||
<span class="label">指标名称:</span>
|
||||
<el-select
|
||||
v-model="item.indicatorId"
|
||||
placeholder="请选择指标名称"
|
||||
<el-select
|
||||
v-model="item.indicatorId"
|
||||
placeholder="请选择指标名称"
|
||||
style="width: 250px"
|
||||
@change="handleIndicatorChange(item, getOriginalIndex(item))"
|
||||
filterable
|
||||
>
|
||||
<el-option
|
||||
v-for="indicator in availableIndicators"
|
||||
:key="indicator.id"
|
||||
:label="indicator.indicatorName"
|
||||
:value="indicator.id"
|
||||
/>
|
||||
<el-option v-for="indicator in availableIndicators" :key="indicator.id" :label="indicator.indicatorName" :value="indicator.id" />
|
||||
</el-select>
|
||||
</div>
|
||||
<div class="row-item">
|
||||
@@ -153,13 +131,13 @@ const filteredIndicatorList = computed(() => {
|
||||
// 没有搜索条件时,显示所有指标
|
||||
return indicatorList.value;
|
||||
}
|
||||
|
||||
|
||||
// 有搜索条件时,只显示匹配的指标
|
||||
return indicatorList.value.filter(item => {
|
||||
return indicatorList.value.filter((item) => {
|
||||
// 根据indicatorId查找对应的指标名称
|
||||
const indicator = availableIndicators.value.find(ind => ind.id == item.indicatorId);
|
||||
const indicator = availableIndicators.value.find((ind) => ind.id == item.indicatorId);
|
||||
const indicatorName = indicator?.indicatorName || '';
|
||||
|
||||
|
||||
// 检查指标名称是否包含搜索关键词(不区分大小写)
|
||||
return indicatorName.toLowerCase().includes(keyword.toLowerCase());
|
||||
});
|
||||
@@ -167,10 +145,11 @@ const filteredIndicatorList = computed(() => {
|
||||
|
||||
// 获取指标在原始列表中的索引
|
||||
const getOriginalIndex = (item: BmzrAssessmentSchemeIndicatorForm) => {
|
||||
return indicatorList.value.findIndex(originalItem =>
|
||||
originalItem === item ||
|
||||
(originalItem.id && originalItem.id === item.id) ||
|
||||
(originalItem.indicatorId && originalItem.indicatorId === item.indicatorId && originalItem.sortOrder === item.sortOrder)
|
||||
return indicatorList.value.findIndex(
|
||||
(originalItem) =>
|
||||
originalItem === item ||
|
||||
(originalItem.id && originalItem.id === item.id) ||
|
||||
(originalItem.indicatorId && originalItem.indicatorId === item.indicatorId && originalItem.sortOrder === item.sortOrder)
|
||||
);
|
||||
};
|
||||
|
||||
@@ -178,10 +157,10 @@ const getOriginalIndex = (item: BmzrAssessmentSchemeIndicatorForm) => {
|
||||
const open = async (id: string | number) => {
|
||||
schemeId.value = id;
|
||||
dialogVisible.value = true;
|
||||
|
||||
|
||||
// 加载可选指标
|
||||
await loadAvailableIndicators();
|
||||
|
||||
|
||||
// 加载当前方案的指标
|
||||
await loadSchemeIndicators();
|
||||
};
|
||||
@@ -194,24 +173,24 @@ const loadAvailableIndicators = async () => {
|
||||
pageNum: 1,
|
||||
pageSize: 1000 // 加载所有指标
|
||||
};
|
||||
|
||||
|
||||
// 如果有搜索条件,添加到查询参数中
|
||||
const hasSearchCondition = !!(searchParams.value.indicatorName && searchParams.value.indicatorName.trim());
|
||||
if (hasSearchCondition) {
|
||||
queryParams.indicatorName = searchParams.value.indicatorName.trim();
|
||||
}
|
||||
|
||||
|
||||
const res = await listBmzrAssessmentIndicator(queryParams);
|
||||
availableIndicators.value = res.rows || [];
|
||||
|
||||
|
||||
// 调试日志
|
||||
console.log('loadAvailableIndicators完成:', {
|
||||
queryParams,
|
||||
hasSearchCondition,
|
||||
resultCount: availableIndicators.value.length,
|
||||
indicatorNames: availableIndicators.value.map(i => i.indicatorName)
|
||||
indicatorNames: availableIndicators.value.map((i) => i.indicatorName)
|
||||
});
|
||||
|
||||
|
||||
// 更新搜索结果信息
|
||||
updateSearchResultInfo(hasSearchCondition, availableIndicators.value.length);
|
||||
} catch (error) {
|
||||
@@ -225,15 +204,16 @@ const loadAvailableIndicators = async () => {
|
||||
const loadSchemeIndicators = async () => {
|
||||
try {
|
||||
const res = await listBySchemeId(schemeId.value);
|
||||
indicatorList.value = res.data?.map((item: any) => ({
|
||||
id: item.id,
|
||||
schemeId: item.schemeId,
|
||||
indicatorId: item.indicatorId,
|
||||
// 优先使用score字段,如果为空则使用customMaxScore字段(兜底方案)
|
||||
score: item.score || item.customMaxScore,
|
||||
remark: item.remark || getIndicatorRemark(item.indicatorId),
|
||||
sortOrder: item.sortOrder
|
||||
})) || [];
|
||||
indicatorList.value =
|
||||
res.data?.map((item: any) => ({
|
||||
id: item.id,
|
||||
schemeId: item.schemeId,
|
||||
indicatorId: item.indicatorId,
|
||||
// 优先使用score字段,如果为空则使用customMaxScore字段(兜底方案)
|
||||
score: item.score || item.customMaxScore,
|
||||
remark: item.remark || getIndicatorRemark(item.indicatorId),
|
||||
sortOrder: item.sortOrder
|
||||
})) || [];
|
||||
} catch (error) {
|
||||
console.error('加载方案指标失败:', error);
|
||||
proxy?.$modal.msgError('加载方案指标失败');
|
||||
@@ -242,7 +222,7 @@ const loadSchemeIndicators = async () => {
|
||||
|
||||
// 根据指标ID获取指标描述
|
||||
const getIndicatorRemark = (indicatorId: string | number) => {
|
||||
const indicator = availableIndicators.value.find(item => item.id == indicatorId);
|
||||
const indicator = availableIndicators.value.find((item) => item.id == indicatorId);
|
||||
return indicator?.remark || '';
|
||||
};
|
||||
|
||||
@@ -261,23 +241,23 @@ const updateSearchResultInfo = (hasSearchCondition: boolean, resultCount: number
|
||||
const getAvailableIndicators = (currentIndex: number) => {
|
||||
// 搜索功能:直接返回后端搜索结果,允许重复选择同一指标
|
||||
// 这样用户可以在不同位置选择相同的指标
|
||||
|
||||
|
||||
// 调试日志
|
||||
console.log('getAvailableIndicators调用:', {
|
||||
currentIndex,
|
||||
totalAvailable: availableIndicators.value.length,
|
||||
searchKeyword: searchParams.value.indicatorName,
|
||||
availableIndicatorIds: availableIndicators.value.map(i => i.id),
|
||||
availableIndicatorNames: availableIndicators.value.map(i => i.indicatorName),
|
||||
availableIndicatorIds: availableIndicators.value.map((i) => i.id),
|
||||
availableIndicatorNames: availableIndicators.value.map((i) => i.indicatorName),
|
||||
currentSelectedIndicatorId: indicatorList.value[currentIndex]?.indicatorId
|
||||
});
|
||||
|
||||
|
||||
return availableIndicators.value;
|
||||
};
|
||||
|
||||
// 指标选择变化
|
||||
const handleIndicatorChange = (item: BmzrAssessmentSchemeIndicatorForm, index: number) => {
|
||||
const selectedIndicator = availableIndicators.value.find(indicator => indicator.id == item.indicatorId);
|
||||
const selectedIndicator = availableIndicators.value.find((indicator) => indicator.id == item.indicatorId);
|
||||
if (selectedIndicator) {
|
||||
item.score = selectedIndicator.score;
|
||||
item.remark = selectedIndicator.remark;
|
||||
@@ -311,7 +291,7 @@ const handleSearchIndicators = async () => {
|
||||
proxy?.$modal.msgWarning('请输入搜索关键词');
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
try {
|
||||
await loadAvailableIndicators();
|
||||
proxy?.$modal.msgSuccess('搜索完成');
|
||||
@@ -337,7 +317,7 @@ const resetSearch = async () => {
|
||||
// 保存
|
||||
const handleSave = async () => {
|
||||
// 验证必填项
|
||||
const invalidItems = indicatorList.value.filter(item => !item.indicatorId);
|
||||
const invalidItems = indicatorList.value.filter((item) => !item.indicatorId);
|
||||
if (invalidItems.length > 0) {
|
||||
proxy?.$modal.msgError('请选择所有指标名称');
|
||||
return;
|
||||
@@ -469,10 +449,10 @@ defineExpose({
|
||||
align-items: flex-start;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
|
||||
.row-item {
|
||||
width: 100%;
|
||||
justify-content: space-between;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
@@ -112,14 +112,26 @@
|
||||
<el-tooltip content="修改" placement="top">
|
||||
<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['bzrkh:assessmentScheme:edit']"></el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip content="指标体系管理" placement="top">
|
||||
<el-button link type="success" icon="Management" @click="handleIndicatorManagement(scope.row)" v-hasPermi="['bzrkh:assessmentSchemeIndicator:list']"></el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip content="删除" placement="top">
|
||||
<el-button link type="danger" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['bzrkh:assessmentScheme:remove']"></el-button>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-tooltip content="指标体系管理" placement="top">
|
||||
<el-button
|
||||
link
|
||||
type="success"
|
||||
icon="Management"
|
||||
@click="handleIndicatorManagement(scope.row)"
|
||||
v-hasPermi="['bzrkh:assessmentSchemeIndicator:list']"
|
||||
></el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip content="删除" placement="top">
|
||||
<el-button
|
||||
link
|
||||
type="danger"
|
||||
icon="Delete"
|
||||
@click="handleDelete(scope.row)"
|
||||
v-hasPermi="['bzrkh:assessmentScheme:remove']"
|
||||
></el-button>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
<div class="pagination-container">
|
||||
@@ -222,9 +234,7 @@ import { BmzrAssessmentSchemeVO, BmzrAssessmentSchemeQuery, BmzrAssessmentScheme
|
||||
import IndicatorManagement from './IndicatorManagement.vue';
|
||||
|
||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||
const { sys_normal_disable, sys_yesno } = toRefs<any>(
|
||||
proxy?.useDict('sys_normal_disable', 'sys_yesno')
|
||||
);
|
||||
const { sys_normal_disable, sys_yesno } = toRefs<any>(proxy?.useDict('sys_normal_disable', 'sys_yesno'));
|
||||
|
||||
const schemeList = ref<BmzrAssessmentSchemeVO[]>([]);
|
||||
const buttonLoading = ref(false);
|
||||
@@ -385,8 +395,6 @@ const handleDelete = async (row?: BmzrAssessmentSchemeVO) => {
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
/** 指标体系管理按钮操作 */
|
||||
const handleIndicatorManagement = (row: BmzrAssessmentSchemeVO) => {
|
||||
indicatorManagementRef.value?.open(row.id);
|
||||
@@ -485,10 +493,6 @@ onMounted(() => {
|
||||
border-bottom: none !important;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* 表单样式 */
|
||||
.scheme-form {
|
||||
padding: 20px;
|
||||
@@ -513,4 +517,4 @@ onMounted(() => {
|
||||
justify-content: flex-end;
|
||||
gap: 12px;
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
@@ -2,13 +2,8 @@
|
||||
<div class="p-2 page-container">
|
||||
<!-- 班级标签页 -->
|
||||
<el-card shadow="never" class="tab-card" v-if="teacherClasses.length > 0">
|
||||
<el-tabs v-model="activeTab" @tab-click="handleTabClick">
|
||||
<el-tab-pane
|
||||
v-for="classItem in teacherClasses"
|
||||
:key="classItem.id"
|
||||
:label="classItem.className"
|
||||
:name="classItem.id?.toString()"
|
||||
>
|
||||
<el-tabs v-model="activeTab" @tab-change="handleTabChange" @tab-click="handleTabClick">
|
||||
<el-tab-pane v-for="classItem in teacherClasses" :key="classItem.id" :label="classItem.className" :name="classItem.id?.toString()">
|
||||
<!-- 搜索区域 -->
|
||||
<transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
|
||||
<div v-show="showSearch" class="mb-[10px]">
|
||||
@@ -41,8 +36,7 @@
|
||||
</template>
|
||||
|
||||
<div class="table-container">
|
||||
<el-table v-loading="loading" border :data="assessmentPlanList" @selection-change="handleSelectionChange" @sort-change="sortChange">
|
||||
<el-table-column type="selection" width="55" align="center" />
|
||||
<el-table v-loading="loading" border :data="assessmentPlanList" @sort-change="sortChange">
|
||||
<el-table-column label="计划名称" align="center" prop="planName" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="计划编码" align="center" prop="planCode" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="考核方案" align="center" prop="schemeName" :show-overflow-tooltip="true" />
|
||||
@@ -67,6 +61,7 @@
|
||||
<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 === '9'" type="primary" 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>
|
||||
@@ -80,46 +75,67 @@
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
|
||||
<template #default="scope">
|
||||
<!-- 未提交状态:显示提交考核按钮 -->
|
||||
<template v-if="!scope.row.submitted">
|
||||
<el-tooltip content="提交考核" placement="top">
|
||||
<el-button
|
||||
link
|
||||
type="primary"
|
||||
icon="Edit"
|
||||
<!-- 审核通过状态:只显示查看考核按钮 -->
|
||||
<template v-if="scope.row.auditStatus === '1'">
|
||||
<el-tooltip content="查看考核" placement="top">
|
||||
<el-button
|
||||
link
|
||||
type="success"
|
||||
icon="View"
|
||||
:disabled="loading || !isDataReady"
|
||||
@click="handleSubmitAssessment(scope.row)"
|
||||
@click="handleViewAssessment(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)"
|
||||
<!-- 未提交状态、草稿状态或审核不通过状态:显示提交考核按钮 -->
|
||||
<template v-if="!scope.row.submitted || scope.row.auditStatus === '9' || scope.row.auditStatus === '2'">
|
||||
<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-if="scope.row.auditStatus === '0'">
|
||||
<el-tooltip content="撤销提交" placement="top">
|
||||
<el-button
|
||||
link
|
||||
type="warning"
|
||||
icon="RefreshLeft"
|
||||
:disabled="loading || !isDataReady"
|
||||
@click="handleWithdrawAssessment(scope.row)"
|
||||
></el-button>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
<el-tooltip content="查看考核" placement="top">
|
||||
<el-button
|
||||
link
|
||||
type="success"
|
||||
icon="View"
|
||||
:disabled="loading || !isDataReady"
|
||||
@click="handleViewAssessment(scope.row)"
|
||||
></el-button>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
<el-tooltip content="查看考核" placement="top">
|
||||
<el-button
|
||||
link
|
||||
type="success"
|
||||
icon="View"
|
||||
:disabled="loading || !isDataReady"
|
||||
@click="handleViewAssessment(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" />
|
||||
<pagination
|
||||
v-show="total > 0"
|
||||
:total="total"
|
||||
v-model:page="queryParams.pageNum"
|
||||
v-model:limit="queryParams.pageSize"
|
||||
@pagination="getList"
|
||||
/>
|
||||
</div>
|
||||
</el-card>
|
||||
</el-tab-pane>
|
||||
@@ -132,12 +148,10 @@
|
||||
</el-card>
|
||||
|
||||
<!-- 考核提交弹窗 -->
|
||||
<SubmitDialog
|
||||
ref="submitDialogRef"
|
||||
:plan-id="currentPlanId"
|
||||
:class-id="currentClassId"
|
||||
@success="handleSubmitSuccess"
|
||||
/>
|
||||
<SubmitDialog ref="submitDialogRef" :plan-id="currentPlanId" :class-id="currentClassId" @success="handleSubmitSuccess" />
|
||||
|
||||
<!-- 考核查看弹窗 -->
|
||||
<ViewDialog ref="viewDialogRef" :plan-id="currentPlanId" :class-id="currentClassId" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -150,13 +164,10 @@ import {
|
||||
getAssessmentDetail,
|
||||
withdrawAssessment
|
||||
} from '@/api/bzrkh/teacherAssessment';
|
||||
import {
|
||||
TeacherClassVO,
|
||||
TeacherAssessmentPlanVO,
|
||||
TeacherAssessmentPlanQuery
|
||||
} from '@/api/bzrkh/teacherAssessment/types';
|
||||
import { TeacherClassVO, TeacherAssessmentPlanVO, TeacherAssessmentPlanQuery } from '@/api/bzrkh/teacherAssessment/types';
|
||||
import { useUserStore } from '@/store/modules/user';
|
||||
import SubmitDialog from './submitDialog.vue';
|
||||
import ViewDialog from './viewDialog.vue';
|
||||
|
||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||
const userStore = useUserStore();
|
||||
@@ -174,6 +185,9 @@ const currentPlanId = ref<string | number>();
|
||||
const currentClassId = ref<string | number>();
|
||||
const submitDialogRef = ref();
|
||||
|
||||
// 考核查看相关状态
|
||||
const viewDialogRef = ref();
|
||||
|
||||
const queryFormRef = ref<ElFormInstance>();
|
||||
|
||||
const data = reactive<PageData<any, TeacherAssessmentPlanQuery>>({
|
||||
@@ -182,7 +196,8 @@ const data = reactive<PageData<any, TeacherAssessmentPlanQuery>>({
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
planName: undefined,
|
||||
planStatus: '1' // 只查询启用状态的计划
|
||||
planStatus: '1', // 只查询启用状态的计划
|
||||
classId: undefined // 添加班级ID参数
|
||||
},
|
||||
rules: {}
|
||||
});
|
||||
@@ -203,10 +218,12 @@ const getTeacherClasses = async () => {
|
||||
classStatus: '1' // 只获取正常状态的班级
|
||||
});
|
||||
teacherClasses.value = res.data || [];
|
||||
|
||||
|
||||
if (teacherClasses.value.length > 0) {
|
||||
// 默认选中第一个班级
|
||||
activeTab.value = teacherClasses.value[0].id?.toString() || '';
|
||||
// 设置查询参数中的班级ID
|
||||
queryParams.value.classId = activeTab.value;
|
||||
// 等待activeTab设置完成后再获取列表
|
||||
await nextTick();
|
||||
await getList();
|
||||
@@ -223,7 +240,21 @@ const getTeacherClasses = async () => {
|
||||
const getList = async () => {
|
||||
loading.value = true;
|
||||
try {
|
||||
console.log('📋 查询参数:', {
|
||||
classId: queryParams.value.classId,
|
||||
teacherId: userStore.userId,
|
||||
planName: queryParams.value.planName,
|
||||
planStatus: queryParams.value.planStatus
|
||||
});
|
||||
|
||||
const res = await listTeacherAssessmentPlans(queryParams.value);
|
||||
console.log('📊 查询结果:', {
|
||||
total: res.total,
|
||||
dataCount: res.rows?.length,
|
||||
firstItemStatus: res.rows?.[0]?.auditStatus,
|
||||
firstItemSubmitted: res.rows?.[0]?.submitted
|
||||
});
|
||||
|
||||
assessmentPlanList.value = res.rows || [];
|
||||
total.value = res.total || 0;
|
||||
} catch (error) {
|
||||
@@ -233,12 +264,36 @@ const getList = async () => {
|
||||
}
|
||||
};
|
||||
|
||||
/** 标签页切换 */
|
||||
const handleTabClick = (tab: any) => {
|
||||
/** 标签页值变化事件 */
|
||||
const handleTabChange = async (tabName: string) => {
|
||||
console.log('🔄 标签页值变化:', {
|
||||
oldClassId: queryParams.value.classId,
|
||||
newTabName: tabName,
|
||||
activeTab: activeTab.value
|
||||
});
|
||||
|
||||
// 重置分页和设置班级ID
|
||||
queryParams.value.pageNum = 1;
|
||||
queryParams.value.classId = tabName;
|
||||
|
||||
console.log('🔄 参数设置完成:', {
|
||||
classId: queryParams.value.classId,
|
||||
activeTab: activeTab.value
|
||||
});
|
||||
|
||||
// 等待参数设置完成后再查询
|
||||
await nextTick();
|
||||
getList();
|
||||
};
|
||||
|
||||
/** 标签页点击事件 */
|
||||
const handleTabClick = (tab: any) => {
|
||||
console.log('🔄 标签页点击:', {
|
||||
tabName: tab.props.name,
|
||||
tabLabel: tab.props.label
|
||||
});
|
||||
};
|
||||
|
||||
/** 搜索按钮操作 */
|
||||
const handleQuery = () => {
|
||||
queryParams.value.pageNum = 1;
|
||||
@@ -251,10 +306,7 @@ const resetQuery = () => {
|
||||
handleQuery();
|
||||
};
|
||||
|
||||
/** 多选框选中数据 */
|
||||
const handleSelectionChange = (selection: TeacherAssessmentPlanVO[]) => {
|
||||
// 不再需要处理批量选择逻辑
|
||||
};
|
||||
|
||||
|
||||
/** 排序触发事件 */
|
||||
const sortChange = (column: any) => {
|
||||
@@ -280,15 +332,15 @@ const handleSubmitAssessment = async (row: TeacherAssessmentPlanVO) => {
|
||||
}
|
||||
|
||||
const plan = row;
|
||||
|
||||
|
||||
// 确保计划ID存在
|
||||
if (!plan.id) {
|
||||
proxy?.$modal.msgError('考核计划ID无效');
|
||||
return;
|
||||
}
|
||||
|
||||
const currentClass = teacherClasses.value.find(c => c.id?.toString() === activeTab.value);
|
||||
|
||||
|
||||
const currentClass = teacherClasses.value.find((c) => c.id?.toString() === activeTab.value);
|
||||
|
||||
if (!currentClass || !currentClass.id) {
|
||||
proxy?.$modal.msgError('获取班级信息失败,请刷新页面后重试');
|
||||
return;
|
||||
@@ -297,10 +349,10 @@ const handleSubmitAssessment = async (row: TeacherAssessmentPlanVO) => {
|
||||
// 设置当前考核的计划ID和班级ID
|
||||
currentPlanId.value = plan.id;
|
||||
currentClassId.value = currentClass.id;
|
||||
|
||||
|
||||
// 确保参数设置成功后再打开弹窗
|
||||
await nextTick();
|
||||
|
||||
|
||||
// 打开提交弹窗
|
||||
submitDialogRef.value?.open();
|
||||
};
|
||||
@@ -317,22 +369,29 @@ const handleViewAssessment = async (row: TeacherAssessmentPlanVO) => {
|
||||
proxy?.$modal.msgWarning('数据加载中,请稍后再试');
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// 确保计划ID存在
|
||||
if (!row.id) {
|
||||
proxy?.$modal.msgError('考核计划ID无效');
|
||||
return;
|
||||
}
|
||||
|
||||
const currentClass = teacherClasses.value.find(c => c.id?.toString() === activeTab.value);
|
||||
|
||||
|
||||
const currentClass = teacherClasses.value.find((c) => c.id?.toString() === activeTab.value);
|
||||
|
||||
if (!currentClass || !currentClass.id) {
|
||||
proxy?.$modal.msgError('获取班级信息失败,请刷新页面后重试');
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: 实现查看考核逻辑
|
||||
proxy?.$modal.msg('查看考核功能待实现');
|
||||
// 设置当前查看的计划ID和班级ID
|
||||
currentPlanId.value = row.id;
|
||||
currentClassId.value = currentClass.id;
|
||||
|
||||
// 确保参数设置成功后再打开弹窗
|
||||
await nextTick();
|
||||
|
||||
// 打开查看弹窗,传递审核状态用于判断显示模式
|
||||
viewDialogRef.value?.open(row.auditStatus);
|
||||
};
|
||||
|
||||
/** 撤销考核提交 */
|
||||
@@ -350,13 +409,13 @@ const handleWithdrawAssessment = async (row: TeacherAssessmentPlanVO) => {
|
||||
}
|
||||
|
||||
// 检查提交状态,只有待审核状态才能撤销
|
||||
if (row.auditStatus !== '0') {
|
||||
if (row.auditStatus !== '0') {
|
||||
proxy?.$modal.msgWarning('只有待审核状态的考核才能撤销');
|
||||
return;
|
||||
}
|
||||
|
||||
const currentClass = teacherClasses.value.find(c => c.id?.toString() === activeTab.value);
|
||||
|
||||
|
||||
const currentClass = teacherClasses.value.find((c) => c.id?.toString() === activeTab.value);
|
||||
|
||||
if (!currentClass || !currentClass.id) {
|
||||
proxy?.$modal.msgError('获取班级信息失败,请刷新页面后重试');
|
||||
return;
|
||||
@@ -365,14 +424,16 @@ const handleWithdrawAssessment = async (row: TeacherAssessmentPlanVO) => {
|
||||
try {
|
||||
// 确认撤销操作
|
||||
await proxy?.$modal.confirm('确定要撤销该考核提交吗?撤销后可以重新修改和提交。');
|
||||
|
||||
|
||||
// 调用撤销API
|
||||
await withdrawAssessment(row.id, currentClass.id);
|
||||
|
||||
proxy?.$modal.msgSuccess('撤销成功');
|
||||
|
||||
// 刷新列表
|
||||
|
||||
proxy?.$modal.msgSuccess('撤销成功!您的评分数据已保留,可以重新修改和提交。');
|
||||
|
||||
// 刷新列表,确保状态更新
|
||||
await getList();
|
||||
|
||||
console.log('撤销成功,列表已刷新');
|
||||
} catch (error) {
|
||||
if (error !== 'cancel') {
|
||||
console.error('撤销考核提交失败:', error);
|
||||
@@ -449,4 +510,4 @@ onMounted(() => {
|
||||
:deep(.el-tabs__item) {
|
||||
font-weight: 500;
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
@@ -1,12 +1,5 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
:title="dialogTitle"
|
||||
v-model="visible"
|
||||
width="1200px"
|
||||
:close-on-click-modal="false"
|
||||
append-to-body
|
||||
@close="handleClose"
|
||||
>
|
||||
<el-dialog :title="dialogTitle" v-model="visible" width="1200px" :close-on-click-modal="false" append-to-body @close="handleClose">
|
||||
<div v-loading="loading" class="submit-dialog-content">
|
||||
<!-- 1. 班级信息卡片 -->
|
||||
<el-card shadow="never" class="info-card">
|
||||
@@ -62,7 +55,9 @@
|
||||
</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-item label="人数系数">{{
|
||||
formatNumber(assessmentDetail?.coefficient?.studentCountCoefficient, 3)
|
||||
}}</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
</el-card>
|
||||
</el-col>
|
||||
@@ -75,7 +70,9 @@
|
||||
</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-item label="住校生系数">{{
|
||||
formatNumber(assessmentDetail?.coefficient?.boardingCoefficient, 3)
|
||||
}}</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
</el-card>
|
||||
</el-col>
|
||||
@@ -92,7 +89,7 @@
|
||||
<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 prop="description" label="指标描述" min-width="200" align="center" :show-overflow-tooltip="true" />
|
||||
<el-table-column prop="score" label="指标分值" width="100" align="center">
|
||||
<el-table-column prop="score" label="指标分值" width="80" align="center">
|
||||
<template #default="scope">
|
||||
<span>{{ scope.row.score || 0 }}</span>
|
||||
</template>
|
||||
@@ -108,6 +105,7 @@
|
||||
style="width: 100%"
|
||||
placeholder="请输入分数"
|
||||
size="small"
|
||||
class="score-input"
|
||||
/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
@@ -116,11 +114,12 @@
|
||||
<el-input
|
||||
v-model="scope.row.selfComment"
|
||||
type="textarea"
|
||||
:rows="2"
|
||||
:rows="1"
|
||||
placeholder="请输入自评意见"
|
||||
maxlength="200"
|
||||
show-word-limit
|
||||
size="small"
|
||||
class="comment-input"
|
||||
/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
@@ -154,7 +153,7 @@
|
||||
<el-input
|
||||
:value="managementEffectivenessForm.classDeductionHalf?.toFixed(2) || '0.00'"
|
||||
readonly
|
||||
style="width: 100%; text-align: center;"
|
||||
style="width: 100%; text-align: center"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
@@ -188,128 +187,96 @@
|
||||
<span>特色工作(加20分)</span>
|
||||
</div>
|
||||
</template>
|
||||
<el-form :model="specialWorkForm" label-width="240px" class="special-work-form">
|
||||
<el-form :model="specialWorkForm" class="special-work-form">
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="及时并妥善处理好学生违纪事件" class="no-wrap-label">
|
||||
<el-form-item label="及时并妥善处理好学生违纪事件" label-width="240px" class="no-wrap-label">
|
||||
<el-input-number
|
||||
v-model="specialWorkForm.score1"
|
||||
:min="0"
|
||||
:max="20"
|
||||
:precision="2"
|
||||
controls-position="right"
|
||||
style="width: 100%"
|
||||
style="width: 150px"
|
||||
placeholder="请输入分值"
|
||||
@change="calculateTotalSpecialScore"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="自评意见">
|
||||
<el-input
|
||||
v-model="specialWorkForm.comment1"
|
||||
type="textarea"
|
||||
:rows="2"
|
||||
placeholder="请输入自评意见"
|
||||
maxlength="200"
|
||||
show-word-limit
|
||||
/>
|
||||
<el-form-item label="自评意见" label-width="80px">
|
||||
<el-input v-model="specialWorkForm.comment1" type="textarea" :rows="1" placeholder="请输入自评意见" maxlength="200" show-word-limit class="special-comment-input" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="班级活动获奖情况">
|
||||
<el-form-item label="班级活动获奖情况" label-width="240px">
|
||||
<el-input-number
|
||||
v-model="specialWorkForm.score2"
|
||||
:min="0"
|
||||
:max="20"
|
||||
:precision="2"
|
||||
controls-position="right"
|
||||
style="width: 100%"
|
||||
style="width: 150px"
|
||||
placeholder="请输入分值"
|
||||
@change="calculateTotalSpecialScore"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="自评意见">
|
||||
<el-input
|
||||
v-model="specialWorkForm.comment2"
|
||||
type="textarea"
|
||||
:rows="2"
|
||||
placeholder="请输入自评意见"
|
||||
maxlength="200"
|
||||
show-word-limit
|
||||
/>
|
||||
<el-form-item label="自评意见" label-width="80px">
|
||||
<el-input v-model="specialWorkForm.comment2" type="textarea" :rows="1" placeholder="请输入自评意见" maxlength="200" show-word-limit class="special-comment-input" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="班级宣传工作有特色" class="no-wrap-label">
|
||||
<el-form-item label="班级宣传工作有特色" label-width="240px" class="no-wrap-label">
|
||||
<el-input-number
|
||||
v-model="specialWorkForm.score3"
|
||||
:min="0"
|
||||
:max="20"
|
||||
:precision="2"
|
||||
controls-position="right"
|
||||
style="width: 100%"
|
||||
style="width: 150px"
|
||||
placeholder="请输入分值"
|
||||
@change="calculateTotalSpecialScore"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="自评意见">
|
||||
<el-input
|
||||
v-model="specialWorkForm.comment3"
|
||||
type="textarea"
|
||||
:rows="2"
|
||||
placeholder="请输入自评意见"
|
||||
maxlength="200"
|
||||
show-word-limit
|
||||
/>
|
||||
<el-form-item label="自评意见" label-width="80px">
|
||||
<el-input v-model="specialWorkForm.comment3" type="textarea" :rows="1" placeholder="请输入自评意见" maxlength="200" show-word-limit class="special-comment-input" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="其他">
|
||||
<el-form-item label="其他" label-width="240px">
|
||||
<el-input-number
|
||||
v-model="specialWorkForm.score4"
|
||||
:min="0"
|
||||
:max="20"
|
||||
:precision="2"
|
||||
controls-position="right"
|
||||
style="width: 100%"
|
||||
style="width: 150px"
|
||||
placeholder="请输入分值"
|
||||
@change="calculateTotalSpecialScore"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="自评意见">
|
||||
<el-input
|
||||
v-model="specialWorkForm.comment4"
|
||||
type="textarea"
|
||||
:rows="2"
|
||||
placeholder="请输入自评意见"
|
||||
maxlength="200"
|
||||
show-word-limit
|
||||
/>
|
||||
<el-form-item label="自评意见" label-width="80px">
|
||||
<el-input v-model="specialWorkForm.comment4" type="textarea" :rows="1" placeholder="请输入自评意见" maxlength="200" show-word-limit class="special-comment-input" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="总分值">
|
||||
<el-input
|
||||
:value="specialWorkForm.totalScore?.toFixed(2) || '0.00'"
|
||||
readonly
|
||||
style="width: 100%; text-align: center;"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="总分值" label-width="240px">
|
||||
<el-input :value="specialWorkForm.totalScore?.toFixed(2) || '0.00'" readonly style="width: 150px; text-align: center" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
@@ -326,11 +293,7 @@
|
||||
<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-input :value="calculateMonthlyScore().toFixed(2)" readonly style="width: 100%; text-align: center" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
@@ -354,25 +317,106 @@
|
||||
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button :loading="submitLoading" type="primary" @click="handleSubmit">保存</el-button>
|
||||
<el-button :loading="saveLoading" type="primary" @click="handleSubmit">保存</el-button>
|
||||
<el-button :loading="submitLoading" type="success" @click="handleSubmitForApproval">提交</el-button>
|
||||
<el-button @click="handleClose">取消</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
<!-- 学生违纪记录和奖励记录弹窗 -->
|
||||
<el-dialog title="学生违规处分信息查看" v-model="studentRecordsVisible" width="1400px" :close-on-click-modal="false" append-to-body>
|
||||
<div v-loading="studentRecordsLoading" class="student-records-content">
|
||||
<!-- 班级信息 -->
|
||||
<el-card shadow="never" class="info-header">
|
||||
<div class="class-info">
|
||||
<h3>{{ studentRecordsData?.className || '班级信息' }}</h3>
|
||||
<div class="statistics">
|
||||
<el-tag type="danger" size="large">违纪记录: {{ studentRecordsData?.disciplineCount || 0 }}条</el-tag>
|
||||
<el-tag type="success" size="large" style="margin-left: 16px">奖励记录: {{ studentRecordsData?.rewardCount || 0 }}条</el-tag>
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
|
||||
<!-- Tab切换 -->
|
||||
<el-tabs type="border-card" style="margin-top: 16px">
|
||||
<!-- 违纪记录Tab -->
|
||||
<el-tab-pane label="违纪记录" name="discipline">
|
||||
<el-table :data="studentRecordsData?.disciplineRecords || []" border style="width: 100%" max-height="400" empty-text="暂无违纪记录">
|
||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||
<el-table-column prop="studentNo" label="学号" width="120" align="center" />
|
||||
<el-table-column prop="studentName" label="学生姓名" width="100" align="center" />
|
||||
<el-table-column prop="disciplineTypeName" label="违纪类型" width="120" align="center" />
|
||||
<el-table-column prop="disciplineDate" label="违纪日期" width="110" align="center">
|
||||
<template #default="scope">
|
||||
<span>{{ scope.row.disciplineDate?.split(' ')[0] || '-' }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="disciplineReason" label="违纪原因" min-width="200" :show-overflow-tooltip="true" />
|
||||
<el-table-column prop="disciplineContent" label="处分内容" min-width="200" :show-overflow-tooltip="true" />
|
||||
<el-table-column prop="scoreDeduction" label="扣分" width="80" align="center">
|
||||
<template #default="scope">
|
||||
<el-tag type="danger" size="small">{{ scope.row.scoreDeduction || 0 }}</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="status" label="状态" width="80" align="center">
|
||||
<template #default="scope">
|
||||
<el-tag :type="scope.row.status === '1' ? 'danger' : 'info'" size="small">
|
||||
{{ scope.row.status === '1' ? '生效' : '已撤销' }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-tab-pane>
|
||||
|
||||
<!-- 奖励记录Tab -->
|
||||
<el-tab-pane label="奖励记录" name="reward">
|
||||
<el-table :data="studentRecordsData?.rewardRecords || []" border style="width: 100%" max-height="400" empty-text="暂无奖励记录">
|
||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||
<el-table-column prop="studentNo" label="学号" width="120" align="center" />
|
||||
<el-table-column prop="studentName" label="学生姓名" width="100" align="center" />
|
||||
<el-table-column prop="rewardTypeName" label="奖励类型" width="120" align="center" />
|
||||
<el-table-column prop="rewardDate" label="奖励日期" width="110" align="center">
|
||||
<template #default="scope">
|
||||
<span>{{ scope.row.rewardDate || '-' }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="rewardContent" label="奖励内容" min-width="300" :show-overflow-tooltip="true" />
|
||||
<el-table-column prop="scoreAddition" label="加分" width="80" align="center">
|
||||
<template #default="scope">
|
||||
<el-tag type="success" size="small">{{ scope.row.scoreAddition || 0 }}</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="status" label="状态" width="80" align="center">
|
||||
<template #default="scope">
|
||||
<el-tag :type="scope.row.status === '1' ? 'success' : 'info'" size="small">
|
||||
{{ scope.row.status === '1' ? '生效' : '撤销' }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</div>
|
||||
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button @click="studentRecordsVisible = false">关闭</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup name="SubmitDialog" lang="ts">
|
||||
import {
|
||||
getAssessmentSubmitDetail,
|
||||
submitAssessmentScore,
|
||||
submitAssessment
|
||||
} from '@/api/bzrkh/teacherAssessment';
|
||||
import { getAssessmentSubmitDetail, submitAssessmentScore, submitAssessment, getClassStudentRecords } from '@/api/bzrkh/teacherAssessment';
|
||||
import {
|
||||
AssessmentDetailVO,
|
||||
AssessmentIndicatorVO,
|
||||
SpecialWorkIndicatorVO,
|
||||
AssessmentSubmitVO
|
||||
AssessmentSubmitVO,
|
||||
ClassStudentRecordsVO,
|
||||
StudentDisciplineRecordVO,
|
||||
StudentRewardRecordVO
|
||||
} from '@/api/bzrkh/teacherAssessment/types';
|
||||
|
||||
interface Props {
|
||||
@@ -387,6 +431,7 @@ const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||
|
||||
const visible = ref(false);
|
||||
const loading = ref(false);
|
||||
const saveLoading = ref(false);
|
||||
const submitLoading = ref(false);
|
||||
|
||||
const assessmentDetail = ref<AssessmentDetailVO>();
|
||||
@@ -417,6 +462,11 @@ const monthlyScoreForm = reactive({
|
||||
overallComment: ''
|
||||
});
|
||||
|
||||
// 学生违纪记录和奖励记录弹窗相关
|
||||
const studentRecordsVisible = ref(false);
|
||||
const studentRecordsLoading = ref(false);
|
||||
const studentRecordsData = ref<ClassStudentRecordsVO>();
|
||||
|
||||
const dialogTitle = computed(() => {
|
||||
const className = assessmentDetail.value?.classDetail?.className || '';
|
||||
return `${className} - 班主任考核提交`;
|
||||
@@ -439,13 +489,13 @@ 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);
|
||||
};
|
||||
|
||||
@@ -456,26 +506,24 @@ const calculateDeductionHalf = () => {
|
||||
|
||||
/** 计算特色工作总分 */
|
||||
const calculateTotalSpecialScore = () => {
|
||||
specialWorkForm.totalScore = (specialWorkForm.score1 || 0) +
|
||||
(specialWorkForm.score2 || 0) +
|
||||
(specialWorkForm.score3 || 0) +
|
||||
(specialWorkForm.score4 || 0);
|
||||
specialWorkForm.totalScore =
|
||||
(specialWorkForm.score1 || 0) + (specialWorkForm.score2 || 0) + (specialWorkForm.score3 || 0) + (specialWorkForm.score4 || 0);
|
||||
};
|
||||
|
||||
/** 计算月考核得分 */
|
||||
const calculateMonthlyScore = () => {
|
||||
// 总系数(K)
|
||||
const totalCoefficient = assessmentDetail.value?.coefficient?.totalCoefficient || 0;
|
||||
|
||||
|
||||
// 班主任常规工作自评分之和
|
||||
const routineWorkTotal = routineWorkScores.value.reduce((sum, item) => sum + (item.selfScore || 0), 0);
|
||||
|
||||
|
||||
// 按班级扣分50%计的分值
|
||||
const deductionHalf = managementEffectivenessForm.classDeductionHalf || 0;
|
||||
|
||||
|
||||
// 特色工作总分值
|
||||
const specialWorkTotal = specialWorkForm.totalScore || 0;
|
||||
|
||||
|
||||
// 月考核得分 = 总系数(K)* (班主任常规工作自评分之和 - 按班级扣分50%计的分值 + 特色工作总分值)
|
||||
return totalCoefficient * (routineWorkTotal - deductionHalf + specialWorkTotal);
|
||||
};
|
||||
@@ -486,7 +534,29 @@ const open = async () => {
|
||||
proxy?.$modal.msgError('参数错误:缺少计划ID或班级ID');
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// 先重置所有表单数据,确保干净的状态
|
||||
routineWorkScores.value = [];
|
||||
Object.assign(managementEffectivenessForm, {
|
||||
classDeduction: 0,
|
||||
classDeductionHalf: 0,
|
||||
selfComment: ''
|
||||
});
|
||||
Object.assign(specialWorkForm, {
|
||||
score1: 0,
|
||||
comment1: '',
|
||||
score2: 0,
|
||||
comment2: '',
|
||||
score3: 0,
|
||||
comment3: '',
|
||||
score4: 0,
|
||||
comment4: '',
|
||||
totalScore: 0
|
||||
});
|
||||
Object.assign(monthlyScoreForm, {
|
||||
overallComment: ''
|
||||
});
|
||||
|
||||
visible.value = true;
|
||||
await loadAssessmentDetail();
|
||||
};
|
||||
@@ -497,24 +567,27 @@ const loadAssessmentDetail = async () => {
|
||||
try {
|
||||
const res = await getAssessmentSubmitDetail(props.planId!, props.classId!);
|
||||
assessmentDetail.value = res.data;
|
||||
|
||||
|
||||
// 初始化班主任常规工作数据
|
||||
routineWorkScores.value = (assessmentDetail.value?.routineWorkIndicators || []).map(item => ({
|
||||
routineWorkScores.value = (assessmentDetail.value?.routineWorkIndicators || []).map((item) => ({
|
||||
...item,
|
||||
selfScore: item.selfScore || 0,
|
||||
selfComment: item.selfComment || ''
|
||||
}));
|
||||
|
||||
|
||||
// 初始化班级管理实效数据
|
||||
if (assessmentDetail.value?.classDeductionIndicator) {
|
||||
managementEffectivenessForm.classDeduction = assessmentDetail.value.classDeductionIndicator.selfScore || 0;
|
||||
managementEffectivenessForm.selfComment = assessmentDetail.value.classDeductionIndicator.selfComment || '';
|
||||
calculateDeductionHalf();
|
||||
}
|
||||
|
||||
|
||||
// 初始化特色工作数据
|
||||
const specialWorkIndicators = assessmentDetail.value?.specialWorkIndicators || [];
|
||||
specialWorkIndicators.forEach(item => {
|
||||
console.log('特色工作指标数据:', specialWorkIndicators);
|
||||
|
||||
specialWorkIndicators.forEach((item) => {
|
||||
console.log(`处理特色工作指标: ${item.indicatorCode}, 分数: ${item.score}, 评论: ${item.selfComment}`);
|
||||
switch (item.indicatorCode) {
|
||||
case 'bzrtsgz001':
|
||||
specialWorkForm.score1 = Number(item.score) || 0;
|
||||
@@ -536,46 +609,87 @@ const loadAssessmentDetail = async () => {
|
||||
});
|
||||
// 确保特色工作总分重新计算
|
||||
calculateTotalSpecialScore();
|
||||
|
||||
|
||||
// 初始化月考核得分数据
|
||||
monthlyScoreForm.overallComment = assessmentDetail.value?.overallComment || '';
|
||||
|
||||
// 调试信息:验证数据是否正确加载
|
||||
console.log('数据回显完成:', {
|
||||
totalSpecialScore: specialWorkForm.totalScore,
|
||||
|
||||
// 详细的调试信息:验证数据是否正确加载
|
||||
console.log('=== 数据回显完成 ===');
|
||||
console.log(
|
||||
'班主任常规工作数据:',
|
||||
routineWorkScores.value.map((item) => ({
|
||||
name: item.indicatorName,
|
||||
selfScore: item.selfScore,
|
||||
selfComment: item.selfComment
|
||||
}))
|
||||
);
|
||||
console.log('班级管理实效数据:', {
|
||||
classDeduction: managementEffectivenessForm.classDeduction,
|
||||
selfComment: managementEffectivenessForm.selfComment
|
||||
});
|
||||
console.log('特色工作数据:', {
|
||||
score1: specialWorkForm.score1,
|
||||
comment1: specialWorkForm.comment1,
|
||||
score2: specialWorkForm.score2,
|
||||
comment2: specialWorkForm.comment2,
|
||||
score3: specialWorkForm.score3,
|
||||
comment3: specialWorkForm.comment3,
|
||||
score4: specialWorkForm.score4,
|
||||
comment4: specialWorkForm.comment4,
|
||||
totalScore: specialWorkForm.totalScore
|
||||
});
|
||||
console.log('月考核数据:', {
|
||||
monthlyScore: calculateMonthlyScore(),
|
||||
overallComment: monthlyScoreForm.overallComment
|
||||
});
|
||||
|
||||
console.log('==================');
|
||||
} catch (error) {
|
||||
console.error('加载考核详情失败:', error);
|
||||
proxy?.$modal.msgError('加载考核详情失败');
|
||||
proxy?.$modal.msgError('加载考核详情失败,请检查网络连接或刷新页面重试');
|
||||
|
||||
// 加载失败时关闭对话框
|
||||
visible.value = false;
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
/** 查看学生违规处分信息 */
|
||||
const handleViewStudentViolations = () => {
|
||||
proxy?.$modal.msg('学生违规处分信息查看功能暂未实现');
|
||||
const handleViewStudentViolations = async () => {
|
||||
if (!props.classId) {
|
||||
proxy?.$modal.msgError('缺少班级ID参数');
|
||||
return;
|
||||
}
|
||||
|
||||
studentRecordsLoading.value = true;
|
||||
try {
|
||||
const res = await getClassStudentRecords(props.classId);
|
||||
studentRecordsData.value = res.data;
|
||||
studentRecordsVisible.value = true;
|
||||
} catch (error) {
|
||||
console.error('查询学生违纪记录和奖励记录失败:', error);
|
||||
proxy?.$modal.msgError('查询学生违纪记录和奖励记录失败');
|
||||
} finally {
|
||||
studentRecordsLoading.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
/** 保存考核数据 */
|
||||
const handleSubmit = async () => {
|
||||
try {
|
||||
// 验证必填项
|
||||
if (routineWorkScores.value.some(item => item.selfScore === undefined || item.selfScore === null)) {
|
||||
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;
|
||||
saveLoading.value = true;
|
||||
|
||||
// 构造提交数据
|
||||
const submitData: AssessmentSubmitVO = {
|
||||
@@ -613,15 +727,26 @@ const handleSubmit = async () => {
|
||||
overallComment: monthlyScoreForm.overallComment // 自我总体评价 - 将存储到数据库 self_overall_comment 字段
|
||||
};
|
||||
|
||||
console.log('提交数据:', submitData);
|
||||
await submitAssessmentScore(submitData);
|
||||
proxy?.$modal.msgSuccess('考核保存成功');
|
||||
emit('success');
|
||||
|
||||
proxy?.$modal.msgSuccess('考核数据已保存为草稿,可继续编辑或点击提交按钮进入审批流程');
|
||||
} catch (error) {
|
||||
console.error('保存考核失败:', error);
|
||||
proxy?.$modal.msgError('保存考核失败');
|
||||
// 显示详细的错误信息
|
||||
let errorMessage = '保存考核失败';
|
||||
if (error && typeof error === 'object' && 'response' in error) {
|
||||
const httpError = error as any;
|
||||
if (httpError.response?.data?.msg) {
|
||||
errorMessage = httpError.response.data.msg;
|
||||
}
|
||||
} else if (error && typeof error === 'object' && 'message' in error) {
|
||||
errorMessage = (error as Error).message;
|
||||
} else if (typeof error === 'string') {
|
||||
errorMessage = error;
|
||||
}
|
||||
proxy?.$modal.msgError(errorMessage);
|
||||
} finally {
|
||||
submitLoading.value = false;
|
||||
saveLoading.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -629,11 +754,11 @@ const handleSubmit = async () => {
|
||||
const handleSubmitForApproval = async () => {
|
||||
try {
|
||||
// 验证必填项
|
||||
if (routineWorkScores.value.some(item => item.selfScore === undefined || item.selfScore === null)) {
|
||||
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');
|
||||
@@ -680,17 +805,28 @@ const handleSubmitForApproval = async () => {
|
||||
|
||||
// 第一步:保存考核评分数据
|
||||
await submitAssessmentScore(submitData);
|
||||
|
||||
|
||||
// 第二步:提交到审批流程
|
||||
await submitAssessment(props.planId, props.classId);
|
||||
|
||||
|
||||
proxy?.$modal.msgSuccess('考核提交成功,已进入审批流程');
|
||||
emit('success');
|
||||
handleClose();
|
||||
|
||||
} catch (error) {
|
||||
console.error('提交审批失败:', error);
|
||||
proxy?.$modal.msgError('提交审批失败');
|
||||
// 显示详细的错误信息
|
||||
let errorMessage = '提交审批失败';
|
||||
if (error && typeof error === 'object' && 'response' in error) {
|
||||
const httpError = error as any;
|
||||
if (httpError.response?.data?.msg) {
|
||||
errorMessage = httpError.response.data.msg;
|
||||
}
|
||||
} else if (error && typeof error === 'object' && 'message' in error) {
|
||||
errorMessage = (error as Error).message;
|
||||
} else if (typeof error === 'string') {
|
||||
errorMessage = error;
|
||||
}
|
||||
proxy?.$modal.msgError(errorMessage);
|
||||
} finally {
|
||||
submitLoading.value = false;
|
||||
}
|
||||
@@ -699,7 +835,7 @@ const handleSubmitForApproval = async () => {
|
||||
/** 关闭弹窗 */
|
||||
const handleClose = () => {
|
||||
visible.value = false;
|
||||
|
||||
|
||||
// 重置表单数据
|
||||
routineWorkScores.value = [];
|
||||
Object.assign(managementEffectivenessForm, {
|
||||
@@ -766,26 +902,48 @@ defineExpose({
|
||||
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;
|
||||
}
|
||||
|
||||
/* 自评分数输入框字体调整 - 参考特色工作输入框字体 */
|
||||
.score-input .el-input-number__input {
|
||||
font-size: 14px !important;
|
||||
font-weight: 400;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/* 覆盖small尺寸的字体大小,与特色工作输入框保持一致 */
|
||||
.el-input-number--small.score-input .el-input-number__input {
|
||||
font-size: 14px !important;
|
||||
}
|
||||
|
||||
/* 自评意见输入框高度调整 - 参考班级总人数高度 */
|
||||
.comment-input .el-textarea__inner {
|
||||
resize: none;
|
||||
min-height: 32px !important;
|
||||
height: 32px !important;
|
||||
line-height: 32px;
|
||||
padding: 0 8px;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.el-textarea__inner {
|
||||
resize: none;
|
||||
min-height: 60px !important;
|
||||
}
|
||||
|
||||
|
||||
/* 响应式调整 */
|
||||
@media (max-width: 1400px) {
|
||||
.el-table__cell {
|
||||
@@ -802,10 +960,19 @@ defineExpose({
|
||||
text-overflow: ellipsis;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
|
||||
.el-form-item__label {
|
||||
font-weight: 500;
|
||||
text-align: center;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
/* 特色工作自评意见高度调整 - 参考班级总人数高度 */
|
||||
.special-comment-input .el-textarea__inner {
|
||||
resize: none;
|
||||
min-height: 32px !important;
|
||||
height: 32px !important;
|
||||
line-height: 32px;
|
||||
padding: 0 8px;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -836,7 +1003,7 @@ defineExpose({
|
||||
text-align: center;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
|
||||
.el-descriptions__content {
|
||||
text-align: center;
|
||||
}
|
||||
@@ -852,9 +1019,53 @@ defineExpose({
|
||||
.submit-dialog-content {
|
||||
padding: 0 10px;
|
||||
}
|
||||
|
||||
|
||||
.info-card {
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
/* 学生记录弹窗样式 */
|
||||
.student-records-content {
|
||||
max-height: 70vh;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.info-header {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.class-info {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
|
||||
h3 {
|
||||
margin: 0;
|
||||
color: #303133;
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.statistics {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
|
||||
/* Tab样式优化 */
|
||||
:deep(.el-tabs--border-card) {
|
||||
border: 1px solid #dcdfe6;
|
||||
border-radius: 4px;
|
||||
|
||||
.el-tabs__header {
|
||||
background-color: #f5f7fa;
|
||||
border-bottom: 1px solid #dcdfe6;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.el-tabs__content {
|
||||
padding: 16px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
File diff suppressed because it is too large.
Load diff
Reference in new issue
Block a user