Commit 7df4e9b1 by zwb

新增推荐岗位详情

parent 5d5196c5
......@@ -114,4 +114,15 @@ public class JobRecommendController {
List<PositionRecommendListVo> aiPositionRecommendRecordVoList = jobRecommendService.queryPositionList(dto);
return new R<>(aiPositionRecommendRecordVoList);
}
/**
* 查询推荐岗位详情
* @param dto
* @return
*/
@PostMapping("/query-position-detail")
public R<AiPositionRecommendRecordVo> queryPositionDetail(@RequestBody PositionQueryDto dto) {
AiPositionRecommendRecordVo aiPositionRecommendRecordVo = jobRecommendService.queryPositionDetail(dto);
return new R<>(aiPositionRecommendRecordVo);
}
}
......@@ -14,10 +14,14 @@ public class PositionQueryDto {
private Long userId;
private Long positionId;
private int minSalary;
private int maxSalary;
private String cityCode;
private List<String> cityCodes;
}
......@@ -113,4 +113,6 @@ public class AiPositionRecommendRecord extends BaseEntity {
//薪资范围
private String salaryRange;
private String platformUrl;
}
\ No newline at end of file
......@@ -11,18 +11,18 @@ import java.util.List;
**/
@Data
public class RecommendItem {
private Long id;
private Long positionId;
private String jobTitle;
private String standardPosition;
private List<String> welfare;
private String salaryRange;
private Integer maxPay;
private String rDetails;
private String companyName;
private Integer companyNature;
private Integer companySize;
private String platformUrl;
private String city;
private String expDemand;
private String eduDemand;
private String createTime;
private String resumeName;
private Integer positionScore;
private String jdMd;
}
\ No newline at end of file
......@@ -45,4 +45,6 @@ public interface PositionRecommendMapper extends BaseMapper<AiPositionRecommendR
Date getLastRecommendTime(@Param("userId") Long userId);
List<PositionRecommendListVo> queryPositionList(@Param("dto") PositionQueryDto dto);
AiPositionRecommendRecordVo selectPositionById(@Param("positionId") Long positionId);
}
......@@ -32,4 +32,11 @@ public interface JobRecommendService {
* @return
*/
List<PositionRecommendListVo> queryPositionList(PositionQueryDto dto);
/**
* 查询推荐岗位详情
* @param dto
* @return
*/
AiPositionRecommendRecordVo queryPositionDetail(PositionQueryDto dto);
}
package com.bkty.system.service.jobRecommend.impl;
import com.google.common.collect.Lists;
import java.util.Date;
import com.bkty.system.domain.entity.FunctionPositionPortraitV2;
import com.google.common.collect.Maps;
import cn.hutool.core.util.ObjectUtil;
import co.elastic.clients.elasticsearch._types.FieldValue;
import co.elastic.clients.elasticsearch._types.query_dsl.BoolQuery;
import co.elastic.clients.elasticsearch._types.query_dsl.QueryBuilders;
import co.elastic.clients.elasticsearch._types.query_dsl.TermQuery;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.TypeReference;
import com.alibaba.nacos.common.utils.StringUtils;
......@@ -21,16 +29,25 @@ import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.dromara.common.core.domain.R;
import org.dromara.common.core.exception.WarnException;
import org.dromara.common.core.utils.DateTimeWrapper;
import org.dromara.common.core.utils.SecurityUtils;
import org.dromara.common.satoken.utils.LoginHelper;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.data.elasticsearch.client.elc.NativeQuery;
import org.springframework.data.elasticsearch.core.ElasticsearchOperations;
import org.springframework.data.elasticsearch.core.SearchHit;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates;
import org.springframework.data.elasticsearch.core.query.SourceFilter;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
......@@ -56,6 +73,10 @@ public class JobRecommendServiceImpl implements JobRecommendService {
private final RedisTemplate<String, String> redisTemplate;
private final ElasticsearchOperations elasticsearchOperations;
private static final String RECOMMEND_ITEM_KEY = "recommend:item:%d";
@Override
public List<Level1Group> getLevel1Groups(String level1) {
......@@ -144,4 +165,108 @@ public class JobRecommendServiceImpl implements JobRecommendService {
return recommendList;
}
@Override
public AiPositionRecommendRecordVo queryPositionDetail(PositionQueryDto dto) {
Long userId = Objects.requireNonNull(LoginHelper.getLoginUser()).getUserId();
// 1. 参数校验
if (ObjectUtil.isEmpty(dto.getPositionId())) {
throw new WarnException("岗位id不能为空");
}
String result = redisTemplate.opsForValue().get(String.format(RECOMMEND_ITEM_KEY, dto.getPositionId()));
if (StringUtils.isNotBlank(result)) {
// 使用TypeReference来处理泛型类型
return JSON.parseObject(result, new TypeReference<AiPositionRecommendRecordVo>() {
});
}
AiPositionRecommendRecordVo aiPositionRecommendRecordVo = positionRecommendMapper.selectPositionById(dto.getPositionId());
if (aiPositionRecommendRecordVo != null) {
return aiPositionRecommendRecordVo;
}
String cityCode = dto.getCityCode();
if (StringUtils.isBlank(cityCode)) {
cityCode = "0000";
}
// 2. 构建布尔查询
BoolQuery.Builder boolBuilder = QueryBuilders.bool();
// 使用term精确匹配positionDataId
TermQuery termQuery = QueryBuilders.term()
.field("positionDataId")
.value(dto.getPositionId())
.build();
boolBuilder.must(termQuery._toQuery());
// 3. 构建原生查询
NativeQuery nativeQuery = NativeQuery.builder()
.withQuery(boolBuilder.build()._toQuery())
.withFields("positionDataId", "jobTitle", "standardPosition", "workPlace",
"salaryRange", "companyName", "platformUrl", "jdHtml",
"expDemand", "eduDemand", "companyNature", "companySize")
.withTrackTotalHits(true)
.withPageable(Pageable.ofSize(1)) // 只需要一条记录
.build();
// 4. 执行查询
String indexName = "function_position_portrait_" + cityCode;
SearchHits<Map> searchHits = elasticsearchOperations.search(
nativeQuery,
Map.class,
IndexCoordinates.of(indexName)
);
// 5. 处理查询结果
if (searchHits.isEmpty()) {
throw new WarnException("未找到岗位ID为[" + dto.getPositionId() + "]的岗位详情");
}
// 6. 构建参返回结果
SearchHit<Map> searchHit = searchHits.getSearchHit(0);
Map<String, Object> sourceMap = searchHit.getContent();
// AiPositionRecommendRecordVo aiPositionRecommendRecordVo = new AiPositionRecommendRecordVo();
aiPositionRecommendRecordVo.setUserId(userId);
aiPositionRecommendRecordVo.setPositionId(Long.valueOf(String.valueOf(sourceMap.get("positionDataId"))));
aiPositionRecommendRecordVo.setCityCode(cityCode);
aiPositionRecommendRecordVo.setJobTitle((String) sourceMap.get("jobTitle"));
aiPositionRecommendRecordVo.setStandardPosition((String) sourceMap.get("standardPosition"));
aiPositionRecommendRecordVo.setCompanySize((Integer) sourceMap.get("companySize"));
aiPositionRecommendRecordVo.setCompanyNature((Integer) sourceMap.get("companyNature"));
aiPositionRecommendRecordVo.setExpDemand((String) sourceMap.get("expDemand"));
aiPositionRecommendRecordVo.setEduDemand((String) sourceMap.get("eduDemand"));
aiPositionRecommendRecordVo.setCompanyName((String) sourceMap.get("companyName"));
aiPositionRecommendRecordVo.setPlatformUrl((String) sourceMap.get("platformUrl"));
aiPositionRecommendRecordVo.setJdMd((String) sourceMap.get("jdHtml"));
aiPositionRecommendRecordVo.setSalaryRange((String) sourceMap.get("salaryRange"));
// aiPositionRecommendRecordVo.setRDetails();
// aiPositionRecommendRecordVo.setMinPay(0);
// aiPositionRecommendRecordVo.setJobProfession("");
// aiPositionRecommendRecordVo.setRScore(0);
// aiPositionRecommendRecordVo.setRDetails("");
// aiPositionRecommendRecordVo.setAnalyzeJson("");
// aiPositionRecommendRecordVo.setEvaluationJson("");
// aiPositionRecommendRecordVo.setPublicPlatform("");
// aiPositionRecommendRecordVo.setMaxPay(0);
// aiPositionRecommendRecordVo.setPositionScore(0);
// aiPositionRecommendRecordVo.setFirstScore(0);
// aiPositionRecommendRecordVo.setAdvantageAnalysis("");
// aiPositionRecommendRecordVo.setMatchRate("");
// aiPositionRecommendRecordVo.setDeliverPrepare("");
// aiPositionRecommendRecordVo.setSelfIntroduction("");
// aiPositionRecommendRecordVo.setCompanyScale("");
// aiPositionRecommendRecordVo.setCompanyIndustry("");
// aiPositionRecommendRecordVo.setAnalysisId(0L);
// aiPositionRecommendRecordVo.setSearchValue("");
// aiPositionRecommendRecordVo.setCreateBy("");
// aiPositionRecommendRecordVo.setCreateTime(new Date());
// aiPositionRecommendRecordVo.setUpdateBy("");
// aiPositionRecommendRecordVo.setUpdateTime(new Date());
// aiPositionRecommendRecordVo.setParams(Maps.newHashMap());
aiPositionRecommendRecordVo.setIsDeleted(false);
return aiPositionRecommendRecordVo;
}
}
......@@ -42,7 +42,7 @@ public class PositionRecommendRedisServiceImpl implements PositionRecommendRedis
private static final String FAVORITE_KEY = "recommend:%d:favorite";
private static final String NOT_SUITABLE_KEY = "recommend:%d:not_suitable";
private static final String DELIVERED_KEY = "recommend:%d:delivered";
private static final String RECOMMEND_ITEM_KEY = "recommend:%d:item:%d";
private static final String RECOMMEND_ITEM_KEY = "recommend:item:%d";
private static final String RECOMMEND_COUNT_KEY = "recommend:count:%d";//推荐次数
@Override
......@@ -97,29 +97,23 @@ public class PositionRecommendRedisServiceImpl implements PositionRecommendRedis
String deliveredKey = String.format(DELIVERED_KEY, userId);
Long resumeId = position.getResumeId();
Long positionId = position.getId();
Long positionId = position.getPositionId();
RecommendItem item = new RecommendItem();
item.setId(position.getId());
item.setCity(position.getCityCode());
item.setPositionId(position.getId());
item.setJobTitle(position.getJobTitle());
item.setStandardPosition(portraitV2.getStandardPosition());
item.setWelfare(portraitV2.getWelfare());
item.setSalaryRange(portraitV2.getSalaryRange());
item.setRDetails(position.getRDetails());
item.setCompanyName(portraitV2.getCompanyName());
item.setCompanyNature(portraitV2.getCompanyNature());
item.setCompanySize(portraitV2.getCompanySize());
item.setPlatformUrl(portraitV2.getPlatformUrl());
item.setCity(position.getCityCode());
item.setExpDemand(position.getExpDemand());
item.setEduDemand(position.getEduDemand());
item.setCreateTime(DateTimeWrapper.parseFromDate(position.getRecommendTime(), null).toString(Constants.DATE_FULL_FORMAT));
item.setRDetails(position.getRDetails());
item.setPositionScore(position.getPositionScore());
//R<String> stringR = remoteResumeService.queryResumeName(resumeId);
item.setResumeName(position.getResumeName());
item.setJobTitle(position.getJobTitle());
item.setJdMd(position.getJdMd());
try {
item.setMaxPay(Integer.valueOf(portraitV2.getSalaryRange().split("-")[1]));
} catch (Exception e){
item.setMaxPay(0);
}
if (resumeId == null || positionId == null) {
return;
}
......@@ -145,7 +139,7 @@ public class PositionRecommendRedisServiceImpl implements PositionRecommendRedis
// 2.3 将 RecommendItem 对象转换为 JSON 字符串并存储到 Redis 中
try {
String jsonString = JSON.toJSONString(item);
redisTemplate.opsForValue().set(String.format(RECOMMEND_ITEM_KEY, userId, positionId), jsonString);
redisTemplate.opsForValue().set(String.format(RECOMMEND_ITEM_KEY, positionId), jsonString, 1, TimeUnit.HOURS);
} catch (Exception e) {
e.printStackTrace();
}
......
......@@ -87,4 +87,9 @@
</if>
ORDER BY position_score DESC
</select>
<select id="selectPositionById" resultType="com.bkty.system.domain.vo.AiPositionRecommendRecordVo">
select *
from ai_position_recommend_record
where position_id = #{positionId}
</select>
</mapper>
\ No newline at end of file
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 sign in to comment