由于要做一个自动打卡的功能,需要用到判断是否是节假日,如果是节假日则需要跳过打卡,如果不是节假日或者需要补班则需要打卡。网上没有找到好用的方法和jar包,这里分享一下自己使用的代码。
1、新建节假日表
CREATE TABLE `sys_holidays` (
`date` varchar(10) NOT NULL COMMENT '日期,作为主键,存储具体的法定节假日及补班日期,格式为 "YYYY-MM-DD"',
`year` varchar(4) NOT NULL COMMENT '年份',
`holiday_name` varchar(50) NOT NULL COMMENT '节假日名称,用于标识对应的节假日',
`is_holiday` tinyint(1) NOT NULL COMMENT '是否为法定节假日,使用布尔值(0或1)表示,0表示非节假日,1表示是节假日',
`is_workday` tinyint(1) NOT NULL COMMENT '是否为补班日期,使用布尔值(0或1)表示,0表示非补班日期,1表示是补班日期',
`description` varchar(255) DEFAULT NULL COMMENT '描述,可用于提供关于该日期的额外信息',
PRIMARY KEY (`date`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
2、新建对应实体类
import java.io.Serializable;
public class SysHolidays implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 日期
*/
private String date;
/**
* 年份
*/
private String year;
/**
* 节假日名称
*/
private String holidayName;
/**
* 是否节假日
*/
private int isHoliday;
/**
* 是否补班日
*/
private int isWorkDay;
/**
* 描述信息
*/
private String description;
public SysHolidays() {
}
public SysHolidays(String date, String year, String holidayName, int isHoliday, int isWorkDay, String description) {
this.date = date;
this.year = year;
this.holidayName = holidayName;
this.isHoliday = isHoliday;
this.isWorkDay = isWorkDay;
this.description = description;
}
public String getDate() {
return date;
}
public void setDate(String date) {
this.date = date;
}
public String getYear() {
return year;
}
public void setYear(String year) {
this.year = year;
}
public String getHolidayName() {
return holidayName;
}
public void setHolidayName(String holidayName) {
this.holidayName = holidayName;
}
public int getIsHoliday() {
return isHoliday;
}
public void setIsHoliday(int isHoliday) {
this.isHoliday = isHoliday;
}
public int getIsWorkDay() {
return isWorkDay;
}
public void setIsWorkDay(int isWorkDay) {
this.isWorkDay = isWorkDay;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
}
3、新建对应mapper
public interface SysHolidaysMapper
{
SysHolidays queryByNowDate();
int insertAll(@Param("holidays") List<SysHolidays> holidays);
int deleteByYear(@Param("year") String year);
}
4、新建对应mapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.job.mapper.SysHolidaysMapper">
<resultMap type="com.ruoyi.job.domain.SysHolidays" id="SysHolidaysResult">
<id property="date" column="date"/>
<result property="year" column="year"/>
<result property="holidayName" column="holiday_name"/>
<result property="isHoliday" column="is_holiday"/>
<result property="isWorkDay" column="is_workday"/>
<result property="description" column="description"/>
</resultMap>
<insert id="insertAll">
INSERT INTO `sys_holidays` (`date`, `year`, `holiday_name`, `is_holiday`, `is_workday`, `description`)
VALUES
<foreach collection="holidays" item="item" separator=",">
(#{item.date}, #{item.year}, #{item.holidayName}, #{item.isHoliday}, #{item.isWorkDay}, #{item.description})
</foreach>
</insert>
<delete id="deleteByYear">
DELETE from sys_holidays where YEAR = #{year}
</delete>
<select id="queryByNowDate" resultMap="SysHolidaysResult">
SELECT date, year, holiday_name, is_holiday, is_workday, description
from sys_holidays
where date = CURDATE()
</select>
</mapper>
5、新增节假日service
public interface ISysHolidaysService
{
SysHolidays queryByNowDate();
int insertAll(List<SysHolidays> holidays);
int deleteByYear(String year);
String saveHolidays(String year);
Boolean isHoliday();
}
6、新增节假日service实现
@Service
public class ISysHolidaysServiceImpl implements ISysHolidaysService {
@Autowired
private SysHolidaysMapper sysHolidaysMapper;
@Override
public SysHolidays queryByNowDate() {
return sysHolidaysMapper.queryByNowDate();
}
@Override
public int insertAll(List<SysHolidays> holidays) {
return sysHolidaysMapper.insertAll(holidays);
}
@Override
public int deleteByYear(String year) {
return sysHolidaysMapper.deleteByYear(year);
}
@Transactional
@Override
public String saveHolidays(String year) {
List<SysHolidays> sysHolidayList = getSysHolidays(year);
if (!sysHolidayList.isEmpty()) {
try {
int deleteRow = deleteByYear(year);
int insertRow = insertAll(sysHolidayList);
return String.format("更新节假日数据成功,本次共删除数据:%d行,新增数据:%d行", deleteRow, insertRow);
} catch (Exception e) {
throw new RuntimeException("更新节假日数据失败", e);
}
}
return "本次操作未更新数据";
}
@Override
public Boolean isHoliday() {
// 判断是否是节假日或者补班
SysHolidays sysHolidays = queryByNowDate();
if (sysHolidays != null ) {
if (sysHolidays.getIsHoliday() == 1) {
return true;
}
if (sysHolidays.getIsWorkDay() == 1) {
return false;
}
}
// 不是节假日,则判断是否为周末,不是周末即为工作日
LocalDate now = LocalDate.now();
DayOfWeek dayOfWeek = now.getDayOfWeek();
return dayOfWeek == DayOfWeek.SATURDAY || dayOfWeek == DayOfWeek.SUNDAY;
}
private List<SysHolidays> getSysHolidays(String year) {
WebClient build = WebClient.builder().baseUrl("https://timor.tech/api/holiday/year/").build();
Mono<String> responseMono = build.get()
.uri(year)
.retrieve()
.bodyToMono(String.class);
String block = responseMono.block();
JSONObject parse = JSONObject.parse(block);
JSONObject holiday = parse.getJSONObject("holiday");
return holiday.keySet().stream()
.map(key -> {
JSONObject jsonObject = holiday.getJSONObject(key);
String date = jsonObject.getString("date");
String name = jsonObject.getString("name");
boolean isHoliday = jsonObject.getBoolean("holiday");
return new SysHolidays(date, year, name, isHoliday ? 1 : 0, isHoliday ? 0 : 1, name);
})
.collect(Collectors.toList());
}
}
7、新增controller接口用于更新每年节假日数据
每年11月份-12月份左右国务院会发布明年的法定节假日及补班日,我们需要调用第三方接口存入到我们的数据库中以便明年使用。如果第三方接口无法使用可自行根据国务院发布的文档自行编写insert语句插入数据到表格中,不使用接口的方式更新。
@RestController
@RequestMapping("/holiday")
public class HolidayController extends BaseController {
@Autowired
private ISysHolidaysService iSysHolidaysService;
@GetMapping("/save/{year}")
public String saveHolidays(@PathVariable String year) {
return iSysHolidaysService.saveHolidays(year);
}
}