Merge branch 'master' of http://47.99.164.66:3000/hzdyjs-xg/all-project
This commit is contained in:
commit
bb2a04ffb9
31 files changed
+3135
-74
No files matched your search
@@ -134,6 +134,7 @@
|
||||
<el-table-column label="申请类型" align="center" prop="applicationType" min-width="100">
|
||||
<template #default="scope">
|
||||
<el-tag v-if="scope.row.applicationType === 'RECOMMEND'" type="primary">教师推荐</el-tag>
|
||||
<el-tag v-else-if="scope.row.applicationType === 'TEACHER_RECOMMEND'" type="primary">教师推荐</el-tag>
|
||||
<el-tag v-else-if="scope.row.applicationType === 'STUDENT'" type="success">学生申请</el-tag>
|
||||
<el-tag v-else-if="scope.row.applicationType === 'AUTO'" type="info">自动评定</el-tag>
|
||||
<el-tag v-else-if="scope.row.applicationType === 'DIRECT'" type="warning">直接指定</el-tag>
|
||||
@@ -311,7 +312,7 @@
|
||||
<div class="flex-1">
|
||||
<div class="student-basic-info flex items-center space-x-4 mb-2">
|
||||
<span class="font-bold">{{ student.studentName }}</span>
|
||||
<span class="text-gray-600">{{ student.studentNo }}</span>
|
||||
<span class="text-gray-600">{{ student.studentCode }}</span>
|
||||
<span class="text-gray-500">{{ student.gender }}</span>
|
||||
<span class="text-gray-500">{{ student.phone }}</span>
|
||||
</div>
|
||||
@@ -963,7 +964,7 @@ const filterStudents = () => {
|
||||
filteredStudents.value = classStudents.value;
|
||||
} else {
|
||||
filteredStudents.value = classStudents.value.filter(
|
||||
(student: any) => student.studentName?.includes(studentKeyword.value) || student.studentNo?.includes(studentKeyword.value)
|
||||
(student: any) => student.studentName?.includes(studentKeyword.value) || student.studentCode?.includes(studentKeyword.value)
|
||||
);
|
||||
}
|
||||
};
|
||||
@@ -989,7 +990,8 @@ const toggleStudentSelection = (student: any, checked: boolean) => {
|
||||
if (availableScholarshipTypes.value.length === 1) {
|
||||
const scholarshipType = availableScholarshipTypes.value[0];
|
||||
if (canSelectScholarshipType(student, scholarshipType)) {
|
||||
student.selectedScholarshipType = scholarshipType;
|
||||
// ✅ 创建对象副本,避免引用问题
|
||||
student.selectedScholarshipType = { ...scholarshipType };
|
||||
updateScholarshipInfo(student);
|
||||
console.log('🎯 自动选择唯一可用的奖学金类型:', scholarshipType.name);
|
||||
} else {
|
||||
@@ -1042,12 +1044,25 @@ const clearSelectedStudents = () => {
|
||||
|
||||
/** 更新奖学金信息 */
|
||||
const updateScholarshipInfo = (student: any) => {
|
||||
console.log('🔄 更新奖学金信息:', { studentName: student.studentName, selectedType: student.selectedScholarshipType?.name });
|
||||
console.log('🔄 更新奖学金信息:', {
|
||||
studentName: student.studentName,
|
||||
selectedType: student.selectedScholarshipType?.name,
|
||||
originalType: student.selectedScholarshipType
|
||||
});
|
||||
|
||||
if (student.selectedScholarshipType) {
|
||||
// ✅ 立即创建对象副本,确保 v-model 绑定的是副本而不是原始引用
|
||||
student.selectedScholarshipType = { ...student.selectedScholarshipType };
|
||||
|
||||
// 使用副本更新相关字段
|
||||
student.selectedLevel = student.selectedScholarshipType.levelType;
|
||||
student.selectedAmount = student.selectedScholarshipType.amount;
|
||||
|
||||
console.log('✅ 创建奖学金类型副本:', {
|
||||
copy: student.selectedScholarshipType,
|
||||
name: student.selectedScholarshipType.name
|
||||
});
|
||||
|
||||
// 检查名额是否足够
|
||||
if (!canSelectScholarshipType(student, student.selectedScholarshipType)) {
|
||||
ElMessage.warning(`${student.selectedScholarshipType.name} 名额不足,请选择其他类型`);
|
||||
@@ -1120,7 +1135,7 @@ const submitBatchApplication = async () => {
|
||||
const studentApplications = selectedStudents.value.map((s: any) => ({
|
||||
studentId: String(s.studentId || s.id),
|
||||
studentName: s.studentName,
|
||||
studentNo: s.studentNo,
|
||||
studentNo: s.studentCode, // ✅ 修复:使用后端返回的 studentCode 字段作为学号
|
||||
scholarshipTypeId: s.selectedScholarshipType.id,
|
||||
deptId: classInfo.value.deptId,
|
||||
applicationReason: `班主任批量申请 - ${s.selectedScholarshipType.name}`,
|
||||
|
||||
@@ -114,6 +114,7 @@
|
||||
<el-form-item label="申请类型" prop="applicationType">
|
||||
<el-select v-model="queryParams.applicationType" placeholder="请选择申请类型" clearable style="width: 100%">
|
||||
<el-option label="教师推荐" value="RECOMMEND" />
|
||||
<el-option label="教师推荐" value="TEACHER_RECOMMEND" />
|
||||
<el-option label="学生申请" value="STUDENT" />
|
||||
<el-option label="自动评定" value="AUTO" />
|
||||
<el-option label="直接指定" value="DIRECT" />
|
||||
@@ -194,6 +195,7 @@
|
||||
<template #default="scope">
|
||||
<el-tag v-if="scope.row.applicationType === 'RECOMMEND'" type="primary">教师推荐</el-tag>
|
||||
<el-tag v-else-if="scope.row.applicationType === 'STUDENT'" type="success">学生申请</el-tag>
|
||||
<el-tag v-else-if="scope.row.applicationType === 'TEACHER_RECOMMEND'" type="primary">教师推荐</el-tag>
|
||||
<el-tag v-else-if="scope.row.applicationType === 'AUTO'" type="info">自动评定</el-tag>
|
||||
<el-tag v-else-if="scope.row.applicationType === 'DIRECT'" type="warning">直接指定</el-tag>
|
||||
<el-tag v-else type="info">{{ scope.row.applicationType }}</el-tag>
|
||||
@@ -684,14 +686,25 @@ function handleReview(row) {
|
||||
console.log('🔍 [DEBUG] handleReview 开始执行');
|
||||
console.log('🔍 [DEBUG] 传入的row数据:', JSON.stringify(row, null, 2));
|
||||
|
||||
reviewForm.value = {
|
||||
id: row.id,
|
||||
status: 'APPROVED',
|
||||
reviewComment: ''
|
||||
};
|
||||
// 先获取完整的申请数据
|
||||
getScholarshipApplication(row.id)
|
||||
.then((response) => {
|
||||
console.log('🔍 [DEBUG] 获取到完整申请数据:', response.data);
|
||||
|
||||
console.log('🔍 [DEBUG] 设置的reviewForm:', JSON.stringify(reviewForm.value, null, 2));
|
||||
reviewOpen.value = true;
|
||||
// 设置完整的审核表单数据
|
||||
reviewForm.value = {
|
||||
...response.data, // 包含所有申请信息
|
||||
status: 'APPROVED', // 默认审核状态
|
||||
reviewComment: '' // 审核意见
|
||||
};
|
||||
|
||||
console.log('🔍 [DEBUG] 设置的完整reviewForm:', JSON.stringify(reviewForm.value, null, 2));
|
||||
reviewOpen.value = true;
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('❌ [ERROR] 获取申请详情失败:', error);
|
||||
proxy.$modal.msgError('获取申请详情失败');
|
||||
});
|
||||
}
|
||||
|
||||
/** 查看详情 */
|
||||
|
||||
@@ -171,6 +171,9 @@
|
||||
@cancel="applyDialogVisible = false"
|
||||
/>
|
||||
</el-dialog>
|
||||
|
||||
<!-- 申请详情对话框(复用组件) -->
|
||||
<ApplicationDetail ref="applicationDetailRef" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -183,12 +186,14 @@ import type { WorkStudyPositionVO } from '@/api/jcbt/workStudyPosition';
|
||||
import { getStudentApplicationStatusList } from '@/api/jcbt/workStudyApplication';
|
||||
import PositionDetail from './detail.vue';
|
||||
import ApplicationForm from './form.vue';
|
||||
import ApplicationDetail from './components/ApplicationDetail.vue';
|
||||
|
||||
const router = useRouter();
|
||||
|
||||
// 组件引用
|
||||
const queryFormRef = ref();
|
||||
const tableRef = ref();
|
||||
const applicationDetailRef = ref();
|
||||
|
||||
// 响应式数据
|
||||
const loading = ref(false);
|
||||
@@ -313,7 +318,14 @@ const handleApply = (position: WorkStudyPositionVO) => {
|
||||
|
||||
// 如果已有申请且状态为已提交或审核中,跳转到申请管理页面
|
||||
if (application && ['submitted', 'college_reviewing', 'final_reviewing'].includes(application.status)) {
|
||||
router.push('/jcbt/workstudy/my-applications');
|
||||
const id = application?.applicationId || application?.id;
|
||||
if (id && applicationDetailRef.value) {
|
||||
applicationDetailRef.value.handleDetail(id, 'application');
|
||||
} else {
|
||||
// 回退到岗位详情对话框
|
||||
selectedPositionId.value = position.id as number;
|
||||
detailDialogVisible.value = true;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -91,7 +91,7 @@
|
||||
<el-button type="primary" :disabled="multiple" @click="handleBatchApplyBed()"> 批量申请床位 </el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="danger" :disabled="multiple" @click="handleBatchCancelBed()"> 批量取消床位 </el-button>
|
||||
<el-button type="danger" :disabled="multiple" @click="handleBatchCancelBed()"> 批量取消床位申请 </el-button>
|
||||
</el-col>
|
||||
<!-- <el-col :span="1.5">
|
||||
<el-button :disabled="multiple" icon="Delete" @click="handleDelete()"> 删除 </el-button>
|
||||
@@ -2285,7 +2285,7 @@ const resetQuery = () => {
|
||||
/** 删除按钮操作 */
|
||||
const handleDelete = async (row?: StudentVO) => {
|
||||
const studentIds = row?.id || ids.value;
|
||||
const [err] = await to(ElMessageBox.confirm('是否确认删除学生编号为"' + row?.name + '"的数据项?', '提示'));
|
||||
const [err] = await to(ElMessageBox.confirm('是否确认删除学生姓名为"' + row?.name + '"的数据项?', '提示'));
|
||||
if (!err) {
|
||||
try {
|
||||
const res = await service.delete(`/studentMsg/studentMsg/${studentIds}`);
|
||||
@@ -2342,23 +2342,93 @@ const handleBatchCancelBed = async () => {
|
||||
return;
|
||||
}
|
||||
|
||||
// 获取选中学生的详细信息
|
||||
const selectedStudents = studentList.value.filter((student) => ids.value.includes(student.id));
|
||||
|
||||
// 分类学生:可以取消和不可以取消的
|
||||
const canCancelStudents: any[] = [];
|
||||
const cannotCancelStudents: any[] = [];
|
||||
|
||||
selectedStudents.forEach((student) => {
|
||||
// 检查学生是否已分配宿舍(宿舍楼栋、房间号、床位号任一不为空)
|
||||
const studentAny = student as any;
|
||||
const hasAssignedBed = studentAny.dormitoryBuilding || studentAny.dormitoryRoom || studentAny.extField1; // 床位号字段
|
||||
|
||||
if (hasAssignedBed) {
|
||||
cannotCancelStudents.push(student);
|
||||
} else {
|
||||
canCancelStudents.push(student);
|
||||
}
|
||||
});
|
||||
|
||||
// 构建确认消息
|
||||
let confirmMessage = '';
|
||||
|
||||
if (canCancelStudents.length > 0) {
|
||||
confirmMessage += `<div style="margin-bottom: 15px;">
|
||||
<strong style="color: #67c23a;">✅ 可以取消床位申请的学生 (${canCancelStudents.length}人):</strong><br/>
|
||||
${canCancelStudents.map((student) => `• ${student.name} (${student.studentNo})`).join('<br/>')}
|
||||
</div>`;
|
||||
}
|
||||
|
||||
if (cannotCancelStudents.length > 0) {
|
||||
confirmMessage += `<div style="margin-bottom: 15px;">
|
||||
<strong style="color: #f56c6c;">❌ 无法取消床位申请的学生 (${cannotCancelStudents.length}人):</strong><br/>
|
||||
${cannotCancelStudents.map((student) => `• ${student.name} (${student.studentNo}) - 已分配宿舍`).join('<br/>')}
|
||||
</div>`;
|
||||
}
|
||||
|
||||
// 如果没有学生可以取消,直接提示
|
||||
if (canCancelStudents.length === 0) {
|
||||
ElMessage.warning('选中的学生都已分配宿舍,无法取消床位申请');
|
||||
return;
|
||||
}
|
||||
|
||||
// 显示确认对话框
|
||||
const [err] = await to(
|
||||
ElMessageBox.confirm('请确认是否取消,会将学生已有宿舍清除!!!', '批量取消床位', {
|
||||
confirmButtonText: '确认取消',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning',
|
||||
dangerouslyUseHTMLString: true
|
||||
})
|
||||
ElMessageBox.confirm(
|
||||
`<div style="text-align: left; max-height: 400px; overflow-y: auto;">
|
||||
<div style="margin-bottom: 15px; font-size: 14px;">
|
||||
<strong>批量取消床位申请确认</strong><br/>
|
||||
系统将只对未分配宿舍的学生执行取消床位申请操作。
|
||||
</div>
|
||||
${confirmMessage}
|
||||
<div style="margin-top: 15px; padding: 10px; background-color: #f0f9ff; border-left: 4px solid #409eff; border-radius: 4px;">
|
||||
<strong>操作说明:</strong><br/>
|
||||
• 已分配宿舍的学生将被跳过<br/>
|
||||
• 仅对未分配宿舍的学生执行取消操作<br/>
|
||||
• 确认后将无法撤销此操作
|
||||
</div>
|
||||
</div>`,
|
||||
'批量取消床位申请',
|
||||
{
|
||||
confirmButtonText: '确认取消',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning',
|
||||
dangerouslyUseHTMLString: true,
|
||||
customClass: 'batch-cancel-bed-dialog'
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
if (!err) {
|
||||
try {
|
||||
// 只对可以取消的学生执行操作
|
||||
const allowedStudentIds = canCancelStudents.map((student) => student.id);
|
||||
|
||||
const res = await service.post('/studentMsg/studentMsg/batchCancelBed', {
|
||||
studentIds: ids.value
|
||||
studentIds: allowedStudentIds
|
||||
});
|
||||
|
||||
if (res && res.code === 200) {
|
||||
await getList();
|
||||
ElMessage.success('批量取消床位成功');
|
||||
|
||||
// 根据操作结果给出不同的提示
|
||||
if (cannotCancelStudents.length > 0) {
|
||||
ElMessage.success(`批量取消床位成功!成功取消 ${canCancelStudents.length} 名学生,跳过 ${cannotCancelStudents.length} 名已分配宿舍的学生`);
|
||||
} else {
|
||||
ElMessage.success('批量取消床位成功');
|
||||
}
|
||||
} else {
|
||||
ElMessage.error(res?.msg || '批量取消床位失败');
|
||||
}
|
||||
@@ -2652,7 +2722,7 @@ const handleAdd = async () => {
|
||||
form.majorName = classData.major_name || classData.majorName;
|
||||
// 确保学历层次为数字类型,避免类型不匹配导致的显示问题
|
||||
const classType = classData.class_type || classData.classType;
|
||||
form.academicLevel = classType ? Number(classType) : undefined;
|
||||
form.academicLevel = classType ? classType : undefined;
|
||||
form.grade = classData.grade;
|
||||
form.enrollmentYear = classData.enrollment_year || classData.enrollmentYear;
|
||||
form.classTeacherId = classData.class_teacher_id || classData.classTeacherId;
|
||||
@@ -3154,4 +3224,26 @@ onMounted(() => {
|
||||
:deep(.el-message) {
|
||||
z-index: 4000 !important;
|
||||
}
|
||||
|
||||
/* 批量取消床位申请确认对话框样式 */
|
||||
:deep(.batch-cancel-bed-dialog) {
|
||||
max-width: 600px !important;
|
||||
}
|
||||
|
||||
:deep(.batch-cancel-bed-dialog .el-message-box__content) {
|
||||
max-height: 500px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
:deep(.batch-cancel-bed-dialog .el-message-box__message) {
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
:deep(.batch-cancel-bed-dialog .el-message-box__message div) {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
:deep(.batch-cancel-bed-dialog .el-message-box__message strong) {
|
||||
font-weight: 600;
|
||||
}
|
||||
</style>
|
||||
Reference in new issue
Block a user