feat: 新增户外招聘会企业退订接口

This commit is contained in:
2026-07-24 11:52:34 +08:00
parent d139e400b1
commit 22ad1aff40
5 changed files with 246 additions and 0 deletions

View File

@@ -18,11 +18,13 @@ import java.time.temporal.ChronoUnit;
import java.time.temporal.TemporalAdjusters;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.ruoyi.cms.domain.FairCompany;
import com.ruoyi.cms.domain.Job;
import com.ruoyi.cms.domain.OutdoorFair;
import com.ruoyi.cms.domain.OutdoorFairBooth;
import com.ruoyi.cms.domain.OutdoorFairBoothBooking;
import com.ruoyi.cms.domain.OutdoorFairCompanyUnsubscribe;
import com.ruoyi.cms.domain.OutdoorFairDevice;
import com.ruoyi.cms.domain.OutdoorFairDictDataRequest;
import com.ruoyi.cms.domain.OutdoorFairJob;
@@ -32,6 +34,7 @@ import com.ruoyi.cms.mapper.FairCompanyMapper;
import com.ruoyi.cms.mapper.OutdoorFairBoothMapper;
import com.ruoyi.cms.mapper.OutdoorFairBoothBookingMapper;
import com.ruoyi.cms.mapper.OutdoorFairDeviceMapper;
import com.ruoyi.cms.mapper.OutdoorFairCompanyUnsubscribeMapper;
import com.ruoyi.cms.mapper.OutdoorFairJobMapper;
import com.ruoyi.cms.mapper.VenueBoothMapper;
import com.ruoyi.cms.mapper.CompanyMapper;
@@ -91,6 +94,9 @@ public class OutdoorFairController extends BaseController
@Autowired
private FairCompanyMapper fairCompanyMapper;
@Autowired
private OutdoorFairCompanyUnsubscribeMapper outdoorFairCompanyUnsubscribeMapper;
@Autowired
private CompanyMapper companyMapper;
@@ -543,6 +549,64 @@ public class OutdoorFairController extends BaseController
return success(data);
}
@ApiOperation("企业退订户外招聘会")
@PreAuthorize("@ss.hasPermi('cms:outdoorFair:unsubscribe')")
@Log(title = "户外招聘会企业退订", businessType = BusinessType.UPDATE)
@PostMapping("/{fairId}/company/unsubscribe")
@Transactional(rollbackFor = Exception.class)
public AjaxResult unsubscribeCompany(@PathVariable Long fairId, @RequestBody Map<String, Object> request)
{
String reason = request == null || request.get("reason") == null
? "" : String.valueOf(request.get("reason")).trim();
if (StringUtils.isBlank(reason)) {
return AjaxResult.error("请填写退订原因");
}
if (reason.length() > 500) {
return AjaxResult.error("退订原因不能超过500个字");
}
Company company = getCurrentCompanyOrThrow();
ensureFairExists(fairId);
FairCompany relation = fairCompanyMapper.selectOne(new LambdaQueryWrapper<FairCompany>()
.eq(FairCompany::getJobFairId, fairId)
.eq(FairCompany::getCompanyId, company.getCompanyId())
.last("LIMIT 1"));
if (relation == null) {
return AjaxResult.error("该企业未报名当前招聘会");
}
if (!"1".equals(relation.getReviewStatus())) {
return AjaxResult.error("仅审核通过的报名可以退订");
}
OutdoorFairCompanyUnsubscribe record = new OutdoorFairCompanyUnsubscribe();
record.setFairId(fairId);
record.setCompanyId(company.getCompanyId());
record.setCompanyName(company.getName());
record.setContactPerson(company.getContactPerson());
record.setContactPhone(company.getContactPersonPhone());
record.setReason(reason);
record.setUnsubscribeTime(new Date());
record.setCreateBy(getUsername());
outdoorFairCompanyUnsubscribeMapper.insert(record);
// 退订无审核流程:保留退订快照后,移除当前招聘会的报名关联及其岗位。
outdoorFairJobMapper.delete(new LambdaQueryWrapper<OutdoorFairJob>()
.eq(OutdoorFairJob::getFairId, fairId)
.eq(OutdoorFairJob::getCompanyId, company.getCompanyId()));
outdoorFairBoothBookingMapper.delete(new LambdaQueryWrapper<OutdoorFairBoothBooking>()
.eq(OutdoorFairBoothBooking::getFairId, fairId)
.eq(OutdoorFairBoothBooking::getCompanyId, company.getCompanyId())
.eq(OutdoorFairBoothBooking::getStatus, "reserved"));
outdoorFairDeviceMapper.update(null, new UpdateWrapper<OutdoorFairDevice>()
.eq("fair_id", fairId)
.eq("company_id", company.getCompanyId())
.set("company_id", null)
.set("company_name", null)
.set("bind_time", null));
fairCompanyMapper.deleteById(relation.getId());
return success();
}
@ApiOperation("获取当前企业户外招聘会二维码内容")
@PreAuthorize("@ss.hasPermi('cms:outdoorFair:list')")
@GetMapping("/{fairId}/company/qrcode")
@@ -649,6 +713,32 @@ public class OutdoorFairController extends BaseController
return result;
}
@ApiOperation("查询户外招聘会企业退订记录")
@PreAuthorize("@ss.hasPermi('cms:outdoorFair:query')")
@GetMapping("/{fairId}/company-unsubscribes")
public AjaxResult listCompanyUnsubscribes(@PathVariable Long fairId, String companyName,
Integer current, Integer pageSize)
{
ensureFairExists(fairId);
LambdaQueryWrapper<OutdoorFairCompanyUnsubscribe> wrapper =
new LambdaQueryWrapper<OutdoorFairCompanyUnsubscribe>()
.eq(OutdoorFairCompanyUnsubscribe::getFairId, fairId)
.like(StringUtils.isNotBlank(companyName),
OutdoorFairCompanyUnsubscribe::getCompanyName, companyName)
.orderByDesc(OutdoorFairCompanyUnsubscribe::getUnsubscribeTime)
.orderByDesc(OutdoorFairCompanyUnsubscribe::getId);
List<OutdoorFairCompanyUnsubscribe> rows = outdoorFairCompanyUnsubscribeMapper.selectList(wrapper);
int total = rows.size();
int page = current == null || current < 1 ? 1 : current;
int size = pageSize == null || pageSize < 1 ? 10 : Math.min(pageSize, 100);
int fromIndex = Math.min((page - 1) * size, total);
int toIndex = Math.min(fromIndex + size, total);
AjaxResult result = AjaxResult.success();
result.put("rows", rows.subList(fromIndex, toIndex));
result.put("total", total);
return result;
}
@ApiOperation("获取户外招聘会参会企业二维码内容")
@PreAuthorize("@ss.hasPermi('cms:outdoorFair:query')")
@GetMapping("/{fairId}/companies/{companyId}/qrcode")

