refactor(service): 修改IEntityService泛型为VO类型并优化缓存策略

重构所有注解@CacheConfig的Service类,将IEntityService泛型从实体类改为VO类
实现实体与VO之间的转换逻辑,使用VO替代实体进行缓存以避免序列化问题
更新相关依赖组件和测试用例,确保功能完整性和系统兼容性
优化Redis缓存配置,清理旧缓存数据并验证新缓存策略有效性
This commit is contained in:
2025-09-28 18:19:00 +08:00
parent df6188db40
commit b03b5385a5
75 changed files with 3144 additions and 1377 deletions

View File

@@ -1,4 +1,37 @@
package com.ecep.contract.ds.company;
import com.ecep.contract.ds.company.service.*;
import org.springframework.beans.BeansException;
public interface CompanyContext {
<T> T getBean(Class<T> requiredType) throws BeansException;
default CompanyService getCompanyService() {
return getBean(CompanyService.class);
}
default CompanyOldNameService getCompanyOldNameService() {
return getBean(CompanyOldNameService.class);
}
default CompanyFileTypeService getCompanyFileTypeService() {
return getBean(CompanyFileTypeService.class);
}
default CompanyFileService getCompanyFileService() {
return getBean(CompanyFileService.class);
}
default CompanyBankAccountService getCompanyBankAccountService() {
return getBean(CompanyBankAccountService.class);
}
default CompanyBlackReasonService getCompanyBlackReasonService() {
return getBean(CompanyBlackReasonService.class);
}
default CompanyInvoiceInfoService getCompanyInvoiceInfoService() {
return getBean(CompanyInvoiceInfoService.class);
}
}

View File

@@ -83,7 +83,7 @@ public class ContractFileTypeService
}
@Caching(evict = {
@CacheEvict(key = "#p0.id"),
@CacheEvict(key = "#p0.id"), @CacheEvict(key = "'by-type-'+#p0.type.name()+'-'+#p0.lang"),
@CacheEvict(key = "'all-'+#p0.getLang()")
})
@Override
@@ -93,6 +93,7 @@ public class ContractFileTypeService
@Caching(evict = {
@CacheEvict(key = "#p0.id"),
@CacheEvict(key = "'by-type-'+#p0.type.name()+'-'+#p0.lang"),
@CacheEvict(key = "'all-'+#p0.getLang()")
})
@Override
@@ -117,4 +118,8 @@ public class ContractFileTypeService
model.setSuggestFileName(vo.getSuggestFileName());
}
@Cacheable(key = "'by-type-'+#p0.name()+'-'+#p1.toLanguageTag()")
public ContractFileTypeLocal findByTypeAndLang(ContractFileType type, Locale locale) {
return repository.findByTypeAndLang(type, locale.toLanguageTag());
}
}

View File

