diff --git a/src/main/java/cn/yinlihupo/common/core/BaseResponse.java b/src/main/java/cn/yinlihupo/common/core/BaseResponse.java new file mode 100644 index 0000000..1e4b22a --- /dev/null +++ b/src/main/java/cn/yinlihupo/common/core/BaseResponse.java @@ -0,0 +1,35 @@ +package cn.yinlihupo.common.core; + +import cn.yinlihupo.common.enums.ErrorCode; +import lombok.Data; + +import java.io.Serializable; + +/** + * 通用返回类 + * + * @param + */ +@Data +public class BaseResponse implements Serializable { + + private int code; + + private T data; + + private String message; + + public BaseResponse(int code, T data, String message) { + this.code = code; + this.data = data; + this.message = message; + } + + public BaseResponse(int code, T data) { + this(code, data, ""); + } + + public BaseResponse(ErrorCode errorCode) { + this(errorCode.getCode(), null, errorCode.getMessage()); + } +} diff --git a/src/main/java/cn/yinlihupo/common/exception/BusinessException.java b/src/main/java/cn/yinlihupo/common/exception/BusinessException.java new file mode 100644 index 0000000..d892a67 --- /dev/null +++ b/src/main/java/cn/yinlihupo/common/exception/BusinessException.java @@ -0,0 +1,29 @@ +package cn.yinlihupo.common.exception; + + +import cn.yinlihupo.common.enums.ErrorCode; + +/** + * 自定义异常类 + */ +public class BusinessException extends RuntimeException { + + /** + * 错误码 + */ + private final int code; + + public BusinessException(ErrorCode errorCode) { + super(errorCode.getMessage()); + this.code = errorCode.getCode(); + } + + public BusinessException(ErrorCode errorCode, String message) { + super(message); + this.code = errorCode.getCode(); + } + + public int getCode() { + return code; + } +} diff --git a/src/main/java/cn/yinlihupo/common/exception/GlobalExceptionHandler.java b/src/main/java/cn/yinlihupo/common/exception/GlobalExceptionHandler.java new file mode 100644 index 0000000..01424c0 --- /dev/null +++ b/src/main/java/cn/yinlihupo/common/exception/GlobalExceptionHandler.java @@ -0,0 +1,63 @@ +package cn.yinlihupo.common.exception; + +import cn.hutool.core.exceptions.UtilException; +import cn.yinlihupo.common.core.BaseResponse; +import cn.yinlihupo.common.enums.ErrorCode; +import cn.yinlihupo.common.util.ResultUtils; +import lombok.extern.slf4j.Slf4j; +import org.springframework.core.Ordered; +import org.springframework.core.annotation.Order; +import org.springframework.validation.BindException; +import org.springframework.validation.FieldError; +import org.springframework.web.bind.MethodArgumentNotValidException; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.RestControllerAdvice; + +import java.util.stream.Collectors; + +/** + * 全局异常处理器 + * + */ +@RestControllerAdvice +@Slf4j +@Order(Ordered.LOWEST_PRECEDENCE) +public class GlobalExceptionHandler { + + @ExceptionHandler(BusinessException.class) + public BaseResponse businessExceptionHandler(BusinessException e) { + log.error("BusinessException", e); + return ResultUtils.error(e.getCode(), e.getMessage()); + } + + @ExceptionHandler(UtilException.class) + public BaseResponse utilExceptionHandler(UtilException e) { + log.error("UtilException", e); + return ResultUtils.error(ErrorCode.SYSTEM_ERROR, e.getMessage()); + } + + @ExceptionHandler(MethodArgumentNotValidException.class) + public BaseResponse methodArgumentNotValidExceptionHandler(MethodArgumentNotValidException e) { + log.error("MethodArgumentNotValidException", e); + String errorMsg = e.getBindingResult().getFieldErrors().stream() + .map(FieldError::getDefaultMessage) + .collect(Collectors.joining("; ")); + return ResultUtils.error(ErrorCode.PARAMS_ERROR, errorMsg); + } + + @ExceptionHandler(BindException.class) + public BaseResponse bindExceptionHandler(BindException e) { + log.error("BindException", e); + String errorMsg = e.getBindingResult().getFieldErrors().stream() + .map(FieldError::getDefaultMessage) + .collect(Collectors.joining("; ")); + return ResultUtils.error(ErrorCode.PARAMS_ERROR, errorMsg); + } + + @ExceptionHandler(RuntimeException.class) + public BaseResponse runtimeExceptionHandler(RuntimeException e) { + log.error("RuntimeException", e); + return ResultUtils.error(ErrorCode.SYSTEM_ERROR, "系统错误"); + } + +} diff --git a/src/main/java/cn/yinlihupo/common/result/Result.java b/src/main/java/cn/yinlihupo/common/result/Result.java deleted file mode 100644 index fffc844..0000000 --- a/src/main/java/cn/yinlihupo/common/result/Result.java +++ /dev/null @@ -1,89 +0,0 @@ -package cn.yinlihupo.common.result; - -import lombok.Data; - -import java.io.Serializable; - -/** - * 统一响应结果封装 - * - * @param 数据类型 - */ -@Data -public class Result implements Serializable { - - private static final long serialVersionUID = 1L; - - /** - * 状态码 - */ - private Integer code; - - /** - * 响应消息 - */ - private String message; - - /** - * 响应数据 - */ - private T data; - - /** - * 时间戳 - */ - private Long timestamp; - - public Result() { - this.timestamp = System.currentTimeMillis(); - } - - public Result(Integer code, String message, T data) { - this.code = code; - this.message = message; - this.data = data; - this.timestamp = System.currentTimeMillis(); - } - - /** - * 成功响应 - */ - public static Result success() { - return new Result<>(200, "操作成功", null); - } - - /** - * 成功响应(带数据) - */ - public static Result success(T data) { - return new Result<>(200, "操作成功", data); - } - - /** - * 成功响应(带消息和数据) - */ - public static Result success(String message, T data) { - return new Result<>(200, message, data); - } - - /** - * 失败响应 - */ - public static Result error() { - return new Result<>(500, "操作失败", null); - } - - /** - * 失败响应(带消息) - */ - public static Result error(String message) { - return new Result<>(500, message, null); - } - - /** - * 失败响应(带状态码和消息) - */ - public static Result error(Integer code, String message) { - return new Result<>(code, message, null); - } -} diff --git a/src/main/java/cn/yinlihupo/common/result/package-info.java b/src/main/java/cn/yinlihupo/common/result/package-info.java deleted file mode 100644 index 6483ba0..0000000 --- a/src/main/java/cn/yinlihupo/common/result/package-info.java +++ /dev/null @@ -1,5 +0,0 @@ -/** - * 统一响应模块 - * 包含统一响应结果封装 - */ -package cn.yinlihupo.ylhpaiprojectmanager.common.result; diff --git a/src/main/java/cn/yinlihupo/common/util/ResultUtils.java b/src/main/java/cn/yinlihupo/common/util/ResultUtils.java new file mode 100644 index 0000000..7c9b008 --- /dev/null +++ b/src/main/java/cn/yinlihupo/common/util/ResultUtils.java @@ -0,0 +1,77 @@ +package cn.yinlihupo.common.util; + + +import cn.yinlihupo.common.core.BaseResponse; +import cn.yinlihupo.common.enums.ErrorCode; + +/** + * 返回工具类 + * + */ +public class ResultUtils { + + /** + * 成功 + * + * @param data + * @param + * @return + */ + public static BaseResponse success(T data) { + return new BaseResponse<>(200, data, "ok"); + } + + /** + * 成功 + * + * @param message 成功消息 + * @param data 数据 + * @param + * @return + */ + public static BaseResponse success(String message, T data) { + return new BaseResponse<>(200, data, message); + } + + /** + * 失败 + * + * @param message 错误消息 + * @return + */ + public static BaseResponse error(String message) { + return new BaseResponse(500, null, message); + } + + /** + * 失败 + * + * @param errorCode + * @return + */ + public static BaseResponse error(ErrorCode errorCode) { + return new BaseResponse<>(errorCode); + } + + /** + * 失败 + * + * @param code + * @param message + * @return + */ + public static BaseResponse error(int code, String message) { + return new BaseResponse(code, null, message); + } + + /** + * 失败 + * + * @param errorCode + * @param message + * @return + */ + public static BaseResponse error(ErrorCode errorCode, String message) { + return new BaseResponse(errorCode.getCode(), null, message); + } +} diff --git a/src/main/java/cn/yinlihupo/controller/oss/OssController.java b/src/main/java/cn/yinlihupo/controller/oss/OssController.java index b51b426..086d422 100644 --- a/src/main/java/cn/yinlihupo/controller/oss/OssController.java +++ b/src/main/java/cn/yinlihupo/controller/oss/OssController.java @@ -1,6 +1,7 @@ package cn.yinlihupo.controller.oss; -import cn.yinlihupo.common.result.Result; +import cn.yinlihupo.common.core.BaseResponse; +import cn.yinlihupo.common.util.ResultUtils; import cn.yinlihupo.service.oss.OssService; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -26,19 +27,19 @@ public class OssController { * @return 文件URL */ @PostMapping("/upload") - public Result uploadFile(@RequestParam("file") MultipartFile file) { + public BaseResponse uploadFile(@RequestParam("file") MultipartFile file) { log.info("收到文件上传请求, 文件名: {}", file.getOriginalFilename()); if (file.isEmpty()) { - return Result.error("上传文件不能为空"); + return ResultUtils.error("上传文件不能为空"); } try { String fileUrl = ossService.uploadFile(file, file.getOriginalFilename()); - return Result.success("文件上传成功", fileUrl); + return ResultUtils.success("文件上传成功", fileUrl); } catch (Exception e) { log.error("文件上传失败: {}", e.getMessage(), e); - return Result.error("文件上传失败: " + e.getMessage()); + return ResultUtils.error("文件上传失败: " + e.getMessage()); } } @@ -50,21 +51,21 @@ public class OssController { * @return 文件URL */ @PostMapping("/upload/{bucketName}") - public Result uploadFileToBucket( + public BaseResponse uploadFileToBucket( @RequestParam("file") MultipartFile file, @PathVariable String bucketName) { log.info("收到文件上传请求, 文件名: {}, 存储桶: {}", file.getOriginalFilename(), bucketName); if (file.isEmpty()) { - return Result.error("上传文件不能为空"); + return ResultUtils.error("上传文件不能为空"); } try { String fileUrl = ossService.uploadFile(file, file.getOriginalFilename(), bucketName); - return Result.success("文件上传成功", fileUrl); + return ResultUtils.success("文件上传成功", fileUrl); } catch (Exception e) { log.error("文件上传失败: {}", e.getMessage(), e); - return Result.error("文件上传失败: " + e.getMessage()); + return ResultUtils.error("文件上传失败: " + e.getMessage()); } } @@ -75,15 +76,15 @@ public class OssController { * @return 操作结果 */ @DeleteMapping("/delete") - public Result deleteFile(@RequestParam("fileUrl") String fileUrl) { + public BaseResponse deleteFile(@RequestParam("fileUrl") String fileUrl) { log.info("收到文件删除请求, fileUrl: {}", fileUrl); try { ossService.deleteFile(fileUrl); - return Result.success("文件删除成功", null); + return ResultUtils.success("文件删除成功", null); } catch (Exception e) { log.error("文件删除失败: {}", e.getMessage(), e); - return Result.error("文件删除失败: " + e.getMessage()); + return ResultUtils.error("文件删除失败: " + e.getMessage()); } } } diff --git a/src/main/java/cn/yinlihupo/controller/project/ProjectController.java b/src/main/java/cn/yinlihupo/controller/project/ProjectController.java index fdf3cb5..0c59f01 100644 --- a/src/main/java/cn/yinlihupo/controller/project/ProjectController.java +++ b/src/main/java/cn/yinlihupo/controller/project/ProjectController.java @@ -1,6 +1,7 @@ package cn.yinlihupo.controller.project; -import cn.yinlihupo.common.result.Result; +import cn.yinlihupo.common.core.BaseResponse; +import cn.yinlihupo.common.util.ResultUtils; import cn.yinlihupo.domain.vo.ProjectInitResult; import cn.yinlihupo.service.oss.OssService; import cn.yinlihupo.service.project.ProjectService; @@ -29,20 +30,20 @@ public class ProjectController { * @return 项目初始化结构化数据 */ @PostMapping("/from-file") - public Result generateFromFile(@RequestParam("file") MultipartFile file) { + public BaseResponse generateFromFile(@RequestParam("file") MultipartFile file) { log.info("收到项目初始化请求(文件上传), 文件名: {}", file.getOriginalFilename()); if (file.isEmpty()) { - return Result.error("上传文件不能为空"); + return ResultUtils.error("上传文件不能为空"); } try { // 上传文件、生成项目初始化数据并保存到数据库 ProjectInitResult result = projectService.generateAndSaveProject(file); - return Result.success("项目初始化成功", result); + return ResultUtils.success("项目初始化成功", result); } catch (Exception e) { log.error("项目初始化失败: {}", e.getMessage(), e); - return Result.error("项目初始化失败: " + e.getMessage()); + return ResultUtils.error("项目初始化失败: " + e.getMessage()); } } diff --git a/src/main/java/cn/yinlihupo/domain/entity/Project.java b/src/main/java/cn/yinlihupo/domain/entity/Project.java index 3c58e17..dc00686 100644 --- a/src/main/java/cn/yinlihupo/domain/entity/Project.java +++ b/src/main/java/cn/yinlihupo/domain/entity/Project.java @@ -17,7 +17,7 @@ import java.util.List; @TableName("project") public class Project { - @TableId(type = IdType.AUTO) + @TableId(type = IdType.ASSIGN_ID) private Long id; /** diff --git a/src/main/java/cn/yinlihupo/domain/entity/ProjectInitRecord.java b/src/main/java/cn/yinlihupo/domain/entity/ProjectInitRecord.java deleted file mode 100644 index 06ea50a..0000000 --- a/src/main/java/cn/yinlihupo/domain/entity/ProjectInitRecord.java +++ /dev/null @@ -1,105 +0,0 @@ -package cn.yinlihupo.domain.entity; - -import cn.yinlihupo.common.handler.JsonbTypeHandler; -import com.baomidou.mybatisplus.annotation.*; -import lombok.Data; - -import java.time.LocalDateTime; -import java.util.List; - -/** - * 项目初始化记录实体类 - * 对应数据库表: project_init_record - */ -@Data -@TableName("project_init_record") -public class ProjectInitRecord { - - @TableId(type = IdType.AUTO) - private Long id; - - /** - * 项目ID - */ - private Long projectId; - - /** - * 上传的文件列表[{name, path, type, size}] - */ - @TableField(typeHandler = JsonbTypeHandler.class) - private List inputFiles; - - /** - * 用户输入的项目描述 - */ - private String inputText; - - /** - * 状态: pending-待解析, processing-解析中, completed-已完成, failed-失败 - */ - private String parseStatus; - - /** - * 解析结果(结构化数据) - */ - @TableField(typeHandler = JsonbTypeHandler.class) - private Object parseResult; - - /** - * 生成的里程碑数量 - */ - private Integer generatedMilestones; - - /** - * 生成的任务数量 - */ - private Integer generatedTasks; - - /** - * 生成的成员数量 - */ - private Integer generatedMembers; - - /** - * 生成的资源数量 - */ - private Integer generatedResources; - - /** - * 使用的AI模型 - */ - private String model; - - /** - * 消耗的Token数 - */ - private Integer tokensUsed; - - /** - * 错误信息 - */ - private String errorMessage; - - /** - * 创建时间 - */ - @TableField(fill = FieldFill.INSERT) - private LocalDateTime createTime; - - /** - * 更新时间 - */ - @TableField(fill = FieldFill.INSERT_UPDATE) - private LocalDateTime updateTime; - - /** - * 输入文件信息内部类 - */ - @Data - public static class InputFile { - private String name; - private String path; - private String type; - private Long size; - } -} diff --git a/src/main/java/cn/yinlihupo/domain/entity/ProjectMember.java b/src/main/java/cn/yinlihupo/domain/entity/ProjectMember.java index 9fe2747..5ad2306 100644 --- a/src/main/java/cn/yinlihupo/domain/entity/ProjectMember.java +++ b/src/main/java/cn/yinlihupo/domain/entity/ProjectMember.java @@ -15,7 +15,7 @@ import java.time.LocalDateTime; @TableName("project_member") public class ProjectMember { - @TableId(type = IdType.AUTO) + @TableId(type = IdType.ASSIGN_ID) private Long id; /** diff --git a/src/main/java/cn/yinlihupo/domain/entity/ProjectMilestone.java b/src/main/java/cn/yinlihupo/domain/entity/ProjectMilestone.java index 141bafc..4506554 100644 --- a/src/main/java/cn/yinlihupo/domain/entity/ProjectMilestone.java +++ b/src/main/java/cn/yinlihupo/domain/entity/ProjectMilestone.java @@ -16,7 +16,7 @@ import java.util.List; @TableName("project_milestone") public class ProjectMilestone { - @TableId(type = IdType.AUTO) + @TableId(type = IdType.ASSIGN_ID) private Long id; /** diff --git a/src/main/java/cn/yinlihupo/domain/entity/ProjectTimeline.java b/src/main/java/cn/yinlihupo/domain/entity/ProjectTimeline.java index 871e71a..7c68042 100644 --- a/src/main/java/cn/yinlihupo/domain/entity/ProjectTimeline.java +++ b/src/main/java/cn/yinlihupo/domain/entity/ProjectTimeline.java @@ -16,7 +16,7 @@ import java.util.List; @TableName("project_timeline") public class ProjectTimeline { - @TableId(type = IdType.AUTO) + @TableId(type = IdType.ASSIGN_ID) private Long id; /** diff --git a/src/main/java/cn/yinlihupo/domain/entity/Resource.java b/src/main/java/cn/yinlihupo/domain/entity/Resource.java index 84993d4..5d305c9 100644 --- a/src/main/java/cn/yinlihupo/domain/entity/Resource.java +++ b/src/main/java/cn/yinlihupo/domain/entity/Resource.java @@ -17,7 +17,7 @@ import java.util.List; @TableName("resource") public class Resource { - @TableId(type = IdType.AUTO) + @TableId(type = IdType.ASSIGN_ID) private Long id; /** diff --git a/src/main/java/cn/yinlihupo/domain/entity/Risk.java b/src/main/java/cn/yinlihupo/domain/entity/Risk.java index 3166823..c3f0f67 100644 --- a/src/main/java/cn/yinlihupo/domain/entity/Risk.java +++ b/src/main/java/cn/yinlihupo/domain/entity/Risk.java @@ -17,7 +17,7 @@ import java.util.List; @TableName("risk") public class Risk { - @TableId(type = IdType.AUTO) + @TableId(type = IdType.ASSIGN_ID) private Long id; /** diff --git a/src/main/java/cn/yinlihupo/domain/entity/Task.java b/src/main/java/cn/yinlihupo/domain/entity/Task.java index e08834f..ad6d830 100644 --- a/src/main/java/cn/yinlihupo/domain/entity/Task.java +++ b/src/main/java/cn/yinlihupo/domain/entity/Task.java @@ -17,7 +17,7 @@ import java.util.List; @TableName("task") public class Task { - @TableId(type = IdType.AUTO) + @TableId(type = IdType.ASSIGN_ID) private Long id; /** diff --git a/src/main/java/cn/yinlihupo/mapper/ProjectInitRecordMapper.java b/src/main/java/cn/yinlihupo/mapper/ProjectInitRecordMapper.java deleted file mode 100644 index 7dfe4e8..0000000 --- a/src/main/java/cn/yinlihupo/mapper/ProjectInitRecordMapper.java +++ /dev/null @@ -1,12 +0,0 @@ -package cn.yinlihupo.mapper; - -import cn.yinlihupo.domain.entity.ProjectInitRecord; -import com.baomidou.mybatisplus.core.mapper.BaseMapper; -import org.apache.ibatis.annotations.Mapper; - -/** - * 项目初始化记录Mapper接口 - */ -@Mapper -public interface ProjectInitRecordMapper extends BaseMapper { -} diff --git a/src/main/java/cn/yinlihupo/service/project/ProjectService.java b/src/main/java/cn/yinlihupo/service/project/ProjectService.java index 4e33b98..dff2616 100644 --- a/src/main/java/cn/yinlihupo/service/project/ProjectService.java +++ b/src/main/java/cn/yinlihupo/service/project/ProjectService.java @@ -3,8 +3,6 @@ package cn.yinlihupo.service.project; import cn.yinlihupo.domain.vo.ProjectInitResult; import org.springframework.web.multipart.MultipartFile; -import java.util.List; - /** * AI项目初始化服务接口 * 使用Spring AI结构化输出能力,从项目文档中提取结构化信息 @@ -40,8 +38,7 @@ public interface ProjectService { * 根据项目资料内容生成并保存项目初始化数据 * * @param content 项目资料文本内容 - * @param inputFiles 输入文件列表信息 * @return 项目初始化结果 */ - ProjectInitResult generateAndSaveProjectFromContent(String content, List inputFiles); + ProjectInitResult generateAndSaveProjectFromContent(String content); } diff --git a/src/main/java/cn/yinlihupo/service/project/impl/ProjectServiceImpl.java b/src/main/java/cn/yinlihupo/service/project/impl/ProjectServiceImpl.java index f019c9a..3d1d5d5 100644 --- a/src/main/java/cn/yinlihupo/service/project/impl/ProjectServiceImpl.java +++ b/src/main/java/cn/yinlihupo/service/project/impl/ProjectServiceImpl.java @@ -44,7 +44,6 @@ public class ProjectServiceImpl implements ProjectService { private final ResourceMapper resourceMapper; private final RiskMapper riskMapper; private final ProjectTimelineMapper projectTimelineMapper; - private final ProjectInitRecordMapper projectInitRecordMapper; /** * 项目初始化系统提示词模板 @@ -214,17 +213,8 @@ public class ProjectServiceImpl implements ProjectService { throw new RuntimeException("无法读取文件内容: " + fileUrl); } - // 3. 构建输入文件信息 - List inputFiles = new ArrayList<>(); - ProjectInitRecord.InputFile inputFile = new ProjectInitRecord.InputFile(); - inputFile.setName(file.getOriginalFilename()); - inputFile.setPath(fileUrl); - inputFile.setType(file.getContentType()); - inputFile.setSize(file.getSize()); - inputFiles.add(inputFile); - - // 4. 生成并保存项目数据 - return generateAndSaveProjectFromContent(content, inputFiles); + // 3. 生成并保存项目数据 + return generateAndSaveProjectFromContent(content); } catch (Exception e) { log.error("项目初始化失败: {}", e.getMessage(), e); @@ -234,22 +224,13 @@ public class ProjectServiceImpl implements ProjectService { @Override @Transactional(rollbackFor = Exception.class) - public ProjectInitResult generateAndSaveProjectFromContent(String content, - List inputFiles) { + public ProjectInitResult generateAndSaveProjectFromContent(String content) { log.info("开始生成并保存项目初始化数据"); - // 1. 先创建初始化记录(状态为处理中) - ProjectInitRecord initRecord = new ProjectInitRecord(); - initRecord.setInputFiles(inputFiles); - initRecord.setInputText(content.length() > 5000 ? content.substring(0, 5000) + "..." : content); - initRecord.setParseStatus("processing"); - projectInitRecordMapper.insert(initRecord); - - ProjectInitResult result = null; - Usage usage = null; + ProjectInitResult result; try { - // 2. 调用AI生成项目数据 + // 1. 调用AI生成项目数据 String userPrompt = "请根据以下项目资料,生成完整的项目初始化结构化数据:\n\n" + content + "\n\n" + "请严格按照系统提示词中的JSON格式输出,确保所有字段都包含合理的值。"; @@ -266,38 +247,15 @@ public class ProjectServiceImpl implements ProjectService { // 使用 BeanOutputConverter 手动转换响应内容 String responseContent = chatResponse.getResult().getOutput().getText(); result = outputConverter.convert(responseContent); - usage = chatResponse.getMetadata().getUsage(); - // 3. 保存项目数据到数据库 + // 2. 保存项目数据到数据库 Long projectId = saveProjectData(result); - // 4. 更新初始化记录为成功状态 - initRecord.setProjectId(projectId); - initRecord.setParseStatus("completed"); - initRecord.setParseResult(result); - initRecord.setGeneratedMilestones(result.getMilestones() != null ? result.getMilestones().size() : 0); - initRecord.setGeneratedTasks(result.getTasks() != null ? result.getTasks().size() : 0); - initRecord.setGeneratedMembers(result.getMembers() != null ? result.getMembers().size() : 0); - initRecord.setGeneratedResources(result.getResources() != null ? result.getResources().size() : 0); - if (usage != null) { - initRecord.setTokensUsed(usage.getTotalTokens()); - } - projectInitRecordMapper.updateById(initRecord); - log.info("项目初始化数据保存成功, projectId: {}", projectId); return result; } catch (Exception e) { log.error("项目初始化失败: {}", e.getMessage(), e); - - // 更新初始化记录为失败状态 - initRecord.setParseStatus("failed"); - initRecord.setErrorMessage(e.getMessage()); - if (usage != null) { - initRecord.setTokensUsed(usage.getTotalTokens()); - } - projectInitRecordMapper.updateById(initRecord); - throw new RuntimeException("项目初始化失败: " + e.getMessage(), e); } }