SpringBoot拉取日历数据
一、前言
万年历API:https://www.mxnzp.com/doc/detail?id=1
二、代码如下
- 按年生成日历数据
- 国家一般当年10月底发布下一年度的节假日安排
package com.qiangesoft.calendar.mxnzp;import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.qiangesoft.calendar.entity.CalendarConfig;
import com.qiangesoft.calendar.service.CalendarConfigService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAdjusters;
import java.util.ArrayList;
import java.util.List;/*** 日历数据生成 定时器执行者** @author qiangesoft* @date 2023-09-29*/
@Slf4j
@Component
public class CalendarTask {@Autowiredprivate CalendarConfigService calendarConfigService;/*** 规则可设置为每日或者每月执行一次*/@Scheduled(cron = "0 0 10 * * ?")public void action() {log.info("Create calendar data start======================>");// 生成未来五年的数据LocalDate thisYearFirstDay = LocalDate.now().with(TemporalAdjusters.firstDayOfYear());for (int i = 0; i < 5; i++) {LocalDate localDate = thisYearFirstDay.plusYears(i);this.doCreate(localDate);}log.info("Create calendar data finish<======================");}/*** 日历数据生成** @param firstDay*/private void doCreate(LocalDate firstDay) {int year = firstDay.getYear();log.info("Create {}year calendar data start!", year);LambdaQueryWrapper<CalendarConfig> queryWrapper = new LambdaQueryWrapper<>();queryWrapper.eq(CalendarConfig::getYear, year);long count = calendarConfigService.count(queryWrapper);if (count > 0) {log.info("Calendar data already created, do nothing!");return;}LocalDate lastDay = firstDay.plusYears(1);List<CalendarConfig> calendarConfigList = new ArrayList<>();LocalDate localDate = firstDay;while (lastDay.isAfter(localDate)) {CalendarConfig calendarConfig = new CalendarConfig();calendarConfig.setYear(year);calendarConfig.setMonth(localDate.getMonthValue());calendarConfig.setDate(localDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));int week = localDate.getDayOfWeek().getValue();calendarConfig.setWeekDay(week);if (week == 6 || week == 7) {calendarConfig.setType("1");} else {calendarConfig.setType("0");}calendarConfigList.add(calendarConfig);localDate = localDate.plusDays(1);}calendarConfigService.saveBatch(calendarConfigList);log.info("Create {}year calendar data finish!", year);}
}
package com.qiangesoft.calendar.mxnzp;import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.qiangesoft.calendar.entity.CalendarConfig;
import com.qiangesoft.calendar.mxnzp.model.CalendarConfigDTO;
import com.qiangesoft.calendar.mxnzp.model.MxnzpCalendarDTO;
import com.qiangesoft.calendar.mxnzp.model.MxnzpResponseData;
import com.qiangesoft.calendar.service.CalendarConfigService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.web.client.RestTemplate;import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;/*** mxnpz数据拉取 定时器执行者** @author qiangesoft* @date 2023-09-29*/
@Slf4j
@Component
public class MxnzpCalendarTask {private static String URL = "https://www.mxnzp.com/api/holiday/list/year/%d?ignoreHoliday=false&app_id=tldkn1hkkoofques&app_secret=kV9qgeRJ5baZworKApsWVbHS3hNxndYZ";@Autowiredprivate RestTemplate restTemplate;@Autowiredprivate CalendarConfigService calendarConfigService;/*** 国家一般当年10月底发布下一年度的节假日安排*/@Scheduled(cron = "0 0 10 * * ?")public void action() {LocalDate today = LocalDate.now();// 从11月开始拉取下一年的数据int year = today.getYear();if (today.getMonthValue() > 10) {year = year + 1;}log.info("Mxnzp data pull {}year start======================>", year);LambdaQueryWrapper<CalendarConfig> countQueryWrapper = new LambdaQueryWrapper<>();countQueryWrapper.eq(CalendarConfig::getYear, year).eq(CalendarConfig::getPullFlag, true);long count = calendarConfigService.count(countQueryWrapper);if (count > 0) {log.info("Mxnzp data already update, do nothing!");return;}ResponseEntity<MxnzpResponseData> responseEntity = restTemplate.getForEntity(String.format(URL, year), MxnzpResponseData.class);HttpStatus statusCode = responseEntity.getStatusCode();if (!HttpStatus.OK.equals(statusCode)) {log.info("Mxnzp data pull fail!");return;}MxnzpResponseData responseData = responseEntity.getBody();if (!responseData.getCode().equals(1)) {log.info("Mxnzp data pull fail!");return;}List<MxnzpCalendarDTO> data = responseData.getData();if (CollectionUtils.isEmpty(data)) {log.info("Mxnzp data pull is empty!");return;}LambdaQueryWrapper<CalendarConfig> queryWrapper = new LambdaQueryWrapper<>();queryWrapper.eq(CalendarConfig::getYear, year);List<CalendarConfig> calendarConfigList = calendarConfigService.list(queryWrapper);Map<String, CalendarConfig> configMap = calendarConfigList.stream().collect(Collectors.toMap(CalendarConfig::getDate, calendarConfig -> calendarConfig));List<CalendarConfig> newConfigList = new ArrayList<>();List<CalendarConfig> updateConfigList = new ArrayList<>();for (MxnzpCalendarDTO monthData : data) {List<CalendarConfigDTO> days = monthData.getDays();for (CalendarConfigDTO day : days) {CalendarConfig calendarConfig = configMap.get(day.getDate());if (calendarConfig == null) {calendarConfig = new CalendarConfig();calendarConfig.setYear(monthData.getYear());calendarConfig.setMonth(monthData.getMonth());calendarConfig.setDate(day.getDate());calendarConfig.setType(day.getType());calendarConfig.setTypeDes(day.getTypeDes());calendarConfig.setWeekDay(day.getWeekDay());calendarConfig.setDayOfYear(day.getDayOfYear());calendarConfig.setWeekOfYear(day.getWeekOfYear());calendarConfig.setIndexWorkDayOfMonth(day.getIndexWorkDayOfMonth());calendarConfig.setLunarCalendar(day.getLunarCalendar());calendarConfig.setSolarTerms(day.getSolarTerms());calendarConfig.setYearTips(day.getYearTips());calendarConfig.setChineseZodiac(day.getChineseZodiac());calendarConfig.setConstellation(day.getConstellation());calendarConfig.setSuit(day.getSuit());calendarConfig.setAvoid(day.getAvoid());calendarConfig.setPullFlag(true);newConfigList.add(calendarConfig);} else {calendarConfig.setType(day.getType());calendarConfig.setTypeDes(day.getTypeDes());calendarConfig.setWeekDay(day.getWeekDay());calendarConfig.setDayOfYear(day.getDayOfYear());calendarConfig.setWeekOfYear(day.getWeekOfYear());calendarConfig.setIndexWorkDayOfMonth(day.getIndexWorkDayOfMonth());calendarConfig.setLunarCalendar(day.getLunarCalendar());calendarConfig.setSolarTerms(day.getSolarTerms());calendarConfig.setYearTips(day.getYearTips());calendarConfig.setChineseZodiac(day.getChineseZodiac());calendarConfig.setConstellation(day.getConstellation());calendarConfig.setSuit(day.getSuit());calendarConfig.setAvoid(day.getAvoid());calendarConfig.setPullFlag(true);updateConfigList.add(calendarConfig);}}}if (!CollectionUtils.isEmpty(newConfigList)) {calendarConfigService.saveBatch(newConfigList);}if (!CollectionUtils.isEmpty(updateConfigList)) {calendarConfigService.updateBatchById(updateConfigList);}log.info("Mxnzp data {}year updated<========================", year);}
}
package com.qiangesoft.calendar.entity;import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;import java.util.Date;/*** 日历配置** @author qiangesoft* @date 2023-10-19 22:28:02*/
@Data
@TableName("calendar_config")
public class CalendarConfig {/*** id*/@TableId(type = IdType.ASSIGN_ID)private Long id;/*** 年份*/private Integer year;/*** 月份*/private Integer month;/*** 日期*/private String date;/*** 类型*/private String type;/*** 类型描述*/private String typeDes;/*** 本周第几天*/private Integer weekDay;/*** 年中第几天*/private Integer dayOfYear;/*** 年中第几周*/private Integer weekOfYear;/*** 当月的第几个工作日*/private Integer indexWorkDayOfMonth;/*** 农历日期*/private String lunarCalendar;/*** 节气描述*/private String solarTerms;/*** 天干地支纪年法*/private String yearTips;/*** 属相*/private String chineseZodiac;/*** 星座*/private String constellation;/*** 宜事项*/private String suit;/*** 忌事项*/private String avoid;/*** 是否拉取日历数据*/private Boolean pullFlag;/*** 创建时间*/@TableField(fill = FieldFill.INSERT)private Date createBy;/*** 创建人*/@TableField(fill = FieldFill.INSERT)private Long createUser;/*** 更新时间*/@TableField(fill = FieldFill.UPDATE)private Date updateTime;/*** 更新人*/@TableField(fill = FieldFill.UPDATE)private Long updateBy;
}
三、源码地址
源码地址:https://gitee.com/qiangesoft/boot-business/tree/master/boot-business-calendar