This commit is contained in:
冯辉
2026-06-26 12:39:57 +08:00
31 changed files with 1660 additions and 4 deletions

View File

@@ -0,0 +1,17 @@
package com.ruoyi.cms.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.ruoyi.cms.domain.OutdoorFairAttendee;
import java.util.List;
/**
* 户外招聘会签到人员 Service。
*/
public interface IOutdoorFairAttendeeService extends IService<OutdoorFairAttendee>
{
/**
* 查询签到人员列表(支持按人员姓名、手机号模糊查询)。
*/
List<OutdoorFairAttendee> selectAttendeeList(OutdoorFairAttendee query);
}

View File

@@ -0,0 +1,31 @@
package com.ruoyi.cms.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.ruoyi.cms.domain.OutdoorFairDevice;
import java.util.List;
/**
* 户外招聘会设备码 Service。
*/
public interface IOutdoorFairDeviceService extends IService<OutdoorFairDevice>
{
/**
* 查询设备码列表(支持按设备码、企业名称模糊查询)。
*/
List<OutdoorFairDevice> selectDeviceList(OutdoorFairDevice query);
/**
* 批量生成设备码UUID
*
* @param fairId 招聘会ID
* @param quantity 生成数量
* @return 已生成的设备码列表
*/
List<OutdoorFairDevice> batchGenerate(Long fairId, Integer quantity);
/**
* 绑定/解绑参会企业companyId 为空表示解绑)。
*/
boolean bindCompany(Long id, Long companyId);
}

View File

