feat: 添加合约文件类型服务及错误处理改进

refactor: 重构合约文件类型相关代码,优化错误处理逻辑

fix: 修复WebSocket会话未绑定用户时的错误处理

style: 调整代码格式,提高可读性

docs: 更新部分代码注释

test: 添加合约文件类型服务的测试用例

chore: 移除无用代码,清理项目结构
This commit is contained in:
2025-09-12 00:12:51 +08:00
parent a1b87de7c0
commit fc263288e4
16 changed files with 357 additions and 124 deletions

View File

@@ -1,7 +1,6 @@
package com.ecep.contract.ds.contract.service;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;
import org.slf4j.Logger;
@@ -23,10 +22,8 @@ import com.ecep.contract.ContractFileType;
import com.ecep.contract.IEntityService;
import com.ecep.contract.QueryService;
import com.ecep.contract.ds.contract.repository.ContractFileRepository;
import com.ecep.contract.ds.contract.repository.ContractFileTypeLocalRepository;
import com.ecep.contract.model.Contract;
import com.ecep.contract.model.ContractFile;
import com.ecep.contract.model.ContractFileTypeLocal;
import com.ecep.contract.util.SpecificationUtils;
import com.fasterxml.jackson.databind.JsonNode;
@@ -38,9 +35,6 @@ public class ContractFileService implements IEntityService<ContractFile>, QueryS
@Lazy
@Autowired
private ContractFileRepository contractFileRepository;
@Lazy
@Autowired
private ContractFileTypeLocalRepository contractFileTypeLocalRepository;
@Override
@Cacheable(key = "#p0")
@@ -172,33 +166,4 @@ public class ContractFileService implements IEntityService<ContractFile>, QueryS
};
return contractFileRepository.findAll(spec);
}
// @Cacheable(key = "'type-locals-'+#p0")
// public List<ContractFileTypeLocal> findAllFileTypes(String lang) {
// Map<ContractFileType, ContractFileTypeLocal> map =
// contractFileTypeLocalRepository.getCompleteMapByLocal(lang);
// List<ContractFileTypeLocal> list = new ArrayList<>(map.values());
// list.sort((o1, o2) -> Objects.compare(o1.getValue(), o2.getValue(),
// String::compareTo));
// return list;
// }
@Cacheable(key = "'type-locals-'+#p0")
public Map<ContractFileType, ContractFileTypeLocal> findAllFileTypes(String lang) {
return contractFileTypeLocalRepository.getCompleteMapByLocal(lang);
}
@Caching(evict = {
@CacheEvict(key = "'type-locals-'+#p0.lang"),
@CacheEvict(key = "'type-'+#p0.type+'-local-'+#p0.lang"),
})
public ContractFileTypeLocal save(ContractFileTypeLocal type) {
return contractFileTypeLocalRepository.save(type);
}
@Cacheable(key = "'type-'+#p0+'-local-'+#p1")
public ContractFileTypeLocal findFileTypeLocalByTypeAndLang(ContractFileType type, String lang) {
return contractFileTypeLocalRepository.getCompleteByTypeAndLang(type, lang);
}
}

View File