@@ -9,7 +9,6 @@ import java.util.ArrayList;
import java.util.Comparator;
import java.util.DoubleSummaryStatistics;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;
@@ -29,7 +28,7 @@ import com.ecep.contract.ds.company.service.CompanyExtendInfoService;
import com.ecep.contract.ds.contract.service.ExtendVendorInfoService;
import com.ecep.contract.ds.converter.NumberStringConverter;
import com.ecep.contract.ds.other.service.EmployeeService;
import com.ecep.contract.ds.project.ProjectCostImportItemsFromContractsTasker;
import com.ecep.contract.service.tasker.ProjectCostImportItemsFromContractsTasker;
import com.ecep.contract.ds.project.service.ProjectBidService;
import com.ecep.contract.ds.project.service.ProjectCostService;
import com.ecep.contract.ds.project.service.ProjectQuotationService;
@@ -197,7 +196,7 @@ public class ContractVerifyComm extends VerifyContext {
/**
* 验证合同是否合规
*
*
* @param company
* @param contract
* @param holder
@@ -227,7 +226,9 @@ public class ContractVerifyComm extends VerifyContext {
case RECEIVE -> {
// 销售合同
CompanyExtendInfo companyExtendInfo = getCompanyExtendInfoService().findByCompany(company);
verifyAsCustomer(company, companyExtendInfo, contract, holder);
if (!verifyAsCustomer(company, companyExtendInfo, contract, holder)) {
passed = false;
}
// 销售合同下的采购合同
List<Contract> list = getContractService().findAllByParent(contract);
@@ -325,7 +326,7 @@ public class ContractVerifyComm extends VerifyContext {
}
private void verifyVendorFile(VendorGroup group, boolean assignedProvider, Contract contract,
MessageHolder holder) {
MessageHolder holder) {
if (group == null) {
return;
}
@@ -400,7 +401,7 @@ public class ContractVerifyComm extends VerifyContext {
}
String getFileTypeLocalValue(ContractFileType type) {
ContractFileTypeLocal fileTypeLocal = getFileTypeLocal(type);
ContractFileTypeLocal fileTypeLocal = getContractFileTypeService().findByTypeAndLang(type, getLocale());
if (fileTypeLocal == null) {
return type.name();
}
@@ -420,18 +421,20 @@ public class ContractVerifyComm extends VerifyContext {
}
private boolean verifyAsCustomer(Company company, CompanyExtendInfo companyExtendInfo, Contract contract,
MessageHolder holder) {
MessageHolder holder) {
boolean passed = true;
Project project = contract.getProject();
if (project == null) {
// 收款的合同时,检查是否关联了项目,如果没有则创建
if (contract.getPayWay() == ContractPayWay.RECEIVE) {
holder.debug("未关联项目,测试关联/创建项目...");
project = getProjectService().findByCode(contract.getCode());
if (project == null) {
holder.info("创建关联项目");
holder.info("根据合同号 " + contract.getCode() + ", 未找到相关项目, 创建相关项目");
try {
project = getProjectService().newInstanceByContract(contract);
project = getProjectService().save(project);
holder.info("创建关联项目成功:" + project.getCode() + " " + project.getName());
} catch (Exception e) {
holder.error("创建关联项目失败: " + e.getMessage());
throw new RuntimeException("code=" + contract.getCode(), e);
@@ -439,20 +442,26 @@ public class ContractVerifyComm extends VerifyContext {
}
contract.setProject(project);
contract = getContractService().save(contract);
holder.info("关联项目:" + project.getCode() + " " + project.getName());
} else {
holder.warn("未关联项目");
}
}
// fixed no hibernate session
if (project != null) {
if (!Hibernate.isInitialized(project)) {
project = getProjectService().findById(project.getId());
// fixed
contract.setProject(project);
}
}
if (project != null) {
holder.info("验证项目信息:" + project.getCode() + " " + project.getName());
verifyProject(contract, project, holder.sub("项目"));
holder.info("验证项目:" + project.getCode() + " " + project.getName());
if (!verifyProject(contract, project, holder.sub("项目"))) {
passed = false;
}
ProjectSaleType saleType = project.getSaleType();
if (saleType != null) {
@@ -463,6 +472,7 @@ public class ContractVerifyComm extends VerifyContext {
}
if (!contract.getPath().startsWith(saleType.getPath())) {
holder.error("合同目录未在销售类型目录下");
passed = false;
}
}
}
@@ -474,7 +484,7 @@ public class ContractVerifyComm extends VerifyContext {
}
if (verifyCustomerFiles) {
holder.debug("核验文件...");
holder.info("核验客户文件...");
if (!verifyContractFileAsCustomer(project, contract, holder)) {
passed = false;
}
@@ -519,7 +529,7 @@ public class ContractVerifyComm extends VerifyContext {
}
private boolean verifyCustomerFileByContract(CompanyCustomer companyCustomer, Contract contract,
MessageHolder holder) {
MessageHolder holder) {
List<LocalDate> verifyDates = new ArrayList<>();
LocalDate minDate = LocalDate.of(2022, 1, 1);
LocalDate developDate = companyCustomer.getDevelopDate();
@@ -605,7 +615,11 @@ public class ContractVerifyComm extends VerifyContext {
return false;
}
private void verifyProject(Contract contract, Project project, MessageHolder holder) {
/**
* 核查合同对应的项目是否合规
*/
private boolean verifyProject(Contract contract, Project project, MessageHolder holder) {
boolean passed = true;
ProjectSaleType saleType = project.getSaleType();
if (saleType == null) {
String code = contract.getCode();
@@ -619,6 +633,7 @@ public class ContractVerifyComm extends VerifyContext {
}
if (project.getAmount() == null || project.getAmount() <= 0) {
holder.error("金额小于等于0");
passed = false;
}
//
@@ -709,6 +724,7 @@ public class ContractVerifyComm extends VerifyContext {
holder.warn("报价未创建");
}
}
return passed;
}
private boolean verifyContractFileAsCustomer(Project project, Contract contract, MessageHolder holder) {

View File

@@ -188,7 +188,7 @@ public class CompanyCustomerService extends CompanyBasicService
@SuppressWarnings("unchecked")
@Override
protected <T, F extends CompanyBasicFile<T>> boolean fillFileAsDefaultType(F dbFile, File file,
Consumer<String> status) {
Consumer<String> status) {
dbFile.setType((T) CustomerFileType.General);
fillFile(dbFile, file, null, status);
companyCustomerFileService.save((CompanyCustomerFile) dbFile);
@@ -197,7 +197,7 @@ public class CompanyCustomerService extends CompanyBasicService
@Override
protected <T, F extends CompanyBasicFile<T>> boolean fillFileAsEvaluationFile(F customerFile, File file,
List<File> fileList, Consumer<String> status) {
List<File> fileList, Consumer<String> status) {
boolean modified = super.fillFileAsEvaluationFile(customerFile, file, fileList, status);
if (fileList != null) {
@@ -231,7 +231,7 @@ public class CompanyCustomerService extends CompanyBasicService
}
private <T, F extends CompanyBasicFile<T>> void updateEvaluationFileByJsonFile(F customerFile, File jsonFile,
Consumer<String> status) throws IOException {
Consumer<String> status) throws IOException {
ObjectMapper objectMapper = new ObjectMapper();
JsonNode root = objectMapper.readTree(jsonFile);
if (!root.isObject()) {
@@ -257,7 +257,7 @@ public class CompanyCustomerService extends CompanyBasicService
@SuppressWarnings("unchecked")
@Override
protected <T, F extends CompanyBasicFile<T>> F fillFileType(File file, List<File> fileList,
Consumer<String> status) {
Consumer<String> status) {
CompanyCustomerFile customerFile = new CompanyCustomerFile();
customerFile.setType(CustomerFileType.General);
if (fillFile(customerFile, file, fileList, status)) {
@@ -281,7 +281,7 @@ public class CompanyCustomerService extends CompanyBasicService
return (fileName.contains(CompanyCustomerConstant.EVALUATION_FORM_NAME1)
|| fileName.contains(CompanyCustomerConstant.EVALUATION_FORM_NAME2))
&& (FileUtils.withExtensions(fileName, FileUtils.JPG, FileUtils.JPEG,
FileUtils.PDF));
FileUtils.PDF));
}
public boolean makePathAbsent(CompanyCustomer companyCustomer) {
@@ -395,11 +395,28 @@ public class CompanyCustomerService extends CompanyBasicService
@Override
public void updateByVo(CompanyCustomer customer, CompanyCustomerVo vo) {
customer.setCompany(SpringApp.getBean(CompanyService.class).findById(vo.getCompanyId()));
customer.setCatalog(SpringApp.getBean(CustomerCatalogService.class).findById(vo.getCatalogId()));
if (vo.getCompanyId() == null) {
customer.setCompany(null);
} else {
CompanyService service = SpringApp.getBean(CompanyService.class);
customer.setCompany(service.findById(vo.getCompanyId()));
}
if (vo.getCatalogId() == null) {
customer.setCatalog(null);
} else {
CustomerCatalogService service = SpringApp.getBean(CustomerCatalogService.class);
customer.setCatalog(service.findById(vo.getCatalogId()));
}
customer.setDevelopDate(vo.getDevelopDate());
customer.setPath(vo.getPath());
customer.setContact(SpringApp.getBean(CompanyContactService.class).findById(vo.getContactId()));
if (vo.getContactId() == null) {
customer.setContact(null);
} else {
CompanyContactService service = SpringApp.getBean(CompanyContactService.class);
customer.setContact(service.findById(vo.getContactId()));
}
customer.setDescription(vo.getDescription());
customer.setCreated(vo.getCreated());

View File

@@ -16,7 +16,7 @@ public interface BaseEnumEntityRepository<N extends Enum<?>, T extends BaseEnumE
List<T> findAllByLang(String lang);
default Map<N, T> getCompleteMapByLocal(String lang) {
HashMap<N, T> map = new HashMap<>();
Map<N, T> map = new HashMap<>();
for (T t : findAllByLang(lang)) {
map.put(t.getType(), t);
}

View File

@@ -18,7 +18,6 @@ import com.ecep.contract.IEntityService;
import com.ecep.contract.QueryService;
import com.ecep.contract.ds.other.repository.DepartmentRepository;
import com.ecep.contract.model.Department;
import com.ecep.contract.model.Employee;
import com.ecep.contract.service.VoableService;
import com.ecep.contract.vo.DepartmentVo;
import com.fasterxml.jackson.databind.JsonNode;