Files
hzdyjs/web/src/views/xskh/assessmentApplication/IndicatorDataDialog.vue
T
2025-09-09 16:07:28 +08:00

271 lines
8.7 KiB
Vue

<template>
<el-dialog :title="`${indicatorName} - 学生数据详情`" v-model="dialogVisible" width="1000px" append-to-body destroy-on-close>
<div v-loading="loading" element-loading-text="正在加载数据...">
<!-- 违纪处分记录区域 - 只有数据时才显示 -->
<el-card class="mb-4" shadow="never" v-if="disciplineRecords.length > 0">
<template #header>
<div class="card-header">
<span>违纪处分记录</span>
<el-tag type="danger" size="small">{{ disciplineRecords.length }} 条记录</el-tag>
</div>
</template>
<el-table :data="disciplineRecords" border style="width: 100%">
<el-table-column label="违纪日期" prop="disciplineDate" width="120">
<template #default="scope">
{{ formatDate(scope.row.disciplineDate) }}
</template>
</el-table-column>
<el-table-column label="违纪类型" prop="disciplineTypeName" width="120" />
<el-table-column label="违纪原因" prop="disciplineReason" min-width="200" show-overflow-tooltip />
<el-table-column label="违纪内容" prop="disciplineContent" min-width="200" show-overflow-tooltip />
<el-table-column label="扣分分值" prop="scoreDeduction" width="100">
<template #default="scope">
<el-tag type="danger" size="small">-{{ scope.row.scoreDeduction || 0 }}</el-tag>
</template>
</el-table-column>
</el-table>
</el-card>
<!-- 奖励记录区域 - 只有数据时才显示 -->
<el-card shadow="never" v-if="rewardRecords.length > 0">
<template #header>
<div class="card-header">
<span>奖励记录</span>
<el-tag type="success" size="small">{{ rewardRecords.length }} 条记录</el-tag>
</div>
</template>
<el-table :data="rewardRecords" border style="width: 100%">
<el-table-column label="奖励日期" prop="rewardDate" width="120">
<template #default="scope">
{{ formatDate(scope.row.rewardDate) }}
</template>
</el-table-column>
<el-table-column label="奖励类型" prop="rewardTypeName" width="120" />
<el-table-column label="奖励内容" prop="rewardContent" min-width="200" show-overflow-tooltip />
<el-table-column label="加分分值" prop="scoreAddition" width="100">
<template #default="scope">
<el-tag type="success" size="small">+{{ scope.row.scoreAddition || 0 }}</el-tag>
</template>
</el-table-column>
</el-table>
</el-card>
<!-- 当没有任何数据时显示 -->
<el-empty v-if="disciplineRecords.length === 0 && rewardRecords.length === 0 && !loading" description="暂无相关数据记录" />
</div>
</el-dialog>
</template>
<script setup name="IndicatorDataDialog" lang="ts">
import { ref, reactive, toRefs, watch } from 'vue';
import ElMessage from 'element-plus/es/components/message/index';
import request from '@/utils/request';
// 类型定义
interface DisciplineRecord {
id: string | number;
disciplineDate: string;
disciplineTypeName: string;
disciplineReason: string;
disciplineContent: string;
scoreDeduction: number;
}
interface RewardRecord {
id: string | number;
rewardDate: string;
rewardTypeName: string;
rewardContent: string;
scoreAddition: number;
}
interface IndicatorDataDialogProps {
indicatorId: string | number;
indicatorName: string;
studentId: string | number;
scheduleId: string | number;
dataStartTime: string; // 数据统计开始时间
dataEndTime: string; // 数据统计结束时间
}
const props = defineProps<IndicatorDataDialogProps>();
const dialogVisible = ref(false);
const loading = ref(false);
const data = reactive({
disciplineRecords: [] as DisciplineRecord[],
rewardRecords: [] as RewardRecord[]
});
const { disciplineRecords, rewardRecords } = toRefs(data);
// 监听props变化,当indicatorId变化时重新加载数据
watch(
() => props.indicatorId,
(newIndicatorId, oldIndicatorId) => {
// 只有当弹窗可见且indicatorId真正发生变化时才重新加载
if (dialogVisible.value && newIndicatorId !== oldIndicatorId && newIndicatorId) {
console.log('indicatorId变化,重新加载数据:', { old: oldIndicatorId, new: newIndicatorId });
loadData();
}
},
{ immediate: false }
);
// 格式化日期
const formatDate = (dateStr: string) => {
if (!dateStr) return '-';
return new Date(dateStr).toLocaleDateString('zh-CN');
};
// 打开弹窗
const openDialog = async () => {
dialogVisible.value = true;
// 强制刷新数据,确保使用最新的props值
await forceRefreshData();
};
// 强制刷新数据
const forceRefreshData = async () => {
// 清空之前的数据
data.disciplineRecords = [];
data.rewardRecords = [];
// 确保使用最新的props值
await loadData();
};
// 加载数据
const loadData = async () => {
// 如果弹窗未显示或没有indicatorId,则不加载数据
if (!dialogVisible.value || !props.indicatorId) {
console.log('弹窗未显示或无indicatorId,跳过数据加载');
return;
}
loading.value = true;
try {
console.log('开始加载指标数据,indicatorId:', props.indicatorId);
// 获取指标关联的违纪处分类型和奖励类型
const indicatorTypesResponse = await request({
url: `/disciplineRecord/disciplineRecord/getIndicatorTypes/${props.indicatorId}`,
method: 'get'
});
if (indicatorTypesResponse.code === 200 && indicatorTypesResponse.data) {
// 修复字段名映射:后端返回下划线格式,前端使用驼峰格式
const disciplineTypeIds = indicatorTypesResponse.data.discipline_type_ids || indicatorTypesResponse.data.disciplineTypeIds;
const rewardTypeIds = indicatorTypesResponse.data.reward_type_ids || indicatorTypesResponse.data.rewardTypeIds;
// 并行加载违纪处分记录和奖励记录
await Promise.all([loadDisciplineRecords(disciplineTypeIds), loadRewardRecords(rewardTypeIds)]);
} else {
ElMessage.warning('获取指标类型信息失败');
}
} catch (error) {
console.error('加载数据失败:', error);
ElMessage.error('加载数据失败,请稍后重试');
} finally {
loading.value = false;
}
};
// 加载违纪处分记录
const loadDisciplineRecords = async (disciplineTypeIds: string) => {
if (!disciplineTypeIds) {
data.disciplineRecords = [];
return;
}
console.log('加载违纪处分记录,props:', props);
console.log('加载违纪处分记录,disciplineTypeIds:', disciplineTypeIds);
console.log('加载违纪处分记录,dataStartTime:', props.dataStartTime);
console.log('加载违纪处分记录,dataEndTime:', props.dataEndTime);
console.log('加载违纪处分记录,studentId:', props.studentId);
try {
const response = await request({
url: '/disciplineRecord/disciplineRecord/getStudentDisciplineRecords',
method: 'get',
params: {
studentId: props.studentId,
disciplineTypeIds: disciplineTypeIds,
startTime: props.dataStartTime,
endTime: props.dataEndTime,
status: 1 // 只查询状态为1的记录
}
});
if (response.code === 200) {
data.disciplineRecords = response.data || [];
} else {
ElMessage.warning('获取违纪处分记录失败');
data.disciplineRecords = [];
}
} catch (error) {
console.error('获取违纪处分记录失败:', error);
data.disciplineRecords = [];
}
};
// 加载奖励记录
const loadRewardRecords = async (rewardTypeIds: string) => {
if (!rewardTypeIds) {
data.rewardRecords = [];
return;
}
try {
const response = await request({
url: '/rewardRecord/rewardRecord/getStudentRewardRecords',
method: 'get',
params: {
studentId: props.studentId,
rewardTypeIds: rewardTypeIds,
startTime: props.dataStartTime,
endTime: props.dataEndTime,
status: 1 // 只查询状态为1的记录
}
});
if (response.code === 200) {
data.rewardRecords = response.data || [];
} else {
ElMessage.warning('获取奖励记录失败');
data.rewardRecords = [];
}
} catch (error) {
console.error('获取奖励记录失败:', error);
data.rewardRecords = [];
}
};
// 关闭弹窗
const closeDialog = () => {
dialogVisible.value = false;
// 清空数据
data.disciplineRecords = [];
data.rewardRecords = [];
};
defineExpose({
openDialog,
closeDialog,
forceRefreshData
});
</script>
<style scoped>
.card-header {
display: flex;
justify-content: space-between;
align-items: center;
}
.mb-4 {
margin-bottom: 16px;
}
</style>