@@ -0,0 +1,93 @@
package com.ecep.contract.ds.contract.service;
import java.util.Locale;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.Caching;
import org.springframework.context.annotation.Lazy;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import com.ecep.contract.ContractFileType;
import com.ecep.contract.IEntityService;
import com.ecep.contract.QueryService;
import com.ecep.contract.ds.contract.repository.ContractFileTypeLocalRepository;
import com.ecep.contract.model.ContractFileTypeLocal;
import com.ecep.contract.util.SpecificationUtils;
import com.fasterxml.jackson.databind.JsonNode;
@Lazy
@Service
@CacheConfig(cacheNames = "contract-file-type")
public class ContractFileTypeService
implements IEntityService<ContractFileTypeLocal>, QueryService<ContractFileTypeLocal> {
@Lazy
@Autowired
private ContractFileTypeLocalRepository repository;
@Override
public Page<ContractFileTypeLocal> findAll(JsonNode paramsNode, Pageable pageable) {
Specification<ContractFileTypeLocal> spec = null;
if (paramsNode.has("searchText")) {
spec = getSpecification(paramsNode.get("searchText").asText());
}
// field
spec = SpecificationUtils.andFieldEqualParam(spec, paramsNode, "lang", "value", "suggestFileName");
return findAll(spec, pageable);
}
@Cacheable(key = "'all-'+#p0.getLanguage()")
public Map<ContractFileType, ContractFileTypeLocal> findAll(Locale locale) {
return repository.getCompleteMapByLocal(locale.getLanguage());
}
@Cacheable(key = "#p0")
@Override
public ContractFileTypeLocal findById(Integer id) {
return repository.findById(id).orElse(null);
}
@Override
public Page<ContractFileTypeLocal> findAll(Specification<ContractFileTypeLocal> spec, Pageable pageable) {
return repository.findAll(spec, pageable);
}
@Override
public Specification<ContractFileTypeLocal> getSpecification(String searchText) {
if (!StringUtils.hasText(searchText)) {
return null;
}
return (root, query, builder) -> {
return builder.or(
builder.like(root.get("type"), "%" + searchText + "%"),
builder.like(root.get("suggestFileName"), "%" + searchText + "%"));
};
}
@Caching(evict = {
@CacheEvict(key = "#p0.id"),
@CacheEvict(key = "'all-'+#p0.getLang()")
})
@Override
public void delete(ContractFileTypeLocal entity) {
repository.delete(entity);
}
@Caching(evict = {
@CacheEvict(key = "#p0.id"),
@CacheEvict(key = "'all-'+#p0.getLang()")
})
@Override
public ContractFileTypeLocal save(ContractFileTypeLocal entity) {
return repository.save(entity);
}
}

View File

@@ -137,35 +137,14 @@ public class ContractService implements IEntityService<Contract>, QueryService<C
}
// field
spec = SpecificationUtils.andParam(spec, paramsNode, "group", "kind", "type", "group");
spec = SpecificationUtils.andFieldEqualParam(spec, paramsNode, "parentCode");
// relation
spec = SpecificationUtils.andParam(spec, paramsNode, "company", "project");
spec = SpecificationUtils.andParam(spec, paramsNode, "group", "kind", "type", "group", "company", "project");
return findAll(spec, pageable);
}
private Specification<Contract> andParam(Specification<Contract> spec, JsonNode paramsNode, String field) {
if (!paramsNode.has(field)) {
return spec;
}
JsonNode param = paramsNode.get(field);
Integer value = null;
if (param.isInt()) {
value = param.asInt();
} else if (param.isObject()) {
value = param.get("id").asInt();
}
if (value == null) {
return spec;
}
final int id = value;
spec = SpecificationUtils.and(spec, (root, query, builder) -> {
return builder.equal(root.get(field).get("id"), id);
});
return spec;
}
public List<Contract> findAllByCompany(Company company) {
return contractRepository.findAllByCompanyId(company.getId());
}

View File

