feat: 添加日志配置和Logback依赖

refactor: 重构实体类equals和hashCode方法

fix: 修复WebSocketService消息发送逻辑

style: 格式化代码和优化导入

docs: 更新JacksonConfig日期序列化格式

test: 添加CompanyFilePathTableCell测试类

chore: 清理无用代码和注释
This commit is contained in:
2025-09-11 19:44:28 +08:00
parent 375de610ef
commit a1b87de7c0
149 changed files with 2246 additions and 1413 deletions

View File

@@ -54,14 +54,18 @@ public class JacksonConfig {
// 配置Java 8时间模块的序列化格式
JavaTimeModule javaTimeModule = new JavaTimeModule();
// LocalDate
javaTimeModule.addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ISO_LOCAL_DATE));
javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
javaTimeModule.addSerializer(LocalTime.class, new LocalTimeSerializer(DateTimeFormatter.ofPattern("HH:mm:ss")));
javaTimeModule.addDeserializer(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ISO_LOCAL_DATE));
javaTimeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
// LocalTime
javaTimeModule.addSerializer(LocalTime.class, new LocalTimeSerializer(DateTimeFormatter.ISO_LOCAL_TIME));
javaTimeModule.addDeserializer(LocalTime.class, new LocalTimeDeserializer(DateTimeFormatter.ISO_LOCAL_TIME));
// LocalDateTime
javaTimeModule.addSerializer(LocalDateTime.class,
new LocalDateTimeSerializer(DateTimeFormatter.ISO_LOCAL_DATE_TIME));
javaTimeModule.addDeserializer(LocalDateTime.class,
new LocalDateTimeDeserializer(DateTimeFormatter.ISO_LOCAL_DATE_TIME));
objectMapper.registerModule(javaTimeModule);
// 添加自定义模块用于处理JPA/Hibernate代理对象

View File

@@ -17,21 +17,22 @@ import org.springframework.util.StringUtils;
import com.ecep.contract.IEntityService;
import com.ecep.contract.MessageHolder;
import com.ecep.contract.QueryService;
import com.ecep.contract.ds.company.repository.CompanyBankAccountRepository;
import com.ecep.contract.model.Company;
import com.ecep.contract.model.CompanyBankAccount;
import com.ecep.contract.util.SpecificationUtils;
import com.fasterxml.jackson.databind.JsonNode;
@Lazy
@Service
@CacheConfig(cacheNames = "company-bank-account")
public class CompanyBankAccountService implements IEntityService<CompanyBankAccount> {
public class CompanyBankAccountService implements IEntityService<CompanyBankAccount>, QueryService<CompanyBankAccount> {
private static final Logger logger = LoggerFactory.getLogger(CompanyBankAccountService.class);
@Lazy
@Autowired
private CompanyBankAccountRepository repository;
public CompanyBankAccount findByAccount(Company company, String account) {
return repository.findByCompanyAndAccount(company, account).orElse(null);
}
@@ -79,7 +80,6 @@ public class CompanyBankAccountService implements IEntityService<CompanyBankAcco
return repository.findById(id).orElse(null);
}
@Override
public Specification<CompanyBankAccount> getSpecification(String searchText) {
if (!StringUtils.hasText(searchText)) {
@@ -91,12 +91,9 @@ public class CompanyBankAccountService implements IEntityService<CompanyBankAcco
builder.isNotNull(root.get("bank")),
builder.or(
builder.like(root.get("bank").get("name"), "%" + searchText + "%"),
builder.like(root.get("bank").get("code"), "%" + searchText + "%")
)
),
builder.like(root.get("bank").get("code"), "%" + searchText + "%"))),
builder.like(root.get("openingBank"), "%" + searchText + "%"),
builder.like(root.get("account"), "%" + searchText + "%")
);
builder.like(root.get("account"), "%" + searchText + "%"));
};
}
@@ -118,4 +115,15 @@ public class CompanyBankAccountService implements IEntityService<CompanyBankAcco
}
return repository.findAll(spec, Pageable.ofSize(10)).getContent();
}
@Override
public Page<CompanyBankAccount> findAll(JsonNode paramsNode, Pageable pageable) {
Specification<CompanyBankAccount> spec = null;
if (paramsNode.has("searchText")) {
spec = getSpecification(paramsNode.get("searchText").asText());
}
// field
spec = SpecificationUtils.andParam(spec, paramsNode, "company");
return findAll(spec, pageable);
}
}

View File

@@ -14,19 +14,21 @@ import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import com.ecep.contract.IEntityService;
import com.ecep.contract.QueryService;
import com.ecep.contract.ds.company.repository.CompanyBlackReasonRepository;
import com.ecep.contract.model.Company;
import com.ecep.contract.model.CompanyBlackReason;
import com.ecep.contract.util.SpecificationUtils;
import com.fasterxml.jackson.databind.JsonNode;
@Lazy
@Service
public class CompanyBlackReasonService implements IEntityService<CompanyBlackReason> {
public class CompanyBlackReasonService implements IEntityService<CompanyBlackReason>, QueryService<CompanyBlackReason> {
private static final Logger logger = LoggerFactory.getLogger(CompanyContactService.class);
@Autowired
private CompanyBlackReasonRepository repository;
public CompanyBlackReason findById(Integer id) {
return repository.findById(id).orElse(null);
}
@@ -40,8 +42,7 @@ public class CompanyBlackReasonService implements IEntityService<CompanyBlackRea
return builder.or(
builder.like(root.get("applyName"), "%" + searchText + "%"),
builder.like(root.get("blackReason"), "%" + searchText + "%"),
builder.like(root.get("description"), "%" + searchText + "%")
);
builder.like(root.get("description"), "%" + searchText + "%"));
};
}
@@ -65,4 +66,15 @@ public class CompanyBlackReasonService implements IEntityService<CompanyBlackRea
public CompanyBlackReason save(CompanyBlackReason companyBlackReason) {
return repository.save(companyBlackReason);
}
@Override
public Page<CompanyBlackReason> findAll(JsonNode paramsNode, Pageable pageable) {
Specification<CompanyBlackReason> spec = null;
if (paramsNode.has("searchText")) {
spec = getSpecification(paramsNode.get("searchText").asText());
}
// field
spec = SpecificationUtils.andParam(spec, paramsNode, "company");
return findAll(spec, pageable);
}
}

View File

