18 changed files with 315 additions and 48 deletions
@ -1,10 +1,10 @@ |
|||
package com.project.appeal.domain.service; |
|||
|
|||
import com.baomidou.mybatisplus.core.metadata.IPage; |
|||
import com.project.appeal.domain.dto.AppealDTO; |
|||
import com.project.appeal.domain.param.AppealParam; |
|||
import com.project.base.domain.result.PageResult; |
|||
import com.project.base.domain.result.Result; |
|||
|
|||
public interface SearchAppealDomainService { |
|||
Result<IPage<AppealDTO>> list(AppealParam appealParam); |
|||
Result<PageResult<AppealDTO>> list(AppealParam appealParam); |
|||
} |
|||
|
|||
@ -1,18 +1,160 @@ |
|||
package com.project.information.application; |
|||
|
|||
import com.fasterxml.jackson.core.JsonProcessingException; |
|||
import com.fasterxml.jackson.core.type.TypeReference; |
|||
import com.fasterxml.jackson.databind.ObjectMapper; |
|||
import com.project.base.domain.result.Result; |
|||
import com.project.information.domain.dto.KnowledgePointStatisticsDTO; |
|||
import com.project.information.domain.entity.KnowledgePointEntity; |
|||
import com.project.information.domain.service.KnowledgePointBaseService; |
|||
import com.project.information.domain.service.SearchKnowledgePointDomainService; |
|||
import lombok.extern.slf4j.Slf4j; |
|||
import org.apache.commons.lang3.ObjectUtils; |
|||
import org.springframework.beans.factory.annotation.Autowired; |
|||
import org.springframework.beans.factory.annotation.Value; |
|||
import org.springframework.core.io.ByteArrayResource; |
|||
import org.springframework.http.HttpEntity; |
|||
import org.springframework.http.HttpHeaders; |
|||
import org.springframework.http.MediaType; |
|||
import org.springframework.http.ResponseEntity; |
|||
import org.springframework.scheduling.annotation.Async; |
|||
import org.springframework.stereotype.Service; |
|||
import org.springframework.util.CollectionUtils; |
|||
import org.springframework.util.LinkedMultiValueMap; |
|||
import org.springframework.util.MultiValueMap; |
|||
import org.springframework.web.client.RestTemplate; |
|||
import org.springframework.web.multipart.MultipartFile; |
|||
|
|||
import java.util.*; |
|||
import java.util.stream.Collectors; |
|||
|
|||
@Service |
|||
@Slf4j |
|||
public class KnowledgePointApplicationServiceImpl implements KnowledgePointApplicationService { |
|||
@Autowired |
|||
private SearchKnowledgePointDomainService searchKnowledgePointDomainService; |
|||
@Autowired |
|||
private KnowledgePointBaseService knowledgePointBaseService; |
|||
|
|||
private final RestTemplate restTemplate = new RestTemplate(); |
|||
|
|||
@Value("${analysis.host:172.16.204.50}") |
|||
private String analysisHost; |
|||
@Value("${analysis.port:8888}") |
|||
private String analysisPort; |
|||
@Value("${analysis.url:/word/parse}") |
|||
private String analysisUrl; |
|||
|
|||
@Override |
|||
public Result<KnowledgePointStatisticsDTO> getSum(Long subLineId) { |
|||
return Result.success(searchKnowledgePointDomainService.getSum(subLineId)); |
|||
} |
|||
|
|||
@Override |
|||
@Async("parseExecutor") |
|||
public void parse(Map<Long, MultipartFile> fileMap) { |
|||
for (Long id : fileMap.keySet()) { |
|||
try { |
|||
uploadToPython(fileMap.get(id),id); |
|||
} catch (Exception e) { |
|||
log.error("文件解析失败:{}", fileMap.get(id).getOriginalFilename(), e); |
|||
} |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* 发送请求,解析文档知识点 |
|||
*/ |
|||
private void uploadToPython(MultipartFile file,Long id) throws Exception { |
|||
HttpHeaders headers = new HttpHeaders(); |
|||
headers.setContentType(MediaType.MULTIPART_FORM_DATA); |
|||
headers.setAccept(MediaType.parseMediaTypes("*/*")); |
|||
|
|||
MultiValueMap<String, Object> body = new LinkedMultiValueMap<>(); |
|||
|
|||
ByteArrayResource fileResource = new ByteArrayResource(file.getBytes()) { |
|||
@Override |
|||
public String getFilename() { |
|||
return file.getOriginalFilename(); |
|||
} |
|||
}; |
|||
|
|||
body.add("file", fileResource); |
|||
|
|||
HttpEntity<MultiValueMap<String, Object>> requestEntity = |
|||
new HttpEntity<>(body, headers); |
|||
|
|||
ResponseEntity<String> response = |
|||
restTemplate.postForEntity("http://"+analysisHost+":"+analysisPort+analysisUrl, requestEntity, String.class); |
|||
|
|||
log.info("文件 [{}] 解析完成,返回结果:{}", file.getOriginalFilename(), response.getBody()); |
|||
|
|||
List<KnowledgePointEntity> knowledgePointEntities = parseAnalysisResponse(response,id); |
|||
if(!CollectionUtils.isEmpty(knowledgePointEntities)){ |
|||
knowledgePointBaseService.saveBatch(knowledgePointEntities); |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* 解析返回数据 |
|||
*/ |
|||
public List<KnowledgePointEntity> parseAnalysisResponse(ResponseEntity<String> response,Long id) throws JsonProcessingException { |
|||
if (response == null || response.getBody() == null) { |
|||
return Collections.emptyList(); |
|||
} |
|||
|
|||
ObjectMapper mapper = new ObjectMapper(); |
|||
|
|||
Map<String, Object> root = |
|||
mapper.readValue(response.getBody(), new TypeReference<>() {}); |
|||
|
|||
if (root.containsKey("detail")) { |
|||
log.error("文件解析失败:{}", root.get("detail")); |
|||
return Collections.emptyList(); |
|||
} |
|||
|
|||
List<Map<String, Object>> data = new ArrayList<>(); |
|||
Object dataObj = root.get("data"); |
|||
if (dataObj instanceof List && ObjectUtils.isNotEmpty(dataObj)) { |
|||
data = (List<Map<String, Object>>) dataObj; |
|||
}else{ |
|||
log.error("文件解析失败"); |
|||
return Collections.emptyList(); |
|||
} |
|||
|
|||
return data.stream() |
|||
.filter(item -> { |
|||
Object attrs = item.get("attrs"); |
|||
return attrs instanceof List && !((List<?>) attrs).isEmpty(); |
|||
}) |
|||
.map(item -> { |
|||
|
|||
List<Map<String, String>> attrs = |
|||
(List<Map<String, String>>) item.get("attrs"); |
|||
|
|||
//判断是否存在精准知识点
|
|||
boolean hasYellow = attrs.stream() |
|||
.flatMap(m -> m.values().stream()) |
|||
.anyMatch("黄色"::equals); |
|||
|
|||
//收集考点信息
|
|||
List<KnowledgePointEntity.ExamFocus> focusList = attrs.stream() |
|||
.flatMap(m -> m.entrySet().stream()) |
|||
.map(e -> { |
|||
KnowledgePointEntity.ExamFocus f = new KnowledgePointEntity.ExamFocus(); |
|||
f.setExamFocusContent(e.getKey()); |
|||
f.setColor(e.getValue()); |
|||
return f; |
|||
}) |
|||
.collect(Collectors.toList()); |
|||
|
|||
KnowledgePointEntity entity = new KnowledgePointEntity(); |
|||
entity.setContent((String) item.get("knowledge")); |
|||
entity.setKnowledgeType(hasYellow ? 0 : 1); |
|||
entity.setExamFocusList(focusList); |
|||
entity.setInformationId(id); |
|||
|
|||
return entity; |
|||
}).collect(Collectors.toList()); |
|||
} |
|||
} |
|||
|
|||
@ -0,0 +1,41 @@ |
|||
package com.project.information.config; |
|||
|
|||
import org.springframework.context.annotation.Bean; |
|||
import org.springframework.context.annotation.Configuration; |
|||
import org.springframework.scheduling.annotation.EnableAsync; |
|||
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; |
|||
|
|||
import java.util.concurrent.Executor; |
|||
import java.util.concurrent.ThreadPoolExecutor; |
|||
|
|||
/** |
|||
* 异步配置类:开启异步支持 |
|||
*/ |
|||
@Configuration |
|||
@EnableAsync |
|||
public class InformationAsyncConfig { |
|||
|
|||
/** |
|||
* 自定义发生通知异步线程池 |
|||
*/ |
|||
@Bean(name = "parseExecutor") |
|||
public Executor parseExecutor() { |
|||
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); |
|||
// 核心线程数(根据业务量调整)
|
|||
executor.setCorePoolSize(5); |
|||
// 最大线程数
|
|||
executor.setMaxPoolSize(10); |
|||
// 队列容量
|
|||
executor.setQueueCapacity(100); |
|||
// 线程前缀名(便于日志排查)
|
|||
executor.setThreadNamePrefix("parse-file-"); |
|||
// 线程空闲超时时间
|
|||
executor.setKeepAliveSeconds(60); |
|||
// 拒绝策略:队列满时由调用线程执行
|
|||
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); |
|||
// 初始化线程池
|
|||
executor.initialize(); |
|||
return executor; |
|||
} |
|||
|
|||
} |
|||
@ -1,13 +1,11 @@ |
|||
package com.project.operation.domain.service; |
|||
|
|||
import com.baomidou.mybatisplus.core.metadata.IPage; |
|||
import com.project.base.domain.result.PageResult; |
|||
import com.project.base.domain.result.Result; |
|||
import com.project.operation.domain.dto.OperationLogDTO; |
|||
import com.project.operation.domain.param.OperationLogParam; |
|||
|
|||
import java.util.List; |
|||
|
|||
public interface SearchOperationLogDomainService { |
|||
|
|||
Result<IPage<OperationLogDTO>> list(OperationLogParam param); |
|||
Result<PageResult<OperationLogDTO>> list(OperationLogParam param); |
|||
} |
|||
|
|||
Loading…
Reference in new issue