wuzhen update

This commit is contained in:
wuzhen committed 2025-08-21 14:21:15 +08:00
1 parent cf5eb97553
commit be3d48b6e3
13 files changed
+273 -59

No files matched your search

@@ -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;
/**
@@ -48,12 +48,6 @@ public class JcbtWorkStudyPosition extends BaseEntity {
*/
private String workTime;
/**
* 工作地点
*/
@TableField(exist = false)
private String workLocation;
/**
* 岗位有效期开始
*/
@@ -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;
}
@@ -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;
/**
* 岗位有效期开始
*/
@@ -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;
}
@@ -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;
}
/**
* 更改批次状态
*/
@@ -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
@@ -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
View File
@@ -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
View File
@@ -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',
-4
View File
@@ -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
View File
@@ -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('新增成功');
}
@@ -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: '',