@@ -15,11 +15,13 @@ import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import com.ecep.contract.IEntityService;
import com.ecep.contract.QueryService;
import com.ecep.contract.ds.company.repository.CompanyContactRepository;
import com.ecep.contract.model.Company;
import com.ecep.contract.model.CompanyContact;
import com.ecep.contract.util.MyStringUtils;
import com.ecep.contract.util.SpecificationUtils;
import com.fasterxml.jackson.databind.JsonNode;
/**
* 公司联系人服务
@@ -27,7 +29,7 @@ import com.ecep.contract.util.SpecificationUtils;
@Lazy
@Service
@CacheConfig(cacheNames = "company-contact")
public class CompanyContactService implements IEntityService<CompanyContact> {
public class CompanyContactService implements IEntityService<CompanyContact>, QueryService<CompanyContact> {
private static final Logger logger = LoggerFactory.getLogger(CompanyContactService.class);
@Autowired
@@ -82,8 +84,7 @@ public class CompanyContactService implements IEntityService<CompanyContact> {
builder.like(root.get("phone"), "%" + searchText + "%"),
builder.like(root.get("email"), "%" + searchText + "%"),
builder.like(root.get("position"), "%" + searchText + "%"),
builder.like(root.get("memo"), "%" + searchText + "%")
);
builder.like(root.get("memo"), "%" + searchText + "%"));
};
}
@@ -106,4 +107,15 @@ public class CompanyContactService implements IEntityService<CompanyContact> {
public List<CompanyContact> findAllByCompanyAndName(Company company, String contactName) {
return companyContactRepository.findAllByCompanyAndName(company, contactName);
}
@Override
public Page<CompanyContact> findAll(JsonNode paramsNode, Pageable pageable) {
Specification<CompanyContact> spec = null;
if (paramsNode.has("searchText")) {
spec = getSpecification(paramsNode.get("searchText").asText());
}
// field
spec = SpecificationUtils.andParam(spec, paramsNode, "company");
return findAll(spec, pageable);
}
}

View File

@@ -10,13 +10,19 @@ 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.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import com.ecep.contract.QueryService;
import com.ecep.contract.ds.company.repository.CompanyExtendInfoRepository;
import com.ecep.contract.model.Company;
import com.ecep.contract.model.CompanyExtendInfo;
import com.ecep.contract.util.SpecificationUtils;
import com.fasterxml.jackson.databind.JsonNode;
/**
* 公司文件服务
@@ -24,7 +30,7 @@ import com.ecep.contract.model.CompanyExtendInfo;
@Lazy
@Service
@CacheConfig(cacheNames = "company-extend-info")
public class CompanyExtendInfoService {
public class CompanyExtendInfoService implements QueryService<CompanyExtendInfo> {
private static final Logger logger = LoggerFactory.getLogger(CompanyExtendInfoService.class);
@Autowired
private CompanyExtendInfoRepository repository;
@@ -34,27 +40,49 @@ public class CompanyExtendInfoService {
return repository.findById(id).orElse(null);
}
public List<CompanyExtendInfo> findAll(Specification<CompanyExtendInfo> spec, Sort sort) {
return repository.findAll(spec, sort);
}
@Caching(
evict = {
@CacheEvict(key = "#p0.id"),
@CacheEvict(key = "'byCompany-'+#p0.company.id")
}
)
public Specification<CompanyExtendInfo> getSpecification(String searchText) {
if (!StringUtils.hasText(searchText)) {
return null;
}
return (root, query, builder) -> {
return builder.or(
builder.like(root.get("businessScope"), "%" + searchText + "%"),
builder.like(root.get("taxRegistrationNumber"), "%" + searchText + "%"),
builder.like(root.get("legalPerson"), "%" + searchText + "%"));
};
}
public Page<CompanyExtendInfo> findAll(Specification<CompanyExtendInfo> spec, Pageable pageable) {
return repository.findAll(spec, pageable);
}
@Override
public Page<CompanyExtendInfo> findAll(JsonNode paramsNode, Pageable pageable) {
Specification<CompanyExtendInfo> spec = null;
if (paramsNode.has("searchText")) {
spec = getSpecification(paramsNode.get("searchText").asText());
}
// field
spec = SpecificationUtils.andParam(spec, paramsNode, "company");
return findAll(spec, pageable);
}
@Caching(evict = {
@CacheEvict(key = "#p0.id"),
@CacheEvict(key = "'byCompany-'+#p0.company.id")
})
public void delete(CompanyExtendInfo extendInfo) {
repository.delete(extendInfo);
}
@Caching(
evict = {
@CacheEvict(key = "#p0.id"),
@CacheEvict(key = "'byCompany-'+#p0.company.id")
}
)
@Caching(evict = {
@CacheEvict(key = "#p0.id"),
@CacheEvict(key = "'byCompany-'+#p0.company.id")
})
public CompanyExtendInfo save(CompanyExtendInfo extendInfo) {
return repository.save(extendInfo);
}
@@ -71,5 +99,4 @@ public class CompanyExtendInfoService {
return list.getFirst();
}
}

View File

@@ -29,6 +29,7 @@ import org.springframework.util.StringUtils;
import com.ecep.contract.CompanyFileType;
import com.ecep.contract.IEntityService;
import com.ecep.contract.MyDateTimeUtils;
import com.ecep.contract.QueryService;
import com.ecep.contract.SpringApp;
import com.ecep.contract.cloud.rk.CloudRkService;
import com.ecep.contract.cloud.tyc.CloudTycService;
@@ -43,6 +44,8 @@ import com.ecep.contract.model.CompanyFile;
import com.ecep.contract.model.CompanyFileTypeLocal;
import com.ecep.contract.model.CompanyOldName;
import com.ecep.contract.model.Contract;
import com.ecep.contract.util.SpecificationUtils;
import com.fasterxml.jackson.databind.JsonNode;
/**
* 公司文件服务
@@ -50,7 +53,7 @@ import com.ecep.contract.model.Contract;
@Lazy
@Service
@CacheConfig(cacheNames = "company-file")
public class CompanyFileService implements IEntityService<CompanyFile> {
public class CompanyFileService implements IEntityService<CompanyFile>, QueryService<CompanyFile> {
public final static String ENTERPRISE_REPORT = "企业信用报告";
public final static String BUSINESS_LICENSE = "营业执照";
public final static String ORGANIZATION_CODE_CERTIFICATE = "组织机构代码证";
@@ -99,12 +102,23 @@ public class CompanyFileService implements IEntityService<CompanyFile> {
// public List<CompanyFileTypeLocal> findAllFileTypes(String lang) {
// Map<CompanyFileType, CompanyFileTypeLocal> map =
// fileTypeLocalRepository.getCompleteMapByLocal(lang);
// List<CompanyFileTypeLocal> list = new ArrayList<>(map.values());
// public List<CompanyFileTypeLocal> list = new ArrayList<>(map.values());
// list.sort((o1, o2) -> Objects.compare(o1.getValue(), o2.getValue(),
// String::compareTo));
// return list;
// }
@Override
public Page<CompanyFile> findAll(JsonNode paramsNode, Pageable pageable) {
Specification<CompanyFile> spec = null;
if (paramsNode.has("searchText")) {
spec = getSpecification(paramsNode.get("searchText").asText());
}
// field
spec = SpecificationUtils.andParam(spec, paramsNode, "company");
return findAll(spec, pageable);
}
/**
* 根据公司的合同的资信报告文件,推算下一个咨询报告日期
*

View File

@@ -2,17 +2,24 @@ package com.ecep.contract.ds.company.service;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.Cacheable;
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.QueryService;
import com.ecep.contract.ds.company.repository.CompanyInvoiceInfoRepository;
import com.ecep.contract.model.Company;
import com.ecep.contract.model.CompanyInvoiceInfo;
import com.ecep.contract.util.SpecificationUtils;
import com.fasterxml.jackson.databind.JsonNode;
/**
* 公司发票信息服务
@@ -20,7 +27,8 @@ import com.ecep.contract.model.CompanyInvoiceInfo;
@Lazy
@Service
@CacheConfig(cacheNames = "company-invoice-info")
public class CompanyInvoiceInfoService {
public class CompanyInvoiceInfoService implements QueryService<CompanyInvoiceInfo> {
private static final Logger logger = LoggerFactory.getLogger(CompanyInvoiceInfoService.class);
@Lazy
@Autowired
private CompanyInvoiceInfoRepository repository;
@@ -30,7 +38,6 @@ public class CompanyInvoiceInfoService {
return repository.findById(id).orElse(null);
}
public List<CompanyInvoiceInfo> searchByCompany(Company company, String searchText) {
Specification<CompanyInvoiceInfo> spec = (root, query, builder) -> {
return builder.or(
@@ -39,8 +46,7 @@ public class CompanyInvoiceInfoService {
builder.like(root.get("address"), "%" + searchText + "%"),
builder.like(root.get("phone"), "%" + searchText + "%"),
builder.like(root.get("bankName"), "%" + searchText + "%"),
builder.like(root.get("bankAccount"), "%" + searchText + "%")
);
builder.like(root.get("bankAccount"), "%" + searchText + "%"));
};
if (company != null) {
@@ -50,4 +56,34 @@ public class CompanyInvoiceInfoService {
}
return repository.findAll(spec, Pageable.ofSize(10)).getContent();
}
public Specification<CompanyInvoiceInfo> getSpecification(String searchText) {
if (!StringUtils.hasText(searchText)) {
return null;
}
return (root, query, builder) -> {
return builder.or(
builder.like(root.get("name"), "%" + searchText + "%"),
builder.like(root.get("taxId"), "%" + searchText + "%"),
builder.like(root.get("address"), "%" + searchText + "%"),
builder.like(root.get("phone"), "%" + searchText + "%"),
builder.like(root.get("bankName"), "%" + searchText + "%"),
builder.like(root.get("bankAccount"), "%" + searchText + "%"));
};
}
public Page<CompanyInvoiceInfo> findAll(Specification<CompanyInvoiceInfo> spec, Pageable pageable) {
return repository.findAll(spec, pageable);
}
@Override
public Page<CompanyInvoiceInfo> findAll(JsonNode paramsNode, Pageable pageable) {
Specification<CompanyInvoiceInfo> spec = null;
if (paramsNode.has("searchText")) {
spec = getSpecification(paramsNode.get("searchText").asText());
}
// field
spec = SpecificationUtils.andParam(spec, paramsNode, "company");
return findAll(spec, pageable);
}
}

View File

@@ -16,16 +16,18 @@ import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import com.ecep.contract.IEntityService;
import com.ecep.contract.QueryService;
import com.ecep.contract.ds.company.CompanyFileUtils;
import com.ecep.contract.ds.company.repository.CompanyOldNameRepository;
import com.ecep.contract.model.Company;
import com.ecep.contract.model.CompanyOldName;
import com.ecep.contract.util.MyStringUtils;
import com.ecep.contract.util.SpecificationUtils;
import com.fasterxml.jackson.databind.JsonNode;
@Lazy
@Service
public class CompanyOldNameService implements IEntityService<CompanyOldName> {
public class CompanyOldNameService implements IEntityService<CompanyOldName>, QueryService<CompanyOldName> {
private static final Logger logger = LoggerFactory.getLogger(CompanyOldNameService.class);
@Lazy
@Autowired
@@ -34,7 +36,6 @@ public class CompanyOldNameService implements IEntityService<CompanyOldName> {
@Autowired
private CompanyService companyService;
public CompanyOldName findById(Integer id) {
return companyOldNameRepository.findById(id).orElse(null);
}
@@ -51,12 +52,10 @@ public class CompanyOldNameService implements IEntityService<CompanyOldName> {
return (root, query, builder) -> {
return builder.or(
builder.like(root.get("name"), "%" + searchText + "%"),
builder.like(root.get("memo"), "%" + searchText + "%")
);
builder.like(root.get("memo"), "%" + searchText + "%"));
};
}
public CompanyOldName save(CompanyOldName companyOldName) {
return companyOldNameRepository.save(companyOldName);
}
@@ -108,7 +107,6 @@ public class CompanyOldNameService implements IEntityService<CompanyOldName> {
return null;
}
public List<CompanyOldName> findAllByName(String name) {
return companyOldNameRepository.findAllByName(name);
}
@@ -198,6 +196,30 @@ public class CompanyOldNameService implements IEntityService<CompanyOldName> {
return companyOldNameRepository.findAll(spec, pageable);
}
@Override
public Page<CompanyOldName> findAll(JsonNode paramsNode, Pageable pageable) {
Specification<CompanyOldName> spec = null;
if (paramsNode.has("searchText")) {
spec = getSpecification(paramsNode.get("searchText").asText());
}
if (paramsNode.has("company")) {
JsonNode param = paramsNode.get("company");
Integer companyId = null;
if (param.isInt()) {
companyId = param.asInt();
} else if (param.isObject()) {
companyId = param.get("id").asInt();
}
if (companyId != null) {
final int id = companyId;
spec = SpecificationUtils.and(spec, (root, query, builder) -> {
return builder.equal(root.get("companyId"), id);
});
}
}
return findAll(spec, pageable);
}
public CompanyOldName createNew(Company company, String name, boolean ambiguity) {
CompanyOldName companyOldName = new CompanyOldName();
companyOldName.setCompanyId(company.getId());

View File

@@ -127,6 +127,9 @@ public class CompanyService implements IEntityService<Company>, QueryService<Com
@Override
public Page<Company> findAll(JsonNode paramsNode, Pageable pageable) {
Specification<Company> spec = null;
if (paramsNode.has("searchText")) {
spec = getSpecification(paramsNode.get("searchText").asText());
}
return findAll(spec, pageable);
}

View File

@@ -17,19 +17,21 @@ import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import com.ecep.contract.IEntityService;
import com.ecep.contract.QueryService;
import com.ecep.contract.ds.company.repository.InvoiceRepository;
import com.ecep.contract.model.Invoice;
import com.ecep.contract.util.SpecificationUtils;
import com.fasterxml.jackson.databind.JsonNode;
@Lazy
@Service
@CacheConfig(cacheNames = "invoice")
public class InvoiceService implements IEntityService<Invoice> {
public class InvoiceService implements IEntityService<Invoice>, QueryService<Invoice> {
private static final Logger logger = LoggerFactory.getLogger(InvoiceService.class);
@Autowired
private InvoiceRepository repository;
@Cacheable(key = "#p0")
public Invoice findById(Integer id) {
return repository.findById(id).orElse(null);
@@ -44,8 +46,7 @@ public class InvoiceService implements IEntityService<Invoice> {
return (root, query, builder) -> {
return builder.or(
builder.like(root.get("code"), "%" + searchText + "%"),
builder.like(root.get("description"), "%" + searchText + "%")
);
builder.like(root.get("description"), "%" + searchText + "%"));
};
}
@@ -72,4 +73,16 @@ public class InvoiceService implements IEntityService<Invoice> {
public Invoice save(Invoice invoice) {
return repository.save(invoice);
}
@Override
public Page<Invoice> findAll(JsonNode paramsNode, Pageable pageable) {
Specification<Invoice> spec = null;
if (paramsNode.has("searchText")) {
spec = getSpecification(paramsNode.get("searchText").asText());
}
// field
spec = SpecificationUtils.andParam(spec, paramsNode, "company");
return findAll(spec, pageable);
}
}

View File

@@ -13,21 +13,26 @@ import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import com.ecep.contract.IEntityService;
import com.ecep.contract.QueryService;
import com.ecep.contract.ds.contract.repository.ContractBidVendorRepository;
import com.ecep.contract.model.Company;
import com.ecep.contract.model.Contract;
import com.ecep.contract.model.ContractBidVendor;
import com.ecep.contract.util.SpecificationUtils;
import com.fasterxml.jackson.databind.JsonNode;
@Lazy
@Service
@CacheConfig(cacheNames = "contract-ven-bid")
public class ContractBidVendorService implements IEntityService<ContractBidVendor> {
public class ContractBidVendorService implements IEntityService<ContractBidVendor>, QueryService<ContractBidVendor> {
@Lazy
@Autowired
private ContractBidVendorRepository repository;
@Override
@Cacheable(key = "#p0")
public ContractBidVendor findById(Integer id) {
return repository.findById(id).orElse(null);
@@ -35,7 +40,15 @@ public class ContractBidVendorService implements IEntityService<ContractBidVendo
@Override
public Specification<ContractBidVendor> getSpecification(String searchText) {
return null;
if (!StringUtils.hasText(searchText)) {
return null;
}
return (root, query, builder) -> {
return builder.or(
builder.like(root.get("bidName"), "%" + searchText + "%"),
builder.like(root.get("memo"), "%" + searchText + "%")
);
};
}
@Override
@@ -60,6 +73,7 @@ public class ContractBidVendorService implements IEntityService<ContractBidVendo
@CacheEvict(key = "#p0.id"),
@CacheEvict(key = "'allbycontract-'+#p0.contract.id")
})
@Override
public void delete(ContractBidVendor bidVendor) {
repository.delete(bidVendor);
}
@@ -78,4 +92,16 @@ public class ContractBidVendorService implements IEntityService<ContractBidVendo
public List<ContractBidVendor> findByContractAndCompany(Contract contract, Company company) {
return repository.findByContractIdAndCompanyId(contract.getId(), company.getId());
}
@Override
public Page<ContractBidVendor> findAll(JsonNode paramsNode, Pageable pageable) {
Specification<ContractBidVendor> spec = null;
if (paramsNode.has("searchText")) {
spec = getSpecification(paramsNode.get("searchText").asText());
}
// field
spec = SpecificationUtils.andParam(spec, paramsNode, "contract");
return findAll(spec, pageable);
}
}

View File

@@ -8,10 +8,17 @@ 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.IEntityService;
import com.ecep.contract.QueryService;
import com.ecep.contract.ds.contract.repository.ContractCatalogRepository;
import com.ecep.contract.model.ContractCatalog;
import com.fasterxml.jackson.databind.JsonNode;
/**
* 合同分类服务
@@ -19,7 +26,7 @@ import com.ecep.contract.model.ContractCatalog;
@Lazy
@Service
@CacheConfig(cacheNames = "contract-catalog")
public class ContractCatalogService {
public class ContractCatalogService implements IEntityService<ContractCatalog>, QueryService<ContractCatalog> {
@Lazy
@Autowired
private ContractCatalogRepository repository;
@@ -28,6 +35,7 @@ public class ContractCatalogService {
* 根据 id 查找 ContractCatalog
*/
@Cacheable(key = "#p0")
@Override
public ContractCatalog findById(Integer id) {
return repository.findById(id).orElse(null);
}
@@ -60,7 +68,35 @@ public class ContractCatalogService {
@CacheEvict(key = "'code-'+#p0.code"),
@CacheEvict(key = "'catalogs'"),
})
@Override
public void delete(ContractCatalog catalog) {
repository.delete(catalog);
}
@Override
public Specification<ContractCatalog> getSpecification(String searchText) {
if (!StringUtils.hasText(searchText)) {
return null;
}
return (root, query, builder) -> {
return builder.or(
builder.like(root.get("name"), "%" + searchText + "%"),
builder.like(root.get("code"), "%" + searchText + "%"),
builder.like(root.get("memo"), "%" + searchText + "%"));
};
}
@Override
public Page<ContractCatalog> findAll(Specification<ContractCatalog> spec, Pageable pageable) {
return repository.findAll(spec, pageable);
}
@Override
public Page<ContractCatalog> findAll(JsonNode paramsNode, Pageable pageable) {
Specification<ContractCatalog> spec = null;
if (paramsNode.has("searchText")) {
spec = getSpecification(paramsNode.get("searchText").asText());
}
return findAll(spec, pageable);
}
}

