17个文件已删除
41个文件已添加
18个文件已修改
| | |
| | | <artifactId>springfox-swagger-ui</artifactId> |
| | | <version>2.9.2</version> |
| | | </dependency> |
| | | |
| | | <!-- EasyExcel依赖 --> |
| | | <dependency> |
| | | <groupId>com.alibaba</groupId> |
| | | <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> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>org.springframework.boot</groupId> |
| | | <artifactId>spring-boot-starter-webflux</artifactId> |
| | | </dependency> |
| | | |
| | | </dependencies> |
| | | <dependencyManagement> |
| | | <dependencies> |
| | |
| | | import springfox.documentation.builders.ApiInfoBuilder; |
| | | import springfox.documentation.builders.PathSelectors; |
| | | import springfox.documentation.builders.RequestHandlerSelectors; |
| | | import springfox.documentation.builders.ParameterBuilder; |
| | | import springfox.documentation.schema.ModelRef; |
| | | import springfox.documentation.service.ApiInfo; |
| | | import springfox.documentation.service.ApiKey; |
| | | import springfox.documentation.service.AuthorizationScope; |
| | | import springfox.documentation.service.Contact; |
| | | import springfox.documentation.service.Parameter; |
| | | import springfox.documentation.service.SecurityReference; |
| | | import springfox.documentation.spi.DocumentationType; |
| | | import springfox.documentation.spi.service.contexts.SecurityContext; |
| | | import springfox.documentation.spring.web.plugins.Docket; |
| | | import springfox.documentation.swagger2.annotations.EnableSwagger2; |
| | | |
| | | import java.util.ArrayList; |
| | | import java.util.Arrays; |
| | | import java.util.List; |
| | | |
| | | @Configuration |
| | | @EnableSwagger2 // 开启Swagger2 |
| | |
| | | .apis(RequestHandlerSelectors.basePackage("com.linghu.controller")) |
| | | // 匹配所有路径 |
| | | .paths(PathSelectors.any()) |
| | | .build() |
| | | // 添加安全方案配置 |
| | | .securitySchemes(Arrays.asList(securityScheme())) |
| | | .securityContexts(Arrays.asList(securityContext())) |
| | | // 添加全局参数(header中的token参数) |
| | | .globalOperationParameters(globalParameters()); |
| | | } |
| | | |
| | | /** |
| | | * 配置JWT安全方案 |
| | | */ |
| | | private ApiKey securityScheme() { |
| | | return new ApiKey("BearerToken", "Authorization", "header"); |
| | | } |
| | | |
| | | /** |
| | | * 配置安全上下文 |
| | | */ |
| | | private SecurityContext securityContext() { |
| | | return SecurityContext.builder() |
| | | .securityReferences(defaultAuth()) |
| | | .forPaths(PathSelectors.any()) |
| | | .build(); |
| | | } |
| | | |
| | | /** |
| | | * 默认的安全引用 |
| | | */ |
| | | private List<SecurityReference> defaultAuth() { |
| | | AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything"); |
| | | AuthorizationScope[] authorizationScopes = new AuthorizationScope[1]; |
| | | authorizationScopes[0] = authorizationScope; |
| | | return Arrays.asList(new SecurityReference("BearerToken", authorizationScopes)); |
| | | } |
| | | |
| | | /** |
| | | * 配置全局参数 |
| | | */ |
| | | private List<Parameter> globalParameters() { |
| | | List<Parameter> parameters = new ArrayList<>(); |
| | | parameters.add(new ParameterBuilder() |
| | | .name("Authorization") |
| | | .description("JWT Token (格式: Bearer [token])") |
| | | .modelRef(new ModelRef("string")) |
| | | .parameterType("header") |
| | | .required(false) |
| | | .build()); |
| | | return parameters; |
| | | } |
| | | |
| | | /** |
| | | * http://127.0.0.1:8080/swagger-ui.html |
| | | * 配置API文档基本信息(标题、描述、作者等) |
| | | */ |
| | | private ApiInfo apiInfo() { |
| | |
| | | .title("灵狐GEO系统 接口文档") // 文档标题 |
| | | .description("使用 Swagger2 生成的API文档") // 文档描述 |
| | | .version("1.0.0") // 版本号 |
| | | |
| | | .build(); |
| | | } |
| | | } |
New file |
| | |
| | | package com.linghu.config; |
| | | |
| | | import org.springframework.beans.factory.annotation.Value; |
| | | import org.springframework.context.annotation.Bean; |
| | | import org.springframework.context.annotation.Configuration; |
| | | import org.springframework.web.reactive.function.client.WebClient; |
| | | |
| | | @Configuration |
| | | public class WebClientConfig { |
| | | @Value("${linghu.url}") |
| | | private String baseUrl; |
| | | |
| | | @Bean |
| | | public WebClient webClient() { |
| | | return WebClient.create(baseUrl); |
| | | } |
| | | } |
New file |
| | |
| | | package com.linghu.controller; |
| | | |
| | | import java.util.HashMap; |
| | | import java.util.Map; |
| | | |
| | | import org.springframework.beans.factory.annotation.Value; |
| | | import org.springframework.http.ResponseEntity; |
| | | import org.springframework.web.bind.annotation.PostMapping; |
| | | import org.springframework.web.bind.annotation.RequestBody; |
| | | import org.springframework.web.bind.annotation.RequestMapping; |
| | | import org.springframework.web.bind.annotation.RequestParam; |
| | | import org.springframework.web.bind.annotation.RestController; |
| | | |
| | | import com.linghu.model.entity.User; |
| | | import com.linghu.utils.JwtUtils; |
| | | |
| | | @RestController |
| | | @RequestMapping("/auth") |
| | | public class AuthController { |
| | | @Value("${jwt.secret}") |
| | | private String secretKey; |
| | | |
| | | @PostMapping("/login") |
| | | public ResponseEntity<?> externalLogin( |
| | | @RequestBody User user) { |
| | | |
| | | // 生成JWT令牌 |
| | | JwtUtils jwtUtils = new JwtUtils(secretKey, 3600); |
| | | String token = jwtUtils.generateToken(user); |
| | | |
| | | Map<String, String> response = new HashMap<>(); |
| | | response.put("token", token); |
| | | // 返回JWT令牌 |
| | | return ResponseEntity.ok(response); |
| | | } |
| | | |
| | | // 获取用户信息 |
| | | @PostMapping("/getUserInfo") |
| | | public ResponseEntity<?> getUserInfo(@RequestParam String token) { |
| | | // 解析JWT令牌,获取用户信息 |
| | | JwtUtils jwtUtils = new JwtUtils(secretKey, 3600); |
| | | User user = jwtUtils.parseToken(token); |
| | | // 返回用户信息 |
| | | return ResponseEntity.ok(user); |
| | | } |
| | | } |
New file |
| | |
| | | package com.linghu.controller; |
| | | |
| | | import java.time.LocalDateTime; |
| | | import java.util.ArrayList; |
| | | import java.util.Date; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | import java.util.stream.Collectors; |
| | | |
| | | import javax.servlet.http.HttpServletRequest; |
| | | |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.beans.factory.annotation.Value; |
| | | import org.springframework.core.ParameterizedTypeReference; |
| | | import org.springframework.http.*; |
| | | import org.springframework.web.client.RestTemplate; |
| | | import org.springframework.web.reactive.function.client.WebClient; |
| | | import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; |
| | | |
| | | import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; |
| | | import com.linghu.model.common.ResponseResult; |
| | | import com.linghu.model.dto.SearchTaskRequest; |
| | | import com.linghu.model.entity.Keyword; |
| | | import com.linghu.model.entity.Question; |
| | | import com.linghu.model.entity.User; |
| | | import com.linghu.service.KeywordService; |
| | | import com.linghu.service.QuestionService; |
| | | import com.linghu.service.ReferenceService; |
| | | import com.linghu.utils.JwtUtils; |
| | | import com.linghu.model.dto.SearchTaskResponse; |
| | | import com.linghu.model.dto.TaskStatusResponse; |
| | | import com.linghu.model.dto.TaskCancelResponse; |
| | | |
| | | import io.jsonwebtoken.lang.Collections; |
| | | import io.swagger.annotations.Api; |
| | | import io.swagger.annotations.ApiOperation; |
| | | import reactor.core.publisher.Mono; |
| | | |
| | | import org.springframework.web.bind.annotation.*; |
| | | import org.springframework.http.HttpStatus; |
| | | import com.linghu.model.dto.TaskResultResponse; |
| | | import com.linghu.model.dto.TaskResultResponse.QuestionResult; |
| | | import com.linghu.model.dto.TaskResultResponse.UserResult; |
| | | import com.linghu.model.entity.Reference; |
| | | import java.util.stream.Collectors; |
| | | |
| | | @RestController |
| | | @RequestMapping("/collect") |
| | | @Api(value = "采集接口", tags = "采集管理") |
| | | public class CollectController { |
| | | |
| | | @Autowired |
| | | private ReferenceService referenceService; |
| | | |
| | | @Value("${linghu.url}") |
| | | private String baseUrl; |
| | | |
| | | @Autowired |
| | | private WebClient webClient; |
| | | |
| | | @Autowired |
| | | private JwtUtils jwtUtils; |
| | | @Autowired |
| | | private KeywordService keywordService; |
| | | @Autowired |
| | | private QuestionService questionService; |
| | | |
| | | @PostMapping("/search") |
| | | @ApiOperation(value = "开始采集") |
| | | public Mono<ResponseResult<SearchTaskResponse>> createSearchTask( |
| | | @RequestBody SearchTaskRequest searchTaskRequest, |
| | | HttpServletRequest request) { |
| | | String token = request.getHeader("Authorization"); |
| | | User user = jwtUtils.parseToken(token); |
| | | List<User> users = new ArrayList<>(); |
| | | users.add(user); |
| | | searchTaskRequest.setUsers(users); |
| | | |
| | | return webClient.post() |
| | | .uri(baseUrl + "/search") |
| | | .contentType(MediaType.APPLICATION_JSON) |
| | | .bodyValue(searchTaskRequest) |
| | | .retrieve() |
| | | .bodyToMono(new ParameterizedTypeReference<ResponseResult<SearchTaskResponse>>() { |
| | | }) |
| | | .flatMap(responseResult -> { |
| | | // 提取任务ID |
| | | SearchTaskResponse taskResponse = responseResult.getData(); |
| | | if (taskResponse != null && taskResponse.getTask_id() != null) { |
| | | // 保存任务ID到关键词 |
| | | LambdaUpdateWrapper<Keyword> updateWrapper = new LambdaUpdateWrapper<>(); |
| | | updateWrapper.eq(Keyword::getKeyword_id, searchTaskRequest.getKeyword_id()); |
| | | updateWrapper.set(Keyword::getTask_id, taskResponse.getTask_id()); |
| | | keywordService.update(updateWrapper); |
| | | // 可选:更新响应中的其他信息 |
| | | // taskResponse.setMessage("任务已提交并保存,ID: " + taskResponse.getTaskId()); |
| | | } |
| | | return Mono.just(responseResult); |
| | | }) |
| | | .onErrorResume(e -> { |
| | | return Mono.just(ResponseResult.error("调用失败: " + e.getMessage())); |
| | | }); |
| | | } |
| | | |
| | | @ApiOperation(value = "查询任务状态") |
| | | @GetMapping("/status") |
| | | public Mono<TaskStatusResponse> getTaskStatus(String taskId) { |
| | | return webClient.get() |
| | | .uri(baseUrl + "/tasks/" + taskId) |
| | | .accept(MediaType.APPLICATION_JSON) |
| | | .retrieve() |
| | | .onStatus(HttpStatus::is4xxClientError, response -> response.bodyToMono(String.class) |
| | | .flatMap(errorBody -> Mono.error(new RuntimeException("任务不存在: " + errorBody)))) |
| | | .bodyToMono(TaskStatusResponse.class) |
| | | .flatMap(result -> { |
| | | TaskStatusResponse taskStatusResponse = result; |
| | | if (taskStatusResponse != null && taskStatusResponse.getStatus() != null) { |
| | | List<Question> updateQuestions = taskStatusResponse.getQuestions_status().stream() |
| | | .map(qs -> { |
| | | Question question = new Question(); |
| | | question.setQuestion_id(qs.getQuestion_id()); |
| | | question.setStatus(qs.getStatus()); |
| | | return question; |
| | | }).collect(Collectors.toList()); |
| | | |
| | | questionService.updateBatchById(updateQuestions); |
| | | } |
| | | return Mono.just(result); |
| | | }); |
| | | } |
| | | |
| | | @PostMapping("/cancel/{taskId}") |
| | | @ApiOperation(value = "取消任务") |
| | | public Mono<ResponseResult<TaskCancelResponse>> cancelTask(@PathVariable String taskId) { |
| | | return webClient.post() |
| | | .uri(baseUrl + "/tasks/" + taskId + "/cancel") |
| | | .contentType(MediaType.APPLICATION_JSON) |
| | | .bodyValue(Collections.emptyMap()) // 添加空请求体 |
| | | .retrieve() |
| | | .onStatus(HttpStatus::isError, response -> { |
| | | if (response.statusCode() == HttpStatus.NOT_FOUND) { |
| | | return response.bodyToMono(String.class) |
| | | .flatMap(errorBody -> Mono.error(new RuntimeException("任务不存在"))); |
| | | } else if (response.statusCode() == HttpStatus.BAD_REQUEST) { |
| | | return response.bodyToMono(String.class) |
| | | .flatMap(errorBody -> Mono.error(new RuntimeException("任务已经完成,无法取消"))); |
| | | } |
| | | return response.createException().flatMap(Mono::error); |
| | | }) |
| | | .bodyToMono(TaskCancelResponse.class) |
| | | .map(data -> ResponseResult.success(data)) |
| | | .onErrorResume(e -> { |
| | | if (e.getMessage().contains("任务不存在")) { |
| | | return Mono.just(ResponseResult.error(404, "任务不存在")); |
| | | } else if (e.getMessage().contains("无法取消")) { |
| | | return Mono.just(ResponseResult.error(400, "任务已完成,无法取消")); |
| | | } |
| | | return Mono.just(ResponseResult.error(500, "取消任务失败: " + e.getMessage())); |
| | | }); |
| | | } |
| | | // @ApiOperation(value = "获取任务结果") |
| | | // @GetMapping("/tasks/{taskId}/result") |
| | | // public Mono<ResponseResult<TaskResultResponse>> getTaskResult(@PathVariable |
| | | // String taskId) { |
| | | // return webClient.get() |
| | | // .uri(baseUrl + "/tasks/" + taskId + "/result") |
| | | // .retrieve() |
| | | // .onStatus(HttpStatus::isError, response -> response.bodyToMono(String.class) |
| | | // .flatMap(errorBody -> Mono.error(new RuntimeException("获取结果失败: " + |
| | | // errorBody)))) |
| | | // .bodyToMono(TaskResultResponse.class) |
| | | // .flatMap(result -> { |
| | | // // 更新keyword状态 |
| | | // LambdaUpdateWrapper<Keyword> keywordWrapper = new LambdaUpdateWrapper<>(); |
| | | // keywordWrapper.eq(Keyword::getTask_id, taskId) |
| | | // .set(Keyword::getStatus, "completed"); |
| | | // keywordService.update(keywordWrapper); |
| | | |
| | | // // 更新question信息并收集references |
| | | // List<Question> updateQuestions = new ArrayList<>(); |
| | | // List<Reference> references = new ArrayList<>(); |
| | | |
| | | // result.getResults().forEach(userResult -> { |
| | | // userResult.getQuestions_results().forEach(qResult -> { |
| | | // Question question = new Question(); |
| | | // question.setQuestion_id(qResult.getQuestion_id()); |
| | | // question.setResponse(qResult.getResponse()); |
| | | // question.setStatus(qResult.getStatus()); |
| | | // updateQuestions.add(question); |
| | | |
| | | // // 转换references |
| | | // references.addAll(qResult.getReferences().stream() |
| | | // .map(ref -> new Reference( |
| | | // qResult.getQuestion_id(), |
| | | // ref.getTitle(), |
| | | // ref.getUrl(), |
| | | // ref.getDomain(), |
| | | // result.getTask_id(), |
| | | // )) |
| | | // .collect(Collectors.toList())); |
| | | // }); |
| | | // }); |
| | | |
| | | // // 批量更新和插入 |
| | | // if (!updateQuestions.isEmpty()) { |
| | | // questionService.updateBatchById(updateQuestions); |
| | | // } |
| | | // if (!references.isEmpty()) { |
| | | // referenceService.saveBatch(references); |
| | | // } |
| | | |
| | | // return Mono.just(ResponseResult.success(result)); |
| | | // }) |
| | | // .onErrorResume(e -> Mono.just(ResponseResult.error(e.getMessage()))); |
| | | // } |
| | | |
| | | // @ApiOperation(value = "获取任务结果") |
| | | // @GetMapping("/tasks/{taskId}/result") |
| | | // public Mono<ResponseResult<TaskResultResponse>> |
| | | // getTaskResultlMono(@PathVariable String taskId) { |
| | | // return webClient.get() |
| | | // .uri(baseUrl + "/tasks/" + taskId + "/result") |
| | | // .accept(MediaType.APPLICATION_JSON) |
| | | // .retrieve() |
| | | // .onStatus(HttpStatus::is4xxClientError, response -> { |
| | | // if (response.statusCode() == HttpStatus.NOT_FOUND) { |
| | | // return response.bodyToMono(String.class) |
| | | // .flatMap(errorBody -> Mono.error(new RuntimeException("任务不存在"))); |
| | | // } else if (response.statusCode() == HttpStatus.BAD_REQUEST) { |
| | | // return response.bodyToMono(String.class) |
| | | // .flatMap(errorBody -> Mono.error(new RuntimeException("任务未完成,无法获取结果"))); |
| | | // } |
| | | // return response.createException().flatMap(Mono::error); |
| | | // }) |
| | | // .bodyToMono(new |
| | | // ParameterizedTypeReference<ResponseResult<TaskResultResponse>>() {}) |
| | | // .flatMap(responseResult -> { |
| | | // TaskResultResponse result = responseResult.getData(); |
| | | // if (result != null && result.getResults() != null) { |
| | | // // 处理结果并更新数据库 |
| | | // return updateQuestionAndReference(result) |
| | | // .thenReturn(responseResult); |
| | | // } |
| | | // return Mono.just(responseResult); |
| | | // }) |
| | | // .onErrorResume(e -> { |
| | | |
| | | // return Mono.just(ResponseResult.error(e.getMessage())); |
| | | // }); |
| | | // } |
| | | |
| | | // 更新问题和引用数据 |
| | | // private Mono<Void> updateQuestionAndReference(TaskResultResponse result) { |
| | | // return Mono.fromRunnable(() -> { |
| | | // // 1. 更新关键词状态 |
| | | // LambdaUpdateWrapper<Keyword> keywordUpdate = new LambdaUpdateWrapper<>(); |
| | | // keywordUpdate.eq(Keyword::getTask_id, result.getTask_id()) |
| | | // .set(Keyword::getStatus, "completed"); |
| | | // keywordService.update(keywordUpdate); |
| | | |
| | | // // 2. 处理每个用户的问题结果 |
| | | // for (UserResult userResult : result.getResults()) { |
| | | // for (QuestionResult questionResult : userResult.getQuestions_results()) { |
| | | // // 2.1 更新问题状态 |
| | | // LambdaUpdateWrapper<Question> questionUpdate = new LambdaUpdateWrapper<>(); |
| | | // questionUpdate.eq(Question::getTa, result.getTask_id()) |
| | | // .eq(Question::getContent, questionResult.getQuestion()) |
| | | // .set(Question::getStatus, questionResult.getStatus()) |
| | | // .set(Question::getResponse, questionResult.getResponse()) |
| | | // .set(Question::getProcessTime, |
| | | // LocalDateTime.parse(questionResult.getTimestamp())); |
| | | // questionService.update(questionUpdate); |
| | | |
| | | // // 2.2 保存引用数据 |
| | | // List<Reference> references = questionResult.getReferences().stream() |
| | | // .map(ref -> { |
| | | // Reference reference = new Reference(); |
| | | // reference.setQuestionId(questionService.getOne(questionUpdate).getId()); |
| | | // reference.setTitle(ref.getTitle()); |
| | | // reference.setUrl(ref.getUrl()); |
| | | // reference.setDomain(ref.getDomain()); |
| | | // reference.setCreateTime(LocalDateTime.now()); |
| | | // return reference; |
| | | // }) |
| | | // .collect(Collectors.toList()); |
| | | |
| | | // if (!references.isEmpty()) { |
| | | // referenceService.saveBatch(references); |
| | | // } |
| | | // } |
| | | // } |
| | | // }); |
| | | // } |
| | | |
| | | } |
New file |
| | |
| | | package com.linghu.controller; |
| | | |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
| | | import com.fasterxml.jackson.databind.util.BeanUtil; |
| | | import com.linghu.model.common.ResponseResult; |
| | | import com.linghu.model.entity.Order; |
| | | import com.linghu.model.dto.OrderDto; |
| | | import com.linghu.service.OrderService; |
| | | |
| | | import org.springframework.beans.BeanUtils; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.web.bind.annotation.*; |
| | | |
| | | import java.text.SimpleDateFormat; |
| | | import java.util.Date; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * 订单管理接口 |
| | | */ |
| | | @RestController |
| | | @RequestMapping("/order") |
| | | public class OrderController { |
| | | |
| | | @Autowired |
| | | private OrderService orderService; |
| | | |
| | | /** |
| | | * 新增订单 |
| | | */ |
| | | @PostMapping |
| | | public ResponseResult<Order> add(@RequestBody OrderDto orderDto) { |
| | | //将dto转entity |
| | | Order order = new Order(); |
| | | BeanUtils.copyProperties(orderDto, order); |
| | | |
| | | if (order.getClient_name() == null || order.getClient_name().trim().isEmpty()) { |
| | | return ResponseResult.error("客户名称不能为空"); |
| | | } |
| | | |
| | | // 生成订单ID:日期+当天的订单数量(如:202507060001) |
| | | SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd"); |
| | | String dateStr = dateFormat.format(new Date()); |
| | | |
| | | // 查询当天订单数量 |
| | | LambdaQueryWrapper<Order> queryWrapper = new LambdaQueryWrapper<>(); |
| | | queryWrapper.likeRight(Order::getOrder_id, dateStr); |
| | | long count = orderService.count(queryWrapper); |
| | | |
| | | // 生成订单ID |
| | | String orderId = String.format("%s%04d", dateStr, count + 1); |
| | | order.setOrder_id(orderId); |
| | | |
| | | // 设置初始状态 |
| | | order.setStatus(1); // 待处理 |
| | | order.setDel_flag(0); // 未删除 |
| | | order.setCreate_time(new Date()); |
| | | //保存关键词 |
| | | boolean saveOrderWithKeywords = orderService.saveOrderWithKeywords(orderDto); |
| | | |
| | | |
| | | if (orderService.save(order)) { |
| | | return ResponseResult.success(order); |
| | | } |
| | | return ResponseResult.error("添加订单失败"); |
| | | } |
| | | |
| | | /** |
| | | * 删除订单(逻辑删除) |
| | | */ |
| | | @DeleteMapping("/{orderId}") |
| | | public ResponseResult<Void> delete(@PathVariable String orderId) { |
| | | Order order = orderService.getById(orderId); |
| | | if (order == null) { |
| | | return ResponseResult.error("订单不存在"); |
| | | } |
| | | |
| | | order.setDel_flag(1); |
| | | order.setUpdate_time(new Date()); |
| | | |
| | | if (orderService.updateById(order)) { |
| | | return ResponseResult.success(); |
| | | } |
| | | return ResponseResult.error("删除订单失败"); |
| | | } |
| | | |
| | | /** |
| | | * 更新订单 |
| | | */ |
| | | @PutMapping |
| | | public ResponseResult<Void> update(@RequestBody Order order) { |
| | | if (order.getOrder_id() == null) { |
| | | return ResponseResult.error("订单ID不能为空"); |
| | | } |
| | | if (order.getClient_name() == null || order.getClient_name().trim().isEmpty()) { |
| | | return ResponseResult.error("客户名称不能为空"); |
| | | } |
| | | |
| | | Order existingOrder = orderService.getById(order.getOrder_id()); |
| | | if (existingOrder == null) { |
| | | return ResponseResult.error("订单不存在"); |
| | | } |
| | | |
| | | order.setUpdate_time(new Date()); |
| | | |
| | | if (orderService.updateById(order)) { |
| | | return ResponseResult.success(); |
| | | } |
| | | return ResponseResult.error("更新订单失败"); |
| | | } |
| | | |
| | | /** |
| | | * 根据ID查询订单 |
| | | */ |
| | | @GetMapping("/{orderId}") |
| | | public ResponseResult<Order> getById(@PathVariable String orderId) { |
| | | Order order = orderService.getById(orderId); |
| | | if (order == null || order.getDel_flag() == 1) { |
| | | return ResponseResult.error("订单不存在"); |
| | | } |
| | | return ResponseResult.success(order); |
| | | } |
| | | |
| | | /** |
| | | * 查询订单列表 |
| | | */ |
| | | @GetMapping |
| | | public ResponseResult<List<Order>> list( |
| | | @RequestParam(required = false) Integer pageNum, |
| | | @RequestParam(required = false) Integer pageSize, |
| | | @RequestParam(required = false) String clientName, |
| | | @RequestParam(required = false) Integer status) { |
| | | |
| | | LambdaQueryWrapper<Order> queryWrapper = new LambdaQueryWrapper<>(); |
| | | queryWrapper.eq(Order::getDel_flag, 0); // 只查询未删除的订单 |
| | | |
| | | // 添加查询条件 |
| | | if (clientName != null && !clientName.trim().isEmpty()) { |
| | | queryWrapper.like(Order::getClient_name, clientName); |
| | | } |
| | | if (status != null) { |
| | | queryWrapper.eq(Order::getStatus, status); |
| | | } |
| | | |
| | | // 分页查询 |
| | | if (pageNum != null && pageSize != null) { |
| | | Page<Order> pageInfo = new Page<>(pageNum, pageSize); |
| | | Page<Order> result = orderService.page(pageInfo, queryWrapper); |
| | | return ResponseResult.success(result.getRecords()); |
| | | } |
| | | |
| | | // 不分页 |
| | | List<Order> list = orderService.list(queryWrapper); |
| | | return ResponseResult.success(list); |
| | | } |
| | | } |
New file |
| | |
| | | package com.linghu.controller; |
| | | |
| | | import com.alibaba.excel.EasyExcel; |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
| | | import com.linghu.model.common.ResponseResult; |
| | | import com.linghu.model.entity.Platform; |
| | | import com.linghu.model.entity.Type; |
| | | import com.linghu.model.excel.PlatformExcel; |
| | | import com.linghu.service.PlatformService; |
| | | 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.http.HttpHeaders; |
| | | import org.springframework.http.MediaType; |
| | | import org.springframework.http.ResponseEntity; |
| | | import org.springframework.util.StringUtils; |
| | | import org.springframework.web.bind.annotation.*; |
| | | import org.springframework.web.multipart.MultipartFile; |
| | | |
| | | import java.io.ByteArrayOutputStream; |
| | | import java.io.IOException; |
| | | |
| | | import java.util.ArrayList; |
| | | import java.util.Date; |
| | | import java.util.List; |
| | | import java.util.stream.Collectors; |
| | | |
| | | @RestController |
| | | @RequestMapping("/platform") |
| | | @Api(value = "平台相关接口", tags = "设置-平台") |
| | | public class PlatformController { |
| | | |
| | | @Autowired |
| | | private PlatformService platformService; |
| | | @Autowired |
| | | private TypeService typeService; |
| | | |
| | | @PostMapping |
| | | @ApiOperation(value = "添加平台") |
| | | public ResponseResult<Platform> add(@RequestBody Platform platform) { |
| | | // 校验平台名称和域名不能为空 |
| | | if (!StringUtils.hasText(platform.getPlatform_name())) { |
| | | return ResponseResult.error("平台名称不能为空"); |
| | | } |
| | | if (!StringUtils.hasText(platform.getDomain())) { |
| | | return ResponseResult.error("平台域名不能为空"); |
| | | } |
| | | |
| | | boolean success = platformService.save(platform); |
| | | if (success) { |
| | | return ResponseResult.success(platform); |
| | | } |
| | | return ResponseResult.error("添加平台失败"); |
| | | } |
| | | |
| | | @DeleteMapping("/{platformId}") |
| | | public ResponseResult<Void> delete(@PathVariable Integer platformId) { |
| | | boolean success = platformService.removeById(platformId); |
| | | if (success) { |
| | | return ResponseResult.success(); |
| | | } |
| | | return ResponseResult.error("删除平台失败"); |
| | | } |
| | | |
| | | @PutMapping |
| | | public ResponseResult<Void> update(@RequestBody Platform platform) { |
| | | // 校验平台名称和域名不能为空 |
| | | if (!StringUtils.hasText(platform.getPlatform_name())) { |
| | | return ResponseResult.error("平台名称不能为空"); |
| | | } |
| | | if (!StringUtils.hasText(platform.getDomain())) { |
| | | return ResponseResult.error("平台域名不能为空"); |
| | | } |
| | | |
| | | boolean success = platformService.updateById(platform); |
| | | if (success) { |
| | | return ResponseResult.success(); |
| | | } |
| | | return ResponseResult.error("更新平台失败"); |
| | | } |
| | | |
| | | @GetMapping("/{platformId}") |
| | | public ResponseResult<Platform> getById(@PathVariable Integer platformId) { |
| | | Platform platform = platformService.getById(platformId); |
| | | if (platform != null) { |
| | | return ResponseResult.success(platform); |
| | | } |
| | | return ResponseResult.error("平台不存在"); |
| | | } |
| | | |
| | | @GetMapping("/list") |
| | | public ResponseResult<List<Platform>> list( |
| | | @RequestParam(required = false) Integer page, |
| | | @RequestParam(required = false) Integer pageSize) { |
| | | if (page != null && pageSize != null) { |
| | | Page<Platform> pageInfo = new Page<>(page, pageSize); |
| | | Page<Platform> result = platformService.page(pageInfo); |
| | | return ResponseResult.success(result.getRecords()); |
| | | } else { |
| | | List<Platform> list = platformService.list(); |
| | | return ResponseResult.success(list); |
| | | } |
| | | } |
| | | |
| | | @GetMapping("/download") |
| | | @ApiOperation("下载平台模板") |
| | | public ResponseEntity<byte[]> downloadTemplate() throws IOException { |
| | | ByteArrayOutputStream out = new ByteArrayOutputStream(); |
| | | EasyExcel.write(out, PlatformExcel.class).sheet("平台模板").doWrite(new ArrayList<>()); |
| | | |
| | | return ResponseEntity.ok() |
| | | .header(HttpHeaders.CONTENT_DISPOSITION, "attachment;filename=platform_template.xlsx") |
| | | .contentType(MediaType.APPLICATION_OCTET_STREAM) |
| | | .body(out.toByteArray()); |
| | | } |
| | | |
| | | @PostMapping("/import") |
| | | @ApiOperation("导入平台数据") |
| | | public ResponseResult<String> importPlatforms(@RequestParam("file") MultipartFile file) { |
| | | try { |
| | | // 检查文件是否为空 |
| | | if (file.isEmpty()) { |
| | | return ResponseResult.error("上传文件不能为空"); |
| | | } |
| | | |
| | | // 读取Excel数据 |
| | | List<PlatformExcel> excelList = EasyExcel.read(file.getInputStream()) |
| | | .head(PlatformExcel.class) |
| | | .sheet() |
| | | .doReadSync(); |
| | | |
| | | // 数据转换与验证 |
| | | List<Platform> platforms = new ArrayList<>(); |
| | | List<String> errorMessages = new ArrayList<>(); |
| | | |
| | | for (PlatformExcel excel : excelList) { |
| | | // 检查必要字段 |
| | | if (!StringUtils.hasText(excel.getPlatform_name())) { |
| | | errorMessages.add("平台名称不能为空"); |
| | | continue; |
| | | } |
| | | if (!StringUtils.hasText(excel.getType_name())) { |
| | | errorMessages.add("平台类型不能为空"); |
| | | continue; |
| | | } |
| | | if (!StringUtils.hasText(excel.getDomain())) { |
| | | errorMessages.add("平台域名不能为空"); |
| | | continue; |
| | | } |
| | | |
| | | // 查找类型 |
| | | Type typeByName = typeService.getTypeByName(excel.getType_name()); |
| | | if (typeByName == null) { |
| | | errorMessages.add("未知的平台类型: " + excel.getType_name()); |
| | | continue; |
| | | } |
| | | |
| | | // 构建平台对象 |
| | | Platform platform = new Platform(); |
| | | platform.setPlatform_name(excel.getPlatform_name()); |
| | | platform.setDomain(excel.getDomain()); |
| | | platform.setType_id(typeByName.getType_id()); |
| | | |
| | | // 设置创建时间(解决之前的数据库错误) |
| | | platform.setCreate_time(new Date()); |
| | | |
| | | platforms.add(platform); |
| | | } |
| | | |
| | | // 处理错误 |
| | | if (!errorMessages.isEmpty()) { |
| | | return ResponseResult.error("数据验证失败: " + String.join("; ", errorMessages)); |
| | | } |
| | | |
| | | // 批量保存 |
| | | if (!platforms.isEmpty()) { |
| | | platformService.saveBatch(platforms); |
| | | return ResponseResult.success("成功导入" + platforms.size() + "条数据"); |
| | | } else { |
| | | return ResponseResult.error("没有有效数据可导入"); |
| | | } |
| | | |
| | | } catch (Exception e) { |
| | | // 记录详细异常信息 |
| | | |
| | | return ResponseResult.error("文件解析失败:" + e.getMessage()); |
| | | } |
| | | } |
| | | } |
New file |
| | |
| | | package com.linghu.controller; |
| | | |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
| | | import com.linghu.model.common.ResponseResult; |
| | | import com.linghu.model.entity.Question; |
| | | import com.linghu.service.QuestionService; |
| | | import io.swagger.annotations.Api; |
| | | import io.swagger.annotations.ApiOperation; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | import org.springframework.web.bind.annotation.*; |
| | | import com.linghu.model.dto.KeywordDto; |
| | | |
| | | import java.util.Arrays; |
| | | import java.util.List; |
| | | import java.util.stream.Collectors; |
| | | |
| | | @RestController |
| | | @RequestMapping("/question") |
| | | @Api(value = "提问词相关接口", tags = "设置-提问词") |
| | | public class QuestionController { |
| | | |
| | | @Autowired |
| | | private QuestionService questionService; |
| | | |
| | | @PostMapping |
| | | @ApiOperation(value = "添加提问词") |
| | | @Transactional |
| | | public ResponseResult<List<Question>> add(@RequestBody KeywordDto keywordDto) { |
| | | |
| | | List<Question> questionList = Arrays.stream(keywordDto.getQuestions().split("\\n")) |
| | | .filter(q -> !q.trim().isEmpty()) |
| | | .map(q -> { |
| | | Question question = new Question(); |
| | | question.setKeyword_id(keywordDto.getKeyword_id()); |
| | | question.setQuestion(q.trim()); |
| | | question.setStatus("pending"); |
| | | |
| | | return question; |
| | | }).collect(Collectors.toList()); |
| | | |
| | | boolean success = questionService.saveBatch(questionList); |
| | | if (success) { |
| | | return ResponseResult.success(questionList); |
| | | } |
| | | return ResponseResult.error("添加提问词失败"); |
| | | } |
| | | |
| | | // @DeleteMapping("/{questionId}") |
| | | // public ResponseResult<Void> delete(@PathVariable Integer questionId) { |
| | | // Question question = new Question(); |
| | | // question.setQuestion_id(questionId); |
| | | // question.setDel_flag(1); |
| | | // boolean success = questionService.updateById(question); |
| | | // if (success) { |
| | | // return ResponseResult.success(); |
| | | // } |
| | | // return ResponseResult.error("删除提问词失败"); |
| | | // } |
| | | |
| | | @PutMapping |
| | | @Transactional |
| | | public ResponseResult<Void> update(@RequestBody List<Question> questions) { |
| | | boolean success = questionService.updateBatchById(questions); |
| | | // 不存在的问题id就新增 |
| | | List<Question> newQuestions = questions.stream() |
| | | .filter(q -> q.getQuestion_id() == null) |
| | | .collect(Collectors.toList()); |
| | | if (!newQuestions.isEmpty()) { |
| | | questionService.saveBatch(newQuestions); |
| | | } |
| | | if (success) { |
| | | return ResponseResult.success(); |
| | | } |
| | | return ResponseResult.error("更新提问词失败"); |
| | | } |
| | | |
| | | @GetMapping("/{questionId}") |
| | | public ResponseResult<Question> getById(@PathVariable Integer questionId) { |
| | | Question question = questionService.getById(questionId); |
| | | if (question != null) { |
| | | return ResponseResult.success(question); |
| | | } |
| | | return ResponseResult.error("提问词不存在"); |
| | | } |
| | | |
| | | // @DeleteMapping("/batch") |
| | | // @Transactional |
| | | // public ResponseResult<Void> batchDelete(@RequestBody List<Integer> |
| | | // questionIds) { |
| | | // List<Question> questions = questionIds.stream().map(id -> { |
| | | // Question question = new Question(); |
| | | // question.setQuestion_id(id); |
| | | // return question; |
| | | // }).collect(Collectors.toList()); |
| | | |
| | | // boolean success = questionService.updateBatchById(questions); |
| | | // if (success) { |
| | | // return ResponseResult.success(); |
| | | // } |
| | | // return ResponseResult.error("批量删除提问词失败"); |
| | | // } |
| | | |
| | | @GetMapping("/list") |
| | | public ResponseResult<List<Question>> list() { |
| | | LambdaQueryWrapper<Question> queryWrapper = new LambdaQueryWrapper<>(); |
| | | List<Question> list = questionService.list(queryWrapper); |
| | | return ResponseResult.success(list); |
| | | |
| | | } |
| | | } |
| | |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.web.bind.annotation.*; |
| | | |
| | | import java.util.Date; |
| | | import java.util.List; |
| | | |
| | | @RestController |
| | |
| | | @PostMapping |
| | | @ApiOperation(value = "添加类型") |
| | | public ResponseResult<Type> add(@RequestBody Type type) { |
| | | type.setDelFlag(0); |
| | | type.setDel_flag(0); |
| | | boolean success = typeService.save(type); |
| | | if (success) { |
| | | return ResponseResult.success(type); |
| | |
| | | |
| | | @PostMapping("/batch") |
| | | public ResponseResult<Void> batchAdd(@RequestBody List<Type> types) { |
| | | types.forEach(type -> type.setDel_flag(0)); |
| | | |
| | | boolean success = typeService.saveBatch(types); |
| | | if (success) { |
| | | return ResponseResult.success(); |
| | |
| | | @DeleteMapping("/{typeId}") |
| | | public ResponseResult<Void> delete(@PathVariable Integer typeId) { |
| | | Type type = new Type(); |
| | | type.setTypeId(typeId); |
| | | type.setDelFlag(1); |
| | | type.setType_id(typeId); |
| | | type.setDel_flag(1); |
| | | boolean success = typeService.updateById(type); |
| | | if (success) { |
| | | return ResponseResult.success(); |
| | | } |
| | | return ResponseResult.error("删除类型失败"); |
| | | } |
| | | |
| | | @DeleteMapping("/batch") |
| | | public ResponseResult<Void> batchDelete(@RequestBody List<Integer> typeIds) { |
| | | boolean success = typeService.removeBatchByIds(typeIds); |
| | | if (success) { |
| | | return ResponseResult.success(); |
| | | } |
| | | return ResponseResult.error("批量删除类型失败"); |
| | | } |
| | | |
| | | @PutMapping |
| | |
| | | @GetMapping("/{typeId}") |
| | | public ResponseResult<Type> getById(@PathVariable Integer typeId) { |
| | | Type type = typeService.getById(typeId); |
| | | if (type != null && type.getDelFlag() != 1) { |
| | | if (type != null && type.getDel_flag() != 1) { |
| | | return ResponseResult.success(type); |
| | | } |
| | | return ResponseResult.error("类型不存在"); |
| | | } |
| | | |
| | | @GetMapping("/list") |
| | | public ResponseResult<?> list( |
| | | @RequestParam(required = false) Integer pageNum, |
| | | @RequestParam(required = false) Integer pageSize, |
| | | @RequestParam(required = false) String typeName) { |
| | | |
| | | // 不传分页参数则返回全部数据 |
| | | if (pageNum == null || pageSize == null) { |
| | | List<Type> types = typeService.listAllAvailable(); |
| | | return ResponseResult.success(types); |
| | | @DeleteMapping("/batch") |
| | | public ResponseResult<Void> batchDelete(@RequestBody List<Integer> typeIds) { |
| | | List<Type> types = typeIds.stream().map(id -> { |
| | | Type type = new Type(); |
| | | type.setType_id(id); |
| | | type.setDel_flag(1); |
| | | return type; |
| | | }).collect(java.util.stream.Collectors.toList()); |
| | | boolean success = typeService.updateBatchById(types); |
| | | if (success) { |
| | | return ResponseResult.success(); |
| | | } |
| | | return ResponseResult.error("批量删除类型失败"); |
| | | } |
| | | |
| | | @GetMapping("/list") |
| | | public ResponseResult<List<Type>> list( |
| | | @RequestParam(required = false) Integer page, |
| | | @RequestParam(required = false) Integer pageSize) { |
| | | LambdaQueryWrapper<Type> queryWrapper = new LambdaQueryWrapper<>(); |
| | | queryWrapper.eq(Type::getDelFlag, 0) |
| | | .like(typeName != null, Type::getTypeName, typeName); |
| | | queryWrapper.eq(Type::getDel_flag, 0); |
| | | |
| | | Page<Type> page = typeService.page(new Page<>(pageNum, pageSize), queryWrapper); |
| | | return ResponseResult.success(page); |
| | | if (page != null && pageSize != null) { |
| | | Page<Type> pageInfo = new Page<>(page, pageSize); |
| | | Page<Type> result = typeService.page(pageInfo, queryWrapper); |
| | | return ResponseResult.success(result.getRecords()); |
| | | } else { |
| | | List<Type> list = typeService.list(queryWrapper); |
| | | return ResponseResult.success(list); |
| | | } |
| | | } |
| | | } |
| | |
| | | /** |
| | | * @author xy |
| | | * @description 针对表【keyword】的数据库操作Mapper |
| | | * @createDate 2025-07-02 16:32:19 |
| | | * @Entity generator.entity.Keyword |
| | | * @createDate 2025-07-04 20:17:33 |
| | | * @Entity com.linghu.model.entity.Keyword |
| | | */ |
| | | public interface KeywordMapper extends BaseMapper<Keyword> { |
| | | |
| | |
| | | /** |
| | | * @author xy |
| | | * @description 针对表【order】的数据库操作Mapper |
| | | * @createDate 2025-07-02 16:32:19 |
| | | * @Entity generator.entity.Order |
| | | * @createDate 2025-07-04 20:17:33 |
| | | * @Entity com.linghu.model.entity.Order |
| | | */ |
| | | public interface OrderMapper extends BaseMapper<Order> { |
| | | |
New file |
| | |
| | | package com.linghu.mapper; |
| | | |
| | | import com.linghu.model.entity.Platform; |
| | | import com.baomidou.mybatisplus.core.mapper.BaseMapper; |
| | | |
| | | /** |
| | | * @author xy |
| | | * @description 针对表【platfrom】的数据库操作Mapper |
| | | * @createDate 2025-07-04 20:17:33 |
| | | * @Entity com.linghu.model.entity.Platfrom |
| | | */ |
| | | public interface PlatformMapper extends BaseMapper<Platform> { |
| | | |
| | | } |
New file |
| | |
| | | package com.linghu.mapper; |
| | | |
| | | import com.linghu.model.entity.Question; |
| | | import com.baomidou.mybatisplus.core.mapper.BaseMapper; |
| | | |
| | | /** |
| | | * @author xy |
| | | * @description 针对表【question】的数据库操作Mapper |
| | | * @createDate 2025-07-04 20:17:33 |
| | | * @Entity com.linghu.model.entity.Question |
| | | */ |
| | | public interface QuestionMapper extends BaseMapper<Question> { |
| | | |
| | | } |
| | | |
| | | |
| | | |
| | | |
New file |
| | |
| | | package com.linghu.mapper; |
| | | |
| | | import com.linghu.model.entity.Reference; |
| | | import com.baomidou.mybatisplus.core.mapper.BaseMapper; |
| | | |
| | | /** |
| | | * @author xy |
| | | * @description 针对表【reference】的数据库操作Mapper |
| | | * @createDate 2025-07-04 20:17:33 |
| | | * @Entity com.linghu.model.entity.Reference |
| | | */ |
| | | public interface ReferenceMapper extends BaseMapper<Reference> { |
| | | |
| | | } |
| | | |
| | | |
| | | |
| | | |
| | |
| | | /** |
| | | * @author xy |
| | | * @description 针对表【type】的数据库操作Mapper |
| | | * @createDate 2025-07-02 16:32:19 |
| | | * @Entity generator.entity.Type |
| | | * @createDate 2025-07-04 20:10:31 |
| | | * @Entity com.linghu.model.entity.Type |
| | | */ |
| | | public interface TypeMapper extends BaseMapper<Type> { |
| | | |
New file |
| | |
| | | package com.linghu.mapper; |
| | | |
| | | import com.linghu.model.entity.User; |
| | | import com.baomidou.mybatisplus.core.mapper.BaseMapper; |
| | | |
| | | /** |
| | | * @author xy |
| | | * @description 针对表【user】的数据库操作Mapper |
| | | * @createDate 2025-07-07 10:26:00 |
| | | * @Entity com.linghu.model.entity.User |
| | | */ |
| | | public interface UserMapper extends BaseMapper<User> { |
| | | |
| | | } |
| | | |
| | | |
| | | |
| | | |
New file |
| | |
| | | package com.linghu.model.dto; |
| | | |
| | | import lombok.Data; |
| | | import lombok.EqualsAndHashCode; |
| | | import com.linghu.model.entity.Keyword; |
| | | |
| | | @EqualsAndHashCode(callSuper = true) |
| | | @Data |
| | | public class KeywordDto extends Keyword { |
| | | /** |
| | | * 提问词列表,用换行符分隔 |
| | | */ |
| | | private String questions; |
| | | } |
New file |
| | |
| | | package com.linghu.model.dto; |
| | | |
| | | import com.linghu.model.entity.Order; |
| | | import lombok.Data; |
| | | import lombok.EqualsAndHashCode; |
| | | |
| | | /** |
| | | * 订单数据传输对象,扩展Order实体 |
| | | */ |
| | | @Data |
| | | @EqualsAndHashCode(callSuper = true) |
| | | public class OrderDto extends Order { |
| | | /** |
| | | * 关键词列表,用换行符分隔 |
| | | */ |
| | | private String keywords; |
| | | } |
New file |
| | |
| | | package com.linghu.model.dto; |
| | | |
| | | import lombok.Data; |
| | | import javax.validation.Valid; |
| | | import javax.validation.constraints.*; |
| | | |
| | | import com.linghu.model.entity.User; |
| | | |
| | | import java.util.List; |
| | | |
| | | @Data |
| | | public class SearchTaskRequest { |
| | | @Valid |
| | | @NotEmpty(message = "用户列表不能为空") |
| | | private List<User> users; |
| | | |
| | | @NotEmpty(message = "问题列表不能为空") |
| | | private List<String> questions; |
| | | |
| | | @Valid |
| | | private ConfigDTO config; |
| | | |
| | | private Boolean save_to_database = false; |
| | | private String webhook_url; |
| | | private Integer keyword_id; |
| | | |
| | | @Data |
| | | public static class ConfigDTO { |
| | | @Min(value = 1, message = "最大并发用户数至少为1") |
| | | private Integer max_concurrent_users = 3; |
| | | |
| | | @Min(value = 0, message = "用户启动延迟不能为负数") |
| | | private Integer user_start_delay = 1; |
| | | |
| | | private Boolean headless = true; |
| | | } |
| | | } |
New file |
| | |
| | | package com.linghu.model.dto; |
| | | |
| | | import lombok.Data; |
| | | |
| | | @Data |
| | | public class SearchTaskResponse { |
| | | private String task_id; |
| | | private String status; |
| | | private String message; |
| | | |
| | | } |
New file |
| | |
| | | package com.linghu.model.dto; |
| | | |
| | | import lombok.Data; |
| | | |
| | | @Data |
| | | public class TaskCancelResponse { |
| | | private String task_id; |
| | | private String status; |
| | | private String message; |
| | | |
| | | public TaskCancelResponse(String taskId, String status, String message) { |
| | | this.task_id = taskId; |
| | | this.status = status; |
| | | this.message = message; |
| | | } |
| | | } |
New file |
| | |
| | | package com.linghu.model.dto; |
| | | |
| | | import lombok.Data; |
| | | import lombok.NoArgsConstructor; |
| | | import lombok.AllArgsConstructor; |
| | | |
| | | import java.util.Date; |
| | | import java.util.List; |
| | | |
| | | @Data |
| | | @NoArgsConstructor |
| | | @AllArgsConstructor |
| | | public class TaskResultResponse { |
| | | private String task_id; |
| | | private Integer total_users; |
| | | private Integer total_questions; |
| | | private Integer successful_users; |
| | | private Date total_duration; |
| | | private List<UserResult> results; |
| | | |
| | | @Data |
| | | @NoArgsConstructor |
| | | @AllArgsConstructor |
| | | public static class UserResult { |
| | | |
| | | private String user_name; |
| | | private String user_email; |
| | | private String status; |
| | | private List<QuestionResult> questions_results; |
| | | } |
| | | |
| | | @Data |
| | | @NoArgsConstructor |
| | | @AllArgsConstructor |
| | | public static class QuestionResult { |
| | | private String question; |
| | | private String response; |
| | | private String status; |
| | | private Integer extracted_count; |
| | | private Date timestamp; |
| | | private String error; |
| | | private List<Reference> references; |
| | | } |
| | | |
| | | @Data |
| | | @NoArgsConstructor |
| | | @AllArgsConstructor |
| | | public static class Reference { |
| | | private String title; |
| | | private String url; |
| | | private String domain; |
| | | } |
| | | } |
New file |
| | |
| | | package com.linghu.model.dto; |
| | | |
| | | import java.util.List; |
| | | |
| | | import lombok.Data; |
| | | |
| | | @Data |
| | | public class TaskStatusResponse { |
| | | private String task_id; |
| | | private String status; |
| | | private double progress; |
| | | private String message; |
| | | private String start_time; |
| | | private String end_time; |
| | | private int users_count; |
| | | private int questions_count; |
| | | private boolean save_to_database; |
| | | private String webhook_url; |
| | | private List<QuestionStatus> questions_status; |
| | | |
| | | @Data |
| | | public static class QuestionStatus { |
| | | private int question_id; |
| | | private String question; |
| | | private String user_name; |
| | | private String user_email; |
| | | private String status; |
| | | private String timestamp; |
| | | private int extracted_count; |
| | | |
| | | // Getters and Setters |
| | | |
| | | } |
| | | } |
| | |
| | | * 关键词 |
| | | */ |
| | | @TableId(type = IdType.AUTO) |
| | | private Integer keywordId; |
| | | private Integer keyword_id; |
| | | |
| | | /** |
| | | * 关联订单id |
| | | */ |
| | | private String orderId; |
| | | private String order_id; |
| | | |
| | | /** |
| | | * 关键词名称 |
| | | */ |
| | | private String keywordName; |
| | | private String keyword_name; |
| | | |
| | | /** |
| | | * 采集轮数 |
| | | */ |
| | | private Integer num; |
| | | |
| | | /** |
| | | * 任务唯一标识符 |
| | | */ |
| | | private String task_id; |
| | | |
| | | /** |
| | | * 任务状态(notSubmitted:待处理;submitted:已提交 ; ) |
| | | */ |
| | | private String status; |
| | | |
| | | @TableField(exist = false) |
| | | private static final long serialVersionUID = 1L; |
| | |
| | | return false; |
| | | } |
| | | Keyword other = (Keyword) that; |
| | | return (this.getKeywordId() == null ? other.getKeywordId() == null : this.getKeywordId().equals(other.getKeywordId())) |
| | | && (this.getOrderId() == null ? other.getOrderId() == null : this.getOrderId().equals(other.getOrderId())) |
| | | && (this.getKeywordName() == null ? other.getKeywordName() == null : this.getKeywordName().equals(other.getKeywordName())) |
| | | && (this.getNum() == null ? other.getNum() == null : this.getNum().equals(other.getNum())); |
| | | return (this.getKeyword_id() == null ? other.getKeyword_id() == null : this.getKeyword_id().equals(other.getKeyword_id())) |
| | | && (this.getOrder_id() == null ? other.getOrder_id() == null : this.getOrder_id().equals(other.getOrder_id())) |
| | | && (this.getKeyword_name() == null ? other.getKeyword_name() == null : this.getKeyword_name().equals(other.getKeyword_name())) |
| | | && (this.getNum() == null ? other.getNum() == null : this.getNum().equals(other.getNum())) |
| | | && (this.getTask_id() == null ? other.getTask_id() == null : this.getTask_id().equals(other.getTask_id())) |
| | | && (this.getStatus() == null ? other.getStatus() == null : this.getStatus().equals(other.getStatus())); |
| | | } |
| | | |
| | | @Override |
| | | public int hashCode() { |
| | | final int prime = 31; |
| | | int result = 1; |
| | | result = prime * result + ((getKeywordId() == null) ? 0 : getKeywordId().hashCode()); |
| | | result = prime * result + ((getOrderId() == null) ? 0 : getOrderId().hashCode()); |
| | | result = prime * result + ((getKeywordName() == null) ? 0 : getKeywordName().hashCode()); |
| | | result = prime * result + ((getKeyword_id() == null) ? 0 : getKeyword_id().hashCode()); |
| | | result = prime * result + ((getOrder_id() == null) ? 0 : getOrder_id().hashCode()); |
| | | result = prime * result + ((getKeyword_name() == null) ? 0 : getKeyword_name().hashCode()); |
| | | result = prime * result + ((getNum() == null) ? 0 : getNum().hashCode()); |
| | | result = prime * result + ((getTask_id() == null) ? 0 : getTask_id().hashCode()); |
| | | result = prime * result + ((getStatus() == null) ? 0 : getStatus().hashCode()); |
| | | return result; |
| | | } |
| | | |
| | |
| | | sb.append(getClass().getSimpleName()); |
| | | sb.append(" ["); |
| | | sb.append("Hash = ").append(hashCode()); |
| | | sb.append(", keywordId=").append(keywordId); |
| | | sb.append(", orderId=").append(orderId); |
| | | sb.append(", keywordName=").append(keywordName); |
| | | sb.append(", keyword_id=").append(keyword_id); |
| | | sb.append(", order_id=").append(order_id); |
| | | sb.append(", keyword_name=").append(keyword_name); |
| | | sb.append(", num=").append(num); |
| | | sb.append(", task_id=").append(task_id); |
| | | sb.append(", status=").append(status); |
| | | sb.append(", serialVersionUID=").append(serialVersionUID); |
| | | sb.append("]"); |
| | | return sb.toString(); |
| | |
| | | package com.linghu.model.entity; |
| | | |
| | | import com.baomidou.mybatisplus.annotation.IdType; |
| | | import com.baomidou.mybatisplus.annotation.TableField; |
| | | import com.baomidou.mybatisplus.annotation.TableId; |
| | | import com.baomidou.mybatisplus.annotation.TableName; |
| | |
| | | @Data |
| | | public class Order implements Serializable { |
| | | /** |
| | | * 订单id,格式:日期-数量 |
| | | * 订单id,格式:日期-数量(202506100001) |
| | | */ |
| | | @TableId |
| | | private String orderId; |
| | | private String order_id; |
| | | |
| | | /** |
| | | * 客户名称 |
| | | */ |
| | | private String clientName; |
| | | private String client_name; |
| | | |
| | | /** |
| | | * 状态 1-待处理,2-执行中,3-已完成 |
| | |
| | | /** |
| | | * 0-未删除 1-已删除 |
| | | */ |
| | | private Integer delFlag; |
| | | private Integer del_flag; |
| | | |
| | | /** |
| | | * 提交人 |
| | | */ |
| | | private String createBy; |
| | | private String create_by; |
| | | |
| | | /** |
| | | * 创建时间 |
| | | */ |
| | | private Date createTime; |
| | | private Date create_time; |
| | | |
| | | /** |
| | | * |
| | | */ |
| | | private String updateBy; |
| | | private String update_by; |
| | | |
| | | /** |
| | | * |
| | | */ |
| | | private Date updateTime; |
| | | private Date update_time; |
| | | |
| | | @TableField(exist = false) |
| | | private static final long serialVersionUID = 1L; |
| | |
| | | return false; |
| | | } |
| | | Order other = (Order) that; |
| | | return (this.getOrderId() == null ? other.getOrderId() == null : this.getOrderId().equals(other.getOrderId())) |
| | | && (this.getClientName() == null ? other.getClientName() == null : this.getClientName().equals(other.getClientName())) |
| | | return (this.getOrder_id() == null ? other.getOrder_id() == null : this.getOrder_id().equals(other.getOrder_id())) |
| | | && (this.getClient_name() == null ? other.getClient_name() == null : this.getClient_name().equals(other.getClient_name())) |
| | | && (this.getStatus() == null ? other.getStatus() == null : this.getStatus().equals(other.getStatus())) |
| | | && (this.getDelFlag() == null ? other.getDelFlag() == null : this.getDelFlag().equals(other.getDelFlag())) |
| | | && (this.getCreateBy() == null ? other.getCreateBy() == null : this.getCreateBy().equals(other.getCreateBy())) |
| | | && (this.getCreateTime() == null ? other.getCreateTime() == null : this.getCreateTime().equals(other.getCreateTime())) |
| | | && (this.getUpdateBy() == null ? other.getUpdateBy() == null : this.getUpdateBy().equals(other.getUpdateBy())) |
| | | && (this.getUpdateTime() == null ? other.getUpdateTime() == null : this.getUpdateTime().equals(other.getUpdateTime())); |
| | | && (this.getDel_flag() == null ? other.getDel_flag() == null : this.getDel_flag().equals(other.getDel_flag())) |
| | | && (this.getCreate_by() == null ? other.getCreate_by() == null : this.getCreate_by().equals(other.getCreate_by())) |
| | | && (this.getCreate_time() == null ? other.getCreate_time() == null : this.getCreate_time().equals(other.getCreate_time())) |
| | | && (this.getUpdate_by() == null ? other.getUpdate_by() == null : this.getUpdate_by().equals(other.getUpdate_by())) |
| | | && (this.getUpdate_time() == null ? other.getUpdate_time() == null : this.getUpdate_time().equals(other.getUpdate_time())); |
| | | } |
| | | |
| | | @Override |
| | | public int hashCode() { |
| | | final int prime = 31; |
| | | int result = 1; |
| | | result = prime * result + ((getOrderId() == null) ? 0 : getOrderId().hashCode()); |
| | | result = prime * result + ((getClientName() == null) ? 0 : getClientName().hashCode()); |
| | | result = prime * result + ((getOrder_id() == null) ? 0 : getOrder_id().hashCode()); |
| | | result = prime * result + ((getClient_name() == null) ? 0 : getClient_name().hashCode()); |
| | | result = prime * result + ((getStatus() == null) ? 0 : getStatus().hashCode()); |
| | | result = prime * result + ((getDelFlag() == null) ? 0 : getDelFlag().hashCode()); |
| | | result = prime * result + ((getCreateBy() == null) ? 0 : getCreateBy().hashCode()); |
| | | result = prime * result + ((getCreateTime() == null) ? 0 : getCreateTime().hashCode()); |
| | | result = prime * result + ((getUpdateBy() == null) ? 0 : getUpdateBy().hashCode()); |
| | | result = prime * result + ((getUpdateTime() == null) ? 0 : getUpdateTime().hashCode()); |
| | | result = prime * result + ((getDel_flag() == null) ? 0 : getDel_flag().hashCode()); |
| | | result = prime * result + ((getCreate_by() == null) ? 0 : getCreate_by().hashCode()); |
| | | result = prime * result + ((getCreate_time() == null) ? 0 : getCreate_time().hashCode()); |
| | | result = prime * result + ((getUpdate_by() == null) ? 0 : getUpdate_by().hashCode()); |
| | | result = prime * result + ((getUpdate_time() == null) ? 0 : getUpdate_time().hashCode()); |
| | | return result; |
| | | } |
| | | |
| | |
| | | sb.append(getClass().getSimpleName()); |
| | | sb.append(" ["); |
| | | sb.append("Hash = ").append(hashCode()); |
| | | sb.append(", orderId=").append(orderId); |
| | | sb.append(", clientName=").append(clientName); |
| | | sb.append(", order_id=").append(order_id); |
| | | sb.append(", client_name=").append(client_name); |
| | | sb.append(", status=").append(status); |
| | | sb.append(", delFlag=").append(delFlag); |
| | | sb.append(", createBy=").append(createBy); |
| | | sb.append(", createTime=").append(createTime); |
| | | sb.append(", updateBy=").append(updateBy); |
| | | sb.append(", updateTime=").append(updateTime); |
| | | sb.append(", del_flag=").append(del_flag); |
| | | sb.append(", create_by=").append(create_by); |
| | | sb.append(", create_time=").append(create_time); |
| | | sb.append(", update_by=").append(update_by); |
| | | sb.append(", update_time=").append(update_time); |
| | | sb.append(", serialVersionUID=").append(serialVersionUID); |
| | | sb.append("]"); |
| | | return sb.toString(); |
New file |
| | |
| | | package com.linghu.model.entity; |
| | | |
| | | import com.baomidou.mybatisplus.annotation.IdType; |
| | | import com.baomidou.mybatisplus.annotation.TableField; |
| | | import com.baomidou.mybatisplus.annotation.TableId; |
| | | import com.baomidou.mybatisplus.annotation.TableName; |
| | | import java.io.Serializable; |
| | | import java.util.Date; |
| | | import lombok.Data; |
| | | |
| | | /** |
| | | * |
| | | * @TableName platfrom |
| | | */ |
| | | @TableName(value = "platform") |
| | | @Data |
| | | public class Platform implements Serializable { |
| | | /** |
| | | * 平台id |
| | | */ |
| | | @TableId(type = IdType.AUTO) |
| | | private Integer platform_id; |
| | | |
| | | /** |
| | | * 类型id |
| | | */ |
| | | private Integer type_id; |
| | | |
| | | /** |
| | | * 平台名称 |
| | | */ |
| | | private String platform_name; |
| | | |
| | | /** |
| | | * 平台域名 |
| | | */ |
| | | private String domain; |
| | | |
| | | /** |
| | | * |
| | | */ |
| | | private Date create_time; |
| | | |
| | | /** |
| | | * |
| | | */ |
| | | private String create_by; |
| | | |
| | | /** |
| | | * |
| | | */ |
| | | private Date update_time; |
| | | |
| | | /** |
| | | * |
| | | */ |
| | | private String update_by; |
| | | |
| | | /** |
| | | * 0-未删除,1-已删除 |
| | | */ |
| | | private Integer del_flag; |
| | | |
| | | @TableField(exist = false) |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | @Override |
| | | public boolean equals(Object that) { |
| | | if (this == that) { |
| | | return true; |
| | | } |
| | | if (that == null) { |
| | | return false; |
| | | } |
| | | if (getClass() != that.getClass()) { |
| | | return false; |
| | | } |
| | | Platform other = (Platform) that; |
| | | return (this.getPlatform_id() == null ? other.getPlatform_id() == null |
| | | : this.getPlatform_id().equals(other.getPlatform_id())) |
| | | && (this.getType_id() == null ? other.getType_id() == null |
| | | : this.getType_id().equals(other.getType_id())) |
| | | && (this.getPlatform_name() == null ? other.getPlatform_name() == null |
| | | : this.getPlatform_name().equals(other.getPlatform_name())) |
| | | && (this.getDomain() == null ? other.getDomain() == null : this.getDomain().equals(other.getDomain())) |
| | | && (this.getCreate_time() == null ? other.getCreate_time() == null |
| | | : this.getCreate_time().equals(other.getCreate_time())) |
| | | && (this.getCreate_by() == null ? other.getCreate_by() == null |
| | | : this.getCreate_by().equals(other.getCreate_by())) |
| | | && (this.getUpdate_time() == null ? other.getUpdate_time() == null |
| | | : this.getUpdate_time().equals(other.getUpdate_time())) |
| | | && (this.getUpdate_by() == null ? other.getUpdate_by() == null |
| | | : this.getUpdate_by().equals(other.getUpdate_by())) |
| | | && (this.getDel_flag() == null ? other.getDel_flag() == null |
| | | : this.getDel_flag().equals(other.getDel_flag())); |
| | | } |
| | | |
| | | @Override |
| | | public int hashCode() { |
| | | final int prime = 31; |
| | | int result = 1; |
| | | result = prime * result + ((getPlatform_id() == null) ? 0 : getPlatform_id().hashCode()); |
| | | result = prime * result + ((getType_id() == null) ? 0 : getType_id().hashCode()); |
| | | result = prime * result + ((getPlatform_name() == null) ? 0 : getPlatform_name().hashCode()); |
| | | result = prime * result + ((getDomain() == null) ? 0 : getDomain().hashCode()); |
| | | result = prime * result + ((getCreate_time() == null) ? 0 : getCreate_time().hashCode()); |
| | | result = prime * result + ((getCreate_by() == null) ? 0 : getCreate_by().hashCode()); |
| | | result = prime * result + ((getUpdate_time() == null) ? 0 : getUpdate_time().hashCode()); |
| | | result = prime * result + ((getUpdate_by() == null) ? 0 : getUpdate_by().hashCode()); |
| | | result = prime * result + ((getDel_flag() == null) ? 0 : getDel_flag().hashCode()); |
| | | return result; |
| | | } |
| | | |
| | | @Override |
| | | public String toString() { |
| | | StringBuilder sb = new StringBuilder(); |
| | | sb.append(getClass().getSimpleName()); |
| | | sb.append(" ["); |
| | | sb.append("Hash = ").append(hashCode()); |
| | | sb.append(", platform_id=").append(platform_id); |
| | | sb.append(", type_id=").append(type_id); |
| | | sb.append(", platform_name=").append(platform_name); |
| | | sb.append(", domain=").append(domain); |
| | | sb.append(", create_time=").append(create_time); |
| | | sb.append(", create_by=").append(create_by); |
| | | sb.append(", update_time=").append(update_time); |
| | | sb.append(", update_by=").append(update_by); |
| | | sb.append(", del_flag=").append(del_flag); |
| | | sb.append(", serialVersionUID=").append(serialVersionUID); |
| | | sb.append("]"); |
| | | return sb.toString(); |
| | | } |
| | | } |
New file |
| | |
| | | package com.linghu.model.entity; |
| | | |
| | | import com.baomidou.mybatisplus.annotation.IdType; |
| | | import com.baomidou.mybatisplus.annotation.TableField; |
| | | import com.baomidou.mybatisplus.annotation.TableId; |
| | | import com.baomidou.mybatisplus.annotation.TableName; |
| | | import java.io.Serializable; |
| | | import java.util.Date; |
| | | import lombok.Data; |
| | | |
| | | /** |
| | | * |
| | | * @TableName question |
| | | */ |
| | | @TableName(value ="question") |
| | | @Data |
| | | public class Question implements Serializable { |
| | | /** |
| | | * 提问词id |
| | | */ |
| | | @TableId(type = IdType.AUTO) |
| | | private Integer question_id; |
| | | |
| | | /** |
| | | * 关键词id |
| | | */ |
| | | private Integer keyword_id; |
| | | |
| | | /** |
| | | * 提问词 |
| | | */ |
| | | private String question; |
| | | |
| | | /** |
| | | * 提示词状态,(pending:待处理;processing:处理中 ; success:处理成功;failed:处理失败 ) |
| | | */ |
| | | private String status; |
| | | |
| | | /** |
| | | * 提交人 |
| | | */ |
| | | private String user_name; |
| | | |
| | | /** |
| | | * 提交人邮箱 |
| | | */ |
| | | private String user_email; |
| | | |
| | | /** |
| | | * 采集时间 |
| | | */ |
| | | private Date timestamp; |
| | | |
| | | /** |
| | | * 提取的引用数量 |
| | | */ |
| | | private Integer extracted_count; |
| | | |
| | | /** |
| | | * AI回复内容 |
| | | */ |
| | | private String response; |
| | | |
| | | /** |
| | | * 错误信息 |
| | | */ |
| | | private String error; |
| | | |
| | | @TableField(exist = false) |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | @Override |
| | | public boolean equals(Object that) { |
| | | if (this == that) { |
| | | return true; |
| | | } |
| | | if (that == null) { |
| | | return false; |
| | | } |
| | | if (getClass() != that.getClass()) { |
| | | return false; |
| | | } |
| | | Question other = (Question) that; |
| | | return (this.getQuestion_id() == null ? other.getQuestion_id() == null : this.getQuestion_id().equals(other.getQuestion_id())) |
| | | && (this.getKeyword_id() == null ? other.getKeyword_id() == null : this.getKeyword_id().equals(other.getKeyword_id())) |
| | | && (this.getQuestion() == null ? other.getQuestion() == null : this.getQuestion().equals(other.getQuestion())) |
| | | && (this.getStatus() == null ? other.getStatus() == null : this.getStatus().equals(other.getStatus())) |
| | | && (this.getUser_name() == null ? other.getUser_name() == null : this.getUser_name().equals(other.getUser_name())) |
| | | && (this.getUser_email() == null ? other.getUser_email() == null : this.getUser_email().equals(other.getUser_email())) |
| | | && (this.getTimestamp() == null ? other.getTimestamp() == null : this.getTimestamp().equals(other.getTimestamp())) |
| | | && (this.getExtracted_count() == null ? other.getExtracted_count() == null : this.getExtracted_count().equals(other.getExtracted_count())) |
| | | && (this.getResponse() == null ? other.getResponse() == null : this.getResponse().equals(other.getResponse())) |
| | | && (this.getError() == null ? other.getError() == null : this.getError().equals(other.getError())); |
| | | } |
| | | |
| | | @Override |
| | | public int hashCode() { |
| | | final int prime = 31; |
| | | int result = 1; |
| | | result = prime * result + ((getQuestion_id() == null) ? 0 : getQuestion_id().hashCode()); |
| | | result = prime * result + ((getKeyword_id() == null) ? 0 : getKeyword_id().hashCode()); |
| | | result = prime * result + ((getQuestion() == null) ? 0 : getQuestion().hashCode()); |
| | | result = prime * result + ((getStatus() == null) ? 0 : getStatus().hashCode()); |
| | | result = prime * result + ((getUser_name() == null) ? 0 : getUser_name().hashCode()); |
| | | result = prime * result + ((getUser_email() == null) ? 0 : getUser_email().hashCode()); |
| | | result = prime * result + ((getTimestamp() == null) ? 0 : getTimestamp().hashCode()); |
| | | result = prime * result + ((getExtracted_count() == null) ? 0 : getExtracted_count().hashCode()); |
| | | result = prime * result + ((getResponse() == null) ? 0 : getResponse().hashCode()); |
| | | result = prime * result + ((getError() == null) ? 0 : getError().hashCode()); |
| | | return result; |
| | | } |
| | | |
| | | @Override |
| | | public String toString() { |
| | | StringBuilder sb = new StringBuilder(); |
| | | sb.append(getClass().getSimpleName()); |
| | | sb.append(" ["); |
| | | sb.append("Hash = ").append(hashCode()); |
| | | sb.append(", question_id=").append(question_id); |
| | | sb.append(", keyword_id=").append(keyword_id); |
| | | sb.append(", question=").append(question); |
| | | sb.append(", status=").append(status); |
| | | sb.append(", user_name=").append(user_name); |
| | | sb.append(", user_email=").append(user_email); |
| | | sb.append(", timestamp=").append(timestamp); |
| | | sb.append(", extracted_count=").append(extracted_count); |
| | | sb.append(", response=").append(response); |
| | | sb.append(", error=").append(error); |
| | | sb.append(", serialVersionUID=").append(serialVersionUID); |
| | | sb.append("]"); |
| | | return sb.toString(); |
| | | } |
| | | } |
New file |
| | |
| | | package com.linghu.model.entity; |
| | | |
| | | import com.baomidou.mybatisplus.annotation.TableField; |
| | | import com.baomidou.mybatisplus.annotation.TableId; |
| | | import com.baomidou.mybatisplus.annotation.TableName; |
| | | import java.io.Serializable; |
| | | import java.util.Date; |
| | | import lombok.Data; |
| | | |
| | | /** |
| | | * |
| | | * @TableName reference |
| | | */ |
| | | @TableName(value = "reference") |
| | | @Data |
| | | public class Reference implements Serializable { |
| | | /** |
| | | * 结果id |
| | | */ |
| | | @TableId |
| | | private Integer reference_id; |
| | | |
| | | /** |
| | | * 类型id |
| | | */ |
| | | private Integer type_id; |
| | | |
| | | /** |
| | | * 平台id |
| | | */ |
| | | private Integer platform_id; |
| | | |
| | | /** |
| | | * 标题 |
| | | */ |
| | | private String title; |
| | | |
| | | /** |
| | | * 重复次数 |
| | | */ |
| | | private Integer repetition_num; |
| | | |
| | | /** |
| | | * 创建时间 |
| | | */ |
| | | private Date create_time; |
| | | |
| | | /** |
| | | * 采集轮数 |
| | | */ |
| | | private Integer num; |
| | | |
| | | /** |
| | | * 来源url |
| | | */ |
| | | private String url; |
| | | |
| | | /** |
| | | * 域名 |
| | | */ |
| | | private String domain; |
| | | |
| | | /** |
| | | * 任务id |
| | | */ |
| | | private String task_id; |
| | | |
| | | /** |
| | | * 关键词id |
| | | */ |
| | | private Integer keyword_id; |
| | | /** |
| | | * 问题id |
| | | */ |
| | | private Integer question_id; |
| | | |
| | | @TableField(exist = false) |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | public Reference(Integer question_id, String title, String url, String domain, Integer keyword_id, String task_id) { |
| | | this.question_id = question_id; |
| | | this.title = title; |
| | | this.url = url; |
| | | this.domain = domain; |
| | | this.task_id = task_id; |
| | | this.keyword_id = keyword_id; |
| | | |
| | | } |
| | | |
| | | @Override |
| | | public boolean equals(Object that) { |
| | | if (this == that) { |
| | | return true; |
| | | } |
| | | if (that == null) { |
| | | return false; |
| | | } |
| | | if (getClass() != that.getClass()) { |
| | | return false; |
| | | } |
| | | Reference other = (Reference) that; |
| | | return (this.getReference_id() == null ? other.getReference_id() == null |
| | | : this.getReference_id().equals(other.getReference_id())) |
| | | && (this.getType_id() == null ? other.getType_id() == null |
| | | : this.getType_id().equals(other.getType_id())) |
| | | && (this.getPlatform_id() == null ? other.getPlatform_id() == null |
| | | : this.getPlatform_id().equals(other.getPlatform_id())) |
| | | && (this.getTitle() == null ? other.getTitle() == null : this.getTitle().equals(other.getTitle())) |
| | | && (this.getRepetition_num() == null ? other.getRepetition_num() == null |
| | | : this.getRepetition_num().equals(other.getRepetition_num())) |
| | | && (this.getCreate_time() == null ? other.getCreate_time() == null |
| | | : this.getCreate_time().equals(other.getCreate_time())) |
| | | && (this.getNum() == null ? other.getNum() == null : this.getNum().equals(other.getNum())) |
| | | && (this.getUrl() == null ? other.getUrl() == null : this.getUrl().equals(other.getUrl())) |
| | | && (this.getDomain() == null ? other.getDomain() == null : this.getDomain().equals(other.getDomain())) |
| | | && (this.getTask_id() == null ? other.getTask_id() == null |
| | | : this.getTask_id().equals(other.getTask_id())) |
| | | && (this.getKeyword_id() == null ? other.getKeyword_id() == null |
| | | : this.getKeyword_id().equals(other.getKeyword_id())) |
| | | && (this.getQuestion_id() == null ? other.getQuestion_id() == null |
| | | : this.getQuestion_id().equals(other.getQuestion_id())); |
| | | } |
| | | |
| | | @Override |
| | | public int hashCode() { |
| | | final int prime = 31; |
| | | int result = 1; |
| | | result = prime * result + ((getReference_id() == null) ? 0 : getReference_id().hashCode()); |
| | | result = prime * result + ((getType_id() == null) ? 0 : getType_id().hashCode()); |
| | | result = prime * result + ((getPlatform_id() == null) ? 0 : getPlatform_id().hashCode()); |
| | | result = prime * result + ((getTitle() == null) ? 0 : getTitle().hashCode()); |
| | | result = prime * result + ((getRepetition_num() == null) ? 0 : getRepetition_num().hashCode()); |
| | | result = prime * result + ((getCreate_time() == null) ? 0 : getCreate_time().hashCode()); |
| | | result = prime * result + ((getNum() == null) ? 0 : getNum().hashCode()); |
| | | result = prime * result + ((getUrl() == null) ? 0 : getUrl().hashCode()); |
| | | result = prime * result + ((getDomain() == null) ? 0 : getDomain().hashCode()); |
| | | result = prime * result + ((getTask_id() == null) ? 0 : getTask_id().hashCode()); |
| | | result = prime * result + ((getKeyword_id() == null) ? 0 : getKeyword_id().hashCode()); |
| | | result = prime * result + ((getQuestion_id() == null) ? 0 : getQuestion_id().hashCode()); |
| | | return result; |
| | | } |
| | | |
| | | @Override |
| | | public String toString() { |
| | | StringBuilder sb = new StringBuilder(); |
| | | sb.append(getClass().getSimpleName()); |
| | | sb.append(" ["); |
| | | sb.append("Hash = ").append(hashCode()); |
| | | sb.append(", reference_id=").append(reference_id); |
| | | sb.append(", type_id=").append(type_id); |
| | | sb.append(", platform_id=").append(platform_id); |
| | | sb.append(", title=").append(title); |
| | | sb.append(", repetition_num=").append(repetition_num); |
| | | sb.append(", create_time=").append(create_time); |
| | | sb.append(", num=").append(num); |
| | | sb.append(", url=").append(url); |
| | | sb.append(", domain=").append(domain); |
| | | sb.append(", task_id=").append(task_id); |
| | | sb.append(", keyword_id=").append(keyword_id); |
| | | sb.append(", question_id=").append(question_id); |
| | | sb.append(", serialVersionUID=").append(serialVersionUID); |
| | | sb.append("]"); |
| | | return sb.toString(); |
| | | } |
| | | } |
| | |
| | | * 类型 |
| | | */ |
| | | @TableId(type = IdType.AUTO) |
| | | private Integer typeId; |
| | | private Integer type_id; |
| | | |
| | | /** |
| | | * 名字 |
| | | */ |
| | | private String typeName; |
| | | private String type_name; |
| | | |
| | | /** |
| | | * 0-未删除 1-删除 |
| | | */ |
| | | private Integer delFlag; |
| | | private Integer del_flag; |
| | | |
| | | @TableField(exist = false) |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | @Override |
| | | public boolean equals(Object that) { |
| | | if (this == that) { |
| | | return true; |
| | | } |
| | | if (that == null) { |
| | | return false; |
| | | } |
| | | if (getClass() != that.getClass()) { |
| | | return false; |
| | | } |
| | | Type other = (Type) that; |
| | | return (this.getTypeId() == null ? other.getTypeId() == null : this.getTypeId().equals(other.getTypeId())) |
| | | && (this.getTypeName() == null ? other.getTypeName() == null : this.getTypeName().equals(other.getTypeName())) |
| | | && (this.getDelFlag() == null ? other.getDelFlag() == null : this.getDelFlag().equals(other.getDelFlag())); |
| | | } |
| | | |
| | | @Override |
| | | public int hashCode() { |
| | | final int prime = 31; |
| | | int result = 1; |
| | | result = prime * result + ((getTypeId() == null) ? 0 : getTypeId().hashCode()); |
| | | result = prime * result + ((getTypeName() == null) ? 0 : getTypeName().hashCode()); |
| | | result = prime * result + ((getDelFlag() == null) ? 0 : getDelFlag().hashCode()); |
| | | return result; |
| | | } |
| | | |
| | | @Override |
| | | public String toString() { |
| | | StringBuilder sb = new StringBuilder(); |
| | | sb.append(getClass().getSimpleName()); |
| | | sb.append(" ["); |
| | | sb.append("Hash = ").append(hashCode()); |
| | | sb.append(", typeId=").append(typeId); |
| | | sb.append(", typeName=").append(typeName); |
| | | sb.append(", delFlag=").append(delFlag); |
| | | sb.append(", serialVersionUID=").append(serialVersionUID); |
| | | sb.append("]"); |
| | | return sb.toString(); |
| | | } |
| | | // @Override |
| | | // public boolean equals(Object that) { |
| | | // if (this == that) { |
| | | // return true; |
| | | // } |
| | | // if (that == null) { |
| | | // return false; |
| | | // } |
| | | // if (getClass() != that.getClass()) { |
| | | // return false; |
| | | // } |
| | | // Type other = (Type) that; |
| | | // return (this.getType_id() == null ? other.getType_id() == null : this.getType_id().equals(other.getType_id())) |
| | | // && (this.getType_name() == null ? other.getType_name() == null : this.getType_name().equals(other.getType_name())) |
| | | // && (this.getDel_flag() == null ? other.getDel_flag() == null : this.getDel_flag().equals(other.getDel_flag())); |
| | | // } |
| | | // |
| | | // @Override |
| | | // public int hashCode() { |
| | | // final int prime = 31; |
| | | // int result = 1; |
| | | // result = prime * result + ((getType_id() == null) ? 0 : getType_id().hashCode()); |
| | | // result = prime * result + ((getType_name() == null) ? 0 : getType_name().hashCode()); |
| | | // result = prime * result + ((getDel_flag() == null) ? 0 : getDel_flag().hashCode()); |
| | | // return result; |
| | | // } |
| | | // |
| | | // @Override |
| | | // public String toString() { |
| | | // StringBuilder sb = new StringBuilder(); |
| | | // sb.append(getClass().getSimpleName()); |
| | | // sb.append(" ["); |
| | | // sb.append("Hash = ").append(hashCode()); |
| | | // sb.append(", type_id=").append(type_id); |
| | | // sb.append(", type_name=").append(type_name); |
| | | // sb.append(", del_flag=").append(del_flag); |
| | | // sb.append(", serialVersionUID=").append(serialVersionUID); |
| | | // sb.append("]"); |
| | | // return sb.toString(); |
| | | // } |
| | | } |
New file |
| | |
| | | package com.linghu.model.entity; |
| | | |
| | | import com.baomidou.mybatisplus.annotation.TableField; |
| | | import com.baomidou.mybatisplus.annotation.TableId; |
| | | import com.baomidou.mybatisplus.annotation.TableName; |
| | | import java.io.Serializable; |
| | | |
| | | import javax.validation.constraints.Email; |
| | | import javax.validation.constraints.NotBlank; |
| | | import javax.validation.constraints.Size; |
| | | |
| | | import lombok.Data; |
| | | |
| | | /** |
| | | * |
| | | * @TableName user |
| | | */ |
| | | @TableName(value = "user") |
| | | @Data |
| | | public class User implements Serializable { |
| | | /** |
| | | * 用户id |
| | | */ |
| | | @TableId |
| | | private Integer user_id; |
| | | |
| | | /** |
| | | * 用户名 |
| | | */ |
| | | @NotBlank(message = "用户名不能为空") |
| | | private String user_name; |
| | | |
| | | /** |
| | | * 用户邮箱 |
| | | */ |
| | | @NotBlank(message = "邮箱不能为空") |
| | | @Email(message = "邮箱格式不正确") |
| | | private String user_email; |
| | | |
| | | /** |
| | | * 密码 |
| | | */ |
| | | @NotBlank(message = "密码不能为空") |
| | | @Size(min = 6, message = "密码长度至少6位") |
| | | private String password; |
| | | |
| | | /** |
| | | * 手机号 |
| | | */ |
| | | private Integer phone; |
| | | |
| | | @TableField(exist = false) |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | @Override |
| | | public boolean equals(Object that) { |
| | | if (this == that) { |
| | | return true; |
| | | } |
| | | if (that == null) { |
| | | return false; |
| | | } |
| | | if (getClass() != that.getClass()) { |
| | | return false; |
| | | } |
| | | User other = (User) that; |
| | | return (this.getUser_id() == null ? other.getUser_id() == null : this.getUser_id().equals(other.getUser_id())) |
| | | && (this.getUser_name() == null ? other.getUser_name() == null |
| | | : this.getUser_name().equals(other.getUser_name())) |
| | | && (this.getUser_email() == null ? other.getUser_email() == null |
| | | : this.getUser_email().equals(other.getUser_email())) |
| | | && (this.getPassword() == null ? other.getPassword() == null |
| | | : this.getPassword().equals(other.getPassword())) |
| | | && (this.getPhone() == null ? other.getPhone() == null : this.getPhone().equals(other.getPhone())); |
| | | } |
| | | |
| | | @Override |
| | | public int hashCode() { |
| | | final int prime = 31; |
| | | int result = 1; |
| | | result = prime * result + ((getUser_id() == null) ? 0 : getUser_id().hashCode()); |
| | | result = prime * result + ((getUser_name() == null) ? 0 : getUser_name().hashCode()); |
| | | result = prime * result + ((getUser_email() == null) ? 0 : getUser_email().hashCode()); |
| | | result = prime * result + ((getPassword() == null) ? 0 : getPassword().hashCode()); |
| | | result = prime * result + ((getPhone() == null) ? 0 : getPhone().hashCode()); |
| | | return result; |
| | | } |
| | | |
| | | @Override |
| | | public String toString() { |
| | | StringBuilder sb = new StringBuilder(); |
| | | sb.append(getClass().getSimpleName()); |
| | | sb.append(" ["); |
| | | sb.append("Hash = ").append(hashCode()); |
| | | sb.append(", user_id=").append(user_id); |
| | | sb.append(", user_name=").append(user_name); |
| | | sb.append(", user_email=").append(user_email); |
| | | sb.append(", password=").append(password); |
| | | sb.append(", phone=").append(phone); |
| | | sb.append(", serialVersionUID=").append(serialVersionUID); |
| | | sb.append("]"); |
| | | return sb.toString(); |
| | | } |
| | | } |
New file |
| | |
| | | package com.linghu.model.excel; |
| | | |
| | | import com.alibaba.excel.annotation.ExcelProperty; |
| | | import lombok.Data; |
| | | |
| | | @Data |
| | | public class PlatformExcel { |
| | | @ExcelProperty("平台名称") |
| | | private String platform_name; |
| | | |
| | | @ExcelProperty("发布网址") |
| | | private String domain; |
| | | |
| | | @ExcelProperty("类型名称") |
| | | private String type_name; |
| | | } |
| | |
| | | /** |
| | | * @author xy |
| | | * @description 针对表【keyword】的数据库操作Service |
| | | * @createDate 2025-07-02 16:32:19 |
| | | * @createDate 2025-07-04 20:17:33 |
| | | */ |
| | | public interface KeywordService extends IService<Keyword> { |
| | | |
| | |
| | | package com.linghu.service; |
| | | |
| | | import com.linghu.model.entity.Order; |
| | | import com.linghu.model.dto.OrderDto; |
| | | import com.baomidou.mybatisplus.extension.service.IService; |
| | | |
| | | /** |
| | | * @author xy |
| | | * @description 针对表【order】的数据库操作Service |
| | | * @createDate 2025-07-02 16:32:19 |
| | | * @createDate 2025-07-04 20:17:33 |
| | | */ |
| | | public interface OrderService extends IService<Order> { |
| | | boolean updateOrderWithKeywords(OrderDto orderDto, Integer currentStatus); |
| | | |
| | | /** |
| | | * 保存订单及其关键词 |
| | | * |
| | | * @param orderDto 订单数据传输对象 |
| | | * @return 是否保存成功 |
| | | */ |
| | | boolean saveOrderWithKeywords(OrderDto orderDto); |
| | | } |
New file |
| | |
| | | package com.linghu.service; |
| | | |
| | | import com.alibaba.excel.EasyExcel; |
| | | import com.alibaba.excel.context.AnalysisContext; |
| | | import com.alibaba.excel.read.listener.ReadListener; |
| | | import com.linghu.model.entity.Platform; |
| | | import com.linghu.model.entity.Type; |
| | | import com.linghu.model.excel.PlatformExcel; |
| | | import com.linghu.service.TypeService; |
| | | import com.linghu.service.PlatformService; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | import org.springframework.web.multipart.MultipartFile; |
| | | |
| | | import javax.servlet.http.HttpServletResponse; |
| | | import java.io.IOException; |
| | | import java.net.URLEncoder; |
| | | import java.util.ArrayList; |
| | | import java.util.Date; |
| | | import java.util.List; |
| | | |
| | | @Service |
| | | public class PlatformExcelService { |
| | | |
| | | @Autowired |
| | | private PlatformService platformService; |
| | | |
| | | @Autowired |
| | | private TypeService typeService; |
| | | |
| | | /** |
| | | * 下载平台导入模板 |
| | | */ |
| | | public void downloadTemplate(HttpServletResponse response) throws IOException { |
| | | response.setContentType("application/vnd.ms-excel"); |
| | | response.setCharacterEncoding("utf-8"); |
| | | String fileName = URLEncoder.encode("平台导入模板", "UTF-8"); |
| | | response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx"); |
| | | EasyExcel.write(response.getOutputStream(), PlatformExcel.class).sheet("平台信息").doWrite(new ArrayList<>()); |
| | | } |
| | | |
| | | /** |
| | | * 导入平台信息 |
| | | */ |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public void importPlatform(MultipartFile file) throws IOException { |
| | | EasyExcel.read(file.getInputStream(), PlatformExcel.class, new ReadListener<PlatformExcel>() { |
| | | private List<Platform> platforms = new ArrayList<>(); |
| | | |
| | | @Override |
| | | public void invoke(PlatformExcel data, AnalysisContext context) { |
| | | // 根据类型名称获取类型ID |
| | | Type type = typeService.getTypeByName(data.getType_name()); |
| | | if (type == null) { |
| | | throw new RuntimeException("类型名称不存在:" + data.getType_name()); |
| | | } |
| | | |
| | | Platform platform = new Platform(); |
| | | platform.setPlatform_name(data.getPlatform_name()); |
| | | platform.setDomain(data.getDomain()); |
| | | platform.setType_id(type.getType_id()); |
| | | platform.setCreate_time(new Date()); |
| | | platform.setDel_flag(0); |
| | | platforms.add(platform); |
| | | |
| | | // 每100条保存一次 |
| | | if (platforms.size() >= 100) { |
| | | saveData(); |
| | | platforms.clear(); |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | public void doAfterAllAnalysed(AnalysisContext context) { |
| | | saveData(); |
| | | } |
| | | |
| | | private void saveData() { |
| | | if (!platforms.isEmpty()) { |
| | | platformService.saveBatch(platforms); |
| | | } |
| | | } |
| | | }).sheet().doRead(); |
| | | } |
| | | } |
New file |
| | |
| | | package com.linghu.service; |
| | | |
| | | import com.linghu.model.entity.Platform; |
| | | import com.baomidou.mybatisplus.extension.service.IService; |
| | | |
| | | /** |
| | | * @author xy |
| | | * @description 针对表【platfrom】的数据库操作Service |
| | | * @createDate 2025-07-04 20:17:33 |
| | | */ |
| | | public interface PlatformService extends IService<Platform> { |
| | | |
| | | } |
New file |
| | |
| | | package com.linghu.service; |
| | | |
| | | import com.linghu.model.entity.Question; |
| | | import com.baomidou.mybatisplus.extension.service.IService; |
| | | |
| | | /** |
| | | * @author xy |
| | | * @description 针对表【question】的数据库操作Service |
| | | * @createDate 2025-07-04 20:17:33 |
| | | */ |
| | | public interface QuestionService extends IService<Question> { |
| | | |
| | | } |
New file |
| | |
| | | package com.linghu.service; |
| | | |
| | | import com.linghu.model.entity.Reference; |
| | | import com.baomidou.mybatisplus.extension.service.IService; |
| | | |
| | | /** |
| | | * @author xy |
| | | * @description 针对表【reference】的数据库操作Service |
| | | * @createDate 2025-07-04 20:17:33 |
| | | */ |
| | | public interface ReferenceService extends IService<Reference> { |
| | | |
| | | } |
| | |
| | | import com.linghu.model.entity.Type; |
| | | import com.baomidou.mybatisplus.extension.service.IService; |
| | | |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * @author xy |
| | | * @description 针对表【type】的数据库操作Service |
| | | * @createDate 2025-07-02 16:32:19 |
| | | * @createDate 2025-07-04 20:10:31 |
| | | */ |
| | | public interface TypeService extends IService<Type> { |
| | | /** |
| | | * 批量添加类型 |
| | | * |
| | | * @param types 类型列表 |
| | | * @return 是否成功 |
| | | */ |
| | | boolean saveBatch(List<Type> types); |
| | | |
| | | /** |
| | | * 批量更新类型 |
| | | * |
| | | * @param types 类型列表 |
| | | * @return 是否成功 |
| | | */ |
| | | boolean updateBatchById(List<Type> types); |
| | | public Type getTypeByName(String typeName); |
| | | |
| | | /** |
| | | * 批量删除类型 |
| | | * |
| | | * @param typeIds 类型ID列表 |
| | | * @return 是否成功 |
| | | */ |
| | | boolean removeBatchByIds(List<Integer> typeIds); |
| | | |
| | | /** |
| | | * 获取所有未删除的类型 |
| | | * |
| | | * @return 类型列表 |
| | | */ |
| | | List<Type> listAllAvailable(); |
| | | } |
New file |
| | |
| | | package com.linghu.service; |
| | | |
| | | import com.linghu.model.entity.User; |
| | | import com.baomidou.mybatisplus.extension.service.IService; |
| | | |
| | | /** |
| | | * @author xy |
| | | * @description 针对表【user】的数据库操作Service |
| | | * @createDate 2025-07-07 10:26:00 |
| | | */ |
| | | public interface UserService extends IService<User> { |
| | | |
| | | } |
| | |
| | | /** |
| | | * @author xy |
| | | * @description 针对表【keyword】的数据库操作Service实现 |
| | | * @createDate 2025-07-02 16:32:19 |
| | | * @createDate 2025-07-04 20:17:33 |
| | | */ |
| | | @Service |
| | | public class KeywordServiceImpl extends ServiceImpl<KeywordMapper, Keyword> |
| | |
| | | package com.linghu.service.impl; |
| | | |
| | | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
| | | import com.linghu.model.dto.OrderDto; |
| | | import com.linghu.model.entity.Keyword; |
| | | import com.linghu.model.entity.Order; |
| | | import com.linghu.service.KeywordService; |
| | | import com.linghu.service.OrderService; |
| | | import com.linghu.mapper.OrderMapper; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | import org.springframework.util.StringUtils; |
| | | |
| | | /** |
| | | * @author xy |
| | | * @description 针对表【order】的数据库操作Service实现 |
| | | * @createDate 2025-07-02 16:32:19 |
| | | * @createDate 2025-07-04 20:17:33 |
| | | */ |
| | | @Service |
| | | public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> |
| | | implements OrderService{ |
| | | |
| | | @Autowired |
| | | private KeywordService keywordService; |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public boolean saveOrderWithKeywords(OrderDto orderDto) { |
| | | // 保存订单 |
| | | if (!this.save(orderDto)) { |
| | | return false; |
| | | } |
| | | |
| | | // 如果有关键词,则保存关键词 |
| | | if (StringUtils.hasText(orderDto.getKeywords())) { |
| | | String[] keywordArray = orderDto.getKeywords().split("\\n"); |
| | | for (String keywordName : keywordArray) { |
| | | if (StringUtils.hasText(keywordName)) { |
| | | Keyword keyword = new Keyword(); |
| | | keyword.setOrder_id(orderDto.getOrder_id()); |
| | | keyword.setKeyword_name(keywordName.trim()); |
| | | keyword.setStatus("notSubmitted"); |
| | | // keyword.setNum(1); // 默认采集轮数为1 |
| | | keywordService.save(keyword); |
| | | } |
| | | } |
| | | } |
| | | |
| | | return true; |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public boolean updateOrderWithKeywords(OrderDto orderDto, Integer currentStatus) { |
| | | // 状态为2或3时禁止修改 |
| | | if (currentStatus >= 2) { |
| | | throw new RuntimeException("执行中和已完成状态的订单不可修改"); |
| | | } |
| | | |
| | | // 更新订单基本信息 |
| | | if (!this.updateById(orderDto)) { |
| | | return false; |
| | | } |
| | | |
| | | // 删除旧关键词(当状态为1时允许修改关键词) |
| | | keywordService.lambdaUpdate() |
| | | .eq(Keyword::getOrder_id, orderDto.getOrder_id()) |
| | | .eq(Keyword::getStatus, "notSubmitted") |
| | | .remove(); |
| | | |
| | | // 保存新关键词 |
| | | if (StringUtils.hasText(orderDto.getKeywords())) { |
| | | String[] keywordArray = orderDto.getKeywords().split("\\n"); |
| | | for (String keywordName : keywordArray) { |
| | | if (StringUtils.hasText(keywordName)) { |
| | | Keyword keyword = new Keyword(); |
| | | keyword.setOrder_id(orderDto.getOrder_id()); |
| | | keyword.setKeyword_name(keywordName.trim()); |
| | | keyword.setStatus("notSubmitted"); |
| | | keywordService.save(keyword); |
| | | } |
| | | } |
| | | } |
| | | |
| | | return true; |
| | | } |
| | | } |
New file |
| | |
| | | package com.linghu.service.impl; |
| | | |
| | | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
| | | import com.linghu.model.entity.Platform; |
| | | import com.linghu.service.PlatformService; |
| | | import com.linghu.mapper.PlatformMapper; |
| | | import org.springframework.stereotype.Service; |
| | | |
| | | /** |
| | | * @author xy |
| | | * @description 针对表【platfrom】的数据库操作Service实现 |
| | | * @createDate 2025-07-04 20:17:33 |
| | | */ |
| | | @Service |
| | | public class PlatformServiceImpl extends ServiceImpl<PlatformMapper, Platform> |
| | | implements PlatformService { |
| | | |
| | | } |
New file |
| | |
| | | package com.linghu.service.impl; |
| | | |
| | | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
| | | import com.linghu.model.entity.Question; |
| | | import com.linghu.service.QuestionService; |
| | | import com.linghu.mapper.QuestionMapper; |
| | | import org.springframework.stereotype.Service; |
| | | |
| | | /** |
| | | * @author xy |
| | | * @description 针对表【question】的数据库操作Service实现 |
| | | * @createDate 2025-07-04 20:17:33 |
| | | */ |
| | | @Service |
| | | public class QuestionServiceImpl extends ServiceImpl<QuestionMapper, Question> |
| | | implements QuestionService{ |
| | | |
| | | } |
| | | |
| | | |
| | | |
| | | |
New file |
| | |
| | | package com.linghu.service.impl; |
| | | |
| | | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
| | | import com.linghu.model.entity.Reference; |
| | | import com.linghu.service.ReferenceService; |
| | | import com.linghu.mapper.ReferenceMapper; |
| | | import org.springframework.stereotype.Service; |
| | | |
| | | /** |
| | | * @author xy |
| | | * @description 针对表【reference】的数据库操作Service实现 |
| | | * @createDate 2025-07-04 20:17:33 |
| | | */ |
| | | @Service |
| | | public class ReferenceServiceImpl extends ServiceImpl<ReferenceMapper, Reference> |
| | | implements ReferenceService{ |
| | | |
| | | } |
| | | |
| | | |
| | | |
| | | |
| | |
| | | package com.linghu.service.impl; |
| | | |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; |
| | | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
| | | import com.linghu.model.entity.Type; |
| | | import com.linghu.service.TypeService; |
| | | import com.linghu.mapper.TypeMapper; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | |
| | | import java.util.List; |
| | | import javax.annotation.Resource; |
| | | |
| | | /** |
| | | * @author xy |
| | | * @description 针对表【type】的数据库操作Service实现 |
| | | * @createDate 2025-07-02 16:32:19 |
| | | * @createDate 2025-07-04 20:10:31 |
| | | */ |
| | | @Service |
| | | public class TypeServiceImpl extends ServiceImpl<TypeMapper, Type> |
| | | implements TypeService { |
| | | |
| | | @Resource |
| | | private TypeMapper typeMapper; |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public boolean saveBatch(List<Type> types) { |
| | | types.forEach(type -> type.setDelFlag(0)); |
| | | return super.saveBatch(types); |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public boolean updateBatchById(List<Type> types) { |
| | | return super.updateBatchById(types); |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public boolean removeBatchByIds(List<Integer> typeIds) { |
| | | List<Type> types = this.listByIds(typeIds); |
| | | types.forEach(type -> type.setDelFlag(1)); |
| | | return this.updateBatchById(types); |
| | | } |
| | | |
| | | @Override |
| | | public List<Type> listAllAvailable() { |
| | | public Type getTypeByName(String typeName) { |
| | | // 查询 |
| | | LambdaQueryWrapper<Type> queryWrapper = new LambdaQueryWrapper<>(); |
| | | queryWrapper.eq(Type::getDelFlag, 0); |
| | | return this.list(queryWrapper); |
| | | queryWrapper.eq(Type::getType_name, typeName); |
| | | queryWrapper.eq(Type::getDel_flag, 0); |
| | | return typeMapper.selectOne(queryWrapper); |
| | | |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | package com.linghu.service.impl; |
| | | |
| | | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
| | | import com.linghu.model.entity.User; |
| | | import com.linghu.service.UserService; |
| | | import com.linghu.mapper.UserMapper; |
| | | import org.springframework.stereotype.Service; |
| | | |
| | | /** |
| | | * @author xy |
| | | * @description 针对表【user】的数据库操作Service实现 |
| | | * @createDate 2025-07-07 10:26:00 |
| | | */ |
| | | @Service |
| | | public class UserServiceImpl extends ServiceImpl<UserMapper, User> |
| | | implements UserService{ |
| | | |
| | | } |
| | | |
| | | |
| | | |
| | | |
New file |
| | |
| | | package com.linghu.utils; |
| | | |
| | | import org.springframework.beans.factory.annotation.Value; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | import com.linghu.model.entity.User; |
| | | |
| | | import io.jsonwebtoken.Claims; |
| | | import io.jsonwebtoken.ExpiredJwtException; |
| | | import io.jsonwebtoken.Jwts; |
| | | import io.jsonwebtoken.MalformedJwtException; |
| | | import io.jsonwebtoken.SignatureAlgorithm; |
| | | import io.jsonwebtoken.UnsupportedJwtException; |
| | | import io.jsonwebtoken.security.Keys; |
| | | import io.jsonwebtoken.security.SignatureException; |
| | | |
| | | import javax.crypto.SecretKey; |
| | | import java.util.Date; |
| | | import java.util.Map; |
| | | |
| | | @Component |
| | | public class JwtUtils { |
| | | @Value("${jwt.secret}") |
| | | private final String secret; |
| | | |
| | | @Value("${jwt.expiration}") |
| | | private final Long expiration; |
| | | |
| | | // 生成安全的密钥 |
| | | private SecretKey getSigningKey() { |
| | | return Keys.hmacShaKeyFor(secret.getBytes()); |
| | | } |
| | | |
| | | // 通过构造函数注入配置值 |
| | | public JwtUtils( |
| | | @Value("${jwt.secret}") String secret, |
| | | @Value("${jwt.expiration}") long expiration) { |
| | | |
| | | this.secret = secret; |
| | | this.expiration = expiration; |
| | | } |
| | | |
| | | public String generateToken(User user) { |
| | | SecretKey key = Keys.hmacShaKeyFor(secret.getBytes()); |
| | | |
| | | return Jwts.builder() |
| | | .setSubject(user.getUser_name()) |
| | | .claim("email", user.getUser_email()) |
| | | .setIssuedAt(new Date()) |
| | | .setExpiration(new Date(System.currentTimeMillis() + expiration * 1000)) |
| | | .signWith(key, SignatureAlgorithm.HS256) |
| | | .compact(); |
| | | } |
| | | |
| | | public User parseToken(String token) |
| | | throws ExpiredJwtException, UnsupportedJwtException, |
| | | MalformedJwtException, SignatureException, IllegalArgumentException { |
| | | |
| | | Claims claims = Jwts.parser() |
| | | .setSigningKey(getSigningKey()) |
| | | .build() |
| | | .parseClaimsJws(token) |
| | | .getBody(); |
| | | |
| | | // 创建User对象并填充数据 |
| | | User user = new User(); |
| | | user.setUser_name(claims.getSubject()); // 主题是用户名 |
| | | user.setUser_email(claims.get("email", String.class)); |
| | | |
| | | // 添加角色信息(如果存在) |
| | | // if (claims.containsKey("roles")) { |
| | | // user.setRoles(claims.get("roles", String.class)); |
| | | // } |
| | | |
| | | return user; |
| | | } |
| | | |
| | | public boolean validateToken(String token) { |
| | | try { |
| | | parseToken(token); |
| | | return true; |
| | | } catch (Exception e) { |
| | | return false; |
| | | } |
| | | } |
| | | } |
| | |
| | | |
| | | server: |
| | | port: 8080 |
| | | |
| | | # JWT配置 |
| | | jwt: |
| | | secret: linghu-system-mySuperSecretKeyThatIsAtLeast-key-2024 |
| | | expiration: 3600 |
| | | |
| | | spring: |
| | | datasource: |
| | | url: jdbc:mysql://192.168.110.21:3306/linghu_geo_system?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&characterEncoding=UTF-8 |
| | | # url: jdbc:mysql://127.0.0.1:3306/linghu?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&characterEncoding=UTF-8 |
| | | username: root |
| | | password: "123456" |
| | | driver-class-name: com.mysql.cj.jdbc.Driver |
| | | mvc: |
| | | pathmatch: |
| | | matching-strategy: ant_path_matcher # 使用 AntPathMatcher 替代 PathPatternMatcher |
| | | mybatis-plus: |
| | | global-config: |
| | | db-config: |
| | | logic-delete-field: del_flag #默认deleted |
| | | logic-delete-value: 1 |
| | | logic-not-delete-value: 0 |
| | | configuration: |
| | | map-underscore-to-camel-case: false |
| | | |
| | | linghu: |
| | | url: http://182.92.208.99:8000/api/v1 |
| | |
| | | <mapper namespace="com.linghu.mapper.OrderMapper"> |
| | | |
| | | <resultMap id="BaseResultMap" type="com.linghu.model.entity.Order"> |
| | | <id property="orderId" column="order_id" jdbcType="VARCHAR"/> |
| | | <result property="clientName" column="client_name" jdbcType="VARCHAR"/> |
| | | <id property="order_id" column="order_id" jdbcType="VARCHAR"/> |
| | | <result property="client_name" column="client_name" jdbcType="VARCHAR"/> |
| | | <result property="status" column="status" jdbcType="TINYINT"/> |
| | | <result property="delFlag" column="del_flag" jdbcType="TINYINT"/> |
| | | <result property="createBy" column="create_by" jdbcType="VARCHAR"/> |
| | | <result property="createTime" column="create_time" jdbcType="TIMESTAMP"/> |
| | | <result property="updateBy" column="update_by" jdbcType="VARCHAR"/> |
| | | <result property="updateTime" column="update_time" jdbcType="TIMESTAMP"/> |
| | | <result property="del_flag" column="del_flag" jdbcType="TINYINT"/> |
| | | <result property="create_by" column="create_by" jdbcType="VARCHAR"/> |
| | | <result property="create_time" column="create_time" jdbcType="TIMESTAMP"/> |
| | | <result property="update_by" column="update_by" jdbcType="VARCHAR"/> |
| | | <result property="update_time" column="update_time" jdbcType="TIMESTAMP"/> |
| | | </resultMap> |
| | | |
| | | <sql id="Base_Column_List"> |
New file |
| | |
| | | <?xml version="1.0" encoding="UTF-8"?> |
| | | <!DOCTYPE mapper |
| | | PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" |
| | | "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> |
| | | <mapper namespace="com.linghu.mapper.PlatformMapper"> |
| | | |
| | | <resultMap id="BaseResultMap" type="com.linghu.model.entity.Platform"> |
| | | <id property="platform_id" column="platform_id" jdbcType="INTEGER"/> |
| | | <result property="type_id" column="type_id" jdbcType="INTEGER"/> |
| | | <result property="platform_name" column="platform_name" jdbcType="VARCHAR"/> |
| | | <result property="domain" column="domain" jdbcType="VARCHAR"/> |
| | | <result property="create_time" column="create_time" jdbcType="TIMESTAMP"/> |
| | | <result property="create_by" column="create_by" jdbcType="VARCHAR"/> |
| | | <result property="update_time" column="update_time" jdbcType="TIMESTAMP"/> |
| | | <result property="update_by" column="update_by" jdbcType="VARCHAR"/> |
| | | <result property="del_flag" column="del_flag" jdbcType="TINYINT"/> |
| | | </resultMap> |
| | | |
| | | <sql id="Base_Column_List"> |
| | | platform_id,type_id,platform_name, |
| | | domain,create_time,create_by, |
| | | update_time,update_by,del_flag |
| | | </sql> |
| | | </mapper> |
New file |
| | |
| | | <?xml version="1.0" encoding="UTF-8"?> |
| | | <!DOCTYPE mapper |
| | | PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" |
| | | "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> |
| | | <mapper namespace="com.linghu.mapper.QuestionMapper"> |
| | | |
| | | <resultMap id="BaseResultMap" type="com.linghu.model.entity.Question"> |
| | | <id property="question_id" column="question_id" jdbcType="INTEGER"/> |
| | | <result property="keyword_id" column="keyword_id" jdbcType="INTEGER"/> |
| | | <result property="question" column="question" jdbcType="VARCHAR"/> |
| | | <result property="status" column="status" jdbcType="VARCHAR"/> |
| | | <result property="user_name" column="user_name" jdbcType="VARCHAR"/> |
| | | <result property="user_email" column="user_email" jdbcType="VARCHAR"/> |
| | | <result property="timestamp" column="timestamp" jdbcType="TIMESTAMP"/> |
| | | <result property="extracted_count" column="extracted_count" jdbcType="INTEGER"/> |
| | | <result property="response" column="response" jdbcType="VARCHAR"/> |
| | | <result property="error" column="error" jdbcType="VARCHAR"/> |
| | | </resultMap> |
| | | |
| | | <sql id="Base_Column_List"> |
| | | question_id,keyword_id,question, |
| | | status,user_name,user_email, |
| | | timestamp,extracted_count,response, |
| | | error |
| | | </sql> |
| | | </mapper> |
New file |
| | |
| | | <?xml version="1.0" encoding="UTF-8"?> |
| | | <!DOCTYPE mapper |
| | | PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" |
| | | "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> |
| | | <mapper namespace="com.linghu.mapper.ReferenceMapper"> |
| | | |
| | | <resultMap id="BaseResultMap" type="com.linghu.model.entity.Reference"> |
| | | <id property="reference_id" column="reference_id" jdbcType="INTEGER"/> |
| | | <result property="type_id" column="type_id" jdbcType="INTEGER"/> |
| | | <result property="platform_id" column="platform_id" jdbcType="INTEGER"/> |
| | | <result property="title" column="title" jdbcType="VARCHAR"/> |
| | | <result property="repetition_num" column="repetition_num" jdbcType="INTEGER"/> |
| | | <result property="create_time" column="create_time" jdbcType="TIMESTAMP"/> |
| | | <result property="num" column="num" jdbcType="INTEGER"/> |
| | | <result property="url" column="url" jdbcType="VARCHAR"/> |
| | | <result property="domain" column="domain" jdbcType="VARCHAR"/> |
| | | <result property="task_id" column="task_id" jdbcType="VARCHAR"/> |
| | | </resultMap> |
| | | |
| | | <sql id="Base_Column_List"> |
| | | reference_id,type_id,platform_id, |
| | | title,repetition_num,create_time, |
| | | num,url,domain, |
| | | task_id |
| | | </sql> |
| | | </mapper> |
| | |
| | | <mapper namespace="com.linghu.mapper.TypeMapper"> |
| | | |
| | | <resultMap id="BaseResultMap" type="com.linghu.model.entity.Type"> |
| | | <id property="typeId" column="type_id" jdbcType="INTEGER"/> |
| | | <result property="typeName" column="type_name" jdbcType="VARCHAR"/> |
| | | <result property="delFlag" column="del_flag" jdbcType="TINYINT"/> |
| | | <id property="type_id" column="type_id" jdbcType="INTEGER"/> |
| | | <result property="type_name" column="type_name" jdbcType="VARCHAR"/> |
| | | <result property="del_flag" column="del_flag" jdbcType="TINYINT"/> |
| | | </resultMap> |
| | | |
| | | <sql id="Base_Column_List"> |
New file |
| | |
| | | <?xml version="1.0" encoding="UTF-8"?> |
| | | <!DOCTYPE mapper |
| | | PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" |
| | | "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> |
| | | <mapper namespace="com.linghu.mapper.UserMapper"> |
| | | |
| | | <resultMap id="BaseResultMap" type="com.linghu.model.entity.User"> |
| | | <id property="user_id" column="user_id" jdbcType="INTEGER"/> |
| | | <result property="user_name" column="user_name" jdbcType="VARCHAR"/> |
| | | <result property="user_email" column="user_email" jdbcType="VARCHAR"/> |
| | | <result property="password" column="password" jdbcType="VARCHAR"/> |
| | | <result property="phone" column="phone" jdbcType="INTEGER"/> |
| | | </resultMap> |
| | | |
| | | <sql id="Base_Column_List"> |
| | | user_id,user_name,user_email, |
| | | password,phone |
| | | </sql> |
| | | </mapper> |
New file |
| | |
| | | <?xml version="1.0" encoding="UTF-8"?> |
| | | <!DOCTYPE mapper |
| | | PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" |
| | | "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> |
| | | <mapper namespace="com.linghu.mapper.KeywordMapper"> |
| | | |
| | | <resultMap id="BaseResultMap" type="com.linghu.model.entity.Keyword"> |
| | | <id property="keyword_id" column="keyword_id" jdbcType="INTEGER"/> |
| | | <result property="order_id" column="order_id" jdbcType="VARCHAR"/> |
| | | <result property="keyword_name" column="keyword_name" jdbcType="VARCHAR"/> |
| | | <result property="num" column="num" jdbcType="INTEGER"/> |
| | | <result property="task_id" column="task_id" jdbcType="VARCHAR"/> |
| | | <result property="status" column="status" jdbcType="VARCHAR"/> |
| | | </resultMap> |
| | | |
| | | <sql id="Base_Column_List"> |
| | | keyword_id,order_id,keyword_name, |
| | | num,task_id,status |
| | | </sql> |
| | | </mapper> |
New file |
| | |
| | | -- 订单表 |
| | | CREATE TABLE IF NOT EXISTS `order` ( |
| | | `order_id` varchar(20) NOT NULL COMMENT '订单ID', |
| | | `client_name` varchar(100) NOT NULL COMMENT '客户名称', |
| | | `status` int(1) NOT NULL DEFAULT 1 COMMENT '状态:1-待处理', |
| | | `del_flag` int(1) NOT NULL DEFAULT 0 COMMENT '删除标记:0-未删除,1-已删除', |
| | | `create_time` datetime NOT NULL COMMENT '创建时间', |
| | | `update_time` datetime DEFAULT NULL COMMENT '更新时间', |
| | | PRIMARY KEY (`order_id`) |
| | | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='订单表'; |
| | | |
| | | -- 平台表 |
| | | CREATE TABLE IF NOT EXISTS `platform` ( |
| | | `platform_id` int(11) NOT NULL AUTO_INCREMENT COMMENT '平台ID', |
| | | `platform_name` varchar(100) NOT NULL COMMENT '平台名称', |
| | | `domain` varchar(100) NOT NULL COMMENT '平台域名', |
| | | `del_flag` int(1) NOT NULL DEFAULT 0 COMMENT '删除标记:0-未删除,1-已删除', |
| | | `create_time` datetime NOT NULL COMMENT '创建时间', |
| | | `update_time` datetime DEFAULT NULL COMMENT '更新时间', |
| | | PRIMARY KEY (`platform_id`) |
| | | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='平台表'; |
| | | |
| | | -- 类型表 |
| | | CREATE TABLE IF NOT EXISTS `type` ( |
| | | `type_id` int(11) NOT NULL AUTO_INCREMENT COMMENT '类型ID', |
| | | `type_name` varchar(100) NOT NULL COMMENT '类型名称', |
| | | `del_flag` int(1) NOT NULL DEFAULT 0 COMMENT '删除标记:0-未删除,1-已删除', |
| | | `create_time` datetime NOT NULL COMMENT '创建时间', |
| | | `update_time` datetime DEFAULT NULL COMMENT '更新时间', |
| | | PRIMARY KEY (`type_id`) |
| | | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='类型表'; |
| | | |
| | | -- 提问词表 |
| | | CREATE TABLE IF NOT EXISTS `question` ( |
| | | `question_id` int(11) NOT NULL AUTO_INCREMENT COMMENT '提问词ID', |
| | | `question` varchar(500) NOT NULL COMMENT '提问词内容', |
| | | `status` varchar(20) NOT NULL DEFAULT 'pending' COMMENT '状态:pending-待处理', |
| | | `del_flag` int(1) NOT NULL DEFAULT 0 COMMENT '删除标记:0-未删除,1-已删除', |
| | | `create_time` datetime NOT NULL COMMENT '创建时间', |
| | | `update_time` datetime DEFAULT NULL COMMENT '更新时间', |
| | | PRIMARY KEY (`question_id`) |
| | | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='提问词表'; |
New file |
| | |
| | | CREATE TABLE `keyword` ( |
| | | `keyword_id` INT NOT NULL AUTO_INCREMENT COMMENT '关键词', |
| | | `order_id` VARCHAR(50) NOT NULL COMMENT '关联订单id', |
| | | `keyword_name` VARCHAR(255) NOT NULL COMMENT '关键词名称', |
| | | `num` INT DEFAULT 0 COMMENT '采集轮数', |
| | | `task_id` VARCHAR(50) COMMENT '任务唯一标识符', |
| | | `status` VARCHAR(50) DEFAULT 'notSubmitted' COMMENT '任务状态(notSubmitted:待处理;submitted:已提交)', |
| | | `del_flag` INT DEFAULT 0 COMMENT '0-未删除 1-删除', |
| | | `create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', |
| | | `update_time` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', |
| | | PRIMARY KEY (`keyword_id`) |
| | | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='关键词表'; |
New file |
| | |
| | | CREATE TABLE `question` ( |
| | | `question_id` varchar(255) NOT NULL COMMENT '提问词ID', |
| | | `keyword_id` int(11) DEFAULT NULL COMMENT '关键词ID', |
| | | `question` varchar(255) DEFAULT NULL COMMENT '提问词', |
| | | `status` varchar(20) DEFAULT NULL COMMENT '提示词状态(pending:待处理;processing:处理中;success:处理成功;failed:处理失败)', |
| | | `user_name` varchar(255) DEFAULT NULL COMMENT '提交人', |
| | | `user_email` varchar(255) DEFAULT NULL COMMENT '提交人邮箱', |
| | | `timestamp` datetime DEFAULT NULL COMMENT '采集时间', |
| | | `extracted_count` int(11) DEFAULT NULL COMMENT '提取的引用数量', |
| | | `response` text COMMENT 'AI回复内容', |
| | | `error` text COMMENT '错误信息', |
| | | PRIMARY KEY (`question_id`), |
| | | KEY `idx_keyword_id` (`keyword_id`) |
| | | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='提问词表'; |
New file |
| | |
| | | CREATE TABLE `reference` ( |
| | | `reference_id` int(11) NOT NULL COMMENT '结果ID', |
| | | `type_id` int(11) DEFAULT NULL COMMENT '类型ID', |
| | | `platform_id` int(11) DEFAULT NULL COMMENT '平台ID', |
| | | `title` varchar(255) DEFAULT NULL COMMENT '标题', |
| | | `repetition_num` int(11) DEFAULT NULL COMMENT '重复次数', |
| | | `create_time` datetime DEFAULT NULL COMMENT '创建时间', |
| | | `num` int(11) DEFAULT NULL COMMENT '采集轮数', |
| | | `url` varchar(255) DEFAULT NULL COMMENT '来源url', |
| | | `domain` varchar(255) DEFAULT NULL COMMENT '域名', |
| | | `task_id` varchar(255) DEFAULT NULL COMMENT '任务id', |
| | | `keyword_id` int(11) DEFAULT NULL COMMENT '关键词id', |
| | | PRIMARY KEY (`reference_id`), |
| | | KEY `idx_type_id` (`type_id`), |
| | | KEY `idx_platform_id` (`platform_id`), |
| | | KEY `idx_keyword_id` (`keyword_id`) |
| | | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='引用表'; |