View File

@@ -0,0 +1,50 @@
package com.ruoyi.cms.domain;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.ruoyi.common.core.domain.BaseEntity;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.Date;
/**
* 户外招聘会企业退订记录。
*
* <p>退订后报名关联会被移除,本表保留企业提交的退订快照,便于管理端查询和审计。</p>
*/
@Data
@ApiModel("户外招聘会企业退订记录")
@TableName("cms_outdoor_fair_company_unsubscribe")
public class OutdoorFairCompanyUnsubscribe extends BaseEntity
{
private static final long serialVersionUID = 1L;
@TableId(value = "id", type = IdType.AUTO)
private Long id;
@ApiModelProperty("招聘会ID")
private Long fairId;
@ApiModelProperty("企业ID")
private Long companyId;
@ApiModelProperty("企业名称快照")
private String companyName;
@ApiModelProperty("联系人快照")
private String contactPerson;
@ApiModelProperty("联系电话快照")
private String contactPhone;
@ApiModelProperty("退订原因")
private String reason;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@ApiModelProperty("退订时间")
private Date unsubscribeTime;
}

View File

@@ -0,0 +1,11 @@
package com.ruoyi.cms.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.ruoyi.cms.domain.OutdoorFairCompanyUnsubscribe;
/**
* 户外招聘会企业退订记录 Mapper。
*/
public interface OutdoorFairCompanyUnsubscribeMapper extends BaseMapper<OutdoorFairCompanyUnsubscribe>
{
}

View File

@@ -24,6 +24,18 @@ class OutdoorFairControllerTest
assertEquals("@ss.hasPermi('cms:outdoorFair:qrcode')", annotation.value());
}
@Test
void companyUnsubscribeEndpointRequiresDedicatedPermission() throws Exception
{
Method method = OutdoorFairController.class.getDeclaredMethod(
"unsubscribeCompany", Long.class, java.util.Map.class);
org.springframework.security.access.prepost.PreAuthorize annotation =
method.getAnnotation(org.springframework.security.access.prepost.PreAuthorize.class);
assertNotNull(annotation);
assertEquals("@ss.hasPermi('cms:outdoorFair:unsubscribe')", annotation.value());
}
@Test
void companyQrCodeUrlUsesPublicForwardedHost() throws Exception
{