@@ -1,12 +1,36 @@
package com.ecep.contract.ds.contract.tasker;
import com.ecep.contract.*;
import java.io.File;
import java.text.NumberFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
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;
import org.hibernate.Hibernate;
import org.springframework.security.core.userdetails.User;
import org.springframework.util.StringUtils;
import com.ecep.contract.CompanyCustomerFileType;
import com.ecep.contract.ContractFileType;
import com.ecep.contract.ContractPayWay;
import com.ecep.contract.MessageHolder;
import com.ecep.contract.MyDateTimeUtils;
import com.ecep.contract.SpringApp;
import com.ecep.contract.ds.company.CompanyFileUtils;
import com.ecep.contract.ds.company.service.CompanyExtendInfoService;
import com.ecep.contract.ds.company.service.CompanyFileService;
import com.ecep.contract.ds.company.service.CompanyService;
import com.ecep.contract.ds.contract.service.ContractBidVendorService;
import com.ecep.contract.ds.contract.service.ContractFileService;
import com.ecep.contract.ds.contract.service.ContractFileTypeService;
import com.ecep.contract.ds.contract.service.ContractService;
import com.ecep.contract.ds.contract.service.ExtendVendorInfoService;
import com.ecep.contract.ds.converter.NumberStringConverter;
@@ -14,27 +38,36 @@ import com.ecep.contract.ds.customer.service.CompanyCustomerFileService;
import com.ecep.contract.ds.customer.service.CompanyCustomerService;
import com.ecep.contract.ds.other.service.EmployeeService;
import com.ecep.contract.ds.project.ProjectCostImportItemsFromContractsTasker;
import com.ecep.contract.ds.project.service.*;
import com.ecep.contract.ds.project.service.ProjectBidService;
import com.ecep.contract.ds.project.service.ProjectCostService;
import com.ecep.contract.ds.project.service.ProjectQuotationService;
import com.ecep.contract.ds.project.service.ProjectSaleTypeRequireFileTypeService;
import com.ecep.contract.ds.project.service.ProjectService;
import com.ecep.contract.ds.project.service.SaleTypeService;
import com.ecep.contract.ds.vendor.service.CompanyVendorService;
import com.ecep.contract.ds.vendor.service.VendorGroupRequireFileTypeService;
import com.ecep.contract.ds.vendor.service.VendorGroupService;
import com.ecep.contract.model.*;
import com.ecep.contract.model.Company;
import com.ecep.contract.model.CompanyCustomer;
import com.ecep.contract.model.CompanyCustomerFile;
import com.ecep.contract.model.CompanyExtendInfo;
import com.ecep.contract.model.Contract;
import com.ecep.contract.model.ContractBidVendor;
import com.ecep.contract.model.ContractFile;
import com.ecep.contract.model.ContractFileTypeLocal;
import com.ecep.contract.model.Employee;
import com.ecep.contract.model.ExtendVendorInfo;
import com.ecep.contract.model.Project;
import com.ecep.contract.model.ProjectBid;
import com.ecep.contract.model.ProjectCost;
import com.ecep.contract.model.ProjectQuotation;
import com.ecep.contract.model.ProjectSaleType;
import com.ecep.contract.model.ProjectSaleTypeRequireFileType;
import com.ecep.contract.model.VendorGroup;
import com.ecep.contract.model.VendorGroupRequireFileType;
import com.ecep.contract.util.SecurityUtils;
import lombok.Data;
import org.hibernate.Hibernate;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.util.StringUtils;
import java.io.File;
import java.text.NumberFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.*;
import java.util.stream.Collectors;
@Data
public class ContractVerifyComm {
@@ -48,6 +81,7 @@ public class ContractVerifyComm {
// Contract
private ContractService contractService;
private ContractFileService contractFileService;
private ContractFileTypeService contractFileTypeService;
private ContractBidVendorService contractBidVendorService;
// Company
@@ -121,6 +155,13 @@ public class ContractVerifyComm {
return contractFileService;
}
private ContractFileTypeService getContractFileTypeService() {
if (contractFileTypeService == null) {
contractFileTypeService = SpringApp.getBean(ContractFileTypeService.class);
}
return contractFileTypeService;
}
private ContractBidVendorService getContractBidVendorService() {
if (contractBidVendorService == null) {
contractBidVendorService = SpringApp.getBean(ContractBidVendorService.class);
@@ -469,7 +510,7 @@ public class ContractVerifyComm {
ContractFileTypeLocal getFileTypeLocal(ContractFileType type) {
if (fileTypeLocalMap == null) {
fileTypeLocalMap = getContractFileService().findAllFileTypes(getLocale().toLanguageTag());
fileTypeLocalMap = getContractFileTypeService().findAll(getLocale());
}
return fileTypeLocalMap.get(type);
}

View File

@@ -5,14 +5,14 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.repository.NoRepositoryBean;
import com.ecep.contract.ds.MyRepository;
import com.ecep.contract.model.BaseEnumEntity;
@NoRepositoryBean
public interface BaseEnumEntityRepository<N extends Enum<?>, T extends BaseEnumEntity<N>, ID>
extends JpaRepository<T, ID> {
extends MyRepository<T, ID> {
List<T> findAllByLang(String lang);
default Map<N, T> getCompleteMapByLocal(String lang) {