Commit 53a92860 authored by alex yao's avatar alex yao

feat(human-resources): 添加简历自然语言检索功能

- 移除服务层方法的异常声明以简化接口
- 添加简历自然语言检索搜索的REST接口
- 实现检索搜索功能包括参数验证和业务逻辑处理
- 创建自然语言检索日志相关的实体、模型和转换器
- 添加检索日志的数据访问层和业务服务层实现
- 集成Dify工作流客户端实现AI检索能力
- 添加单元测试验证检索功能的正确性
parent 8d0a69cb
...@@ -169,6 +169,18 @@ public interface HumanResourceService { ...@@ -169,6 +169,18 @@ public interface HumanResourceService {
*/ */
void deleteResumes(Long userId, Long... resumeIds) throws Exception; void deleteResumes(Long userId, Long... resumeIds) throws Exception;
/**
* 自然语言检索简历
*
* @param userId 用户id
* @param requirements 需求
* @param positionId 职位id
* @param resumeIds 简历id
*/
List<BizHumanResourceResumeEntity> retrievalSearchResume(Long userId, String requirements, Long positionId,
List<Long> resumeIds) throws Exception;
} }
...@@ -6,6 +6,7 @@ import java.io.File; ...@@ -6,6 +6,7 @@ import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
...@@ -16,6 +17,7 @@ import java.util.stream.Collectors; ...@@ -16,6 +17,7 @@ import java.util.stream.Collectors;
import cn.com.gsst.dify_client.DifyChatClient; import cn.com.gsst.dify_client.DifyChatClient;
import cn.com.gsst.dify_client.DifyClientFactory; import cn.com.gsst.dify_client.DifyClientFactory;
import cn.com.gsst.dify_client.DifyWorkflowClient;
import cn.com.gsst.dify_client.callback.ChatStreamCallback; import cn.com.gsst.dify_client.callback.ChatStreamCallback;
import cn.com.gsst.dify_client.enums.FileTransferMethod; import cn.com.gsst.dify_client.enums.FileTransferMethod;
import cn.com.gsst.dify_client.enums.FileType; import cn.com.gsst.dify_client.enums.FileType;
...@@ -26,7 +28,10 @@ import cn.com.gsst.dify_client.exception.DifyApiException; ...@@ -26,7 +28,10 @@ import cn.com.gsst.dify_client.exception.DifyApiException;
import cn.com.gsst.dify_client.model.chat.ChatMessage; import cn.com.gsst.dify_client.model.chat.ChatMessage;
import cn.com.gsst.dify_client.model.chat.ChatMessageResponse; import cn.com.gsst.dify_client.model.chat.ChatMessageResponse;
import cn.com.gsst.dify_client.model.file.FileInfo; import cn.com.gsst.dify_client.model.file.FileInfo;
import cn.com.gsst.dify_client.model.workflow.WorkflowRunRequest;
import cn.com.gsst.dify_client.model.workflow.WorkflowRunResponse;
import cn.com.poc.common.constant.CommonConstant; import cn.com.poc.common.constant.CommonConstant;
import cn.com.poc.common.utils.DateUtils;
import cn.com.poc.common.utils.DocumentLoad; import cn.com.poc.common.utils.DocumentLoad;
import cn.com.poc.common.utils.JsonUtils; import cn.com.poc.common.utils.JsonUtils;
import cn.com.poc.common.utils.SSEUtil; import cn.com.poc.common.utils.SSEUtil;
...@@ -38,6 +43,7 @@ import cn.com.poc.human_resources.entity.BizHumanResourcePositionEntity; ...@@ -38,6 +43,7 @@ import cn.com.poc.human_resources.entity.BizHumanResourcePositionEntity;
import cn.com.poc.human_resources.entity.BizHumanResourceResumeContentEntity; import cn.com.poc.human_resources.entity.BizHumanResourceResumeContentEntity;
import cn.com.poc.human_resources.entity.BizHumanResourceResumeEntity; import cn.com.poc.human_resources.entity.BizHumanResourceResumeEntity;
import cn.com.poc.human_resources.entity.HumanResourcePositionBaseInfo; import cn.com.poc.human_resources.entity.HumanResourcePositionBaseInfo;
import cn.com.poc.human_resources.entity.HumanResourceResumeNaturalLanguageRetrievalLogEntity;
import cn.com.poc.human_resources.entity.position.BaseInfo; import cn.com.poc.human_resources.entity.position.BaseInfo;
import cn.com.poc.human_resources.entity.position.Job; import cn.com.poc.human_resources.entity.position.Job;
import cn.com.poc.human_resources.entity.position.Por; import cn.com.poc.human_resources.entity.position.Por;
...@@ -50,6 +56,7 @@ import cn.com.poc.human_resources.query.ResumeQueryItem; ...@@ -50,6 +56,7 @@ import cn.com.poc.human_resources.query.ResumeQueryItem;
import cn.com.poc.human_resources.service.BizHumanResourcePositionService; import cn.com.poc.human_resources.service.BizHumanResourcePositionService;
import cn.com.poc.human_resources.service.BizHumanResourceResumeContentService; import cn.com.poc.human_resources.service.BizHumanResourceResumeContentService;
import cn.com.poc.human_resources.service.BizHumanResourceResumeService; import cn.com.poc.human_resources.service.BizHumanResourceResumeService;
import cn.com.poc.human_resources.service.HumanResourceResumeNaturalLanguageRetrievalLogService;
import cn.com.poc.thirdparty.resource.demand.ai.entity.largemodel.LargeModelDemandResult; import cn.com.poc.thirdparty.resource.demand.ai.entity.largemodel.LargeModelDemandResult;
import cn.com.yict.framemax.core.exception.BusinessException; import cn.com.yict.framemax.core.exception.BusinessException;
import cn.com.yict.framemax.data.model.PagingInfo; import cn.com.yict.framemax.data.model.PagingInfo;
...@@ -79,6 +86,9 @@ public class HumanResourceServiceImpl implements HumanResourceService { ...@@ -79,6 +86,9 @@ public class HumanResourceServiceImpl implements HumanResourceService {
@Resource @Resource
private BizHumanResourceResumeContentService bizHumanResourceResumeContentService; private BizHumanResourceResumeContentService bizHumanResourceResumeContentService;
@Resource
private HumanResourceResumeNaturalLanguageRetrievalLogService humanResourceResumeNaturalLanguageRetrievalLogService;
@Override @Override
@Retryable(value = Exception.class, maxAttempts = 2, backoff = @Backoff(delay = 1000, multiplier = 2)) @Retryable(value = Exception.class, maxAttempts = 2, backoff = @Backoff(delay = 1000, multiplier = 2))
public Resume uploadResume(String fileURL, Long positionId, Long userId) throws Exception { public Resume uploadResume(String fileURL, Long positionId, Long userId) throws Exception {
...@@ -390,6 +400,74 @@ public class HumanResourceServiceImpl implements HumanResourceService { ...@@ -390,6 +400,74 @@ public class HumanResourceServiceImpl implements HumanResourceService {
} }
} }
@Override
public List<BizHumanResourceResumeEntity> retrievalSearchResume(Long userId, String requirements, Long positionId,
List<Long> resumeIds) {
BizHumanResourcePositionEntity bizHumanResourcePositionEntity = bizHumanResourcePositionService.get(positionId);
if (bizHumanResourcePositionEntity == null || !bizHumanResourcePositionEntity.getMemberId().equals(userId)) {
throw new BusinessException("无岗位信息");
}
BizHumanResourceResumeEntity bizHumanResourceResumeEntity = new BizHumanResourceResumeEntity();
bizHumanResourceResumeEntity.setPosition(positionId);
bizHumanResourceResumeEntity.setIsDeleted(CommonConstant.IsDeleted.N);
List<BizHumanResourceResumeEntity> entities =
bizHumanResourceResumeService.findByExample(bizHumanResourceResumeEntity, null);
if (CollectionUtils.isEmpty(entities)) {
return Collections.emptyList();
}
// 获取与resumeIds的交集
if (CollectionUtils.isNotEmpty(resumeIds)) {
entities = entities.stream()
.filter(entity -> resumeIds.contains(entity.getId()))
.collect(Collectors.toList());
}
String resume = JsonUtils.serialize(entities);
String position = JsonUtils.serialize(bizHumanResourcePositionEntity);
List<Long> result = new ArrayList<>();
try {
Map<String, Object> inputs = new HashMap<>();
inputs.put("resume", resume);
inputs.put("position", position);
inputs.put("requirements", requirements);
// 创建聊天客户端
DifyWorkflowClient client =
DifyClientFactory.createWorkflowClient(DIFY_BASE_URL, "app-xdQ9vgrG1DjhrWfXt7qRH0gS");
// 创建聊天消息
WorkflowRunRequest request = WorkflowRunRequest.builder()
.inputs(inputs)
.responseMode(ResponseMode.BLOCKING)
.user(DateUtils.getCurrDate())
.build();
WorkflowRunResponse workflowRunResponse = client.runWorkflow(request);
WorkflowRunResponse.WorkflowRunData data = workflowRunResponse.getData();
Map<String, Object> outputs = data.getOutputs();
if (outputs == null) {
return Collections.emptyList();
}
List<Integer> output = (ArrayList<Integer>) outputs.get("output");
if (output == null || CollectionUtils.isEmpty(output)) {
return Collections.emptyList();
}
result = output.stream().map(Long::valueOf).collect(Collectors.toList());
List<Long> finalResult = result;
return entities.stream().filter(entity -> finalResult.contains(entity.getId())).collect(Collectors.toList());
} catch (Exception e) {
throw new BusinessException("");
} finally {
// 保存检索结果日志
HumanResourceResumeNaturalLanguageRetrievalLogEntity humanResourceResumeNaturalLanguageRetrievalLogEntity =
new HumanResourceResumeNaturalLanguageRetrievalLogEntity();
humanResourceResumeNaturalLanguageRetrievalLogEntity.setPostionId(positionId);
humanResourceResumeNaturalLanguageRetrievalLogEntity.setPositionContent(position);
humanResourceResumeNaturalLanguageRetrievalLogEntity.setResumeIds(CollectionUtils.isNotEmpty(result) ?
JsonUtils.serialize(result) : "[]");
humanResourceResumeNaturalLanguageRetrievalLogEntity.setRetrievalContent(requirements);
humanResourceResumeNaturalLanguageRetrievalLogService.save(humanResourceResumeNaturalLanguageRetrievalLogEntity);
}
}
private void saveResumeContent(String fileURL, Long positionId, Long resumeId) throws Exception { private void saveResumeContent(String fileURL, Long positionId, Long resumeId) throws Exception {
File file = DocumentLoad.downloadURLDocument(fileURL); File file = DocumentLoad.downloadURLDocument(fileURL);
String resumeContent = DocumentLoad.documentToText(file); String resumeContent = DocumentLoad.documentToText(file);
......
package cn.com.poc.human_resources.convert;
import cn.com.poc.human_resources.model.HumanResourceResumeNaturalLanguageRetrievalLogModel;
import cn.com.poc.human_resources.entity.HumanResourceResumeNaturalLanguageRetrievalLogEntity;
import cn.com.poc.human_resources.dto.HumanResourceResumeNaturalLanguageRetrievalLogDto;
public class HumanResourceResumeNaturalLanguageRetrievalLogConvert {
public static HumanResourceResumeNaturalLanguageRetrievalLogEntity modelToEntity(HumanResourceResumeNaturalLanguageRetrievalLogModel model){
HumanResourceResumeNaturalLanguageRetrievalLogEntity entity = new HumanResourceResumeNaturalLanguageRetrievalLogEntity();
entity.setId(model.getId());
entity.setPostionId(model.getPostionId());
entity.setPositionContent(model.getPositionContent());
entity.setResumeIds(model.getResumeIds());
entity.setRetrievalContent(model.getRetrievalContent());
entity.setCreator(model.getCreator());
entity.setCreatedTime(model.getCreatedTime());
entity.setModifier(model.getModifier());
entity.setModifiedTime(model.getModifiedTime());
entity.setSysVersion(model.getSysVersion());
return entity;
}
public static HumanResourceResumeNaturalLanguageRetrievalLogModel entityToModel(HumanResourceResumeNaturalLanguageRetrievalLogEntity entity){
HumanResourceResumeNaturalLanguageRetrievalLogModel model = new HumanResourceResumeNaturalLanguageRetrievalLogModel();
model.setId(entity.getId());
model.setPostionId(entity.getPostionId());
model.setPositionContent(entity.getPositionContent());
model.setResumeIds(entity.getResumeIds());
model.setRetrievalContent(entity.getRetrievalContent());
model.setCreator(entity.getCreator());
model.setCreatedTime(entity.getCreatedTime());
model.setModifier(entity.getModifier());
model.setModifiedTime(entity.getModifiedTime());
model.setSysVersion(entity.getSysVersion());
return model;
}
public static HumanResourceResumeNaturalLanguageRetrievalLogDto entityToDto(HumanResourceResumeNaturalLanguageRetrievalLogEntity entity){
HumanResourceResumeNaturalLanguageRetrievalLogDto dto = new HumanResourceResumeNaturalLanguageRetrievalLogDto();
dto.setId(entity.getId());
dto.setPostionId(entity.getPostionId());
dto.setPositionContent(entity.getPositionContent());
dto.setResumeIds(entity.getResumeIds());
dto.setRetrievalContent(entity.getRetrievalContent());
dto.setCreator(entity.getCreator());
dto.setCreatedTime(entity.getCreatedTime());
dto.setModifier(entity.getModifier());
dto.setModifiedTime(entity.getModifiedTime());
dto.setSysVersion(entity.getSysVersion());
return dto;
}
public static HumanResourceResumeNaturalLanguageRetrievalLogEntity dtoToEntity(HumanResourceResumeNaturalLanguageRetrievalLogDto dto){
HumanResourceResumeNaturalLanguageRetrievalLogEntity entity = new HumanResourceResumeNaturalLanguageRetrievalLogEntity();
entity.setId(dto.getId());
entity.setPostionId(dto.getPostionId());
entity.setPositionContent(dto.getPositionContent());
entity.setResumeIds(dto.getResumeIds());
entity.setRetrievalContent(dto.getRetrievalContent());
entity.setCreator(dto.getCreator());
entity.setCreatedTime(dto.getCreatedTime());
entity.setModifier(dto.getModifier());
entity.setModifiedTime(dto.getModifiedTime());
entity.setSysVersion(dto.getSysVersion());
return entity;
}
}
\ No newline at end of file
package cn.com.poc.human_resources.dto;
public class HumanResourceResumeNaturalLanguageRetrievalLogDto {
private static final long serialVersionUID = 1L;
/** id
*
*/
private java.lang.Long id;
public java.lang.Long getId(){
return this.id;
}
public void setId(java.lang.Long id){
this.id = id;
}
/** postion_id
*岗位id
*/
private java.lang.Long postionId;
public java.lang.Long getPostionId(){
return this.postionId;
}
public void setPostionId(java.lang.Long postionId){
this.postionId = postionId;
}
/** position_content
*岗位信息
*/
private java.lang.String positionContent;
public java.lang.String getPositionContent(){
return this.positionContent;
}
public void setPositionContent(java.lang.String positionContent){
this.positionContent = positionContent;
}
/** resume_ids
*命中的简历id列表
*/
private java.lang.String resumeIds;
public java.lang.String getResumeIds(){
return this.resumeIds;
}
public void setResumeIds(java.lang.String resumeIds){
this.resumeIds = resumeIds;
}
/** retrieval_content
*检索内容-用户输入的自然语言
*/
private java.lang.String retrievalContent;
public java.lang.String getRetrievalContent(){
return this.retrievalContent;
}
public void setRetrievalContent(java.lang.String retrievalContent){
this.retrievalContent = retrievalContent;
}
/** CREATOR
*创建人
*/
private java.lang.String creator;
public java.lang.String getCreator(){
return this.creator;
}
public void setCreator(java.lang.String creator){
this.creator = creator;
}
/** CREATED_TIME
*创建时间
*/
private java.util.Date createdTime;
public java.util.Date getCreatedTime(){
return this.createdTime;
}
public void setCreatedTime(java.util.Date createdTime){
this.createdTime = createdTime;
}
/** MODIFIER
*修改人
*/
private java.lang.String modifier;
public java.lang.String getModifier(){
return this.modifier;
}
public void setModifier(java.lang.String modifier){
this.modifier = modifier;
}
/** MODIFIED_TIME
*修改时间
*/
private java.util.Date modifiedTime;
public java.util.Date getModifiedTime(){
return this.modifiedTime;
}
public void setModifiedTime(java.util.Date modifiedTime){
this.modifiedTime = modifiedTime;
}
/** SYS_VERSION
*乐观锁,版本号
*/
private java.lang.Integer sysVersion;
public java.lang.Integer getSysVersion(){
return this.sysVersion;
}
public void setSysVersion(java.lang.Integer sysVersion){
this.sysVersion = sysVersion;
}
}
\ No newline at end of file
package cn.com.poc.human_resources.dto;
import java.util.List;
/**
* @author alex.yao
* @date 2026/1/9
*/
public class HumanResourceRetrievalSearchResumeDto {
private Long positionId;
private List<Long> resumeIds;
private String requirements;
public Long getPositionId() {
return positionId;
}
public void setPositionId(Long positionId) {
this.positionId = positionId;
}
public List<Long> getResumeIds() {
return resumeIds;
}
public void setResumeIds(List<Long> resumeIds) {
this.resumeIds = resumeIds;
}
public String getRequirements() {
return requirements;
}
public void setRequirements(String requirements) {
this.requirements = requirements;
}
}
package cn.com.poc.human_resources.entity;
public class HumanResourceResumeNaturalLanguageRetrievalLogEntity {
private static final long serialVersionUID = 1L;
/** id
*
*/
private java.lang.Long id;
public java.lang.Long getId(){
return this.id;
}
public void setId(java.lang.Long id){
this.id = id;
}
/** postion_id
*岗位id
*/
private java.lang.Long postionId;
public java.lang.Long getPostionId(){
return this.postionId;
}
public void setPostionId(java.lang.Long postionId){
this.postionId = postionId;
}
/** position_content
*岗位信息
*/
private java.lang.String positionContent;
public java.lang.String getPositionContent(){
return this.positionContent;
}
public void setPositionContent(java.lang.String positionContent){
this.positionContent = positionContent;
}
/** resume_ids
*命中的简历id列表
*/
private java.lang.String resumeIds;
public java.lang.String getResumeIds(){
return this.resumeIds;
}
public void setResumeIds(java.lang.String resumeIds){
this.resumeIds = resumeIds;
}
/** retrieval_content
*检索内容-用户输入的自然语言
*/
private java.lang.String retrievalContent;
public java.lang.String getRetrievalContent(){
return this.retrievalContent;
}
public void setRetrievalContent(java.lang.String retrievalContent){
this.retrievalContent = retrievalContent;
}
/** CREATOR
*创建人
*/
private java.lang.String creator;
public java.lang.String getCreator(){
return this.creator;
}
public void setCreator(java.lang.String creator){
this.creator = creator;
}
/** CREATED_TIME
*创建时间
*/
private java.util.Date createdTime;
public java.util.Date getCreatedTime(){
return this.createdTime;
}
public void setCreatedTime(java.util.Date createdTime){
this.createdTime = createdTime;
}
/** MODIFIER
*修改人
*/
private java.lang.String modifier;
public java.lang.String getModifier(){
return this.modifier;
}
public void setModifier(java.lang.String modifier){
this.modifier = modifier;
}
/** MODIFIED_TIME
*修改时间
*/
private java.util.Date modifiedTime;
public java.util.Date getModifiedTime(){
return this.modifiedTime;
}
public void setModifiedTime(java.util.Date modifiedTime){
this.modifiedTime = modifiedTime;
}
/** SYS_VERSION
*乐观锁,版本号
*/
private java.lang.Integer sysVersion;
public java.lang.Integer getSysVersion(){
return this.sysVersion;
}
public void setSysVersion(java.lang.Integer sysVersion){
this.sysVersion = sysVersion;
}
}
\ No newline at end of file
package cn.com.poc.human_resources.model;
import java.io.Serializable;
import cn.com.yict.framemax.data.model.BaseModelClass;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Table;
import javax.persistence.Id;
import org.hibernate.annotations.DynamicInsert;
import org.hibernate.annotations.DynamicUpdate;
import javax.persistence.Version;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
/**
* Model class for human_resource_resume_natural_language_retrieval_log
* AI人力- 自然语言检索简历 记录日志
*/
@Entity
@Table(name = "human_resource_resume_natural_language_retrieval_log")
@DynamicInsert
@DynamicUpdate
public class HumanResourceResumeNaturalLanguageRetrievalLogModel extends BaseModelClass implements Serializable {
private static final long serialVersionUID = 1L;
/** id
*
*/
private java.lang.Long id;
@Column(name = "id",length = 19)
@Id @GeneratedValue(strategy = GenerationType.AUTO)
public java.lang.Long getId(){
return this.id;
}
public void setId(java.lang.Long id){
this.id = id;
super.addValidField("id");
}
/** postion_id
*岗位id
*/
private java.lang.Long postionId;
@Column(name = "postion_id",length = 19)
public java.lang.Long getPostionId(){
return this.postionId;
}
public void setPostionId(java.lang.Long postionId){
this.postionId = postionId;
super.addValidField("postionId");
}
/** position_content
*岗位信息
*/
private java.lang.String positionContent;
@Column(name = "position_content",length = 1073741824)
public java.lang.String getPositionContent(){
return this.positionContent;
}
public void setPositionContent(java.lang.String positionContent){
this.positionContent = positionContent;
super.addValidField("positionContent");
}
/** resume_ids
*命中的简历id列表
*/
private java.lang.String resumeIds;
@Column(name = "resume_ids",length = 1073741824)
public java.lang.String getResumeIds(){
return this.resumeIds;
}
public void setResumeIds(java.lang.String resumeIds){
this.resumeIds = resumeIds;
super.addValidField("resumeIds");
}
/** retrieval_content
*检索内容-用户输入的自然语言
*/
private java.lang.String retrievalContent;
@Column(name = "retrieval_content",length = 2147483647)
public java.lang.String getRetrievalContent(){
return this.retrievalContent;
}
public void setRetrievalContent(java.lang.String retrievalContent){
this.retrievalContent = retrievalContent;
super.addValidField("retrievalContent");
}
/** CREATOR
*创建人
*/
private java.lang.String creator;
@Column(name = "CREATOR",length = 50)
public java.lang.String getCreator(){
return this.creator;
}
public void setCreator(java.lang.String creator){
this.creator = creator;
super.addValidField("creator");
}
/** CREATED_TIME
*创建时间
*/
private java.util.Date createdTime;
@Column(name = "CREATED_TIME",length = 19)
public java.util.Date getCreatedTime(){
return this.createdTime;
}
public void setCreatedTime(java.util.Date createdTime){
this.createdTime = createdTime;
super.addValidField("createdTime");
}
/** MODIFIER
*修改人
*/
private java.lang.String modifier;
@Column(name = "MODIFIER",length = 50)
public java.lang.String getModifier(){
return this.modifier;
}
public void setModifier(java.lang.String modifier){
this.modifier = modifier;
super.addValidField("modifier");
}
/** MODIFIED_TIME
*修改时间
*/
private java.util.Date modifiedTime;
@Column(name = "MODIFIED_TIME",length = 19)
public java.util.Date getModifiedTime(){
return this.modifiedTime;
}
public void setModifiedTime(java.util.Date modifiedTime){
this.modifiedTime = modifiedTime;
super.addValidField("modifiedTime");
}
/** SYS_VERSION
*乐观锁,版本号
*/
private java.lang.Integer sysVersion;
@Column(name = "SYS_VERSION",length = 10)
@Version
public java.lang.Integer getSysVersion(){
return this.sysVersion;
}
public void setSysVersion(java.lang.Integer sysVersion){
this.sysVersion = sysVersion;
super.addValidField("sysVersion");
}
}
\ No newline at end of file
package cn.com.poc.human_resources.repository;
import cn.com.yict.framemax.data.repository.Repository;
import cn.com.poc.human_resources.model.HumanResourceResumeNaturalLanguageRetrievalLogModel;
public interface HumanResourceResumeNaturalLanguageRetrievalLogRepository extends Repository<HumanResourceResumeNaturalLanguageRetrievalLogModel,java.lang.Long> {
}
\ No newline at end of file
...@@ -109,4 +109,12 @@ public interface HumanResourceRest extends BaseRest { ...@@ -109,4 +109,12 @@ public interface HumanResourceRest extends BaseRest {
*/ */
void deleteResumes(@RequestParam Long... resumeIds) throws Exception; void deleteResumes(@RequestParam Long... resumeIds) throws Exception;
/**
* 简历自然语言检索搜索
*
* @param dto
* @return
* @throws Exception
*/
List<ResumeDto> retrievalSearchResume(@RequestBody HumanResourceRetrievalSearchResumeDto dto) throws Exception;
} }
\ No newline at end of file
package cn.com.poc.human_resources.rest.impl; package cn.com.poc.human_resources.rest.impl;
import javax.annotation.Resource;
import java.util.List;
import java.util.stream.Collectors;
import cn.com.poc.common.utils.Assert; import cn.com.poc.common.utils.Assert;
import cn.com.poc.common.utils.BlContext; import cn.com.poc.common.utils.BlContext;
import cn.com.poc.human_resources.aggregate.HumanResourceService; import cn.com.poc.human_resources.aggregate.HumanResourceService;
import cn.com.poc.human_resources.convert.BizHumanResourcePositionConvert; import cn.com.poc.human_resources.convert.BizHumanResourcePositionConvert;
import cn.com.poc.human_resources.convert.BizHumanResourceResumeConvert; import cn.com.poc.human_resources.convert.BizHumanResourceResumeConvert;
import cn.com.poc.human_resources.dto.*; import cn.com.poc.human_resources.dto.HumanResourcePositionBaseInfoDto;
import cn.com.poc.human_resources.dto.HumanResourcePositionDto;
import cn.com.poc.human_resources.dto.HumanResourceRetrievalSearchResumeDto;
import cn.com.poc.human_resources.dto.PositionAssistantDto;
import cn.com.poc.human_resources.dto.ResumeDto;
import cn.com.poc.human_resources.dto.SaveResumeDto;
import cn.com.poc.human_resources.dto.UploadResumeDto;
import cn.com.poc.human_resources.entity.BizHumanResourcePositionEntity; import cn.com.poc.human_resources.entity.BizHumanResourcePositionEntity;
import cn.com.poc.human_resources.entity.HumanResourcePositionBaseInfo; import cn.com.poc.human_resources.entity.HumanResourcePositionBaseInfo;
import cn.com.poc.human_resources.rest.HumanResourceRest; import cn.com.poc.human_resources.rest.HumanResourceRest;
...@@ -13,10 +23,6 @@ import cn.com.yict.framemax.core.exception.BusinessException; ...@@ -13,10 +23,6 @@ import cn.com.yict.framemax.core.exception.BusinessException;
import cn.com.yict.framemax.data.model.PagingInfo; import cn.com.yict.framemax.data.model.PagingInfo;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.List;
import java.util.stream.Collectors;
/** /**
* @author alex.yao * @author alex.yao
* @date 2025/9/28 * @date 2025/9/28
...@@ -27,6 +33,7 @@ public class HumanResourceRestImpl implements HumanResourceRest { ...@@ -27,6 +33,7 @@ public class HumanResourceRestImpl implements HumanResourceRest {
@Resource @Resource
private HumanResourceService humanResourceService; private HumanResourceService humanResourceService;
@Override @Override
public Object uploadResume(UploadResumeDto uploadResumeDto) throws Exception { public Object uploadResume(UploadResumeDto uploadResumeDto) throws Exception {
Assert.notBlank(uploadResumeDto.getFileURL(), "文件不能为空"); Assert.notBlank(uploadResumeDto.getFileURL(), "文件不能为空");
...@@ -163,4 +170,17 @@ public class HumanResourceRestImpl implements HumanResourceRest { ...@@ -163,4 +170,17 @@ public class HumanResourceRestImpl implements HumanResourceRest {
Assert.notEmpty(resumeIds, "请选择要删除的简历"); Assert.notEmpty(resumeIds, "请选择要删除的简历");
humanResourceService.deleteResumes(BlContext.getCurrentUser().getUserId(), resumeIds); humanResourceService.deleteResumes(BlContext.getCurrentUser().getUserId(), resumeIds);
} }
@Override
public List<ResumeDto> retrievalSearchResume(HumanResourceRetrievalSearchResumeDto dto) throws Exception {
Assert.notNull(dto.getPositionId());
Assert.notBlank(dto.getRequirements(), "检索条件不能为空");
Assert.isTrue(dto.getRequirements().length() <= 1000, "检索条件不能超过1000个字符");
return humanResourceService.retrievalSearchResume(
BlContext.getCurrentUser().getUserId(),
dto.getRequirements(),
dto.getPositionId(),
dto.getResumeIds()).stream().map(BizHumanResourceResumeConvert::entityToResumeDto
).collect(Collectors.toList());
}
} }
...@@ -12,8 +12,7 @@ public interface BizHumanResourceResumeService extends BaseService { ...@@ -12,8 +12,7 @@ public interface BizHumanResourceResumeService extends BaseService {
BizHumanResourceResumeEntity get(java.lang.Long id) throws Exception; BizHumanResourceResumeEntity get(java.lang.Long id) throws Exception;
List<BizHumanResourceResumeEntity> findByExample(BizHumanResourceResumeEntity example, PagingInfo pagingInfo) List<BizHumanResourceResumeEntity> findByExample(BizHumanResourceResumeEntity example, PagingInfo pagingInfo);
throws Exception;
BizHumanResourceResumeEntity save(BizHumanResourceResumeEntity entity) throws Exception; BizHumanResourceResumeEntity save(BizHumanResourceResumeEntity entity) throws Exception;
......
package cn.com.poc.human_resources.service;
import cn.com.yict.framemax.core.service.BaseService;
import cn.com.poc.human_resources.entity.HumanResourceResumeNaturalLanguageRetrievalLogEntity;
import cn.com.yict.framemax.data.model.PagingInfo;
import java.util.Collection;
import java.util.List;
public interface HumanResourceResumeNaturalLanguageRetrievalLogService extends BaseService {
HumanResourceResumeNaturalLanguageRetrievalLogEntity get(java.lang.Long id) throws Exception;
List<HumanResourceResumeNaturalLanguageRetrievalLogEntity> findByExample(HumanResourceResumeNaturalLanguageRetrievalLogEntity example,PagingInfo pagingInfo) throws Exception;
HumanResourceResumeNaturalLanguageRetrievalLogEntity save(HumanResourceResumeNaturalLanguageRetrievalLogEntity entity);
HumanResourceResumeNaturalLanguageRetrievalLogEntity update(HumanResourceResumeNaturalLanguageRetrievalLogEntity entity) throws Exception;
void deletedById(java.lang.Long id) throws Exception;
}
\ No newline at end of file
...@@ -40,8 +40,7 @@ public class BizHumanResourceResumeServiceImpl extends BaseServiceImpl ...@@ -40,8 +40,7 @@ public class BizHumanResourceResumeServiceImpl extends BaseServiceImpl
} }
public List<BizHumanResourceResumeEntity> findByExample(BizHumanResourceResumeEntity example, PagingInfo pagingInfo) public List<BizHumanResourceResumeEntity> findByExample(BizHumanResourceResumeEntity example, PagingInfo pagingInfo) {
throws Exception {
List<BizHumanResourceResumeEntity> result = new ArrayList<BizHumanResourceResumeEntity>(); List<BizHumanResourceResumeEntity> result = new ArrayList<BizHumanResourceResumeEntity>();
BizHumanResourceResumeModel model = new BizHumanResourceResumeModel(); BizHumanResourceResumeModel model = new BizHumanResourceResumeModel();
if (example != null) { if (example != null) {
......
package cn.com.poc.human_resources.service.impl;
import cn.com.yict.framemax.core.service.impl.BaseServiceImpl;
import cn.com.poc.human_resources.service.HumanResourceResumeNaturalLanguageRetrievalLogService;
import cn.com.poc.human_resources.model.HumanResourceResumeNaturalLanguageRetrievalLogModel;
import cn.com.poc.human_resources.entity.HumanResourceResumeNaturalLanguageRetrievalLogEntity;
import cn.com.poc.human_resources.convert.HumanResourceResumeNaturalLanguageRetrievalLogConvert;
import cn.com.poc.human_resources.repository.HumanResourceResumeNaturalLanguageRetrievalLogRepository;
import cn.com.yict.framemax.data.model.PagingInfo;
import org.springframework.stereotype.Service;
import org.apache.commons.collections4.CollectionUtils;
import java.util.ArrayList;
import java.util.stream.Collectors;
import java.util.List;
import javax.annotation.Resource;
import org.springframework.util.Assert;
@Service
public class HumanResourceResumeNaturalLanguageRetrievalLogServiceImpl extends BaseServiceImpl
implements HumanResourceResumeNaturalLanguageRetrievalLogService {
@Resource
private HumanResourceResumeNaturalLanguageRetrievalLogRepository repository;
public HumanResourceResumeNaturalLanguageRetrievalLogEntity get(java.lang.Long id) throws Exception{
Assert.notNull(id);
HumanResourceResumeNaturalLanguageRetrievalLogModel model = this.repository.get(id);
if (model == null){
return null;
}
return HumanResourceResumeNaturalLanguageRetrievalLogConvert.modelToEntity(model);
}
public List<HumanResourceResumeNaturalLanguageRetrievalLogEntity> findByExample(HumanResourceResumeNaturalLanguageRetrievalLogEntity example,PagingInfo pagingInfo) throws Exception{
List<HumanResourceResumeNaturalLanguageRetrievalLogEntity> result = new ArrayList<HumanResourceResumeNaturalLanguageRetrievalLogEntity>();
HumanResourceResumeNaturalLanguageRetrievalLogModel model = new HumanResourceResumeNaturalLanguageRetrievalLogModel();
if (example != null){
model = HumanResourceResumeNaturalLanguageRetrievalLogConvert.entityToModel(example);
}
List<HumanResourceResumeNaturalLanguageRetrievalLogModel> models = this.repository.findByExample(model,pagingInfo);
if (CollectionUtils.isNotEmpty(models)) {
result = models.stream().map(HumanResourceResumeNaturalLanguageRetrievalLogConvert::modelToEntity).collect(Collectors.toList());
}
return result;
}
public HumanResourceResumeNaturalLanguageRetrievalLogEntity save(HumanResourceResumeNaturalLanguageRetrievalLogEntity entity) {
Assert.notNull(entity);
entity.setId(null);
HumanResourceResumeNaturalLanguageRetrievalLogModel model = HumanResourceResumeNaturalLanguageRetrievalLogConvert.entityToModel(entity);
HumanResourceResumeNaturalLanguageRetrievalLogModel saveModel = this.repository.save(model);
return HumanResourceResumeNaturalLanguageRetrievalLogConvert.modelToEntity(saveModel);
}
public HumanResourceResumeNaturalLanguageRetrievalLogEntity update(HumanResourceResumeNaturalLanguageRetrievalLogEntity entity) throws Exception{
Assert.notNull(entity);
Assert.notNull(entity.getId(),"update pk can not be null");
HumanResourceResumeNaturalLanguageRetrievalLogModel model = this.repository.get(entity.getId());
if (entity.getPostionId() != null){
model.setPostionId(entity.getPostionId());
}
if (entity.getPositionContent() != null){
model.setPositionContent(entity.getPositionContent());
}
if (entity.getResumeIds() != null){
model.setResumeIds(entity.getResumeIds());
}
if (entity.getRetrievalContent() != null){
model.setRetrievalContent(entity.getRetrievalContent());
}
if (entity.getCreator() != null){
model.setCreator(entity.getCreator());
}
if (entity.getCreatedTime() != null){
model.setCreatedTime(entity.getCreatedTime());
}
if (entity.getModifier() != null){
model.setModifier(entity.getModifier());
}
if (entity.getModifiedTime() != null){
model.setModifiedTime(entity.getModifiedTime());
}
if (entity.getSysVersion() != null){
model.setSysVersion(entity.getSysVersion());
}
HumanResourceResumeNaturalLanguageRetrievalLogModel saveModel = this.repository.save(model);
return HumanResourceResumeNaturalLanguageRetrievalLogConvert.modelToEntity(saveModel);
}
public void deletedById(java.lang.Long id) throws Exception{
Assert.notNull(id);
HumanResourceResumeNaturalLanguageRetrievalLogModel model = this.repository.get(id);
if (model != null){
}
}
}
\ No newline at end of file
package cn.com.poc.humanResource; package cn.com.poc.humanResource;
import cn.com.gsst.dify_client.DifyClientFactory;
import cn.com.gsst.dify_client.DifyWorkflowClient;
import cn.com.gsst.dify_client.enums.ResponseMode;
import cn.com.gsst.dify_client.model.workflow.WorkflowRunRequest;
import cn.com.gsst.dify_client.model.workflow.WorkflowRunResponse;
import cn.com.poc.common.constant.CommonConstant;
import cn.com.poc.common.utils.BlContext; import cn.com.poc.common.utils.BlContext;
import cn.com.poc.common.utils.DateUtils;
import cn.com.poc.common.utils.JsonUtils;
import cn.com.poc.human_resources.aggregate.HumanResourceService; import cn.com.poc.human_resources.aggregate.HumanResourceService;
import cn.com.poc.human_resources.entity.BizHumanResourcePositionEntity;
import cn.com.poc.human_resources.entity.BizHumanResourceResumeEntity;
import cn.com.poc.human_resources.query.ResumeContentQueryItem; import cn.com.poc.human_resources.query.ResumeContentQueryItem;
import cn.com.poc.human_resources.service.BizHumanResourcePositionService;
import cn.com.poc.human_resources.service.BizHumanResourceResumeContentService; import cn.com.poc.human_resources.service.BizHumanResourceResumeContentService;
import cn.com.poc.human_resources.service.BizHumanResourceResumeService;
import cn.com.yict.framemax.core.exception.BusinessException;
import cn.com.yict.framemax.core.spring.SingleContextInitializer; import cn.com.yict.framemax.core.spring.SingleContextInitializer;
import org.apache.commons.collections4.CollectionUtils;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.ContextConfiguration;
...@@ -12,7 +26,12 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; ...@@ -12,7 +26,12 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration; import org.springframework.test.context.web.WebAppConfiguration;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/** /**
* @author alex.yao * @author alex.yao
...@@ -46,4 +65,18 @@ public class HumanResourceTest { ...@@ -46,4 +65,18 @@ public class HumanResourceTest {
bizHumanResourceResumeContentService.searchByResumeContent(query, positionId); bizHumanResourceResumeContentService.searchByResumeContent(query, positionId);
System.out.println(resumeContentQueryItems.size()); System.out.println(resumeContentQueryItems.size());
} }
@Test
public void test_retrievalSearchResume() throws Exception {
Long positionId = 8L;
Long userId = 197L;
List<Long> resumeIds = Arrays.asList(30L);
String requirements = "有Java开发经验;本科及以上;计算机二级;女生";
List<BizHumanResourceResumeEntity> resourceResumeEntities =
humanResourceService.retrievalSearchResume(userId, requirements, positionId, resumeIds);
System.out.println(JsonUtils.serialize(resourceResumeEntities));
}
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment