You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
170 lines
6.7 KiB
170 lines
6.7 KiB
package com.mydreamjob.company;
|
|
|
|
import com.mydreamjob.auth.User;
|
|
import com.mydreamjob.auth.UserRepository;
|
|
import com.mydreamjob.common.exception.BusinessException;
|
|
import com.mydreamjob.common.exception.ErrorCode;
|
|
import com.mydreamjob.company.dto.CompanyCreateRequest;
|
|
import com.mydreamjob.company.dto.CompanyPublicView;
|
|
import com.mydreamjob.company.dto.CompanyUpdateRequest;
|
|
import com.mydreamjob.job.JobService;
|
|
import com.mydreamjob.job.dto.JobSearchItem;
|
|
import lombok.extern.slf4j.Slf4j;
|
|
import org.springframework.data.domain.Page;
|
|
import org.springframework.stereotype.Service;
|
|
import org.springframework.transaction.annotation.Transactional;
|
|
|
|
import java.util.HashMap;
|
|
import java.util.Map;
|
|
|
|
/**
|
|
* 企业管理 Service
|
|
* 角色校验优先——所有写操作在业务逻辑前先校验角色。
|
|
*/
|
|
@Slf4j
|
|
@Service
|
|
public class CompanyService {
|
|
|
|
private final com.mydreamjob.security.UserRoleGuard userRoleGuard;
|
|
private final CompanyRepository companyRepository;
|
|
private final UserRepository userRepository;
|
|
private final JobService jobService;
|
|
|
|
public CompanyService(CompanyRepository companyRepository, UserRepository userRepository,
|
|
JobService jobService,
|
|
com.mydreamjob.security.UserRoleGuard userRoleGuard) {
|
|
this.companyRepository = companyRepository;
|
|
this.userRepository = userRepository;
|
|
this.jobService = jobService;
|
|
this.userRoleGuard = userRoleGuard;
|
|
}
|
|
|
|
// ── 角色校验(最先执行)───────────────────────────────────
|
|
|
|
public void assertCompanyRole(Long userId) {
|
|
userRoleGuard.requireCompany(userId);
|
|
}
|
|
|
|
public void assertStudentRole(Long userId) {
|
|
userRoleGuard.requireStudent(userId);
|
|
}
|
|
|
|
// ── 业务方法 ──────────────────────────────────────────────
|
|
|
|
/**
|
|
* 查询当前用户绑定的企业资料(含角色校验:非 COMPANY 返回 403)
|
|
*/
|
|
public Company findCompanyByOwnerUserId(Long userId) {
|
|
assertCompanyRole(userId);
|
|
return companyRepository.findByOwnerUserId(userId).orElse(null);
|
|
}
|
|
|
|
/**
|
|
* 创建企业资料(仅 COMPANY 角色,已存在时 409)
|
|
*/
|
|
@Transactional
|
|
public Company createCompany(Long userId, CompanyCreateRequest req) {
|
|
assertCompanyRole(userId);
|
|
if (companyRepository.findByOwnerUserId(userId).isPresent()) {
|
|
throw new BusinessException(ErrorCode.COMPANY_ALREADY_EXISTS);
|
|
}
|
|
Company company = Company.builder()
|
|
.ownerUserId(userId)
|
|
.name(req.getName())
|
|
.logoUrl(req.getLogoUrl())
|
|
.description(req.getDescription())
|
|
.industry(req.getIndustry())
|
|
.website(req.getWebsite())
|
|
.address(req.getAddress())
|
|
.verified(false)
|
|
.build();
|
|
return companyRepository.save(company);
|
|
}
|
|
|
|
/**
|
|
* 更新企业资料(幂等:不传字段则保留原值)
|
|
*/
|
|
@Transactional
|
|
public Company updateCompany(Long userId, CompanyUpdateRequest req) {
|
|
assertCompanyRole(userId);
|
|
Company company = companyRepository.findByOwnerUserId(userId)
|
|
.orElseThrow(() -> new BusinessException(ErrorCode.COMPANY_NOT_FOUND));
|
|
|
|
if (req.getName() != null) company.setName(req.getName());
|
|
if (req.getLogoUrl() != null) company.setLogoUrl(req.getLogoUrl());
|
|
if (req.getDescription() != null) company.setDescription(req.getDescription());
|
|
if (req.getIndustry() != null) company.setIndustry(req.getIndustry());
|
|
if (req.getWebsite() != null) company.setWebsite(req.getWebsite());
|
|
if (req.getAddress() != null) company.setAddress(req.getAddress());
|
|
|
|
return companyRepository.save(company);
|
|
}
|
|
|
|
/**
|
|
* 将企业 Entity 转为 API 视图(排除敏感字段)
|
|
*/
|
|
public Map<String, Object> toView(Company company) {
|
|
if (company == null) return null;
|
|
Map<String, Object> view = new HashMap<>();
|
|
view.put("id", company.getId());
|
|
view.put("ownerUserId", company.getOwnerUserId());
|
|
view.put("name", company.getName());
|
|
view.put("logoUrl", company.getLogoUrl());
|
|
view.put("description", company.getDescription());
|
|
view.put("industry", company.getIndustry());
|
|
view.put("website", company.getWebsite());
|
|
view.put("address", company.getAddress());
|
|
view.put("verified", company.getVerified());
|
|
view.put("createdAt", company.getCreatedAt());
|
|
return view;
|
|
}
|
|
|
|
// ── 公开端:企业详情 ────────────────────────────────────────
|
|
|
|
/**
|
|
* 查询企业公开信息(匿名可访问)。
|
|
* 仅返回 6 个公开字段,不泄露 ownerUserId、联系方式、审核信息等。
|
|
*/
|
|
public CompanyPublicView getPublicCompany(Long companyId) {
|
|
Company company = companyRepository.findById(companyId)
|
|
.orElseThrow(() -> new BusinessException(ErrorCode.COMPANY_NOT_FOUND));
|
|
return toPublicView(company);
|
|
}
|
|
|
|
/**
|
|
* 将企业 Entity 转为公开视图(仅 6 个字段)。
|
|
* 不修改现有 toView() 方法。
|
|
*/
|
|
public CompanyPublicView toPublicView(Company company) {
|
|
return CompanyPublicView.builder()
|
|
.id(company.getId())
|
|
.name(company.getName())
|
|
.logoUrl(company.getLogoUrl())
|
|
.description(company.getDescription())
|
|
.industry(company.getIndustry())
|
|
.verified(company.getVerified())
|
|
.build();
|
|
}
|
|
|
|
// ── 公开端:企业岗位列表 ────────────────────────────────────
|
|
|
|
/**
|
|
* 查询企业公开岗位列表(匿名可访问)。
|
|
* 先确认企业存在,再复用已验收的 JobService.searchJobs。
|
|
*/
|
|
public Page<JobSearchItem> getCompanyJobs(Long companyId, String sort, int page, int size) {
|
|
companyRepository.findById(companyId)
|
|
.orElseThrow(() -> new BusinessException(ErrorCode.COMPANY_NOT_FOUND));
|
|
return jobService.searchJobs(
|
|
null, // keyword
|
|
null, // city
|
|
null, // employmentType
|
|
null, // salaryMin
|
|
null, // salaryMax
|
|
companyId, // companyId
|
|
sort, // sort
|
|
page, // page
|
|
size // size
|
|
);
|
|
}
|
|
}
|
|
|