@@ -806,6 +806,7 @@ public class ESJobSearchImpl implements IESJobSearchService
@Override
public void deleteJob(Long jobId) {
ensureJobDocumentIndexExists();
LambdaEsQueryWrapper<ESJobDocument> lambdaEsQueryWrapper = new LambdaEsQueryWrapper();
lambdaEsQueryWrapper.eq(ESJobDocument::getJobId,jobId);
esJobDocumentMapper.delete(lambdaEsQueryWrapper);
@@ -847,12 +848,31 @@ public class ESJobSearchImpl implements IESJobSearchService
if(StringUtil.isEmptyOrNull(job.getCompanyNature())){
esJobDocument.setCompanyNature("6");
}
ensureJobDocumentIndexExists();
LambdaEsQueryWrapper<ESJobDocument> lambdaEsQueryWrapper = new LambdaEsQueryWrapper();
lambdaEsQueryWrapper.eq(ESJobDocument::getJobId,job.getJobId());
esJobDocumentMapper.delete(lambdaEsQueryWrapper);
esJobDocumentMapper.insert(esJobDocument);
}
/**
* 确保job_document索引存在缺失时懒创建仅建空索引与映射不重建全量数据
* process-index-mode: manual 下easy-es不会自动建索引缺失时delete/update等写操作
* 会抛 index_not_found_exception 导致业务接口500并回滚事务故在写操作前调用以自愈。
*/
private void ensureJobDocumentIndexExists() {
try {
if (!esJobDocumentMapper.existsIndex("job_document")) {
esJobDocumentMapper.createIndex();
logger.info("job_document索引不存在已自动创建");
}
} catch (Exception e) {
// 并发场景下其他请求可能已创建索引,忽略“索引已存在”类异常
logger.warn("自动创建job_document索引异常可能已被其他请求创建忽略", e);
}
}
public List<ESJobDocument> selectByIds(Long[] jobIds) {
LambdaEsQueryWrapper<ESJobDocument> wrapper = new LambdaEsQueryWrapper<>();
wrapper.in(ESJobDocument::getJobId,jobIds);

View File

@@ -0,0 +1,32 @@
package com.ruoyi.cms.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.cms.domain.OutdoorFairAttendee;
import com.ruoyi.cms.mapper.OutdoorFairAttendeeMapper;
import com.ruoyi.cms.service.IOutdoorFairAttendeeService;
import com.ruoyi.common.utils.StringUtils;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* 户外招聘会签到人员 Service 实现。
*/
@Service
public class OutdoorFairAttendeeServiceImpl
extends ServiceImpl<OutdoorFairAttendeeMapper, OutdoorFairAttendee>
implements IOutdoorFairAttendeeService
{
@Override
public List<OutdoorFairAttendee> selectAttendeeList(OutdoorFairAttendee query)
{
LambdaQueryWrapper<OutdoorFairAttendee> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(query.getFairId() != null, OutdoorFairAttendee::getFairId, query.getFairId());
wrapper.like(StringUtils.isNotBlank(query.getName()), OutdoorFairAttendee::getName, query.getName());
wrapper.like(StringUtils.isNotBlank(query.getPhone()), OutdoorFairAttendee::getPhone, query.getPhone());
wrapper.orderByDesc(OutdoorFairAttendee::getCheckInTime);
wrapper.orderByDesc(OutdoorFairAttendee::getId);
return list(wrapper);
}
}

View File

@@ -0,0 +1,112 @@
package com.ruoyi.cms.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.cms.domain.FairCompany;
import com.ruoyi.cms.domain.OutdoorFairDevice;
import com.ruoyi.cms.mapper.CompanyMapper;
import com.ruoyi.cms.mapper.FairCompanyMapper;
import com.ruoyi.cms.mapper.OutdoorFairDeviceMapper;
import com.ruoyi.cms.service.IOutdoorFairDeviceService;
import com.ruoyi.common.core.domain.entity.Company;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;
/**
* 户外招聘会设备码 Service 实现。
*/
@Service
public class OutdoorFairDeviceServiceImpl
extends ServiceImpl<OutdoorFairDeviceMapper, OutdoorFairDevice>
implements IOutdoorFairDeviceService
{
@Autowired
private FairCompanyMapper fairCompanyMapper;
@Autowired
private CompanyMapper companyMapper;
@Override
public List<OutdoorFairDevice> selectDeviceList(OutdoorFairDevice query)
{
LambdaQueryWrapper<OutdoorFairDevice> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(query.getFairId() != null, OutdoorFairDevice::getFairId, query.getFairId());
wrapper.eq(query.getCompanyId() != null, OutdoorFairDevice::getCompanyId, query.getCompanyId());
wrapper.like(StringUtils.isNotBlank(query.getDeviceCode()), OutdoorFairDevice::getDeviceCode, query.getDeviceCode());
wrapper.like(StringUtils.isNotBlank(query.getCompanyName()), OutdoorFairDevice::getCompanyName, query.getCompanyName());
wrapper.orderByDesc(OutdoorFairDevice::getId);
return list(wrapper);
}
@Override
public List<OutdoorFairDevice> batchGenerate(Long fairId, Integer quantity)
{
if (fairId == null) {
throw new ServiceException("招聘会ID不能为空");
}
int count = quantity == null ? 0 : quantity;
if (count <= 0) {
throw new ServiceException("生成数量必须大于0");
}
if (count > 1000) {
throw new ServiceException("单次生成数量不能超过1000");
}
List<OutdoorFairDevice> devices = new ArrayList<>(count);
for (int i = 0; i < count; i++) {
OutdoorFairDevice device = new OutdoorFairDevice();
device.setFairId(fairId);
// 去掉中划线,得到 32 位十六进制设备码
device.setDeviceCode(UUID.randomUUID().toString().replace("-", ""));
devices.add(device);
}
saveBatch(devices);
return devices;
}
@Override
public boolean bindCompany(Long id, Long companyId)
{
OutdoorFairDevice device = getById(id);
if (device == null) {
throw new ServiceException("设备码不存在");
}
// 使用 UpdateWrapper 显式 set避免 updateById 默认跳过 null 字段导致解绑失效
UpdateWrapper<OutdoorFairDevice> wrapper = new UpdateWrapper<>();
wrapper.eq("id", id);
if (companyId != null) {
// 仅允许绑定已参加当前招聘会的企业
Long count = fairCompanyMapper.selectCount(new LambdaQueryWrapper<FairCompany>()
.eq(FairCompany::getJobFairId, device.getFairId())
.eq(FairCompany::getCompanyId, companyId));
if (count == null || count == 0) {
throw new ServiceException("该企业未参加当前招聘会");
}
// 同一招聘会下,一个企业只能绑定一个设备码
Long bound = baseMapper.selectCount(new LambdaQueryWrapper<OutdoorFairDevice>()
.eq(OutdoorFairDevice::getFairId, device.getFairId())
.eq(OutdoorFairDevice::getCompanyId, companyId));
if (bound != null && bound > 0) {
throw new ServiceException("该企业已绑定其他设备码");
}
Company company = companyMapper.selectById(companyId);
wrapper.set("company_id", companyId)
.set("company_name", company == null ? null : company.getName())
.set("bind_time", new Date());
}
else {
// 解绑:显式置空
wrapper.set("company_id", null)
.set("company_name", null)
.set("bind_time", null);
}
return baseMapper.update(null, wrapper) > 0;
}
}

View File

@@ -40,6 +40,7 @@ public class OutdoorFairServiceImpl extends ServiceImpl<OutdoorFairMapper, Outdo
queryWrapper.eq(StringUtils.isNotBlank(outdoorFair.getFairType()), OutdoorFair::getFairType, outdoorFair.getFairType());
queryWrapper.eq(StringUtils.isNotBlank(outdoorFair.getRegion()), OutdoorFair::getRegion, outdoorFair.getRegion());
queryWrapper.eq(outdoorFair.getVenueId() != null, OutdoorFair::getVenueId, outdoorFair.getVenueId());
queryWrapper.eq(outdoorFair.getOnlineApply() != null, OutdoorFair::getOnlineApply, outdoorFair.getOnlineApply());
queryWrapper.orderByDesc(OutdoorFair::getHoldTime);
queryWrapper.orderByDesc(OutdoorFair::getCreateTime);
return list(queryWrapper);