guyue
2025-08-12 a271ed5a232236383bc96c8c1e380a5c91dc1c3c
代码规范
1个文件已删除
22个文件已修改
4个文件已添加
370 ■■■■ 已修改文件
pom.xml 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/linghu/config/FinalStatus.java 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/linghu/config/GlobalExceptionHandler.java 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/linghu/controller/AuthController.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/linghu/controller/CollectController.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/linghu/controller/KeywordController.java 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/linghu/controller/PlatformController.java 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/linghu/controller/QuestionController.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/linghu/controller/SectionalizationController.java 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/linghu/controller/TypeController.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/linghu/controller/UserController.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/linghu/model/dto/KeywordDto.java 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/linghu/model/entity/Keyword.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/linghu/model/entity/Platform.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/linghu/model/entity/Question.java 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/linghu/model/entity/Sectionalization.java 5 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/linghu/model/entity/Type.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/linghu/model/validator/CreateGroup.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/linghu/model/validator/QueryGroup.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/linghu/model/validator/UpdateGroup.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/linghu/service/impl/CollectionServiceImpl.java 22 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/linghu/service/impl/KeywordServiceImpl.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/linghu/service/impl/OrderServiceImpl.java 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/linghu/service/impl/QuestionServiceImpl.java 14 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/linghu/service/impl/TypeServiceImpl.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/linghu/timeTask/ScheduledTasks.java 38 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/linghu/utils/JwtUtils.java 82 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pom.xml
@@ -55,23 +55,7 @@
            <artifactId>easyexcel</artifactId>
            <version>3.3.2</version>
        </dependency>
        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt-api</artifactId>
            <version>0.12.5</version>
        </dependency>
        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt-impl</artifactId>
            <version>0.12.5</version>
        </dependency>
        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt-jackson</artifactId> <!-- 或 jjwt-gson -->
            <version>0.12.5</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-validation</artifactId>
src/main/java/com/linghu/config/FinalStatus.java
@@ -4,19 +4,34 @@
@Getter
public enum FinalStatus {
    //成功
    SUCCESS("success"),
    //没有结果
    NO_RESULTS("no_results"),
    //繁忙
    BUSYNESS("busyness"),
    //已取消
    CANCELLED("cancelled"),
    //已完成
    COMPLETED("completed"),
    CANCELED("canceled"),
    //报错
    ERROR("ERROR"),
    //已提交
    SUBMITTED("submitted"),
    //待处理
    PENDING("pending"),
    //网络错误
    FALSE("false"),
    //不存在
    NONENTITY("nonentity"),
    //未提交
    NOTSUBMITTED("notSubmitted"),
    //执行中
    RUNNING("running"),
    //失败
    FAILED("failed");
    private final String value;
    
