diff --git a/.gitignore b/.gitignore index fb41a99..8ca3bd7 100644 --- a/.gitignore +++ b/.gitignore @@ -54,3 +54,4 @@ nbdist/ .local/ local.sh +.claude \ No newline at end of file diff --git a/ruoyi-bussiness/src/main/java/com/ruoyi/cms/domain/ESJobDocument.java b/ruoyi-bussiness/src/main/java/com/ruoyi/cms/domain/ESJobDocument.java index 4c80f48..e77c382 100644 --- a/ruoyi-bussiness/src/main/java/com/ruoyi/cms/domain/ESJobDocument.java +++ b/ruoyi-bussiness/src/main/java/com/ruoyi/cms/domain/ESJobDocument.java @@ -82,6 +82,9 @@ public class ESJobDocument @ApiModelProperty("是否火") private Integer isHot; + @ApiModelProperty("是否急聘") + private Integer isUrgent; + @ApiModelProperty("申请次数") private Integer applyNum; diff --git a/ruoyi-bussiness/src/main/java/com/ruoyi/cms/domain/Job.java b/ruoyi-bussiness/src/main/java/com/ruoyi/cms/domain/Job.java index 8acf763..3c49c63 100644 --- a/ruoyi-bussiness/src/main/java/com/ruoyi/cms/domain/Job.java +++ b/ruoyi-bussiness/src/main/java/com/ruoyi/cms/domain/Job.java @@ -103,6 +103,9 @@ public class Job extends BaseEntity @ApiModelProperty("是否火") private Integer isHot; + @ApiModelProperty("是否急聘 0否 1是") + private Integer isUrgent; + @ApiModelProperty("申请次数") @JsonIgnore private Integer applyNum; diff --git a/ruoyi-bussiness/src/main/java/com/ruoyi/cms/service/impl/ESJobSearchImpl.java b/ruoyi-bussiness/src/main/java/com/ruoyi/cms/service/impl/ESJobSearchImpl.java index 4171a9e..e745d14 100644 --- a/ruoyi-bussiness/src/main/java/com/ruoyi/cms/service/impl/ESJobSearchImpl.java +++ b/ruoyi-bussiness/src/main/java/com/ruoyi/cms/service/impl/ESJobSearchImpl.java @@ -346,6 +346,13 @@ public class ESJobSearchImpl implements IESJobSearchService if(!StringUtil.isEmptyOrNull(appUser.getSalaryMin())){ newSearch.setMinSalary(Long.valueOf(appUser.getSalaryMin())); } + // 请求参数覆盖用户资料中的薪资偏好 + if(Objects.nonNull(esJobSearch.getSalaryMin()) || Objects.nonNull(esJobSearch.getMinSalary())){ + newSearch.setMinSalary(Objects.nonNull(esJobSearch.getSalaryMin()) ? esJobSearch.getSalaryMin() : esJobSearch.getMinSalary()); + } + if(Objects.nonNull(esJobSearch.getSalaryMax()) || Objects.nonNull(esJobSearch.getMaxSalary())){ + newSearch.setMaxSalary(Objects.nonNull(esJobSearch.getSalaryMax()) ? esJobSearch.getSalaryMax() : esJobSearch.getMaxSalary()); + } if(!StringUtil.isEmptyOrNull(esJobSearch.getJobType())){ newSearch.setJobType(esJobSearch.getJobType()); } @@ -891,8 +898,16 @@ public class ESJobSearchImpl implements IESJobSearchService ESJobSearch newSearch = new ESJobSearch(); BeanUtils.copyProperties(esJobSearch,newSearch); - //查询 - if(appUser!=null){ + + // 判断是否为用户主动搜索(有明确的搜索条件),而非纯推荐场景 + boolean isExplicitSearch = !StringUtil.isEmptyOrNull(esJobSearch.getJobTitle()) + || !StringUtil.isEmptyOrNull(esJobSearch.getJobCategory()) + || !StringUtil.isEmptyOrNull(esJobSearch.getCompanyName()) + || !StringUtil.isEmptyOrNull(esJobSearch.getDescription()); + + // 用户资料偏好仅在"纯推荐"场景下作为个性化过滤条件; + // 用户主动搜索时不应被资料中的薪资/学历/经验/区域等偏好缩小结果范围 + if(appUser != null && !isExplicitSearch){ if(!ListUtil.isEmptyOrNull(appUser.getJobTitle())){ List jobTitle = appUser.getJobTitle(); newSearch.setJobTitle(String.join(",", jobTitle)); @@ -906,9 +921,6 @@ public class ESJobSearchImpl implements IESJobSearchService if(!StringUtil.isEmptyOrNull(appUser.getWorkExperience())){ newSearch.setExperience(appUser.getWorkExperience()); } - if(!StringUtil.isEmptyOrNull(esJobSearch.getExperience())){ - newSearch.setExperience(esJobSearch.getExperience()); - } if(!StringUtil.isEmptyOrNull(appUser.getSalaryMax())){ newSearch.setMaxSalary(Long.valueOf(appUser.getSalaryMax())); } @@ -917,12 +929,22 @@ public class ESJobSearchImpl implements IESJobSearchService } } + // 请求参数始终优先于用户资料偏好 + if(Objects.nonNull(esJobSearch.getSalaryMin()) || Objects.nonNull(esJobSearch.getMinSalary())){ + newSearch.setMinSalary(Objects.nonNull(esJobSearch.getSalaryMin()) ? esJobSearch.getSalaryMin() : esJobSearch.getMinSalary()); + } + if(Objects.nonNull(esJobSearch.getSalaryMax()) || Objects.nonNull(esJobSearch.getMaxSalary())){ + newSearch.setMaxSalary(Objects.nonNull(esJobSearch.getSalaryMax()) ? esJobSearch.getSalaryMax() : esJobSearch.getMaxSalary()); + } if(!StringUtil.isEmptyOrNull(esJobSearch.getArea())){ newSearch.setArea(esJobSearch.getArea()); } if(!StringUtil.isEmptyOrNull(esJobSearch.getEducation())){ newSearch.setEducation(esJobSearch.getEducation()); } + if(!StringUtil.isEmptyOrNull(esJobSearch.getExperience())){ + newSearch.setExperience(esJobSearch.getExperience()); + } if(!StringUtil.isEmptyOrNull(esJobSearch.getJobTitle())){ newSearch.setJobTitle(esJobSearch.getJobTitle()); } diff --git a/ruoyi-bussiness/src/main/java/com/ruoyi/cms/service/impl/JobServiceImpl.java b/ruoyi-bussiness/src/main/java/com/ruoyi/cms/service/impl/JobServiceImpl.java index fa50db0..c9b935e 100644 --- a/ruoyi-bussiness/src/main/java/com/ruoyi/cms/service/impl/JobServiceImpl.java +++ b/ruoyi-bussiness/src/main/java/com/ruoyi/cms/service/impl/JobServiceImpl.java @@ -35,15 +35,20 @@ import org.dromara.easyes.core.biz.EsPageInfo; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.context.event.ApplicationReadyEvent; +import org.springframework.context.event.EventListener; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import javax.servlet.http.HttpServletRequest; +import javax.sql.DataSource; import java.io.BufferedReader; import java.io.InputStreamReader; import java.math.BigDecimal; import java.net.HttpURLConnection; import java.net.URL; +import java.sql.Connection; +import java.sql.Statement; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.*; @@ -97,6 +102,34 @@ public class JobServiceImpl extends ServiceImpl implements IJobSe @Autowired private NoticeMapper noticeMapper; + @Autowired + private DataSource dataSource; + + /** + * 应用启动后自动迁移:添加 is_urgent 列(幂等) + */ + @EventListener(ApplicationReadyEvent.class) + public void migrateIsUrgentColumn() { + try (Connection conn = dataSource.getConnection(); + Statement stmt = conn.createStatement()) { + String checkSql = "SELECT COUNT(*) FROM information_schema.columns WHERE table_name='job' AND column_name='is_urgent'"; + java.sql.ResultSet rs = stmt.executeQuery(checkSql); + boolean exists = false; + if (rs.next()) { + exists = rs.getInt(1) > 0; + } + rs.close(); + if (!exists) { + stmt.execute("ALTER TABLE job ADD COLUMN is_urgent CHAR(1) DEFAULT '0'"); + logger.info("急聘功能迁移: 成功添加 job.is_urgent 列"); + } else { + logger.info("急聘功能迁移: job.is_urgent 列已存在,跳过"); + } + } catch (Exception e) { + logger.error("急聘功能迁移失败: {}", e.getMessage()); + } + } + /** * 更新工作地址的经纬度信息 */ diff --git a/ruoyi-bussiness/src/main/resources/mapper/app/JobApplyMapper.xml b/ruoyi-bussiness/src/main/resources/mapper/app/JobApplyMapper.xml index 6e9584f..4ceef72 100644 --- a/ruoyi-bussiness/src/main/resources/mapper/app/JobApplyMapper.xml +++ b/ruoyi-bussiness/src/main/resources/mapper/app/JobApplyMapper.xml @@ -141,13 +141,24 @@ and latest_ii.job_id = a.job_id and latest_ii.del_flag = '0' where a.del_flag='0' - and b.job_title like concat('%', cast(#{company.jobTitle, jdbcType=VARCHAR} as varchar), '%') - and b.education = #{company.education} - and b.experience = #{company.experience} - and b.company_name like concat('%', cast(#{company.companyName, jdbcType=VARCHAR} as varchar), '%') - and b.company_id = #{company.companyId} - and l.code =#{company.code} - and b.job_title like concat('%', cast(#{name, jdbcType=VARCHAR} as varchar), '%') + + and e.name like concat('%', cast(#{name, jdbcType=VARCHAR} as varchar), '%') + + and e.phone like concat('%', cast(#{phone, jdbcType=VARCHAR} as varchar), '%') + + and e.education = #{education} + + and e.sex = #{sex} + + and e.area = #{area} + + and e.political_affiliation = #{politicalAffiliation} + + and e.id_card like concat('%', cast(#{idCard, jdbcType=VARCHAR} as varchar), '%') + + and e.birth_date = #{birthDate} + + and b.job_title like concat('%', cast(#{jobName, jdbcType=VARCHAR} as varchar), '%')