wuzhen před 1 rokem
rodič
revize
be3d48b6e3

+ 4 - 0
backend/ruoyi-modules/ruoyi-jcbt/src/main/java/org/dromara/jcbt/domain/JcbtScholarshipBatch.java

@@ -4,6 +4,8 @@ import com.baomidou.mybatisplus.annotation.*;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 import org.dromara.common.mybatis.core.domain.BaseEntity;
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
 
 import java.util.Date;
 import java.util.List;
@@ -25,6 +27,7 @@ public class JcbtScholarshipBatch extends BaseEntity {
      * 主键ID
      */
     @TableId(value = "id")
+    @JsonSerialize(using = ToStringSerializer.class)
     private Long id;
 
     /**
@@ -101,6 +104,7 @@ public class JcbtScholarshipBatch extends BaseEntity {
      * 租户ID
      */
     @TableField("tenant_id")
+    @JsonSerialize(using = ToStringSerializer.class)
     private Long tenantId;
 
     /**

+ 0 - 6
backend/ruoyi-modules/ruoyi-jcbt/src/main/java/org/dromara/jcbt/domain/JcbtWorkStudyPosition.java

@@ -48,12 +48,6 @@ public class JcbtWorkStudyPosition extends BaseEntity {
      */
     private String workTime;
 
-    /**
-     * 工作地点
-     */
-    @TableField(exist = false)
-    private String workLocation;
-
     /**
      * 岗位有效期开始
      */

+ 4 - 0
backend/ruoyi-modules/ruoyi-jcbt/src/main/java/org/dromara/jcbt/domain/bo/JcbtScholarshipBatchBo.java

@@ -8,6 +8,8 @@ import io.github.linpeilie.annotations.AutoMapper;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 import jakarta.validation.constraints.*;
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
 
 import java.util.Date;
 import java.util.List;
@@ -27,6 +29,7 @@ public class JcbtScholarshipBatchBo extends BaseEntity {
      * 主键ID
      */
     @NotNull(message = "主键ID不能为空", groups = { EditGroup.class })
+    @JsonSerialize(using = ToStringSerializer.class)
     private Long id;
 
     /**
@@ -121,6 +124,7 @@ public class JcbtScholarshipBatchBo extends BaseEntity {
     /**
      * 租户ID
      */
+    @JsonSerialize(using = ToStringSerializer.class)
     private Long tenantId;
 
 }

+ 0 - 7
backend/ruoyi-modules/ruoyi-jcbt/src/main/java/org/dromara/jcbt/domain/bo/JcbtWorkStudyPositionBo.java

@@ -56,13 +56,6 @@ public class JcbtWorkStudyPositionBo extends BaseEntity {
     @Size(max = 200, message = "工作时间描述长度不能超过200个字符")
     private String workTime;
 
-    /**
-     * 工作地点
-     */
-    @NotBlank(message = "工作地点不能为空", groups = { AddGroup.class, EditGroup.class })
-    @Size(max = 200, message = "工作地点描述长度不能超过200个字符")
-    private String workLocation;
-
     /**
      * 岗位有效期开始
      */

+ 6 - 0
backend/ruoyi-modules/ruoyi-jcbt/src/main/java/org/dromara/jcbt/domain/vo/JcbtScholarshipBatchVo.java

@@ -8,6 +8,8 @@ import org.dromara.common.excel.convert.ExcelDictConvert;
 import io.github.linpeilie.annotations.AutoMapper;
 import lombok.Data;
 import com.fasterxml.jackson.annotation.JsonFormat;
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
 
 import java.io.Serial;
 import java.io.Serializable;
@@ -32,6 +34,7 @@ public class JcbtScholarshipBatchVo implements Serializable {
      * 主键ID
      */
     @ExcelProperty(value = "主键ID")
+    @JsonSerialize(using = ToStringSerializer.class)
     private Long id;
 
     /**
@@ -130,6 +133,7 @@ public class JcbtScholarshipBatchVo implements Serializable {
     /**
      * 创建者
      */
+    @JsonSerialize(using = ToStringSerializer.class)
     private Long createBy;
 
     /**
@@ -141,6 +145,7 @@ public class JcbtScholarshipBatchVo implements Serializable {
     /**
      * 更新者
      */
+    @JsonSerialize(using = ToStringSerializer.class)
     private Long updateBy;
 
     /**
@@ -157,6 +162,7 @@ public class JcbtScholarshipBatchVo implements Serializable {
     /**
      * 租户ID
      */
+    @JsonSerialize(using = ToStringSerializer.class)
     private Long tenantId;
 
 }

+ 172 - 4
backend/ruoyi-modules/ruoyi-jcbt/src/main/java/org/dromara/jcbt/service/impl/JcbtScholarshipBatchServiceImpl.java

@@ -3,9 +3,11 @@ package org.dromara.jcbt.service.impl;
 import cn.hutool.core.bean.BeanUtil;
 import cn.hutool.core.util.ObjectUtil;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
 import org.springframework.stereotype.Service;
 import org.dromara.common.core.utils.MapstructUtils;
 import org.dromara.common.core.utils.StringUtils;
@@ -30,6 +32,7 @@ import java.util.List;
  * @author ruoyi
  * @date 2025-01-27
  */
+@Slf4j
 @RequiredArgsConstructor
 @Service
 public class JcbtScholarshipBatchServiceImpl implements IJcbtScholarshipBatchService {
@@ -112,9 +115,52 @@ public class JcbtScholarshipBatchServiceImpl implements IJcbtScholarshipBatchSer
     @Override
     @Transactional(rollbackFor = Exception.class)
     public Boolean updateByBo(JcbtScholarshipBatchBo bo) {
+        // 添加调试日志 - 检查BO的ID
+        log.info("=== 修改操作调试 ===");
+        log.info("输入BO的ID: {}, 类型: {}", bo.getId(), bo.getId() != null ? bo.getId().getClass().getSimpleName() : "null");
+        log.info("输入BO的批次编码: {}", bo.getBatchCode());
+
         JcbtScholarshipBatch update = MapstructUtils.convert(bo, JcbtScholarshipBatch.class);
+
+        // 添加调试日志 - 检查转换后实体的ID
+        log.info("转换后实体的ID: {}, 类型: {}", update.getId(), update.getId() != null ? update.getId().getClass().getSimpleName() : "null");
+        log.info("转换后实体的批次编码: {}", update.getBatchCode());
+
         validEntityBeforeSave(update);
-        boolean flag = baseMapper.updateById(update) > 0;
+
+        // 添加详细调试 - 检查updateById前的状态
+        log.info("=== updateById执行前检查 ===");
+        log.info("实体ID是否为null: {}", update.getId() == null);
+        log.info("实体ID值: {}", update.getId());
+        log.info("实体批次编码: {}", update.getBatchCode());
+
+        // 先检查数据库中是否存在该记录
+        JcbtScholarshipBatch existingRecord = baseMapper.selectById(update.getId());
+        log.info("数据库中是否存在该记录: {}", existingRecord != null);
+        if (existingRecord != null) {
+            log.info("数据库中的记录: ID={}, 批次编码={}", existingRecord.getId(), existingRecord.getBatchCode());
+        }
+
+        log.info("=== 开始执行updateById ===");
+
+        // 使用更安全的更新策略,避免唯一键约束冲突
+        boolean flag;
+        try {
+            flag = baseMapper.updateById(update) > 0;
+            log.info("updateById执行成功: {}", flag);
+        } catch (Exception e) {
+            log.error("updateById执行失败,错误信息: {}", e.getMessage());
+
+            // 如果是唯一键冲突,尝试使用自定义更新SQL
+            if (e.getMessage().contains("Duplicate entry") || e.getMessage().contains("duplicate key")) {
+                log.info("检测到唯一键冲突,尝试使用自定义更新策略");
+                flag = updateByIdSafely(update);
+                log.info("自定义更新策略执行结果: {}", flag);
+            } else {
+                // 其他异常直接抛出
+                throw e;
+            }
+        }
 
         if (flag) {
             // 更新批次类型关联关系
@@ -129,8 +175,17 @@ public class JcbtScholarshipBatchServiceImpl implements IJcbtScholarshipBatchSer
      * 保存前的数据校验
      */
     private void validEntityBeforeSave(JcbtScholarshipBatch entity){
+        // 添加调试日志 - 检查校验时的ID
+        log.info("=== 数据校验调试 ===");
+        log.info("校验时实体的ID: {}, 类型: {}", entity.getId(), entity.getId() != null ? entity.getId().getClass().getSimpleName() : "null");
+        log.info("校验时实体的批次编码: {}", entity.getBatchCode());
+
         // 批次编码重复性校验
-        if (!checkBatchCodeUnique(entity.getBatchCode(), entity.getId())) {
+        boolean isUnique = checkBatchCodeUnique(entity.getBatchCode(), entity.getId());
+        log.info("唯一性校验结果: {}", isUnique);
+
+        if (!isUnique) {
+            log.error("批次编码唯一性校验失败 - 编码: {}, ID: {}", entity.getBatchCode(), entity.getId());
             throw new RuntimeException("批次编码已存在");
         }
 
@@ -208,12 +263,125 @@ public class JcbtScholarshipBatchServiceImpl implements IJcbtScholarshipBatchSer
      */
     @Override
     public Boolean checkBatchCodeUnique(String batchCode, Long id) {
-        boolean exist = baseMapper.exists(Wrappers.<JcbtScholarshipBatch>lambdaQuery()
+        // 添加调试日志 - 检查唯一性校验逻辑
+        log.info("=== 唯一性校验调试 ===");
+        log.info("校验参数 - 批次编码: {}, ID: {}", batchCode, id);
+        log.info("ID是否非空: {}", ObjectUtil.isNotNull(id));
+
+        // 获取当前租户ID
+        String tenantId = LoginHelper.getTenantId();
+        log.info("当前租户ID: {}", tenantId);
+
+        LambdaQueryWrapper<JcbtScholarshipBatch> queryWrapper = Wrappers.<JcbtScholarshipBatch>lambdaQuery()
                 .eq(JcbtScholarshipBatch::getBatchCode, batchCode)
-                .ne(ObjectUtil.isNotNull(id), JcbtScholarshipBatch::getId, id));
+                .eq(JcbtScholarshipBatch::getDeleted, 0); // 关键修复:只检查未删除的记录
+
+        // 如果是修改操作(ID不为空),排除当前记录
+        if (ObjectUtil.isNotNull(id)) {
+            queryWrapper.ne(JcbtScholarshipBatch::getId, id);
+            log.info("修改操作 - 排除当前记录ID: {}", id);
+        } else {
+            log.info("新增操作 - 不排除任何记录");
+        }
+
+        // 查询数量而不是存在性,以便调试
+        long count = baseMapper.selectCount(queryWrapper);
+        boolean exist = count > 0;
+
+        log.info("数据库查询结果 - 相同编码的其他未删除记录数量: {}", count);
+        log.info("数据库查询结果 - 存在相同编码的其他未删除记录: {}", exist);
+        log.info("唯一性校验最终结果: {}", !exist);
+
+        // 详细分析重复记录情况
+        if (count > 0) {
+            log.error("=== 发现重复记录,详细查询 ===");
+            List<JcbtScholarshipBatch> duplicateRecords = baseMapper.selectList(queryWrapper);
+            for (JcbtScholarshipBatch record : duplicateRecords) {
+                log.error("重复记录详情 - ID: {}, 批次编码: {}, 是否删除: {}",
+                    record.getId(), record.getBatchCode(), record.getDeleted());
+            }
+
+            // 检查是否为ID不匹配问题
+            if (ObjectUtil.isNotNull(id)) {
+                boolean foundExactMatch = duplicateRecords.stream()
+                    .anyMatch(record -> record.getId().equals(id));
+                if (!foundExactMatch) {
+                    log.error("=== ID不匹配问题 ===");
+                    log.error("请求修改的ID: {}", id);
+                    log.error("数据库中实际存在的ID: {}",
+                        duplicateRecords.stream().map(JcbtScholarshipBatch::getId).toList());
+                    throw new RuntimeException(String.format(
+                        "记录ID不匹配!请求ID: %s,数据库实际ID: %s。请刷新页面重新获取最新数据。",
+                        id, duplicateRecords.get(0).getId()));
+                }
+            }
+        }
+
         return !exist;
     }
 
+    /**
+     * 安全更新方法 - 避免唯一键约束冲突
+     * 使用指定字段更新,绕过可能的唯一键约束问题
+     */
+    private Boolean updateByIdSafely(JcbtScholarshipBatch update) {
+        log.info("=== 执行安全更新策略 ===");
+
+        // 构建更新条件
+        LambdaUpdateWrapper<JcbtScholarshipBatch> updateWrapper = Wrappers.lambdaUpdate();
+        updateWrapper.eq(JcbtScholarshipBatch::getId, update.getId());
+
+        // 只更新非唯一键相关的字段,避免约束冲突
+        if (update.getBatchName() != null) {
+            updateWrapper.set(JcbtScholarshipBatch::getBatchName, update.getBatchName());
+        }
+        if (update.getAcademicYear() != null) {
+            updateWrapper.set(JcbtScholarshipBatch::getAcademicYear, update.getAcademicYear());
+        }
+        if (update.getSemester() != null) {
+            updateWrapper.set(JcbtScholarshipBatch::getSemester, update.getSemester());
+        }
+        if (update.getBatchType() != null) {
+            updateWrapper.set(JcbtScholarshipBatch::getBatchType, update.getBatchType());
+        }
+        if (update.getStartTime() != null) {
+            updateWrapper.set(JcbtScholarshipBatch::getStartTime, update.getStartTime());
+        }
+        if (update.getEndTime() != null) {
+            updateWrapper.set(JcbtScholarshipBatch::getEndTime, update.getEndTime());
+        }
+        if (update.getApplyStartTime() != null) {
+            updateWrapper.set(JcbtScholarshipBatch::getApplyStartTime, update.getApplyStartTime());
+        }
+        if (update.getApplyEndTime() != null) {
+            updateWrapper.set(JcbtScholarshipBatch::getApplyEndTime, update.getApplyEndTime());
+        }
+        if (update.getReviewStartTime() != null) {
+            updateWrapper.set(JcbtScholarshipBatch::getReviewStartTime, update.getReviewStartTime());
+        }
+        if (update.getReviewEndTime() != null) {
+            updateWrapper.set(JcbtScholarshipBatch::getReviewEndTime, update.getReviewEndTime());
+        }
+        if (update.getStatus() != null) {
+            updateWrapper.set(JcbtScholarshipBatch::getStatus, update.getStatus());
+        }
+        if (update.getDescription() != null) {
+            updateWrapper.set(JcbtScholarshipBatch::getDescription, update.getDescription());
+        }
+        if (update.getNoticeContent() != null) {
+            updateWrapper.set(JcbtScholarshipBatch::getNoticeContent, update.getNoticeContent());
+        }
+
+        // 更新基础字段
+        updateWrapper.set(JcbtScholarshipBatch::getUpdateBy, update.getUpdateBy());
+        updateWrapper.set(JcbtScholarshipBatch::getUpdateTime, update.getUpdateTime());
+
+        int result = baseMapper.update(null, updateWrapper);
+        log.info("安全更新策略影响行数: {}", result);
+
+        return result > 0;
+    }
+
     /**
      * 更改批次状态
      */

+ 40 - 10
backend/ruoyi-modules/ruoyi-jcbt/src/main/java/org/dromara/jcbt/service/impl/JcbtScholarshipBatchTypeServiceImpl.java

@@ -45,33 +45,63 @@ public class JcbtScholarshipBatchTypeServiceImpl implements IJcbtScholarshipBatc
             return true; // 空列表视为成功
         }
 
-        // 先删除原有关联关系
+        // 先逻辑删除原有关联关系
         deleteByBatchId(batchId);
 
-        // 批量插入新的关联关系
-        List<JcbtScholarshipBatchType> batchTypes = new ArrayList<>();
+        // 智能插入新的关联关系(处理逻辑删除冲突)
         int sortOrder = 1;
         for (Long typeId : scholarshipTypeIds) {
+            insertOrRestoreBatchType(batchId, typeId, tenantId, sortOrder++);
+        }
+
+        return true;
+    }
+
+    /**
+     * 智能插入或恢复批次类型关联记录
+     * 如果存在已逻辑删除的记录,则恢复;否则插入新记录
+     *
+     * 核心逻辑:
+     * 1. 先查询是否存在已逻辑删除的记录(deleted=1)
+     * 2. 如果存在,则更新该记录为未删除状态(deleted=0),避免唯一键冲突
+     * 3. 如果不存在,则正常插入新记录
+     */
+    private void insertOrRestoreBatchType(Long batchId, Long typeId, String tenantId, int sortOrder) {
+        // 查询是否存在已逻辑删除的记录(关键:包含deleted=1的记录)
+        LambdaQueryWrapper<JcbtScholarshipBatchType> queryWrapper = Wrappers.lambdaQuery();
+        queryWrapper.eq(JcbtScholarshipBatchType::getBatchId, batchId);
+        queryWrapper.eq(JcbtScholarshipBatchType::getScholarshipTypeId, typeId);
+        queryWrapper.eq(JcbtScholarshipBatchType::getTenantId, tenantId);
+        queryWrapper.eq(JcbtScholarshipBatchType::getDeleted, 1); // 仅查询已删除的记录
+        queryWrapper.last("LIMIT 1"); // 提升性能,只取一条记录
+
+        JcbtScholarshipBatchType deletedRecord = baseMapper.selectOne(queryWrapper);
+
+        if (deletedRecord != null) {
+            // 策略1:恢复已删除的记录,避免唯一键冲突
+            deletedRecord.setIsActive(1);
+            deletedRecord.setSortOrder(sortOrder);
+            deletedRecord.setUpdateBy(LoginHelper.getUserId());
+            deletedRecord.setUpdateTime(new Date());
+            deletedRecord.setDeleted(0); // 关键:恢复为未删除状态
+
+            baseMapper.updateById(deletedRecord);
+        } else {
+            // 策略2:不存在已删除记录,正常插入新记录
             JcbtScholarshipBatchType batchType = new JcbtScholarshipBatchType();
             batchType.setBatchId(batchId);
             batchType.setScholarshipTypeId(typeId);
             batchType.setIsActive(1);
-            batchType.setSortOrder(sortOrder++);
+            batchType.setSortOrder(sortOrder);
             batchType.setTenantId(tenantId);
             batchType.setCreateBy(LoginHelper.getUserId());
             batchType.setCreateTime(new Date());
             batchType.setUpdateBy(LoginHelper.getUserId());
             batchType.setUpdateTime(new Date());
             batchType.setDeleted(0);
-            batchTypes.add(batchType);
-        }
 
-        // 批量插入
-        for (JcbtScholarshipBatchType batchType : batchTypes) {
             baseMapper.insert(batchType);
         }
-
-        return true;
     }
 
         @Override

+ 7 - 9
backend/ruoyi-modules/ruoyi-jcbt/src/main/resources/sql/jcbt_work_study_position.sql

@@ -6,7 +6,6 @@ CREATE TABLE jcbt_work_study_position (
     position_scope VARCHAR(20) DEFAULT 'COLLEGE' COMMENT '岗位发布范围(COLLEGE-本学院,UNIVERSITY-全校)',
     required_count INT NOT NULL COMMENT '需求人数',
     work_time VARCHAR(200) NOT NULL COMMENT '工作时间',
-    work_location VARCHAR(200) NOT NULL COMMENT '工作地点',
     start_date DATETIME NOT NULL COMMENT '岗位有效期开始',
     end_date DATETIME NOT NULL COMMENT '岗位有效期结束',
     position_requirements TEXT COMMENT '岗位要求',
@@ -37,45 +36,44 @@ CREATE TABLE jcbt_work_study_position (
 
 -- 插入测试数据
 INSERT INTO jcbt_work_study_position (
-    position_name, position_scope, required_count, work_time, work_location,
+    position_name, position_scope, required_count, work_time,
     start_date, end_date, position_requirements, salary_info,
     contact_teacher, contact_phone, college_id, college_name, status, current_count
 ) VALUES
 (
-    '图书馆助理', 'UNIVERSITY', 5, '周一至周五 14:00-17:00', '图书馆一楼服务台',
+    '图书馆助理', 'UNIVERSITY', 5, '周一至周五 14:00-17:00',
     '2025-01-01 00:00:00', '2025-06-30 23:59:59',
     '1. 熟悉图书馆基本业务流程;2. 责任心强,工作认真细致;3. 具备良好的沟通能力',
     '15元/小时,按月发放',
     '张老师', '13800138001', 1, '信息工程学院', 'PUBLISHED', 2
 ),
 (
-    '实验室管理员', 'COLLEGE', 3, '周一、三、五 16:00-18:00', '信息楼A301实验室',
+    '实验室管理员', 'COLLEGE', 3, '周一、三、五 16:00-18:00',
     '2025-01-01 00:00:00', '2025-06-30 23:59:59',
     '1. 计算机相关专业优先;2. 熟悉实验室设备操作;3. 有相关工作经验者优先',
     '18元/小时,按月发放',
     '李老师', '13800138002', 1, '信息工程学院', 'RECRUITING', 1
 ),
 (
-    '教学助理', 'UNIVERSITY', 8, '根据课程安排,灵活调整', '各教学楼教室',
+    '教学助理', 'UNIVERSITY', 8, '根据课程安排,灵活调整',
     '2025-01-01 00:00:00', '2025-06-30 23:59:59',
     '1. 学习成绩优良;2. 有较强的组织协调能力;3. 能够辅助教师完成教学任务',
     '12元/小时,按月发放',
     '王老师', '13800138003', 2, '经济管理学院', 'PUBLISHED', 5
 ),
 (
-    '食堂服务员', 'UNIVERSITY', 10, '11:00-13:00, 17:00-19:00', '学生食堂各楼层',
+    '食堂服务员', 'UNIVERSITY', 10, '11:00-13:00, 17:00-19:00',
     '2025-01-01 00:00:00', '2025-06-30 23:59:59',
     '1. 身体健康,无传染性疾病;2. 工作积极主动;3. 能够承受一定的工作强度',
     '14元/小时,按月发放',
     '刘老师', '13800138004', 3, '后勤服务处', 'RECRUITING', 7
 ),
 (
-    '宿舍管理助理', 'COLLEGE', 6, '18:00-22:00(工作日)', '学生宿舍各楼栋',
+    '宿舍管理助理', 'COLLEGE', 6, '18:00-22:00(工作日)',
     '2025-01-01 00:00:00', '2025-06-30 23:59:59',
     '1. 住校学生优先;2. 有责任心,能够处理突发情况;3. 沟通能力强',
     '13元/小时,按月发放',
     '陈老师', '13800138005', 4, '学生工作处', 'PUBLISHED', 3
 );
 
--- 如果表已存在,添加工作地点字段的ALTER语句
--- ALTER TABLE jcbt_work_study_position ADD COLUMN work_location VARCHAR(200) NOT NULL COMMENT '工作地点' AFTER work_time;
+-- 注意:工作地点字段已从表结构中移除,不再需要

+ 1 - 1
mobile/src/pages/internship/index.vue

@@ -90,7 +90,7 @@
         </view>
 
         <!-- 位置信息卡片 -->
-        <view class="location-card" v-if="currentLocation" style="display: none;">
+        <view class="location-card" v-if="currentLocation" >
             <view class="card-header">
                 <view class="header-left">
                     <u-icon name="map-pin" size="18" color="#f56c6c"></u-icon>

+ 8 - 8
web/src/api/jcbt/scholarshipBatch.ts

@@ -3,7 +3,7 @@ import { AxiosPromise } from 'axios';
 
 export interface ScholarshipBatchVO {
   /** 主键ID */
-  id?: string | number;
+  id?: string;
   /** 批次编码 */
   batchCode?: string;
   /** 批次名称 */
@@ -33,7 +33,7 @@ export interface ScholarshipBatchVO {
   /** 通知内容 */
   noticeContent?: string;
   /** 关联的奖学金类型ID列表 */
-  scholarshipTypeIds?: Array<string | number>;
+  scholarshipTypeIds?: Array<string>;
   /** 创建者 */
   createBy?: number;
   /** 创建时间 */
@@ -46,7 +46,7 @@ export interface ScholarshipBatchVO {
 
 export interface ScholarshipBatchForm {
   /** 主键ID */
-  id?: string | number;
+  id?: string;
   /** 批次编码 */
   batchCode?: string;
   /** 批次名称 */
@@ -76,7 +76,7 @@ export interface ScholarshipBatchForm {
   /** 通知内容 */
   noticeContent?: string;
   /** 关联的奖学金类型ID列表 */
-  scholarshipTypeIds?: Array<string | number>;
+  scholarshipTypeIds?: Array<string>;
 }
 
 export interface ScholarshipBatchQuery extends PageQuery {
@@ -106,7 +106,7 @@ export function listScholarshipBatch(query: ScholarshipBatchQuery): AxiosPromise
 }
 
 // 查询奖学金评定批次详细
-export function getScholarshipBatch(id: string | number): AxiosPromise<ScholarshipBatchVO> {
+export function getScholarshipBatch(id: string): AxiosPromise<ScholarshipBatchVO> {
   return request({
     url: '/jcbt/scholarshipBatch/' + id,
     method: 'get'
@@ -132,7 +132,7 @@ export function updateScholarshipBatch(data: ScholarshipBatchForm) {
 }
 
 // 删除奖学金评定批次
-export function delScholarshipBatch(id: string | number | Array<string | number>) {
+export function delScholarshipBatch(id: string | Array<string>) {
   return request({
     url: '/jcbt/scholarshipBatch/' + id,
     method: 'delete'
@@ -177,7 +177,7 @@ export function getActiveBatches(): AxiosPromise<ScholarshipBatchVO[]> {
 }
 
 // 检查批次编码是否唯一
-export function checkBatchCodeUnique(batchCode: string, id?: string | number): AxiosPromise<boolean> {
+export function checkBatchCodeUnique(batchCode: string, id?: string): AxiosPromise<boolean> {
   return request({
     url: '/jcbt/scholarshipBatch/checkBatchCodeUnique',
     method: 'get',
@@ -189,7 +189,7 @@ export function checkBatchCodeUnique(batchCode: string, id?: string | number): A
 }
 
 // 更改批次状态
-export function changeScholarshipBatchStatus(id: string | number, status: string) {
+export function changeScholarshipBatchStatus(id: string, status: string) {
   return request({
     url: '/jcbt/scholarshipBatch/changeStatus',
     method: 'put',

+ 0 - 4
web/src/api/jcbt/workStudyApplication.ts

@@ -27,8 +27,6 @@ export interface WorkStudyApplicationQuery extends PageQuery {
   positionName?: string;
   /** 岗位类型 */
   positionType?: string;
-  /** 工作地点 */
-  workLocation?: string;
   /** 申请状态 */
   status?: string;
   /** 学院审核状态 */
@@ -76,8 +74,6 @@ export interface WorkStudyApplicationForm {
   positionName: string;
   /** 岗位类型 */
   positionType: string;
-  /** 工作地点 */
-  workLocation: string;
   /** 计划工作时长 */
   plannedWorkHours?: number;
   /** 家庭经济情况 */

+ 30 - 5
web/src/views/jcbt/scholarship/batch/index.vue

@@ -720,12 +720,14 @@ function handleAdd() {
 
 /** 修改按钮操作 */
 async function handleUpdate(row?: ScholarshipBatchVO) {
-  reset();
   const _id = row?.id || ids.value[0];
   const res = await getScholarshipBatch(_id);
 
-  // 先赋值基本数据
-  Object.assign(form.value, res.data);
+  // 关键修复:不调用reset(),直接赋值数据,确保ID不会被重置为undefined
+  form.value = {
+    ...res.data,
+    id: String(_id)  // 🔧 修复:确保ID为字符串格式,避免精度丢失
+  };
 
   // 确保scholarshipTypeIds正确赋值
   if (res.data.scholarshipTypeIds && Array.isArray(res.data.scholarshipTypeIds)) {
@@ -734,6 +736,13 @@ async function handleUpdate(row?: ScholarshipBatchVO) {
     form.value.scholarshipTypeIds = [];
   }
 
+  // 清除表单验证状态,但不重置数据
+  batchFormRef.value?.clearValidate();
+
+  // 调试日志 - 验证ID是否正确
+  console.log('修改操作 - ID:', form.value.id, '类型:', typeof form.value.id);
+  console.log('修改操作 - 完整数据:', JSON.stringify(form.value, null, 2));
+
   dialog.visible = true;
   dialog.title = '修改奖学金评定批次';
 }
@@ -753,6 +762,10 @@ function submitForm() {
     buttonLoading.value = true;
 
     try {
+      // 调试日志 - 提交前检查数据
+      console.log('提交前表单数据:', form.value);
+      console.log('提交前ID值:', form.value.id, '类型:', typeof form.value.id);
+
       // 检查时间冲突
       const conflictCheck = await checkTimeConflict(form.value);
       if (conflictCheck.data) {
@@ -760,10 +773,22 @@ function submitForm() {
         return;
       }
 
-      if (form.value.id) {
-        await updateScholarshipBatch(form.value);
+      // 关键修复:更严格的ID检查逻辑
+      const isUpdate = form.value.id && form.value.id !== undefined && form.value.id !== '' && form.value.id !== null;
+
+      if (isUpdate) {
+        console.log('执行修改操作,ID:', form.value.id, '类型:', typeof form.value.id);
+        // 🔧 修复:保持ID为字符串格式,避免精度丢失
+        // 不再使用parseInt(),直接使用字符串格式的ID
+        const updateData = {
+          ...form.value,
+          id: String(form.value.id)  // 确保ID始终为字符串格式
+        };
+        console.log('发送到后端的修改数据:', JSON.stringify(updateData, null, 2));
+        await updateScholarshipBatch(updateData);
         proxy?.$modal.msgSuccess('修改成功');
       } else {
+        console.log('执行新增操作,ID为:', form.value.id);
         await addScholarshipBatch(form.value);
         proxy?.$modal.msgSuccess('新增成功');
       }

+ 1 - 5
web/src/views/jcbt/workstudy/Application/form.vue

@@ -16,10 +16,7 @@
           <span class="preview-label">岗位名称:</span>
           <el-tag type="primary" size="large">{{ position?.positionName }}</el-tag>
         </div>
-        <div class="preview-item">
-          <span class="preview-label">工作地点:</span>
-          <span class="preview-value">{{ position?.workLocation }}</span>
-        </div>
+
         <div class="preview-item">
           <span class="preview-label">工作时间:</span>
           <span class="preview-value">{{ position?.workTime }}</span>
@@ -196,7 +193,6 @@ const formData = reactive<WorkStudyApplicationForm>({
   positionId: 0,
   positionName: '',
   positionType: '',
-  workLocation: '',
   familyFinancialStatus: '',
   applicationReason: '',
   personalAbility: '',