Quellcode durchsuchen

Merge branch 'master' of http://47.99.164.66:3000/hzdyjs-xg/all-project

zlwu vor 4 Monaten
Ursprung
Commit
b0eba0a07b

+ 3 - 3
backend/ruoyi-modules/ruoyi-zsjy/src/main/java/org/dromara/zsjy/domain/vo/ZsjyEnrollmentInfoVo.java

@@ -47,17 +47,17 @@ public class ZsjyEnrollmentInfoVo implements Serializable {
     private String idCard;
 
     /**
-     * 性别(0-男 1-女)
+     * 性别(M/F 或 0/1)
      */
     @ExcelProperty(value = "性别", converter = ExcelDictConvert.class)
-    @ExcelDictFormat(dictType = "sys_gender")
+    @ExcelDictFormat(readConverterExp = "M=男,F=女,0=男,1=女,2=女")
     private String gender;
 
     /**
      * 是否住校(0-否 1-是)
      */
     @ExcelProperty(value = "是否住校", converter = ExcelDictConvert.class)
-    @ExcelDictFormat(dictType = "sys_yes_no")
+    @ExcelDictFormat(readConverterExp = "0=否,1=是,Y=是,N=否")
     private Integer isBoarding;
 
     /**

+ 15 - 0
backend/ruoyi-modules/ruoyi-zsjy/src/main/java/org/dromara/zsjy/domain/vo/ZsjyEnrollmentProcessVo.java

@@ -229,11 +229,26 @@ public class ZsjyEnrollmentProcessVo implements Serializable {
      */
     private String gender;
 
+    /**
+     * 学院名称 - 从enrollment_info表获取
+     */
+    private String collegeName;
+
     /**
      * 专业名称 - 从enrollment_info表获取
      */
     private String majorName;
 
+    /**
+     * 报考专业 - 从enrollment_info表获取
+     */
+    private String appliedMajor;
+
+    /**
+     * 专业代码 - 从enrollment_info表获取
+     */
+    private String majorCode;
+
     /**
      * 是否住校(0-否 1-是)- 从enrollment_info表获取
      */

+ 1 - 1
backend/ruoyi-modules/ruoyi-zsjy/src/main/java/org/dromara/zsjy/domain/vo/ZsjyEnrollmentRegisterExportVo.java

@@ -35,6 +35,6 @@ public class ZsjyEnrollmentRegisterExportVo implements Serializable {
     @ExcelProperty(value = "预交学费")
     private String prepaidTuitionFlag;
 
-    @ExcelProperty(value = "备注(时间、经办人)")
+    @ExcelProperty(value = "录取时间")
     private String remarkInfo;
 }

+ 58 - 17
backend/ruoyi-modules/ruoyi-zsjy/src/main/java/org/dromara/zsjy/service/impl/ZsjyEnrollmentProcessServiceImpl.java

@@ -16,7 +16,9 @@ import org.dromara.zsjy.domain.bo.ZsjyEnrollmentProcessBo;
 import org.dromara.zsjy.domain.vo.ZsjyEnrollmentProcessVo;
 import org.dromara.zsjy.domain.vo.ZsjyEnrollmentRegisterExportVo;
 import org.dromara.zsjy.domain.ZsjyEnrollmentProcess;
+import org.dromara.zsjy.domain.ZsjyEnrollmentInfo;
 import org.dromara.zsjy.mapper.ZsjyEnrollmentProcessMapper;
+import org.dromara.zsjy.mapper.ZsjyEnrollmentInfoMapper;
 import org.dromara.zsjy.service.IZsjyEnrollmentProcessService;
 
 import java.util.List;
@@ -24,6 +26,7 @@ import java.util.Collection;
 import java.util.Date;
 import java.util.Set;
 import java.util.ArrayList;
+import java.util.LinkedHashSet;
 import java.text.SimpleDateFormat;
 
 /**
@@ -37,7 +40,11 @@ import java.text.SimpleDateFormat;
 @Service
 public class ZsjyEnrollmentProcessServiceImpl implements IZsjyEnrollmentProcessService {
 
+    /** 报名状态:待审核 */
+    private static final String ENROLLMENT_STATUS_PENDING = "0";
+
     private final ZsjyEnrollmentProcessMapper baseMapper;
+    private final ZsjyEnrollmentInfoMapper enrollmentInfoMapper;
 
     /**
      * 查询招生录取流程状态
@@ -167,10 +174,42 @@ public class ZsjyEnrollmentProcessServiceImpl implements IZsjyEnrollmentProcessS
     @Override
     @Transactional(rollbackFor = Exception.class)
     public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
+        if (ids == null || ids.isEmpty()) {
+            return false;
+        }
         if (isValid) {
             // 可以添加删除前的校验逻辑
         }
-        return baseMapper.deleteBatchIds(ids) > 0;
+
+        Set<Long> enrollmentIds = new LinkedHashSet<>();
+        for (Long id : ids) {
+            ZsjyEnrollmentProcess process = baseMapper.selectById(id);
+            if (process != null && process.getEnrollmentId() != null) {
+                enrollmentIds.add(process.getEnrollmentId());
+            }
+        }
+
+        boolean deleted = baseMapper.deleteBatchIds(ids) > 0;
+        if (deleted) {
+            for (Long enrollmentId : enrollmentIds) {
+                revertEnrollmentToPendingAudit(enrollmentId);
+            }
+        }
+        return deleted;
+    }
+
+    /**
+     * 删除流程后,将对应报名信息回退为待审核状态(不触发流程同步,避免重新创建流程)
+     */
+    private void revertEnrollmentToPendingAudit(Long enrollmentId) {
+        ZsjyEnrollmentInfo enrollmentInfo = enrollmentInfoMapper.selectById(enrollmentId);
+        if (enrollmentInfo == null) {
+            log.warn("删除流程后回退报名状态失败,报名记录不存在,enrollmentId={}", enrollmentId);
+            return;
+        }
+        enrollmentInfo.setEnrollmentStatus(ENROLLMENT_STATUS_PENDING);
+        enrollmentInfoMapper.updateById(enrollmentInfo);
+        log.info("删除流程后已将报名ID:{} 状态回退为待审核", enrollmentId);
     }
 
     /**
@@ -465,24 +504,26 @@ public class ZsjyEnrollmentProcessServiceImpl implements IZsjyEnrollmentProcessS
     }
 
     private String buildRegisterRemark(ZsjyEnrollmentProcessVo item) {
-        if (StringUtils.isNotBlank(item.getRemark())) {
-            return item.getRemark();
+        Date admissionTime = resolveAdmissionTime(item);
+        if (admissionTime == null) {
+            return "";
         }
-        StringBuilder remark = new StringBuilder();
-        Date remarkTime = item.getPaymentConfirmTime() != null ? item.getPaymentConfirmTime()
-            : (item.getAdmissionTime() != null ? item.getAdmissionTime() : item.getFinalAuditTime());
-        if (remarkTime != null) {
-            remark.append(new SimpleDateFormat("M.d").format(remarkTime));
+        return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(admissionTime);
+    }
+
+    /**
+     * 解析录取时间:优先录取完成时间,其次录取处理、最终确认、缴费确认时间
+     */
+    private Date resolveAdmissionTime(ZsjyEnrollmentProcessVo item) {
+        if (item.getCompletionTime() != null) {
+            return item.getCompletionTime();
         }
-        String handler = StringUtils.blankToDefault(item.getAdmissionUserName(),
-            StringUtils.blankToDefault(item.getFinalAuditUserName(),
-                StringUtils.blankToDefault(item.getInfoAuditUserName(), item.getCurrentHandlerName())));
-        if (StringUtils.isNotBlank(handler)) {
-            if (!remark.isEmpty()) {
-                remark.append(" ");
-            }
-            remark.append(handler);
+        if (item.getAdmissionTime() != null) {
+            return item.getAdmissionTime();
+        }
+        if (item.getFinalAuditTime() != null) {
+            return item.getFinalAuditTime();
         }
-        return remark.toString();
+        return item.getPaymentConfirmTime();
     }
 }

+ 10 - 1
backend/ruoyi-modules/ruoyi-zsjy/src/main/resources/mapper/zsjy/ZsjyEnrollmentProcessMapper.xml

@@ -77,7 +77,10 @@
         <result property="updateTime" column="update_time"/>
         <!-- 额外字段,用于合并enrollment_info表的数据 -->
         <result property="gender" column="gender"/>
+        <result property="collegeName" column="collegeName"/>
         <result property="majorName" column="majorName"/>
+        <result property="appliedMajor" column="appliedMajor"/>
+        <result property="majorCode" column="majorCode"/>
         <result property="isBoarding" column="isBoarding"/>
         <result property="province" column="province"/>
     </resultMap>
@@ -144,7 +147,13 @@
             COALESCE(p.create_time, ei.create_time) as create_time,
             COALESCE(p.update_by, ei.update_by) as update_by,
             COALESCE(p.update_time, ei.update_time) as update_time,
-            ei.gender, ei.applied_major as majorName, ei.is_boarding as isBoarding, ei.exam_region as province
+            ei.gender,
+            ei.collage_name as collegeName,
+            ei.applied_major as majorName,
+            ei.applied_major as appliedMajor,
+            ei.major_code as majorCode,
+            ei.is_boarding as isBoarding,
+            ei.exam_region as province
         FROM zsjy_enrollment_info ei
         LEFT JOIN zsjy_enrollment_process p ON ei.id = p.enrollment_id AND p.deleted = '0'
         WHERE ei.deleted = '0'

+ 1 - 1
web/src/views/zsjy/enrollment/index.vue

@@ -178,7 +178,7 @@
 
     <!-- 分页 -->
     <div class="pagination-container">
-      <pagination v-show="total > 0" :page="queryParams.pageNum" :limit="queryParams.pageSize" :total="total" @pagination="getList" />
+      <pagination v-show="total > 0" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" :total="total" @pagination="getList" />
     </div>
 
     <!-- 添加或修改招生报名信息对话框 -->

+ 22 - 8
web/src/views/zsjy/enrollmentStatistics/components/StudentDetailDialog.vue

@@ -11,7 +11,7 @@
         <el-descriptions :column="3" border>
           <el-descriptions-item label="姓名">{{ studentData.studentName || studentData.name || '-' }}</el-descriptions-item>
           <el-descriptions-item label="身份证号">{{ formatIdCard(studentData.idCard) }}</el-descriptions-item>
-          <el-descriptions-item label="性别">{{ studentData.gender === 'M' ? '男' : '女' }}</el-descriptions-item>
+          <el-descriptions-item label="性别">{{ formatGender(studentData.gender, studentData.idCard) }}</el-descriptions-item>
           <el-descriptions-item label="出生日期">{{ formatDate(studentData.birthDate) }}</el-descriptions-item>
           <el-descriptions-item label="联系电话">{{ studentData.phone1 || '-' }}</el-descriptions-item>
           <el-descriptions-item label="备用电话">{{ studentData.phone2 || '-' }}</el-descriptions-item>
@@ -54,6 +54,9 @@
           </div>
         </template>
         <el-descriptions :column="2" border>
+          <el-descriptions-item label="所属学院">{{
+            studentData.collegeName || studentData.college_name || studentData.collage_name || '-'
+          }}</el-descriptions-item>
           <el-descriptions-item label="报考专业">{{ studentData.majorName || studentData.appliedMajor || '-' }}</el-descriptions-item>
           <el-descriptions-item label="专业代码">{{ studentData.majorCode || '-' }}</el-descriptions-item>
           <el-descriptions-item label="校服尺码">{{ studentData.uniformSize || '-' }}</el-descriptions-item>
@@ -166,13 +169,6 @@ const dialogVisible = computed({
   }
 });
 