    FinalStatus(String value) {
src/main/java/com/linghu/config/GlobalExceptionHandler.java
New file
@@ -0,0 +1,45 @@
package com.linghu.config;
import com.linghu.model.common.ResponseResult;
import org.springframework.validation.BindingResult;
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 javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
// 全局异常处理器,作用于所有 @RestController 注解的控制器
@RestControllerAdvice
public class GlobalExceptionHandler {
    // 处理 @RequestBody 参数校验失败的异常(如 DTO 中的校验)
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ResponseResult handleMethodArgumentNotValid(MethodArgumentNotValidException e) {
        Map<String, String> errors = new HashMap<>();
        // 获取所有校验失败的字段和消息
        BindingResult bindingResult = e.getBindingResult();
        for (FieldError fieldError : e.getBindingResult().getFieldErrors()) {
            // 字段名 -> 错误消息(如 "keyword: 关键词不能为空")
            errors.put(fieldError.getField(), fieldError.getDefaultMessage());
        }
        // 返回自定义的错误响应(根据你的 ResponseResult 结构调整)
        return ResponseResult.error("参数校验失败"+ errors);
    }
    // 处理 @RequestParam/@PathVariable 参数校验失败的异常
    @ExceptionHandler(ConstraintViolationException.class)
    public ResponseResult<Map<String, String>> handleConstraintViolation(ConstraintViolationException e) {
        Map<String, String> errors = new HashMap<>();
        for (ConstraintViolation<?> violation : e.getConstraintViolations()) {
            String field = violation.getPropertyPath().toString();
            String simplifiedField = field.substring(field.lastIndexOf('.') + 1);
            errors.put(simplifiedField, violation.getMessage());
        }
        return ResponseResult.error("参数校验失败"+ errors);
    }
}
src/main/java/com/linghu/controller/AuthController.java
@@ -32,7 +32,7 @@
    }
    @GetMapping("/getToken")
    @ApiOperation(value = "获取token")
    public ResponseEntity<?> getToken( String user) {
    public ResponseEntity<?> getToken(@RequestParam(value = "user" ) String user) {
        // 创建JwtUtils对象,并生成JWT令牌
        OpenCryptUtil openCryptUtil = new OpenCryptUtil();
        String decrypt = openCryptUtil.encrypt(user);
src/main/java/com/linghu/controller/CollectController.java
@@ -42,13 +42,13 @@
    @ApiOperation(value = "查询任务状态")
    @GetMapping("/status")
    public Mono<TaskStatusResponse> getTaskStatus(String taskId) {
    public Mono<TaskStatusResponse> getTaskStatus(@RequestParam(value = "taskId" )String taskId) {
        return collectionService.getError(taskId);
    }
    @PostMapping("/cancel/{keywordId}")
    @ApiOperation(value = "取消任务")
    public Mono<ResponseResult<TaskCancelResponse>> cancelTask(@PathVariable Integer keywordId) {
    public Mono<ResponseResult<TaskCancelResponse>> cancelTask(@PathVariable  Integer keywordId) {
        return collectionService.getResponseResult(keywordId);
    }
src/main/java/com/linghu/controller/KeywordController.java
@@ -1,6 +1,7 @@
package com.linghu.controller;
import com.alibaba.excel.EasyExcel;
import com.linghu.config.FinalStatus;
import com.linghu.listener.KeywordExcelListener;
import com.linghu.model.common.ResponseResult;
import com.linghu.model.dto.ExportFeedDTO;
@@ -10,6 +11,7 @@
import com.linghu.model.dto.ExportStaticsDTO;
import com.linghu.model.entity.*;
import com.linghu.model.excel.*;
import com.linghu.model.validator.UpdateGroup;
import com.linghu.model.vo.*;
import com.linghu.model.vo.KeywordStaticsListVO;
import com.linghu.model.vo.PlatformProportionVO;
@@ -24,6 +26,7 @@
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
@@ -66,7 +69,7 @@
    @PostMapping(value = "/exportStatics")
    @ApiOperation(value = "EChart图导出")
    public ResponseEntity<byte[]> exportStatics(@RequestBody ExportStaticsDTO exportStaticsDTO) {
    public ResponseEntity<byte[]> exportStatics(@Valid @RequestBody ExportStaticsDTO exportStaticsDTO) {
        return keywordService.exportEChart(exportStaticsDTO);
    }
@@ -92,7 +95,7 @@
     */
    @PostMapping(value = "/exportGetResultByTypeId")
    @ApiOperation(value = "导出:根据类别查看")
    public ResponseEntity<byte[]> exportGetResultByTypeId(@RequestBody ExportGetResultDTO dto) {
    public ResponseEntity<byte[]> exportGetResultByTypeId(@Valid @RequestBody ExportGetResultDTO dto) {
        return keywordService.exportResult(dto);
    }
@@ -190,8 +193,8 @@
     */
    @PostMapping("/updateKeyword")
    @ApiOperation(value = "修改关键词")
    public ResponseResult<String> updateKeyword(@RequestBody Keyword keyword) {
        if("submitted".equals(keyword.getStatus())){
    public ResponseResult<String> updateKeyword(@Validated(UpdateGroup.class) @RequestBody Keyword keyword) {
        if(FinalStatus.SUBMITTED.getValue().equals(keyword.getStatus())){
            return ResponseResult.error("关键词已开始采集不允许修改!");
        }
        keywordService.updateById(keyword);
@@ -205,7 +208,7 @@
    @ApiOperation(value = "删除关键词")
    public ResponseResult<String> deleteKeyword(@RequestParam("keywordId") Integer keywordId) {
        Keyword keyword = keywordService.getById(keywordId);
        if("submitted".equals(keyword.getStatus())){
        if(FinalStatus.SUBMITTED.getValue().equals(keyword.getStatus())){
            return ResponseResult.error("关键词已开始采集或不允许删除!");
        }
        keywordService.removeById(keywordId);
src/main/java/com/linghu/controller/PlatformController.java
@@ -18,6 +18,8 @@
import com.linghu.model.excel.PlatformExcel;
import com.linghu.model.excel.UserExcel;
import com.linghu.model.page.CustomPage;
import com.linghu.model.validator.CreateGroup;
import com.linghu.model.validator.UpdateGroup;
import com.linghu.service.PlatformService;
import com.linghu.service.TypeService;
@@ -35,6 +37,7 @@
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.util.StringUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
@@ -60,14 +63,14 @@
    @PostMapping
    @ApiOperation(value = "添加平台")
    public ResponseResult<Platform> add(@RequestBody Platform platform) {
    public ResponseResult<Platform> add( @Validated(CreateGroup.class) @RequestBody Platform platform) {
        return platformService.addPlatform(platform);
    }
    @DeleteMapping("/{platformId}")
    @ApiOperation(value = "删除平台")
    public ResponseResult<Void> delete(@PathVariable Integer platformId) {
    public ResponseResult<Void> delete( @PathVariable Integer platformId) {
        return platformService.deleteByPlatFormId(platformId);
    }
@@ -75,7 +78,7 @@
    @PutMapping
    @ApiOperation(value = "更新平台")
    public ResponseResult<Void> update(@RequestBody Platform platform) {
    public ResponseResult<Void> update(@Validated(UpdateGroup.class) @RequestBody Platform platform) {
        return platformService.updatePlatform(platform);
    }
src/main/java/com/linghu/controller/QuestionController.java
@@ -14,6 +14,8 @@
import com.linghu.model.entity.Reference;
import com.linghu.model.excel.KeywordExcel;
import com.linghu.model.excel.QuestionExcel;
import com.linghu.model.validator.CreateGroup;
import com.linghu.model.validator.UpdateGroup;
import com.linghu.service.KeywordService;
import com.linghu.service.QuestionService;
import io.swagger.annotations.Api;
@@ -23,10 +25,12 @@
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.validation.Valid;
import javax.validation.constraints.NotEmpty;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.*;
@@ -44,7 +48,7 @@
    @PostMapping
    @ApiOperation(value = "添加提问词")
    public ResponseResult<List<Question>> add(@Valid @RequestBody KeywordDto keywordDto) {
    public ResponseResult<List<Question>> add(@Validated(CreateGroup.class) @RequestBody KeywordDto keywordDto) {
        return questionService.addQuestion(keywordDto);
    }
@@ -52,27 +56,27 @@
    @PutMapping
    @ApiOperation(value = "修改提问词")
    public ResponseResult<List<Question>> update(@RequestBody KeywordDto keywordDto) {
    public ResponseResult<List<Question>> update(@Validated(UpdateGroup.class) @RequestBody KeywordDto keywordDto) {
        return questionService.updateQuestion(keywordDto);
    }
    @PutMapping("/update")
    @ApiOperation(value = "修改单个提问词")
    public ResponseResult<Void> update(@RequestBody Question questions) {
    public ResponseResult<Void> update(@Validated(UpdateGroup.class) @RequestBody Question questions) {
        return questionService.updateKeyWord(questions);
    }
    @DeleteMapping("/batch")
    @ApiOperation(value = "批量删除提问词")
    public ResponseResult<Void> batchDelete(@RequestBody List<Integer> questionIds) {
    public ResponseResult<Void> batchDelete( @RequestBody List<Integer> questionIds) {
        return questionService.batchDeleteQuestion(questionIds);
    }
    @GetMapping("/list")
    @ApiOperation("根据关键词查询提问词列表")
    public ResponseResult<List<Question>> list(Integer keyword_id) {
    public ResponseResult<List<Question>> list(@RequestParam("keyword_id") Integer keyword_id) {
        return questionService.getQuestionListByKeywordId(keyword_id);
    }
@@ -81,7 +85,7 @@
    @GetMapping("/notNullList")
    @ApiOperation("根据关键词查询提问词列表")
    public ResponseResult<List<Question>> notNullList(Integer keyword_id) {
    public ResponseResult<List<Question>> notNullList(@RequestParam("keyword_id") Integer keyword_id) {
        return questionService.notNullQuestionList(keyword_id);
    }
src/main/java/com/linghu/controller/SectionalizationController.java
@@ -3,14 +3,17 @@
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.linghu.model.common.ResponseResult;
import com.linghu.model.entity.Sectionalization;
import com.linghu.model.validator.UpdateGroup;
import com.linghu.model.vo.SectionalizationUserVO;
import com.linghu.service.SectionalizationService;
import com.linghu.service.UserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import java.util.List;
@RestController
@@ -27,7 +30,7 @@
    @PostMapping
    @ApiOperation(value = "添加")
    public ResponseResult add(@RequestBody Sectionalization sectionalization) {
    public ResponseResult add(@Valid @RequestBody Sectionalization sectionalization) {
        return sectionalizationService.addSectionalization(sectionalization);
    }
@@ -36,7 +39,7 @@
     */
    @PutMapping
    @ApiOperation(value = "修改")
    public ResponseResult edit(@RequestBody Sectionalization sectionalization) {
    public ResponseResult edit(@Validated(UpdateGroup.class) @RequestBody Sectionalization sectionalization) {
        return sectionalizationService.edit(sectionalization);
    }
src/main/java/com/linghu/controller/TypeController.java
@@ -8,13 +8,17 @@
import com.linghu.model.entity.Keyword;
import com.linghu.model.entity.Reference;
import com.linghu.model.entity.Type;
import com.linghu.model.validator.CreateGroup;
import com.linghu.model.validator.UpdateGroup;
import com.linghu.service.KeywordService;
import com.linghu.service.TypeService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
@@ -31,7 +35,7 @@
    @PostMapping
    @ApiOperation(value = "添加类型")
    public ResponseResult<Type> add(@RequestBody Type type) {
    public ResponseResult<Type> add(@Validated( CreateGroup.class) @RequestBody Type type) {
        return typeService.addType(type);
    }
@@ -39,7 +43,7 @@
    @PostMapping("/batch")
    @ApiOperation(value = "批量添加类型")
    public ResponseResult<Void> batchAdd(@RequestBody List<Type> types) {
    public ResponseResult<Void> batchAdd(@Validated(CreateGroup.class) @Valid @RequestBody List<Type> types) {
        boolean success = typeService.saveBatch(types);
        if (success) {
            return ResponseResult.success();
@@ -56,14 +60,14 @@
    @PutMapping
    @ApiOperation(value = "更新类型")
    public ResponseResult<Void> update(@RequestBody Type type) {
    public ResponseResult<Void> update(@Validated(UpdateGroup.class) @RequestBody Type type) {
        typeService.updateById(type);
        return ResponseResult.success();
    }
    @PutMapping("/batch")
    @ApiOperation(value = "批量更新类型")
    public ResponseResult<Void> batchUpdate(@RequestBody List<Type> types) {
    public ResponseResult<Void> batchUpdate(@Validated(UpdateGroup.class) @RequestBody List<Type> types) {
        boolean success = typeService.updateBatchById(types);
        if (success) {
            return ResponseResult.success();
src/main/java/com/linghu/controller/UserController.java
@@ -35,6 +35,7 @@
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.validation.Valid;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.time.LocalDateTime;
@@ -55,7 +56,7 @@
    @PostMapping
    @ApiOperation(value = "添加")
    public ResponseResult add(@RequestBody User user) {
    public ResponseResult add(@Valid @RequestBody User user) {
        return userService.addUser(user);
    }
@@ -65,7 +66,7 @@
     */
    @PutMapping
    @ApiOperation(value = "修改")
    public ResponseResult edit(@RequestBody User user) {
    public ResponseResult edit(@Valid @RequestBody User user) {
        return userService.editUser(user);
    }
src/main/java/com/linghu/model/dto/KeywordDto.java
@@ -1,5 +1,6 @@
package com.linghu.model.dto;
import com.linghu.model.validator.CreateGroup;
import lombok.Data;
import lombok.EqualsAndHashCode;
@@ -7,7 +8,9 @@
import com.linghu.model.entity.Keyword;
import com.linghu.model.entity.Question;
import org.springframework.validation.annotation.Validated;
import javax.validation.Valid;
import javax.validation.constraints.NotEmpty;
@EqualsAndHashCode(callSuper = true)
@@ -16,9 +19,10 @@
    /**
     * 提问词列表,用换行符分隔
     */
    @NotEmpty(message = "提问词不能为空")
    @NotEmpty(message = "提问词不能为空",groups = CreateGroup.class)
    private String questions;
    @Valid
    private List<Question> questionList;
    private List<String> taskIdList;
}
src/main/java/com/linghu/model/entity/Keyword.java
@@ -5,7 +5,11 @@
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import java.io.Serializable;
import com.linghu.model.validator.UpdateGroup;
import lombok.Data;
import javax.validation.constraints.NotNull;
/**
 * 
@@ -18,6 +22,7 @@
     * 关键词
     */
    @TableId(type = IdType.AUTO)
    @NotNull(message = "id 不能为空", groups = UpdateGroup.class)
    private Integer keyword_id;
    /**
src/main/java/com/linghu/model/entity/Platform.java
@@ -8,9 +8,13 @@
import java.time.LocalDateTime;
import java.util.Date;
import com.linghu.model.validator.CreateGroup;
import com.linghu.model.validator.UpdateGroup;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import com.fasterxml.jackson.annotation.JsonFormat;
import javax.validation.constraints.NotNull;
/**
 * 
@@ -24,24 +28,28 @@
         */
        @TableId(type = IdType.AUTO)
        @ApiModelProperty("平台id")
        @NotNull(message = "id 不能为空", groups = UpdateGroup.class)
        private Integer platform_id;
        /**
         * 类型id
         */
        @ApiModelProperty("类型id")
        @NotNull(message = "类型id 不能为空", groups = CreateGroup.class)
        private Integer type_id;
        /**
         * 平台名称
         */
        @ApiModelProperty("平台名称")
        @NotNull(message = "平台名称不能为空", groups = CreateGroup.class)
        private String platform_name;
        /**
         * 平台域名
         */
        @ApiModelProperty("平台域名")
        @NotNull(message = "平台域名不能为空", groups = CreateGroup.class)
        private String domain;
        /**
@@ -67,7 +75,7 @@
        /**
         * 
         */
        @ApiModelProperty("创建者")
        @ApiModelProperty("修改者")
        private String update_by;
        @TableField(exist = false)
src/main/java/com/linghu/model/entity/Question.java
@@ -6,9 +6,13 @@
import com.baomidou.mybatisplus.annotation.TableName;
import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.Date;
import com.linghu.model.validator.CreateGroup;
import com.linghu.model.validator.UpdateGroup;
import lombok.Data;
import com.fasterxml.jackson.annotation.JsonFormat;
import javax.validation.constraints.NotNull;
/**
 * 
@@ -21,6 +25,7 @@
     * 提问词id
     */
    @TableId(type = IdType.AUTO)
    @NotNull(message = "id不能为空",groups = UpdateGroup.class)
    private Integer question_id;
    /**
src/main/java/com/linghu/model/entity/Sectionalization.java
@@ -4,10 +4,12 @@
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.linghu.model.validator.UpdateGroup;
import lombok.Data;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
@Data
@TableName(value = "sectionalization")
@@ -16,9 +18,10 @@
    @TableField(exist = false)
    private static final long serialVersionUID = 1L;
    @TableId(type = IdType.AUTO)
    @NotNull(message = "分组id不能为空", groups = UpdateGroup.class)
    private Integer sectionalization_id;
    @NotEmpty(message = "用户名不能为空")
    @NotEmpty(message = "分组名不能为空")
    private String sectionalization_name;
src/main/java/com/linghu/model/entity/Type.java
@@ -5,7 +5,12 @@
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import java.io.Serializable;
import com.linghu.model.validator.CreateGroup;
import com.linghu.model.validator.UpdateGroup;
import lombok.Data;
import javax.validation.constraints.NotNull;
/**
 * 
@@ -18,11 +23,13 @@
     * 类型
     */
    @TableId(type = IdType.AUTO)
    @NotNull(message = "类型ID不能为空", groups = {UpdateGroup.class})
    private Integer type_id;
    /**
     * 名字
     */
    @NotNull(message = "类型不能为空", groups = {CreateGroup.class, UpdateGroup.class})
    private String type_name;
src/main/java/com/linghu/model/validator/CreateGroup.java
New file
@@ -0,0 +1,3 @@
package com.linghu.model.validator;
public interface CreateGroup {}
src/main/java/com/linghu/model/validator/QueryGroup.java
New file
@@ -0,0 +1,3 @@
package com.linghu.model.validator;
public interface QueryGroup {}
src/main/java/com/linghu/model/validator/UpdateGroup.java
New file
@@ -0,0 +1,3 @@
package com.linghu.model.validator;
public interface UpdateGroup {}
src/main/java/com/linghu/service/impl/CollectionServiceImpl.java
@@ -30,7 +30,6 @@
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.ConcurrentMap;
import java.util.stream.Collectors;
@Slf4j
@Service
public class CollectionServiceImpl implements CollectionService {
@@ -181,7 +180,7 @@
        return Flux.fromIterable(tasksToCancelRemotely)
                .flatMap(task -> {
                    // 创建状态更新和远程取消的组合操作
                    Mono<Void> updateStatus = updateTaskStatus(task.getTask_id(), "cancelled");
                    Mono<Void> updateStatus = updateTaskStatus(task.getTask_id(), FinalStatus.CANCELLED.getValue());
                    Mono<ResponseResult<?>> cancelOp = cancelRemoteTask(task.getTask_id())
                            .onErrorResume(e -> {
                                log.error("取消任务 {} 失败: {}", task.getTask_id(), e.getMessage());
@@ -347,7 +346,7 @@
                    // 如果任务状态是"submitted"或"running",继续轮询
                    if (!FinalStatus.COMPLETED.getValue().equalsIgnoreCase(statusResponse.getStatus())
                            && !FinalStatus.FAILED.getValue().equalsIgnoreCase(statusResponse.getStatus())
                            && !FinalStatus.CANCELED.getValue().equalsIgnoreCase(statusResponse.getStatus())
                            && !FinalStatus.CANCELLED.getValue().equalsIgnoreCase(statusResponse.getStatus())
                            && !(FinalStatus.ERROR.getValue().equalsIgnoreCase(statusResponse.getStatus())
                            && statusResponse.getMessage().contains("Task not found")) ) {
                        return Mono.delay(Duration.ofSeconds(5))  // 延迟 5 秒后再次查询
@@ -453,12 +452,12 @@
                                    if (keywordTasks.size() > 0) {
                                        KeywordTask keywordTask = keywordTasks.get(0);
                                        keywordTask.setTask_id(taskResponse.getTask_id());
                                        keywordTask.setStatus("pending");
                                        keywordTask.setStatus(FinalStatus.PENDING.getValue());
                                        keywordTaskService.updateById(keywordTask);
                                    }
                                    //将提问词列表的状态转为pending
                                    for (String questionName : batchRequest.getQuestions()) {
                                        questionService.update(new LambdaUpdateWrapper<Question>().eq(Question::getKeyword_id, keyword.getKeyword_id()).eq(Question::getQuestion,questionName).set(Question::getStatus, "pending"));
                                        questionService.update(new LambdaUpdateWrapper<Question>().eq(Question::getKeyword_id, keyword.getKeyword_id()).eq(Question::getQuestion,questionName).set(Question::getStatus, FinalStatus.PENDING.getValue()));
                                    }
                                    //所有关键词都在采集中或者已完成或者错误设置订单进入采集状态
@@ -497,7 +496,7 @@
                new LambdaQueryWrapper<KeywordTask>()
                        .eq(KeywordTask::getKeyword_id, keywordId)
                        .isNotNull(KeywordTask::getTask_id)
                        .eq(KeywordTask::getStatus, "pending")
                        .eq(KeywordTask::getStatus, FinalStatus.PENDING.getValue())
        );
    }
@@ -524,7 +523,7 @@
                List<KeywordTask> keywordTasks = keywordTaskService.list(keywordTaskWrapper);
                // 更新关键词状态
                keyword.setStatus("completed");
                keyword.setStatus(FinalStatus.COMPLETED.getValue());
                keywordService.updateById(keyword);
                //更新提问词状态为取消
@@ -588,7 +587,7 @@
    private Mono<ResponseResult<?>> cancelRemoteTask(String taskId) {
        // 使用Collections.singletonMap或手动创建Map
        Map<String, Object> requestBody = new HashMap<>();
        requestBody.put("status", "pending");
        requestBody.put("status", FinalStatus.PENDING.getValue());
        return webClient.post()
                .uri(baseUrl + "/api/v1/tasks/" + taskId + "/cancel")
@@ -762,7 +761,6 @@
                .allMatch(task -> FinalStatus.COMPLETED.getValue().equals(task.getStatus())
                        || FinalStatus.FALSE.getValue().equals(task.getStatus())
                        || FinalStatus.CANCELLED.getValue().equals(task.getStatus())
                        || FinalStatus.CANCELED.getValue().equals(task.getStatus())
                        || FinalStatus.NONENTITY.getValue().equals(task.getStatus()));
        if (allCompletedOrFailed) {
@@ -908,7 +906,9 @@
            List<Reference> validRefGroup = refGroup.stream()
                    .filter(Objects::nonNull)
                    .collect(Collectors.toList());
            if (validRefGroup.isEmpty()) return;
            if (validRefGroup.isEmpty()){
                return;
            }
            Optional<Reference> existingRef = validRefGroup.stream()
                    .filter(ref -> ref.getReference_id() != null)
@@ -983,7 +983,7 @@
        // 批量更新问题状态
        List<Question> questionsToUpdate = new ArrayList<>();
        questions.forEach(question -> {
            List<QuestionResultList> results = questionResultsMap.getOrDefault(question.getQuestion(), io.jsonwebtoken.lang.Collections.emptyList());
            List<QuestionResultList> results = questionResultsMap.getOrDefault(question.getQuestion(), Collections.emptyList());
            FinalStatus finalStatus = determineFinalStatus(results);
            // 使用枚举进行switch判断
src/main/java/com/linghu/service/impl/KeywordServiceImpl.java
@@ -8,6 +8,7 @@
import com.alibaba.excel.write.metadata.holder.WriteWorkbookHolder;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.linghu.config.FinalStatus;
import com.linghu.mapper.ReferenceMapper;
import com.linghu.model.common.ResponseResult;
import com.linghu.model.dto.ExportFeedDTO;
@@ -75,7 +76,7 @@
        if (keyword == null) {
            return ResponseResult.error("关键词不存在");
        }
        if (!"completed".equals(keyword.getStatus())) {
        if (!FinalStatus.COMPLETED.getValue().equals(keyword.getStatus())) {
            return ResponseResult.success();
        }
        List<KeywordStaticsVO> statics = this.getBaseMapper().statics(keywordId, questionId, keyword.getNum());
@@ -97,7 +98,7 @@
        if (keyword == null) {
            return ResponseResult.error("关键词不存在");
        }
        if (!"completed".equals(keyword.getStatus())) {
        if (!FinalStatus.COMPLETED.getValue().equals(keyword.getStatus())) {
            return ResponseResult.error("关键词采集未完成");
        }
        List<PlatformProportionVO> result = this.getBaseMapper().getResultByTypeId(keywordId, questionId,
@@ -113,7 +114,7 @@
        if (keyword == null) {
            return ResponseResult.error("关键词不存在");
        }
        if (!"completed".equals(keyword.getStatus())) {
        if (!FinalStatus.COMPLETED.getValue().equals(keyword.getStatus())) {
            return ResponseResult.error("关键词采集未完成");
        }
src/main/java/com/linghu/service/impl/OrderServiceImpl.java
@@ -5,6 +5,7 @@
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.linghu.config.FinalStatus;
import com.linghu.model.common.ResponseResult;
import com.linghu.model.dto.KeywordDto;
import com.linghu.model.dto.OrderDto;
@@ -63,7 +64,7 @@
                    Keyword keyword = new Keyword();
                    keyword.setOrder_id(order_id);
                    keyword.setKeyword_name(keywordName.trim());
                    keyword.setStatus("notSubmitted");
                    keyword.setStatus(FinalStatus.NOTSUBMITTED.getValue());
                    // keyword.setNum(1); // 默认采集轮数为1
                    keywordService.save(keyword);
                }
@@ -87,10 +88,10 @@
            return false;
        }
        // 删除旧关键词(当状态为1时允许修改关键词)
        // 删除旧关键词(当状态为未提交时允许修改关键词)
        keywordService.lambdaUpdate()
                .eq(Keyword::getOrder_id, orderDto.getOrder_id())
                .eq(Keyword::getStatus, "notSubmitted")
                .eq(Keyword::getStatus, FinalStatus.NOTSUBMITTED.getValue())
                .remove();
        // 保存新关键词
@@ -101,7 +102,7 @@
                    Keyword keyword = new Keyword();
                    keyword.setOrder_id(orderDto.getOrder_id());
                    keyword.setKeyword_name(keywordName.trim());
                    keyword.setStatus("notSubmitted");
                    keyword.setStatus(FinalStatus.NOTSUBMITTED.getValue());
                    keywordService.save(keyword);
                }
            }
src/main/java/com/linghu/service/impl/QuestionServiceImpl.java
@@ -3,6 +3,7 @@
import com.alibaba.excel.EasyExcel;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.linghu.config.FinalStatus;
import com.linghu.listener.QuestionExcelListener;
import com.linghu.mapper.KeywordMapper;
import com.linghu.mapper.ReferenceMapper;
@@ -20,6 +21,7 @@
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.web.multipart.MultipartFile;
import java.io.ByteArrayOutputStream;
@@ -52,7 +54,7 @@
                    Question question = new Question();
                    question.setKeyword_id(keywordDto.getKeyword_id());
                    question.setQuestion(q.trim());
                    question.setStatus("pending");
                    question.setStatus(FinalStatus.PENDING.getValue());
                    return question;
                }).collect(Collectors.toList());
@@ -69,7 +71,7 @@
        LambdaQueryWrapper<Question> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Question::getQuestion_id, questions.getQuestion_id());
        Question keyword = this.getOne(queryWrapper);
        if ("submitted".equals(keyword.getStatus()) ) {
        if (FinalStatus.SUBMITTED.getValue().equals(keyword.getStatus()) ) {
            return ResponseResult.error("该关键词在采集中");
        }
@@ -82,6 +84,10 @@
    @Override
    public ResponseResult<Void> batchDeleteQuestion(List<Integer> questionIds) {
        // 新增判断:如果集合为空,直接返回错误
        if (CollectionUtils.isEmpty(questionIds)) {
            return ResponseResult.error("删除失败,至少选择一个提问词");
        }
        // 2. 批量查询所有提问词
        List<Question> questions = this.listByIds(questionIds);
        // 3. 校验所有提问词关联的关键词是否处于采集中
@@ -92,7 +98,7 @@
                return ResponseResult.error("提问词关联的关键词不存在,ID:" + question.getKeyword_id());
            }
            // 核心校验:若有任何关键词在采集中,禁止删除
            if ("submitted".equals(keyword.getStatus())) {
            if (FinalStatus.PENDING.getValue().equals(keyword.getStatus())) {
                return ResponseResult.error("该关键词在采集中,无法删除");
            }
        }
@@ -146,7 +152,7 @@
    @Override
    public ResponseResult<List<Question>> updateQuestion(KeywordDto keywordDto) {
        if ("submitted".equals(keywordDto.getStatus()) ) {
        if (FinalStatus.SUBMITTED.getValue().equals(keywordDto.getStatus()) ) {
            return ResponseResult.error("该关键词在采集中");
        }
        this.updateBatchById(keywordDto.getQuestionList());
src/main/java/com/linghu/service/impl/TypeServiceImpl.java
@@ -50,6 +50,9 @@
    @Override
    public ResponseResult<Void> batchDeleteTypes(List<Integer> typeIds) {
        if (typeIds.isEmpty()) {
            return ResponseResult.error("请选择要删除的类型");
        }
        List<Type> types = typeIds.stream().map(id -> {
            Type type = new Type();
            type.setType_id(id);
src/main/java/com/linghu/timeTask/ScheduledTasks.java
@@ -3,6 +3,7 @@
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.linghu.config.FinalStatus;
import com.linghu.controller.CollectController;
import com.linghu.model.dto.TaskResultResponse;
import com.linghu.model.dto.TaskStatusResponse;
@@ -158,7 +159,7 @@
        try {
            // 查询所有状态为pending的任务
            LambdaQueryWrapper<KeywordTask> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(KeywordTask::getStatus, "pending");
            queryWrapper.eq(KeywordTask::getStatus, FinalStatus.PENDING.getValue());
            List<KeywordTask> tasks = keywordTaskService.list(queryWrapper);
            log.info("查询到 {} 个待处理任务", tasks.size());
@@ -173,7 +174,7 @@
                boolean updatedCount = keywordTaskService.update(
                        new LambdaUpdateWrapper<KeywordTask>()
                                .in(KeywordTask::getId, taskIds) // 限定为查询到的任务
                                .eq(KeywordTask::getStatus, "pending") // 确保状态未被其他进程修改
                                .eq(KeywordTask::getStatus, FinalStatus.PENDING.getValue()) // 确保状态未被其他进程修改
                                .set(KeywordTask::getStatus, "processing")
                );
                log.info("成功标记 {} 个任务为processing(查询到{}个)", updatedCount, tasks.size());
@@ -201,29 +202,29 @@
    private Mono<KeywordTask> processTaskStatus(KeywordTask task) {
        return collectController.getTaskStatus(task.getTask_id())
                .flatMap(statusResponse -> {
                    if ("completed".equalsIgnoreCase(statusResponse.getStatus())) {
                    if (FinalStatus.COMPLETED.getValue().equalsIgnoreCase(statusResponse.getStatus())) {
                        log.info("任务 {} 已完成,获取结果", task.getTask_id());
                        return collectController.getTaskResult(task.getTask_id())
                                .doOnSuccess(result -> log.info("获取任务 {} 结果成功", task.getTask_id()))
                                .thenReturn(task)
                                .map(t -> {
                                    t.setStatus("completed");
                                    t.setStatus(FinalStatus.COMPLETED.getValue());
                                    return t;
                                });
                    } else if (!"submitted".equalsIgnoreCase(statusResponse.getStatus())
                            && !"running".equalsIgnoreCase(statusResponse.getStatus())
                            && !"Error".equalsIgnoreCase(statusResponse.getStatus())) {
                        task.setStatus("false");
                    } else if (!FinalStatus.SUBMITTED.getValue().equalsIgnoreCase(statusResponse.getStatus())
                            && !FinalStatus.RUNNING.getValue().equalsIgnoreCase(statusResponse.getStatus())
                            && !FinalStatus.ERROR.getValue().equalsIgnoreCase(statusResponse.getStatus())) {
                        task.setStatus(FinalStatus.FALSE.getValue());
                        // 新增:处理status为false时的关键词状态更新
                        return updateKeywordStatusWhenTaskFinished(task)
                                .then(Mono.just(task));
                    }else if ( "running".equalsIgnoreCase(statusResponse.getStatus())) {
                    }else if ( FinalStatus.RUNNING.getValue().equalsIgnoreCase(statusResponse.getStatus())) {
                        // 改回 pending,进行下一轮查询
                        task.setStatus("pending");
                        task.setStatus(FinalStatus.PENDING.getValue());
                        //更新每个提问词的状态
                        return updateQuestionStatus(task, statusResponse); // 抽取为独立方法
                    }else if("ERROR".equalsIgnoreCase(statusResponse.getStatus())&&statusResponse.getMessage().contains("Task not found")){
                        task.setStatus("nonentity");
                    }else if(FinalStatus.ERROR.getValue().equalsIgnoreCase(statusResponse.getStatus())&&statusResponse.getMessage().contains("Task not found")){
                        task.setStatus(FinalStatus.NONENTITY.getValue());
                        // 更新关键词状态
                        return updateKeywordStatusWhenTaskFinished(task)
                                .then(Mono.just(task));
@@ -243,7 +244,7 @@
                })
                .onErrorResume(e -> {
                    log.error("处理任务 {} 状态时发生错误: {}", task.getTask_id(), e.getMessage());
                    task.setStatus("error");
                    task.setStatus(FinalStatus.ERROR.getValue());
                    // 将updateById的结果包装成Mono
                    return Mono.fromSupplier(() -> keywordTaskService.updateById(task))
@@ -287,16 +288,15 @@
        }).flatMap(keywordTasks -> {
            // 检查所有关联任务是否都已完成(包括各种结束状态)
            boolean allCompleted = keywordTasks.stream().allMatch(t ->
                    "completed".equals(t.getStatus()) ||
                            "false".equals(t.getStatus()) ||
                            "cancelled".equals(t.getStatus()) ||
                            "canceled".equals(t.getStatus()) ||
                            "nonentity".equals(t.getStatus())
                    FinalStatus.COMPLETED.getValue().equals(t.getStatus()) ||
                            FinalStatus.FALSE.getValue().equals(t.getStatus()) ||
                            FinalStatus.CANCELLED.getValue().equals(t.getStatus()) ||
                            FinalStatus.NONENTITY.getValue().equals(t.getStatus())
            );
            if (allCompleted) {
                Keyword keyword = keywordService.getById(task.getKeyword_id());
                keyword.setStatus("completed");
                keyword.setStatus(FinalStatus.COMPLETED.getValue());
                //
                return Mono.fromSupplier(() -> keywordService.updateById(keyword))
                        .then(); // 转换为Mono<Void>
src/main/java/com/linghu/utils/JwtUtils.java
File was deleted