View File

@@ -21,16 +21,19 @@ 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.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;
@Lazy
@Service
@CacheConfig(cacheNames = "contract-file")
public class ContractFileService implements IEntityService<ContractFile> {
public class ContractFileService implements IEntityService<ContractFile>, QueryService<ContractFile> {
private static final Logger logger = LoggerFactory.getLogger(ContractFileService.class);
@Lazy
@Autowired
@@ -39,6 +42,7 @@ public class ContractFileService implements IEntityService<ContractFile> {
@Autowired
private ContractFileTypeLocalRepository contractFileTypeLocalRepository;
@Override
@Cacheable(key = "#p0")
public ContractFile findById(Integer id) {
return contractFileRepository.findById(id).orElse(null);
@@ -61,6 +65,19 @@ public class ContractFileService implements IEntityService<ContractFile> {
return contractFileRepository.findAll(spec, pageable);
}
@Override
public Page<ContractFile> findAll(JsonNode paramsNode, Pageable pageable) {
Specification<ContractFile> spec = null;
if (paramsNode.has("searchText")) {
spec = getSpecification(paramsNode.get("searchText").asText());
}
// field
spec = SpecificationUtils.andParam(spec, paramsNode, "contract", "type");
return findAll(spec, pageable);
}
public List<ContractFile> findAll(Specification<ContractFile> spec, Sort by) {
return contractFileRepository.findAll(spec, by);
}
@@ -123,6 +140,7 @@ public class ContractFileService implements IEntityService<ContractFile> {
@CacheEvict(key = "#p0.id"),
@CacheEvict(key = "'allbycontract-'+#p0.contract.id")
})
@Override
public void delete(ContractFile file) {
contractFileRepository.deleteById(file.getId());
}

View File

@@ -16,8 +16,10 @@ import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import com.ecep.contract.IEntityService;
import com.ecep.contract.QueryService;
import com.ecep.contract.ds.contract.repository.ContractGroupRepository;
import com.ecep.contract.model.ContractGroup;
import com.fasterxml.jackson.databind.JsonNode;
/**
* 合同分组服务
@@ -25,13 +27,14 @@ import com.ecep.contract.model.ContractGroup;
@Lazy
@Service
@CacheConfig(cacheNames = "contract-group")
public class ContractGroupService implements IEntityService<ContractGroup> {
public class ContractGroupService implements IEntityService<ContractGroup>, QueryService<ContractGroup> {
private static final Logger logger = LoggerFactory.getLogger(ContractGroupService.class);
@Lazy
@Autowired
private ContractGroupRepository repository;
@Override
@Cacheable(key = "#p0")
public ContractGroup findById(Integer id) {
return repository.findById(id).orElse(null);
@@ -42,14 +45,22 @@ public class ContractGroupService implements IEntityService<ContractGroup> {
return repository.findAll(spec, pageable);
}
@Override
public Page<ContractGroup> findAll(JsonNode paramsNode, Pageable pageable) {
Specification<ContractGroup> spec = null;
if (paramsNode.has("searchText")) {
spec = getSpecification(paramsNode.get("searchText").asText());
}
return findAll(spec, pageable);
}
@Override
public Specification<ContractGroup> getSpecification(String searchText) {
return (root, query, builder)->{
return (root, query, builder) -> {
return builder.or(
builder.like(root.get("code"), "%" + searchText + "%"),
builder.like(root.get("name"), "%" + searchText + "%"),
builder.like(root.get("title"), "%" + searchText + "%")
);
builder.like(root.get("title"), "%" + searchText + "%"));
};
}
@@ -89,6 +100,7 @@ public class ContractGroupService implements IEntityService<ContractGroup> {
@CacheEvict(key = "'groups'"),
@CacheEvict(key = "'code-'+#p0.code"),
})
@Override
public void delete(ContractGroup group) {
repository.delete(group);
}
@@ -100,4 +112,5 @@ public class ContractGroupService implements IEntityService<ContractGroup> {
group.setTitle("");
return group;
}
}

View File

@@ -18,23 +18,27 @@ import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import com.ecep.contract.IEntityService;
import com.ecep.contract.QueryService;
import com.ecep.contract.ds.contract.repository.ContractItemRepository;
import com.ecep.contract.model.Contract;
import com.ecep.contract.model.ContractItem;
import com.ecep.contract.model.Inventory;
import com.ecep.contract.util.SpecificationUtils;
import com.fasterxml.jackson.databind.JsonNode;
import jakarta.persistence.criteria.Path;
@Lazy
@Service
@CacheConfig(cacheNames = "contract-item")
public class ContractItemService implements IEntityService<ContractItem> {
public class ContractItemService implements IEntityService<ContractItem>, QueryService<ContractItem> {
private static final Logger logger = LoggerFactory.getLogger(ContractItemService.class);
@Lazy
@Autowired
private ContractItemRepository itemRepository;
@Override
@Cacheable(key = "#p0")
public ContractItem findById(Integer id) {
return itemRepository.findById(id).orElse(null);
@@ -66,6 +70,19 @@ public class ContractItemService implements IEntityService<ContractItem> {
return itemRepository.findAll(spec, pageable);
}
@Override
public Page<ContractItem> findAll(JsonNode paramsNode, Pageable pageable) {
Specification<ContractItem> spec = null;
// TODO 完成参数处理
if (paramsNode.has("searchText")) {
spec = getSpecification(paramsNode.get("searchText").asText());
}
// field
spec = SpecificationUtils.andParam(spec, paramsNode, "contract");
logger.warn("Unsupported paramsNode: {}", paramsNode);
return findAll(spec, pageable);
}
public List<ContractItem> findAllByContract(Contract contract) {
return itemRepository.findByContractId(contract.getId());
}
@@ -88,6 +105,7 @@ public class ContractItemService implements IEntityService<ContractItem> {
@Caching(evict = {
@CacheEvict(key = "#p0.id")
})
@Override
public void delete(ContractItem item) {
itemRepository.delete(item);
}

View File

@@ -16,8 +16,10 @@ import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import com.ecep.contract.IEntityService;
import com.ecep.contract.QueryService;
import com.ecep.contract.ds.contract.repository.ContractKindRepository;
import com.ecep.contract.model.ContractKind;
import com.fasterxml.jackson.databind.JsonNode;
/**
* 合同种类服务
@@ -25,13 +27,14 @@ import com.ecep.contract.model.ContractKind;
@Lazy
@Service
@CacheConfig(cacheNames = "contract-kind")
public class ContractKindService implements IEntityService<ContractKind> {
public class ContractKindService implements IEntityService<ContractKind>, QueryService<ContractKind> {
private static final Logger logger = LoggerFactory.getLogger(ContractKindService.class);
@Lazy
@Autowired
private ContractKindRepository repository;
@Override
@Cacheable(key = "'kind-'+#p0")
public ContractKind findById(Integer id) {
return repository.findById(id).orElse(null);
@@ -42,14 +45,22 @@ public class ContractKindService implements IEntityService<ContractKind> {
return repository.findAll(spec, pageable);
}
@Override
public Page<ContractKind> findAll(JsonNode paramsNode, Pageable pageable) {
Specification<ContractKind> spec = null;
if (paramsNode.has("searchText")) {
spec = getSpecification(paramsNode.get("searchText").asText());
}
return findAll(spec, pageable);
}
@Override
public Specification<ContractKind> getSpecification(String searchText) {
return (root, query, builder) -> {
return builder.or(
builder.like(root.get("code"), "%" + searchText + "%"),
builder.like(root.get("name"), "%" + searchText + "%"),
builder.like(root.get("title"), "%" + searchText + "%")
);
builder.like(root.get("title"), "%" + searchText + "%"));
};
}
@@ -72,23 +83,19 @@ public class ContractKindService implements IEntityService<ContractKind> {
return repository.findAll();
}
@Caching(
evict = {
@CacheEvict(key = "'kinds'"),
@CacheEvict(key = "'kind-'+#p0.id"),
@CacheEvict(key = "'code-'+#p0.name"),
}
)
@Caching(evict = {
@CacheEvict(key = "'kinds'"),
@CacheEvict(key = "'kind-'+#p0.id"),
@CacheEvict(key = "'code-'+#p0.name"),
})
public ContractKind save(ContractKind kind) {
return repository.save(kind);
}
@Caching(
evict = {
@CacheEvict(key = "'kinds'"),
@CacheEvict(key = "'kind-'+#p0"),
}
)
@Caching(evict = {
@CacheEvict(key = "'kinds'"),
@CacheEvict(key = "'kind-'+#p0"),
})
public void delete(Integer id) {
repository.deleteById(id);
}

View File

@@ -15,9 +15,12 @@ import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import com.ecep.contract.IEntityService;
import com.ecep.contract.QueryService;
import com.ecep.contract.ds.contract.repository.ContractPayPlanRepository;
import com.ecep.contract.model.Contract;
import com.ecep.contract.model.ContractPayPlan;
import com.ecep.contract.util.SpecificationUtils;
import com.fasterxml.jackson.databind.JsonNode;
/**
* 合同支付计划服务
@@ -25,7 +28,7 @@ import com.ecep.contract.model.ContractPayPlan;
@Lazy
@Service
@CacheConfig(cacheNames = "contract-pay-plan")
public class ContractPayPlanService implements IEntityService<ContractPayPlan> {
public class ContractPayPlanService implements IEntityService<ContractPayPlan>, QueryService<ContractPayPlan> {
@Lazy
@Autowired
private ContractPayPlanRepository repository;
@@ -51,29 +54,35 @@ public class ContractPayPlanService implements IEntityService<ContractPayPlan> {
return repository.findAll(spec, pageable);
}
@Override
public Page<ContractPayPlan> findAll(JsonNode paramsNode, Pageable pageable) {
Specification<ContractPayPlan> spec = null;
if (paramsNode.has("searchText")) {
spec = getSpecification(paramsNode.get("searchText").asText());
}
// field
spec = SpecificationUtils.andParam(spec, paramsNode, "contract");
return findAll(spec, pageable);
}
public List<ContractPayPlan> findAllByContract(Contract contract) {
return repository.findAllByContract(contract);
}
@Caching(
evict = {
@CacheEvict(key = "#p0.id")
}
)
@Caching(evict = {
@CacheEvict(key = "#p0.id")
})
@Override
public void delete(ContractPayPlan entity) {
repository.delete(entity);
}
@Caching(
evict = {
@CacheEvict(key = "#p0.id")
}
)
@Caching(evict = {
@CacheEvict(key = "#p0.id")
})
@Override
public ContractPayPlan save(ContractPayPlan entity) {
return repository.save(entity);
}
}

View File

@@ -26,6 +26,7 @@ import org.springframework.util.StringUtils;
import com.ecep.contract.ContractPayWay;
import com.ecep.contract.IEntityService;
import com.ecep.contract.QueryService;
import com.ecep.contract.constant.ContractConstant;
import com.ecep.contract.ds.contract.repository.ContractRepository;
import com.ecep.contract.ds.other.service.SysConfService;
@@ -40,6 +41,7 @@ import com.ecep.contract.model.ContractType;
import com.ecep.contract.model.Project;
import com.ecep.contract.util.MyStringUtils;
import com.ecep.contract.util.SpecificationUtils;
import com.fasterxml.jackson.databind.JsonNode;
import jakarta.persistence.criteria.Predicate;
@@ -50,7 +52,7 @@ import jakarta.persistence.criteria.Predicate;
@Lazy
@Service
@CacheConfig(cacheNames = "contract")
public class ContractService implements IEntityService<Contract> {
public class ContractService implements IEntityService<Contract>, QueryService<Contract> {
private static final Logger logger = LoggerFactory.getLogger(ContractService.class);
@Lazy
@Autowired
@@ -127,6 +129,43 @@ public class ContractService implements IEntityService<Contract> {
return contractRepository.findAll(spec, sort);
}
@Override
public Page<Contract> findAll(JsonNode paramsNode, Pageable pageable) {
Specification<Contract> spec = null;
if (paramsNode.has("searchText")) {
spec = getSpecification(paramsNode.get("searchText").asText());
}
// field
spec = SpecificationUtils.andParam(spec, paramsNode, "group", "kind", "type", "group");
// relation
spec = SpecificationUtils.andParam(spec, paramsNode, "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

@@ -16,8 +16,10 @@ import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import com.ecep.contract.IEntityService;
import com.ecep.contract.QueryService;
import com.ecep.contract.ds.contract.repository.ContractTypeRepository;
import com.ecep.contract.model.ContractType;
import com.fasterxml.jackson.databind.JsonNode;
/**
* 合同类型服务
@@ -25,7 +27,7 @@ import com.ecep.contract.model.ContractType;
@Lazy
@Service
@CacheConfig(cacheNames = "contract-type")
public class ContractTypeService implements IEntityService<ContractType> {
public class ContractTypeService implements IEntityService<ContractType>, QueryService<ContractType> {
private static final Logger logger = LoggerFactory.getLogger(ContractTypeService.class);
@Lazy
@@ -42,6 +44,15 @@ public class ContractTypeService implements IEntityService<ContractType> {
return repository.findAll(spec, pageable);
}
@Override
public Page<ContractType> findAll(JsonNode paramsNode, Pageable pageable) {
Specification<ContractType> spec = null;
if (paramsNode.has("searchText")) {
spec = getSpecification(paramsNode.get("searchText").asText());
}
return findAll(spec, pageable);
}
public ContractType findByName(String name) {
return repository.findByName(name).orElse(null);
}

View File

@@ -10,20 +10,26 @@ 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.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import com.ecep.contract.IEntityService;
import com.ecep.contract.QueryService;
import com.ecep.contract.ds.contract.repository.ExtendVendorInfoRepository;
import com.ecep.contract.ds.vendor.service.VendorGroupService;
import com.ecep.contract.model.Contract;
import com.ecep.contract.model.ExtendVendorInfo;
import com.ecep.contract.util.SpecificationUtils;
import com.fasterxml.jackson.databind.JsonNode;
@Lazy
@Service
@CacheConfig(cacheNames = "contract-ext-ven-info")
public class ExtendVendorInfoService {
public class ExtendVendorInfoService implements IEntityService<ExtendVendorInfo>, QueryService<ExtendVendorInfo> {
@Lazy
@Autowired
private ExtendVendorInfoRepository repository;
@@ -31,8 +37,9 @@ public class ExtendVendorInfoService {
@Autowired
private VendorGroupService vendorGroupService;
@Override
@Cacheable(key = "#p0")
public ExtendVendorInfo findById(int id) {
public ExtendVendorInfo findById(Integer id) {
return repository.findById(id).orElse(null);
}
@@ -49,13 +56,46 @@ public class ExtendVendorInfoService {
return repository.save(bidVendor);
}
@Caching(evict = {
@CacheEvict(key = "#p0.id"),
@CacheEvict(key = "'bycontract-'+#p0.contract.id")
})
@Caching(
evict = {
@CacheEvict(key = "#p0.id"),
@CacheEvict(key = "'bycontract-'+#p0.contract.id")
}
)
@Override
public void delete(ExtendVendorInfo bidVendor) {
repository.delete(bidVendor);
}
@Override
public Page<ExtendVendorInfo> findAll(Specification<ExtendVendorInfo> spec, Pageable pageable) {
return repository.findAll(spec, pageable);
}
@Override
public Specification<ExtendVendorInfo> getSpecification(String searchText) {
if (!StringUtils.hasText(searchText)) {
return null;
}
return (root, query, builder) -> {
return builder.or(
builder.like(root.get("contract").get("code"), "%" + searchText + "%"),
builder.like(root.get("contract").get("name"), "%" + searchText + "%"),
builder.like(root.get("codeSequenceNumber").as(String.class), "%" + searchText + "%")
);
};
}
@Override
public Page<ExtendVendorInfo> findAll(JsonNode paramsNode, Pageable pageable) {
Specification<ExtendVendorInfo> spec = null;
if (paramsNode.has("searchText")) {
spec = getSpecification(paramsNode.get("searchText").asText());
}
// field
spec = SpecificationUtils.andParam(spec, paramsNode, "contract");
return findAll(spec, pageable);
}
public List<ExtendVendorInfo> findAll(Specification<ExtendVendorInfo> spec, Sort sort) {
return repository.findAll(spec, sort);

View File

@@ -15,13 +15,16 @@ import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import com.ecep.contract.IEntityService;
import com.ecep.contract.QueryService;
import com.ecep.contract.ds.contract.repository.PurchaseBillVoucherItemRepository;
import com.ecep.contract.model.PurchaseBillVoucherItem;
import com.fasterxml.jackson.databind.JsonNode;
@Lazy
@Service
@CacheConfig(cacheNames = "purchase-bill-voucher-item")
public class PurchaseBillVoucherItemService implements IEntityService<PurchaseBillVoucherItem> {
public class PurchaseBillVoucherItemService
implements IEntityService<PurchaseBillVoucherItem>, QueryService<PurchaseBillVoucherItem> {
@Lazy
@Autowired
private PurchaseBillVoucherItemRepository repository;
@@ -45,6 +48,15 @@ public class PurchaseBillVoucherItemService implements IEntityService<PurchaseBi
return repository.findAll(spec, pageable);
}
@Override
public Page<PurchaseBillVoucherItem> findAll(JsonNode paramsNode, Pageable pageable) {
Specification<PurchaseBillVoucherItem> spec = null;
if (paramsNode.has("searchText")) {
spec = getSpecification(paramsNode.get("searchText").asText());
}
return findAll(spec, pageable);
}
@Caching(evict = {
@CacheEvict(key = "#p0.id"),
@CacheEvict(key = "'refId-'+#p0.refId")

View File

@@ -18,8 +18,11 @@ import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import com.ecep.contract.IEntityService;
import com.ecep.contract.QueryService;
import com.ecep.contract.ds.contract.repository.PurchaseBillVoucherRepository;
import com.ecep.contract.model.PurchaseBillVoucher;
import com.ecep.contract.util.SpecificationUtils;
import com.fasterxml.jackson.databind.JsonNode;
/**
* 采购账单凭证服务
@@ -27,14 +30,15 @@ import com.ecep.contract.model.PurchaseBillVoucher;
@Lazy
@Service
@CacheConfig(cacheNames = "purchase-bill-voucher")
public class PurchaseBillVoucherService implements IEntityService<PurchaseBillVoucher> {
public class PurchaseBillVoucherService
implements IEntityService<PurchaseBillVoucher>, QueryService<PurchaseBillVoucher> {
private static final Logger logger = LoggerFactory.getLogger(PurchaseBillVoucherService.class);
@Lazy
@Autowired
private PurchaseBillVoucherRepository repository;
@Override
@Cacheable(key = "#p0")
public PurchaseBillVoucher findById(Integer id) {
return repository.findById(id).orElse(null);
@@ -50,8 +54,7 @@ public class PurchaseBillVoucherService implements IEntityService<PurchaseBillVo
return (root, query, builder) -> {
return builder.or(
builder.like(root.get("code"), "%" + searchText + "%"),
builder.like(root.get("description"), "%" + searchText + "%")
);
builder.like(root.get("description"), "%" + searchText + "%"));
};
}
@@ -71,24 +74,21 @@ public class PurchaseBillVoucherService implements IEntityService<PurchaseBillVo
* @param voucher 要保存的实体对象
* @return 返回异步调用
*/
@Caching(
evict = {
@CacheEvict(key = "#p0.id"),
@CacheEvict(key = "'code-'+#p0.code"),
@CacheEvict(key = "'refId-'+#p0.refId")
}
)
@Caching(evict = {
@CacheEvict(key = "#p0.id"),
@CacheEvict(key = "'code-'+#p0.code"),
@CacheEvict(key = "'refId-'+#p0.refId")
})
public PurchaseBillVoucher save(PurchaseBillVoucher voucher) {
return repository.save(voucher);
}
@Caching(
evict = {
@CacheEvict(key = "#p0.id"),
@CacheEvict(key = "'code-'+#p0.code"),
@CacheEvict(key = "'refId-'+#p0.refId")
}
)
@Caching(evict = {
@CacheEvict(key = "#p0.id"),
@CacheEvict(key = "'code-'+#p0.code"),
@CacheEvict(key = "'refId-'+#p0.refId")
})
@Override
public void delete(PurchaseBillVoucher order) {
repository.delete(order);
}
@@ -101,10 +101,22 @@ public class PurchaseBillVoucherService implements IEntityService<PurchaseBillVo
return repository.count(spec);
}
@Override
public Page<PurchaseBillVoucher> findAll(Specification<PurchaseBillVoucher> spec, Pageable pageable) {
return repository.findAll(spec, pageable);
}
@Override
public Page<PurchaseBillVoucher> findAll(JsonNode paramsNode, Pageable pageable) {
Specification<PurchaseBillVoucher> spec = null;
if (paramsNode.has("searchText")) {
spec = getSpecification(paramsNode.get("searchText").asText());
}
// field
spec = SpecificationUtils.andParam(spec, paramsNode, "company", "inventory");
return findAll(spec, pageable);
}
public List<PurchaseBillVoucher> findAll(Specification<PurchaseBillVoucher> spec, Sort sort) {
return repository.findAll(spec, sort);
}

View File

@@ -18,13 +18,16 @@ import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import com.ecep.contract.IEntityService;
import com.ecep.contract.QueryService;
import com.ecep.contract.ds.contract.repository.PurchaseOrderItemRepository;
import com.ecep.contract.model.PurchaseOrderItem;
import com.ecep.contract.util.SpecificationUtils;
import com.fasterxml.jackson.databind.JsonNode;
@Lazy
@Service
@CacheConfig(cacheNames = "contract-purchase-order-item")
public class PurchaseOrderItemService implements IEntityService<PurchaseOrderItem> {
public class PurchaseOrderItemService implements IEntityService<PurchaseOrderItem>, QueryService<PurchaseOrderItem> {
private static final Logger logger = LoggerFactory.getLogger(PurchaseOrderItemService.class);
@Lazy
@Autowired
@@ -52,7 +55,6 @@ public class PurchaseOrderItemService implements IEntityService<PurchaseOrderIte
return list.getFirst();
}
@Override
public Specification<PurchaseOrderItem> getSpecification(String searchText) {
if (!StringUtils.hasText(searchText)) {
@@ -68,22 +70,29 @@ public class PurchaseOrderItemService implements IEntityService<PurchaseOrderIte
return repository.findAll(spec, pageable);
}
@Caching(
evict = {
@CacheEvict(key = "#p0.id"),
@CacheEvict(key = "'refId-'+#p0.refId")
}
)
@Override
public Page<PurchaseOrderItem> findAll(JsonNode paramsNode, Pageable pageable) {
Specification<PurchaseOrderItem> spec = null;
if (paramsNode.has("searchText")) {
spec = getSpecification(paramsNode.get("searchText").asText());
}
// field
spec = SpecificationUtils.andParam(spec, paramsNode, "order", "inventory");
return findAll(spec, pageable);
}
@Caching(evict = {
@CacheEvict(key = "#p0.id"),
@CacheEvict(key = "'refId-'+#p0.refId")
})
@Override
public void delete(PurchaseOrderItem entity) {
repository.delete(entity);
}
@Caching(
evict = {
@CacheEvict(key = "#p0.id"), @CacheEvict(key = "'refId-'+#p0.refId")
}
)
@Caching(evict = {
@CacheEvict(key = "#p0.id"), @CacheEvict(key = "'refId-'+#p0.refId")
})
@Override
public PurchaseOrderItem save(PurchaseOrderItem entity) {
return repository.save(entity);

View File

@@ -17,9 +17,12 @@ import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import com.ecep.contract.IEntityService;
import com.ecep.contract.QueryService;
import com.ecep.contract.ds.contract.repository.PurchaseOrderRepository;
import com.ecep.contract.model.Contract;
import com.ecep.contract.model.PurchaseOrder;
import com.ecep.contract.util.SpecificationUtils;
import com.fasterxml.jackson.databind.JsonNode;
/**
* 采购订单服务
@@ -27,14 +30,14 @@ import com.ecep.contract.model.PurchaseOrder;
@Lazy
@Service
@CacheConfig(cacheNames = "contract-purchase-order")
public class PurchaseOrdersService implements IEntityService<PurchaseOrder> {
public class PurchaseOrdersService implements IEntityService<PurchaseOrder>, QueryService<PurchaseOrder> {
private static final Logger logger = LoggerFactory.getLogger(PurchaseOrdersService.class);
@Lazy
@Autowired
private PurchaseOrderRepository purchaseOrderRepository;
@Override
@Cacheable(key = "#p0")
public PurchaseOrder findById(Integer id) {
return purchaseOrderRepository.findById(id).orElse(null);
@@ -45,8 +48,7 @@ public class PurchaseOrdersService implements IEntityService<PurchaseOrder> {
return (root, query, builder) -> {
return builder.or(
builder.like(root.get("code"), "%" + searchText + "%"),
builder.like(root.get("description"), "%" + searchText + "%")
);
builder.like(root.get("description"), "%" + searchText + "%"));
};
}
@@ -66,24 +68,21 @@ public class PurchaseOrdersService implements IEntityService<PurchaseOrder> {
* @param order 要保存的实体对象
* @return 返回异步调用
*/
@Caching(
evict = {
@CacheEvict(key = "#p0.id"),
@CacheEvict(key = "'code-'+#p0.code"),
@CacheEvict(key = "'refId-'+#p0.refId")
}
)
@Caching(evict = {
@CacheEvict(key = "#p0.id"),
@CacheEvict(key = "'code-'+#p0.code"),
@CacheEvict(key = "'refId-'+#p0.refId")
})
public PurchaseOrder save(PurchaseOrder order) {
return purchaseOrderRepository.save(order);
}
@Caching(
evict = {
@CacheEvict(key = "#p0.id"),
@CacheEvict(key = "'code-'+#p0.code"),
@CacheEvict(key = "'refId-'+#p0.refId")
}
)
@Caching(evict = {
@CacheEvict(key = "#p0.id"),
@CacheEvict(key = "'code-'+#p0.code"),
@CacheEvict(key = "'refId-'+#p0.refId")
})
@Override
public void delete(PurchaseOrder order) {
purchaseOrderRepository.delete(order);
}
@@ -96,10 +95,21 @@ public class PurchaseOrdersService implements IEntityService<PurchaseOrder> {
return purchaseOrderRepository.count(spec);
}
@Override
public Page<PurchaseOrder> findAll(Specification<PurchaseOrder> spec, Pageable pageable) {
return purchaseOrderRepository.findAll(spec, pageable);
}
@Override
public Page<PurchaseOrder> findAll(JsonNode paramsNode, Pageable pageable) {
Specification<PurchaseOrder> spec = null;
if (paramsNode.has("searchText")) {
spec = getSpecification(paramsNode.get("searchText").asText());
}
spec = SpecificationUtils.andParam(spec, paramsNode, "contract");
return findAll(spec, pageable);
}
public List<PurchaseOrder> findAll(Specification<PurchaseOrder> spec, Sort sort) {
return purchaseOrderRepository.findAll(spec, sort);
}
@@ -112,8 +122,7 @@ public class PurchaseOrdersService implements IEntityService<PurchaseOrder> {
Specification<PurchaseOrder> spec = (root, query, builder) -> {
return builder.or(
builder.like(root.get("name"), "%" + searchText + "%"),
builder.like(root.get("code"), "%" + searchText + "%")
);
builder.like(root.get("code"), "%" + searchText + "%"));
};
return purchaseOrderRepository.findAll(spec, Pageable.ofSize(10)).getContent();
}

View File

@@ -1,25 +1,21 @@
package com.ecep.contract.handler;
import java.io.IOException;
import java.lang.reflect.Type;
import java.nio.ByteBuffer;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import org.apache.poi.ss.formula.functions.T;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.BinaryMessage;
import org.springframework.web.socket.CloseStatus;
@@ -30,6 +26,7 @@ import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;
import com.ecep.contract.IEntityService;
import com.ecep.contract.PageArgument;
import com.ecep.contract.QueryService;
import com.ecep.contract.SpringApp;
import com.ecep.contract.ds.other.service.EmployeeLoginHistoryService;
@@ -146,25 +143,31 @@ public class WebSocketHandler extends TextWebSocketHandler {
logger.info("处理普通消息: " + payload);
}
private boolean handleAsMessageCallback(WebSocketSession session, String payload)
throws JsonProcessingException, IOException {
private boolean handleAsMessageCallback(WebSocketSession session, String payload) {
if (session == null || !session.isOpen()) {
logger.warn("尝试在已关闭的WebSocket会话上处理消息回调");
return false;
}
JsonNode jsonNode = null;
try {
jsonNode = objectMapper.readTree(payload);
} catch (Exception e) {
logger.warn(payload, e);
logger.warn("解析消息回调JSON失败: {}", payload, e);
return false;
}
jsonNode = objectMapper.readTree(payload);
if (!jsonNode.has("messageId")) {
// 没有 messageId 的消息不处理
return false;
}
String messageId = jsonNode.get("messageId").asText();
if (!jsonNode.has("service")) {
sendError(session, messageId, "缺失 service 参数");
return true;
}
String serviceName = jsonNode.get("service").asText();
Object service = null;
try {
@@ -178,6 +181,7 @@ public class WebSocketHandler extends TextWebSocketHandler {
sendError(session, messageId, "缺失 method 参数");
return true;
}
String methodName = jsonNode.get("method").asText();
try {
@@ -194,98 +198,125 @@ public class WebSocketHandler extends TextWebSocketHandler {
sendError(session, messageId, "未实现的方法: " + methodName);
return true;
}
// 再次检查会话状态
if (!session.isOpen()) {
logger.warn("会话已关闭,无法发送处理结果 (消息ID: {})");
return true;
}
ObjectNode objectNode = objectMapper.createObjectNode();
objectNode.put("messageId", messageId);
objectNode.set("data", objectMapper.valueToTree(result));
session.sendMessage(new TextMessage(objectMapper.writeValueAsString(objectNode)));
} catch (BeansException | IOException | NoSuchElementException e) {
sendError(session, messageId, e.getMessage());
String response = objectMapper.writeValueAsString(objectNode);
session.sendMessage(new TextMessage(response));
return true;
} catch (Exception e) {
// 防止重复发送消息导致的TEXT_PARTIAL_WRITING异常
if (!session.isOpen()) {
logger.warn("会话已关闭,无法发送错误消息 (消息ID: {})");
} else {
sendError(session, messageId, e.getMessage());
}
logger.error("处理消息回调失败 (消息ID: {})", messageId, e);
return true;
}
ObjectNode objectNode = objectMapper.createObjectNode();
objectNode.put("messageId", messageId);
objectNode.put("success", false);
objectNode.put("message", "未找到服务: " + serviceName);
session.sendMessage(new TextMessage(objectMapper.writeValueAsString(objectNode)));
return true;
}
private Object invokerDeleteMethod(Object service, JsonNode paramsNode) {
JsonNode param = paramsNode.get(0);
private Object invokerDeleteMethod(Object service, JsonNode argumentsNode) {
JsonNode paramsNode = argumentsNode.get(0);
if (!paramsNode.has("id")) {
throw new IllegalArgumentException("缺失 id 参数");
}
int id = paramsNode.get("id").asInt();
IEntityService<Object> entityService = (IEntityService<Object>) service;
Object entity = entityService.findById(param.get("id").asInt());
Object entity = entityService.findById(id);
if (entity == null) {
throw new NoSuchElementException("未找到实体: " + param.get("id").asInt());
throw new NoSuchElementException("未找到实体: #" + id);
}
entityService.delete(entity);
return entity;
}
private Object invokerSaveMethod(Object service, JsonNode paramsNode) throws JsonMappingException {
JsonNode param = paramsNode.get(0);
private Object invokerSaveMethod(Object service, JsonNode argumentsNode) throws JsonMappingException {
JsonNode paramsNode = argumentsNode.get(0);
IEntityService<Object> entityService = (IEntityService<Object>) service;
Object entity = entityService.findById(param.get("id").asInt());
objectMapper.updateValue(entity, param);
Object entity = null;
if (paramsNode.has("id")) {
int id = paramsNode.get("id").asInt();
entity = entityService.findById(id);
if (entity == null) {
throw new NoSuchElementException("未找到实体: #" + id);
}
} else {
entity = createNewEntity(entityService);
if (entity == null) {
throw new UnsupportedOperationException("无法创建实体对象, " + service.getClass().getName());
}
}
objectMapper.updateValue(entity, paramsNode);
return entityService.save(entity);
}
private Object createNewEntity(IEntityService<Object> entityService) {
try {
Type[] types = getClass().getGenericInterfaces();
// System.out.println("types = " + Arrays.asList(types));
if (types.length > 0) {
String typeName = types[0].getTypeName();
// System.out.println("typeName = " + typeName);
String clz = typeName.split("<")[1].split(">")[0].split(",")[0].trim();
// System.out.println("clz = " + clz);
Class<?> clazz = Class.forName(clz);
return (T) clazz.getDeclaredConstructor().newInstance();
}
} catch (Exception e) {
throw new RuntimeException("无法创建Entity实例", e);
}
return null;
}
/*
* see client QueryService#findById(Integer)
*/
private Object invokerFindByIdMethod(Object service, JsonNode argumentsNode) {
JsonNode paramsNode = argumentsNode.get(0);
Integer id = paramsNode.get(0).asInt();
Integer id = paramsNode.asInt();
IEntityService<?> entityService = (IEntityService<?>) service;
return entityService.findById(id);
}
private Object invokerFindAllMethod(Object service, JsonNode argumentsNode) {
private Object invokerFindAllMethod(Object service, JsonNode argumentsNode) throws JsonProcessingException {
JsonNode paramsNode = argumentsNode.get(0);
JsonNode pageableNode = argumentsNode.get(1);
// 从pageableNode中解析分页参数
int pageNumber = 0;
int pageSize = 10;
Sort sort = Sort.unsorted();
if (pageableNode.has("pageNumber")) {
pageNumber = pageableNode.get("pageNumber").asInt();
}
if (pageableNode.has("pageSize")) {
pageSize = pageableNode.get("pageSize").asInt();
}
// 处理排序信息
if (pageableNode.has("sort")) {
JsonNode sortNode = pageableNode.get("sort");
// 检查是否有排序字段
if (sortNode.has("sorted") && sortNode.get("sorted").asBoolean() && sortNode.has("orders")) {
JsonNode ordersNode = sortNode.get("orders");
if (ordersNode.isArray() && ordersNode.size() > 0) {
List<Sort.Order> orders = new ArrayList<>();
for (JsonNode orderNode : ordersNode) {
if (orderNode.has("property") && orderNode.has("direction")) {
String property = orderNode.get("property").asText();
String direction = orderNode.get("direction").asText();
orders.add(new Sort.Order(Sort.Direction.valueOf(direction.toUpperCase()),
property));
}
}
if (!orders.isEmpty()) {
sort = Sort.by(orders);
}
}
}
}
Pageable pageable = PageRequest.of(pageNumber, pageSize, sort);
PageArgument pageArgument = objectMapper.treeToValue(pageableNode, PageArgument.class);
QueryService<?> entityService = (QueryService<?>) service;
return entityService.findAll(paramsNode, pageable);
return entityService.findAll(paramsNode, pageArgument.toPageable());
}
private void sendError(WebSocketSession session, String messageId, String string)
throws JsonProcessingException, IOException {
ObjectNode objectNode = objectMapper.createObjectNode();
objectNode.put("messageId", messageId);
objectNode.put("success", false);
objectNode.put("message", messageId);
session.sendMessage(new TextMessage(objectMapper.writeValueAsString(objectNode)));
private void sendError(WebSocketSession session, String messageId, String message) {
if (session == null || !session.isOpen()) {
logger.warn("尝试向已关闭的WebSocket会话发送错误消息: {}", message);
return;
}
try {
ObjectNode objectNode = objectMapper.createObjectNode();
objectNode.put("messageId", messageId);
objectNode.put("success", false);
objectNode.put("message", message);
String errorMessage = objectMapper.writeValueAsString(objectNode);
// 检查会话状态并尝试发送错误消息
if (session.isOpen()) {
session.sendMessage(new TextMessage(errorMessage));
} else {
logger.warn("会话已关闭,无法发送错误消息: {}", message);
}
} catch (Exception e) {
// 捕获所有可能的异常,防止影响主流程
logger.error("发送错误消息失败 (会话ID: {})", session.getId(), e);
}
}
@Override

View File

@@ -1,9 +1,11 @@
package com.ecep.contract.util;
import java.util.function.Function;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.util.StringUtils;
import java.util.function.Function;
import com.fasterxml.jackson.databind.JsonNode;
public class SpecificationUtils {
public static <T> Specification<T> and(Specification<T> one, Specification<T> two) {
@@ -37,7 +39,8 @@ public class SpecificationUtils {
* @param <T> 泛型
* @return 搜索条件为空时返回null否则返回一个Specification对象
*/
public static <T> Specification<T> andWith(String searchText, Function<String, Specification<T>> buildSearchSpecification) {
public static <T> Specification<T> andWith(String searchText,
Function<String, Specification<T>> buildSearchSpecification) {
Specification<T> spec = null;
String[] split = null;
do {
@@ -50,4 +53,27 @@ public class SpecificationUtils {
} while (split != null);
return spec;
}
public static <T> Specification<T> andParam(Specification<T> spec, JsonNode paramsNode, String... fields) {
for (String field : fields) {
if (!paramsNode.has(field)) {
continue;
}
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) {
continue;
}
final int id = value;
spec = SpecificationUtils.and(spec, (root, query, builder) -> {
return builder.equal(root.get(field).get("id"), id);
});
}
return spec;
}
}