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); } var industry = com.mydreamjob.industry.IndustryCatalog.selection(req.getIndustryCode(), req.getIndustry()); Company company = Company.builder() .ownerUserId(userId) .name(req.getName()) .logoUrl(req.getLogoUrl()) .description(req.getDescription()) .industry(industry.name()).industryCode(industry.code()) .companySize(normalizeCompanySize(req.getCompanySize())) .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.findByOwnerUserIdForUpdate(userId) .orElseThrow(() -> new BusinessException(ErrorCode.COMPANY_NOT_FOUND)); var industry = com.mydreamjob.industry.IndustryCatalog.selection(req.getIndustryCode(), req.getIndustry()); 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 || req.getIndustryCode() != null) { company.setIndustry(industry.name()); company.setIndustryCode(industry.code()); } // companySize:null/缺省保持原值;其余交给与创建共用的同一套归一化规则。 if (req.getCompanySize() != null) { company.setCompanySize(normalizeCompanySize(req.getCompanySize())); } if (req.getWebsite() != null) company.setWebsite(req.getWebsite()); if (req.getAddress() != null) company.setAddress(req.getAddress()); return companyRepository.save(company); } /** 企业规模长度上限,与请求 DTO 的 @Size(max = 40) 保持一致。 */ private static final int MAX_COMPANY_SIZE_LENGTH = 40; /** * companySize 统一归一化——创建与更新**共用同一套规则**,避免两套逻辑漂移。 * *