-// 判断学生是否已完成
-const isStudentCompleted = computed(() => {
-  const isCompleted = props.studentData.isCompleted;
-  // 显式检查字符串和数字类型的值
-  return String(isCompleted) === '1';
-});
-
 // 格式化身份证号(隐藏中间部分)
 const formatIdCard = (idCard: string | undefined) => {
   if (!idCard) return '-';
@@ -182,6 +178,24 @@ const formatIdCard = (idCard: string | undefined) => {
   return idCard;
 };
 
+// 判断学生是否已完成
+const isStudentCompleted = computed(() => {
+  const isCompleted = props.studentData.isCompleted;
+  return String(isCompleted) === '1';
+});
+
+const formatGender = (gender?: string, idCard?: string) => {
+  if (gender === 'M' || gender === '0') return '男';
+  if (gender === 'F' || gender === '1') return '女';
+  if (idCard && idCard.length >= 17) {
+    const code = parseInt(idCard.charAt(16), 10);
+    if (!Number.isNaN(code)) {
+      return code % 2 === 0 ? '女' : '男';
+    }
+  }
+  return gender || '-';
+};
+
 // 格式化日期
 const formatDate = (date: string | Date | undefined) => {
   if (!date) return '-';

+ 42 - 33
web/src/views/zsjy/enrollmentStatistics/index.vue

@@ -116,17 +116,17 @@
         <el-table-column prop="idCard" label="身份证号" min-width="180" align="center" :formatter="formatIdCard" show-overflow-tooltip />
         <el-table-column prop="gender" label="性别" width="80" align="center">
           <template #default="scope">
-            {{ scope.row.gender === 'M' ? '男' : '女' }}
+            {{ formatGender(scope.row.gender, scope.row.idCard) }}
           </template>
         </el-table-column>
         <el-table-column label="所属学院" min-width="150" align="center" show-overflow-tooltip>
           <template #default="scope">
-            {{ scope.row.applied_major }}
+            {{ scope.row.collegeName || scope.row.college_name || scope.row.collage_name || '-' }}
           </template>
         </el-table-column>
         <el-table-column label="专业" min-width="150" align="center" show-overflow-tooltip>
           <template #default="scope">
-            {{ scope.row.majorName || scope.row.applied_major || '-' }}
+            {{ scope.row.majorName || scope.row.appliedMajor || scope.row.applied_major || '-' }}
           </template>
         </el-table-column>
         <el-table-column prop="province" label="地区" min-width="100" align="center" />
@@ -174,6 +174,7 @@ import {
   EnrollmentProcessVO,
   getEnrollmentProcess
 } from '@/api/zsjy/enrollmentProcess';
+import { getEnrollmentInfo } from '@/api/zsjy/enrollment';
 import { listDept } from '@/api/system/dept';
 import type { DeptVO } from '@/api/system/dept/types';
 import StudentDetailDialog from './components/StudentDetailDialog.vue';
@@ -511,59 +512,67 @@ const handleExport = () => {
 const handleView = async (row: EnrollmentProcessVO) => {
   detailLoading.value = true;
   try {
-    let processData: any = {};
+    let processData: any = { ...row };
 
-    // 如果是从报名信息表里直接获取的数据(可能没有流程ID)
     if (row.id) {
       const res = await getEnrollmentProcess(row.id);
-      if (res && res.code === 200) {
-        processData = res.data;
-      } else {
-        // 回退到使用行数据
-        processData = { ...row };
+      if (res && res.code === 200 && res.data) {
+        processData = { ...processData, ...res.data };
+      }
+    }
+
+    const enrollmentId = processData.enrollmentId || row.enrollmentId;
+    if (enrollmentId) {
+      const infoRes = await getEnrollmentInfo(enrollmentId);
+      if (infoRes?.code === 200 && infoRes.data) {
+        const info = infoRes.data;
+        processData = {
+          ...processData,
+          ...info,
+          studentName: processData.studentName || info.name,
+          collegeName: info.collegeName || processData.collegeName,
+          majorName: info.appliedMajor || processData.majorName,
+          appliedMajor: info.appliedMajor || processData.appliedMajor,
+          applicationTime: info.applicationTime || processData.applicationTime
+        };
       }
-    } else {
-      // 使用行数据(可能是从enrollment_info表里直接获取的)
-      processData = { ...row };
     }
 
-    // 处理完成状态,确保它是字符串类型
     if (processData.isCompleted !== undefined) {
       processData.isCompleted = String(processData.isCompleted);
     }
 
-    // 处理缴费状态,确保它不为空
     if (processData.paymentStatus === undefined || processData.paymentStatus === null) {
-      processData.paymentStatus = '0'; // 默认为未缴费
+      processData.paymentStatus = '0';
     }
 
-    // 设置当前流程数据
     currentStudent.value = processData;
-
-    // 打开详情对话框
     detailDialogVisible.value = true;
   } catch (error) {
     console.error('获取流程详情失败:', error);
-    // 即使获取详情失败,也尝试使用行数据显示
-    const processData = { ...row };
-
-    // 处理完成状态,确保它是字符串类型
-    if (processData.isCompleted !== undefined) {
-      processData.isCompleted = String(processData.isCompleted);
-    }
-
-    // 处理缴费状态,确保它不为空
-    if (processData.paymentStatus === undefined || processData.paymentStatus === null) {
-      processData.paymentStatus = '0'; // 默认为未缴费
-    }
-
-    currentStudent.value = processData;
+    currentStudent.value = {
+      ...row,
+      isCompleted: row.isCompleted !== undefined ? String(row.isCompleted) : undefined,
+      paymentStatus: row.paymentStatus ?? '0'
+    };
     detailDialogVisible.value = true;
   } finally {
     detailLoading.value = false;
   }
 };
 
+const formatGender = (gender?: string, idCard?: string) => {
+  if (gender === 'M' || gender === '0') return '男';
+  if (gender === 'F' || gender === '1') return '女';
+  if (idCard && idCard.length >= 17) {
+    const code = parseInt(idCard.charAt(16), 10);
+    if (!Number.isNaN(code)) {
+      return code % 2 === 0 ? '女' : '男';
+    }
+  }
+  return gender || '-';
+};
+
 // 格式化身份证号(隐藏中间部分)
 const formatIdCard = (row: any) => {
   if (!row.idCard) return '';