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 toView(Company company) { if (company == null) return null; Map 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 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 ); } }