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.
 
 
 

180 lines
7.3 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.CompanyManagedJobItem;
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
);
}
/** 当前企业自身岗位管理列表;身份和企业归属均由服务端解析。 */
public Page<CompanyManagedJobItem> getMyJobs(Long userId, String status,
String keyword, String city,
int page, int size) {
Company company = findCompanyByOwnerUserId(userId);
if (company == null) throw new BusinessException(ErrorCode.COMPANY_NOT_FOUND);
return jobService.listCompanyJobs(company.getId(), status, keyword, city, page, size);
}
}