feat: 实现节假日服务功能并更新项目版本
refactor(CloudRkManagerWindowController): 简化任务初始化逻辑 feat(HolidayService): 添加节假日调整和检查功能 feat(HolidayTable): 实现Voable接口并添加toVo方法 feat(HolidayTableRepository): 添加节假日查询方法 docs: 添加服务器端Service类规则文档 build: 更新项目版本至0.0.101-SNAPSHOT
This commit is contained in:
@@ -21,7 +21,6 @@ import com.ecep.contract.CustomerFileType;
|
||||
import com.ecep.contract.VendorFileType;
|
||||
import com.ecep.contract.SpringApp;
|
||||
import com.ecep.contract.ds.company.CompanyFileUtils;
|
||||
import com.ecep.contract.ds.other.repository.HolidayTableRepository;
|
||||
import com.ecep.contract.ds.company.model.Company;
|
||||
import com.ecep.contract.model.CompanyBasicFile;
|
||||
import com.ecep.contract.ds.customer.model.CompanyCustomerFile;
|
||||
@@ -46,11 +45,11 @@ public abstract class CompanyBasicService {
|
||||
date = date.plusDays(-2);
|
||||
}
|
||||
|
||||
HolidayTableRepository holidayTableRepository = SpringApp.getBean(HolidayTableRepository.class);
|
||||
//TODO 跳过节假日
|
||||
HolidayService holidayTableRepository = SpringApp.getBean(HolidayService.class);
|
||||
// TODO 跳过节假日
|
||||
int tryDays = 15;
|
||||
while (tryDays-- > 0) {
|
||||
HolidayTable holidayTable = holidayTableRepository.findById(date).orElse(null);
|
||||
HolidayTable holidayTable = holidayTableRepository.getById(date);
|
||||
if (holidayTable == null) {
|
||||
// 没有节假日定义,检查是否是工作日
|
||||
DayOfWeek dayOfWeek = date.getDayOfWeek();
|
||||
@@ -78,7 +77,6 @@ public abstract class CompanyBasicService {
|
||||
@Autowired
|
||||
protected CompanyService companyService;
|
||||
|
||||
|
||||
protected boolean isEditableFile(String fileName) {
|
||||
return FileUtils.withExtensions(fileName,
|
||||
FileUtils.XLS, FileUtils.XLSX,
|
||||
@@ -93,7 +91,8 @@ public abstract class CompanyBasicService {
|
||||
|
||||
public abstract <T, F extends CompanyBasicFile<T>, ID> void deleteFile(F file);
|
||||
|
||||
protected <T, F extends CompanyBasicFile<T>, ID> boolean fetchDbFiles(List<F> dbFiles, Map<String, F> map, Consumer<String> status) {
|
||||
protected <T, F extends CompanyBasicFile<T>, ID> boolean fetchDbFiles(List<F> dbFiles, Map<String, F> map,
|
||||
Consumer<String> status) {
|
||||
boolean modified = false;
|
||||
List<File> editFiles = new ArrayList<>();
|
||||
// 排除掉数据库中重复的
|
||||
@@ -166,8 +165,8 @@ public abstract class CompanyBasicService {
|
||||
* @see CompanyCustomerFile
|
||||
* @see CustomerFileType
|
||||
*/
|
||||
protected abstract <T, F extends CompanyBasicFile<T>> boolean fillFileAsDefaultType(F dbFile, File file, Consumer<String> status);
|
||||
|
||||
protected abstract <T, F extends CompanyBasicFile<T>> boolean fillFileAsDefaultType(F dbFile, File file,
|
||||
Consumer<String> status);
|
||||
|
||||
protected void moveFileToCompany(Company company, List<File> needMoveToCompanyPath) {
|
||||
if (needMoveToCompanyPath.isEmpty()) {
|
||||
@@ -219,8 +218,7 @@ public abstract class CompanyBasicService {
|
||||
List<File> needMoveToCompanyPath,
|
||||
List<F> retrieveFiles,
|
||||
Map<String, F> map,
|
||||
Consumer<String> status
|
||||
) {
|
||||
Consumer<String> status) {
|
||||
if (!StringUtils.hasText(path)) {
|
||||
return;
|
||||
}
|
||||
@@ -281,7 +279,8 @@ public abstract class CompanyBasicService {
|
||||
* @param <T> 类型类
|
||||
* @param <F> 文件类
|
||||
*/
|
||||
protected abstract <T, F extends CompanyBasicFile<T>> F fillFileType(File file, List<File> fileList, Consumer<String> status);
|
||||
protected abstract <T, F extends CompanyBasicFile<T>> F fillFileType(File file, List<File> fileList,
|
||||
Consumer<String> status);
|
||||
|
||||
/**
|
||||
* @param customerFile 文件对象
|
||||
@@ -292,7 +291,8 @@ public abstract class CompanyBasicService {
|
||||
* @param <F> 文件类
|
||||
* @return true 有修改
|
||||
*/
|
||||
protected <T, F extends CompanyBasicFile<T>> boolean fillFile(F customerFile, File file, List<File> fileList, Consumer<String> status) {
|
||||
protected <T, F extends CompanyBasicFile<T>> boolean fillFile(F customerFile, File file, List<File> fileList,
|
||||
Consumer<String> status) {
|
||||
String fileName = file.getName();
|
||||
boolean modified = CompanyFileUtils.fillApplyDateAbsent(file, customerFile, F::getSignDate, F::setSignDate);
|
||||
// 评估表
|
||||
@@ -320,7 +320,8 @@ public abstract class CompanyBasicService {
|
||||
* @param <F> 文件类
|
||||
* @return true:文件对象有修改,否则返回false
|
||||
*/
|
||||
protected <T, F extends CompanyBasicFile<T>> boolean fillFileAsEvaluationFile(F customerFile, File file, List<File> fileList, Consumer<String> status) {
|
||||
protected <T, F extends CompanyBasicFile<T>> boolean fillFileAsEvaluationFile(F customerFile, File file,
|
||||
List<File> fileList, Consumer<String> status) {
|
||||
boolean modified = setFileTypeAsEvaluationForm(customerFile);
|
||||
String fileName = file.getName();
|
||||
|
||||
@@ -353,7 +354,8 @@ public abstract class CompanyBasicService {
|
||||
return modified;
|
||||
}
|
||||
|
||||
private <T, F extends CompanyBasicFile<T>> boolean useAsEditableFile(F customerFile, File file, List<File> fileList, Consumer<String> status) {
|
||||
private <T, F extends CompanyBasicFile<T>> boolean useAsEditableFile(F customerFile, File file, List<File> fileList,
|
||||
Consumer<String> status) {
|
||||
if (fileList == null) {
|
||||
return false;
|
||||
}
|
||||
@@ -403,7 +405,8 @@ public abstract class CompanyBasicService {
|
||||
return false;
|
||||
}
|
||||
|
||||
private <T, F extends CompanyBasicFile<T>> boolean useAsArchiveFile(F customerFile, File file, List<File> fileList, Consumer<String> status) {
|
||||
private <T, F extends CompanyBasicFile<T>> boolean useAsArchiveFile(F customerFile, File file, List<File> fileList,
|
||||
Consumer<String> status) {
|
||||
if (fileList == null) {
|
||||
return false;
|
||||
}
|
||||
@@ -449,7 +452,6 @@ public abstract class CompanyBasicService {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 设置文件类型为表单文件
|
||||
*
|
||||
@@ -468,5 +470,4 @@ public abstract class CompanyBasicService {
|
||||
*/
|
||||
protected abstract boolean isEvaluationFile(String fileName);
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,254 @@
|
||||
package com.ecep.contract.ds.company.service;
|
||||
|
||||
import java.time.DayOfWeek;
|
||||
import java.time.LocalDate;
|
||||
import java.time.format.DateTimeParseException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.cache.annotation.CacheConfig;
|
||||
import org.springframework.cache.annotation.Cacheable;
|
||||
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 com.ecep.contract.IEntityService;
|
||||
import com.ecep.contract.QueryService;
|
||||
import com.ecep.contract.ds.other.repository.HolidayTableRepository;
|
||||
import com.ecep.contract.model.HolidayTable;
|
||||
import com.ecep.contract.service.VoableService;
|
||||
import com.ecep.contract.vo.HolidayTableVo;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
|
||||
import jakarta.persistence.criteria.CriteriaBuilder;
|
||||
import jakarta.persistence.criteria.CriteriaQuery;
|
||||
import jakarta.persistence.criteria.Predicate;
|
||||
import jakarta.persistence.criteria.Root;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
/**
|
||||
* 节假日表服务类
|
||||
*
|
||||
* @author System
|
||||
*/
|
||||
@Service
|
||||
@CacheConfig(cacheNames = "HolidayTable")
|
||||
@Slf4j
|
||||
public class HolidayService implements IEntityService<HolidayTable>, QueryService<HolidayTableVo>, VoableService<HolidayTable, HolidayTableVo> {
|
||||
|
||||
@Autowired
|
||||
private HolidayTableRepository holidayTableRepository;
|
||||
|
||||
/**
|
||||
* 调整日期到工作日
|
||||
*
|
||||
* @param date 要调整的日期
|
||||
* @return 调整的日期
|
||||
*/
|
||||
public LocalDate adjustToWorkDay(LocalDate date) {
|
||||
if (date == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
while (date.getDayOfWeek() == DayOfWeek.SATURDAY || date.getDayOfWeek() == DayOfWeek.SUNDAY || isHoliday(date)) {
|
||||
date = date.plusDays(1);
|
||||
}
|
||||
return date;
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查日期是否为节假日
|
||||
*
|
||||
* @param date 日期
|
||||
* @return 是否为节假日
|
||||
*/
|
||||
public boolean isHoliday(LocalDate date) {
|
||||
if (date == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
HolidayTable holidayTable = holidayTableRepository.findById(date).orElse(null);
|
||||
return holidayTable != null && holidayTable.isHoliday();
|
||||
}
|
||||
|
||||
@Override
|
||||
public HolidayTable getById(Integer id) {
|
||||
throw new UnsupportedOperationException("HolidayTable uses LocalDate as ID, please use getById(LocalDate id) method instead");
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据LocalDate类型的ID查询实体
|
||||
* @param id 实体ID
|
||||
* @return 实体对象
|
||||
*/
|
||||
public HolidayTable getById(LocalDate id) {
|
||||
if (id == null) {
|
||||
return null;
|
||||
}
|
||||
return holidayTableRepository.findById(id).orElse(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public HolidayTable save(HolidayTable entity) {
|
||||
if (entity == null) {
|
||||
return null;
|
||||
}
|
||||
return holidayTableRepository.save(entity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void delete(HolidayTable entity) {
|
||||
if (entity != null && entity.getId() != null) {
|
||||
holidayTableRepository.deleteById(entity.getId());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据LocalDate类型的ID删除实体
|
||||
* @param id 实体ID
|
||||
*/
|
||||
public void deleteById(LocalDate id) {
|
||||
if (id != null) {
|
||||
holidayTableRepository.deleteById(id);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取所有节假日
|
||||
* @param pageable 分页参数
|
||||
* @return 分页结果
|
||||
*/
|
||||
public Page<HolidayTable> findAll(Pageable pageable) {
|
||||
return holidayTableRepository.findAll(pageable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Page<HolidayTable> findAll(Specification<HolidayTable> spec, Pageable pageable) {
|
||||
// 由于HolidayTableRepository不支持Specification查询,返回所有节假日
|
||||
return findAll(pageable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Specification<HolidayTable> getSpecification(String searchText) {
|
||||
// 实现根据搜索文本构建规格化查询
|
||||
return (Root<HolidayTable> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) -> {
|
||||
List<Predicate> predicates = new ArrayList<>();
|
||||
|
||||
if (searchText != null && !searchText.trim().isEmpty()) {
|
||||
try {
|
||||
// 尝试将搜索文本解析为日期
|
||||
LocalDate date = LocalDate.parse(searchText.trim());
|
||||
predicates.add(criteriaBuilder.equal(root.get("id"), date));
|
||||
} catch (DateTimeParseException e) {
|
||||
// 如果不是日期格式,尝试其他搜索方式
|
||||
// 由于HolidayTable只有id和holiday字段,这里无法进行其他字段的模糊搜索
|
||||
log.warn("Search text '{}' is not a valid date format", searchText);
|
||||
}
|
||||
}
|
||||
|
||||
return criteriaBuilder.and(predicates.toArray(new Predicate[0]));
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public HolidayTableVo findById(Integer id) {
|
||||
throw new UnsupportedOperationException("HolidayTable uses LocalDate as ID, please use findById(Object id) instead");
|
||||
}
|
||||
|
||||
@Cacheable(key = "#id", unless = "#result == null")
|
||||
public HolidayTableVo findById(LocalDate id) {
|
||||
HolidayTable entity = getById(id);
|
||||
return entity != null ? entity.toVo() : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Page<HolidayTableVo> findAll(JsonNode paramsNode, Pageable pageable) {
|
||||
// 实现根据JSON参数过滤节假日
|
||||
Page<HolidayTable> entityPage;
|
||||
|
||||
if (paramsNode == null || paramsNode.isEmpty()) {
|
||||
// 如果没有参数,返回所有节假日
|
||||
entityPage = findAll(pageable);
|
||||
} else {
|
||||
// 处理参数过滤
|
||||
Boolean isHoliday = null;
|
||||
LocalDate startDate = null;
|
||||
LocalDate endDate = null;
|
||||
|
||||
if (paramsNode.has("isHoliday")) {
|
||||
isHoliday = paramsNode.get("isHoliday").asBoolean();
|
||||
}
|
||||
|
||||
if (paramsNode.has("startDate")) {
|
||||
try {
|
||||
startDate = LocalDate.parse(paramsNode.get("startDate").asText());
|
||||
} catch (Exception e) {
|
||||
log.warn("Failed to parse startDate: {}", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
if (paramsNode.has("endDate")) {
|
||||
try {
|
||||
endDate = LocalDate.parse(paramsNode.get("endDate").asText());
|
||||
} catch (Exception e) {
|
||||
log.warn("Failed to parse endDate: {}", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
// 根据参数组合选择合适的查询方法
|
||||
if (isHoliday != null && startDate != null && endDate != null) {
|
||||
// 组合条件:是否为节假日 + 日期范围
|
||||
entityPage = holidayTableRepository.findByHolidayAndIdBetween(isHoliday, startDate, endDate, pageable);
|
||||
} else if (isHoliday != null) {
|
||||
// 单个条件:是否为节假日
|
||||
entityPage = holidayTableRepository.findByHoliday(isHoliday, pageable);
|
||||
} else if (startDate != null && endDate != null) {
|
||||
// 单个条件:日期范围
|
||||
entityPage = holidayTableRepository.findByIdBetween(startDate, endDate, pageable);
|
||||
} else {
|
||||
// 不满足上述条件,返回所有节假日
|
||||
entityPage = findAll(pageable);
|
||||
}
|
||||
}
|
||||
|
||||
return entityPage.map(HolidayTable::toVo);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long count(JsonNode paramsNode) {
|
||||
// 简单实现,返回所有节假日数量
|
||||
return holidayTableRepository.count();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateByVo(HolidayTable model, HolidayTableVo vo) {
|
||||
if (model == null || vo == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 更新实体属性
|
||||
model.setHoliday(vo.isHoliday());
|
||||
save(model);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建节假日
|
||||
*
|
||||
* @param vo 节假日VO对象
|
||||
* @return 创建后的节假日VO对象
|
||||
*/
|
||||
public HolidayTableVo createByVo(HolidayTableVo vo) {
|
||||
if (vo == null || vo.getId() == null) {
|
||||
throw new IllegalArgumentException("HolidayTableVo or ID cannot be null");
|
||||
}
|
||||
|
||||
HolidayTable entity = new HolidayTable();
|
||||
entity.setId(vo.getId());
|
||||
entity.setHoliday(vo.isHoliday());
|
||||
|
||||
HolidayTable savedEntity = save(entity);
|
||||
return savedEntity.toVo();
|
||||
}
|
||||
}
|
||||
@@ -1,14 +1,47 @@
|
||||
package com.ecep.contract.ds.other.repository;
|
||||
|
||||
import java.time.LocalDate;
|
||||
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.repository.CrudRepository;
|
||||
import org.springframework.data.repository.PagingAndSortingRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import com.ecep.contract.model.HolidayTable;
|
||||
|
||||
import java.time.LocalDate;
|
||||
|
||||
@Repository
|
||||
public interface HolidayTableRepository // curd
|
||||
extends CrudRepository<HolidayTable, LocalDate>, PagingAndSortingRepository<HolidayTable, LocalDate> {
|
||||
public interface HolidayTableRepository // curd
|
||||
extends CrudRepository<HolidayTable, LocalDate>, PagingAndSortingRepository<HolidayTable, LocalDate> {
|
||||
|
||||
/**
|
||||
* 根据是否为节假日过滤
|
||||
*
|
||||
* @param isHoliday 是否为节假日
|
||||
* @param pageable 分页参数
|
||||
* @return 分页结果
|
||||
*/
|
||||
Page<HolidayTable> findByHoliday(boolean isHoliday, Pageable pageable);
|
||||
|
||||
/**
|
||||
* 根据日期范围过滤
|
||||
*
|
||||
* @param startDate 开始日期
|
||||
* @param endDate 结束日期
|
||||
* @param pageable 分页参数
|
||||
* @return 分页结果
|
||||
*/
|
||||
Page<HolidayTable> findByIdBetween(LocalDate startDate, LocalDate endDate, Pageable pageable);
|
||||
|
||||
/**
|
||||
* 根据是否为节假日和日期范围组合过滤
|
||||
*
|
||||
* @param isHoliday 是否为节假日
|
||||
* @param startDate 开始日期
|
||||
* @param endDate 结束日期
|
||||
* @param pageable 分页参数
|
||||
* @return 分页结果
|
||||
*/
|
||||
Page<HolidayTable> findByHolidayAndIdBetween(boolean isHoliday, LocalDate startDate, LocalDate endDate,
|
||||
Pageable pageable);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user