SpringBoot拉取日历数据

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/661643.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

LEETCODE 170. 交易逆序对的总数

class Solution { public:int reversePairs(vector<int>& record) {if(record.size()<1)return 0;//归并 递归int left,right;left0;rightrecord.size()-1;int nummergeSort(left,right,record);return num;}int mergeSort(int left,int right, vector<int>…

Tomcat -- catalina.bat

Tomcat – catalina.bat 配置 1. 手动分配内存&#xff0c;防溢出 # 位置&#xff1a;..\Tomcat\bin\catalina.bat&#xff1b; # echo off 下面添加&#xff08;第二行&#xff09;&#xff1a; set JAVA_OPTS-server -Xms2048m -Xmx2048m -Xss512k -XX:NewSize256m -XX:Max…

【Qt】Json在Qt中的使用

Json JSON&#xff08;JavaScript Object Notation&#xff09;是一种轻量级的数据交换格式&#xff0c;广泛用于互联网应用程序之间的数据传输。JSON基于JavaScript中的对象语法&#xff0c;但它是独立于语言的&#xff0c;因此在许多编程语言中都有对JSON的解析和生成支持。…

STM32CubeIDE 使用标准库来编写程序

这些天我想找一个软件来实现软件的替代。就找到了st 的生态。可是现在st 生态都在极力的推荐HAL 库,但是习惯了标准库的朋友们,还不是很习惯。 先上总结一下,为了好记忆: 一、 在编译栏做如下设置 1、头文件设置 2、源文件设置 二、指定具体的预定义宏 1、USE_STDPERIPH_D…

数据结构-图的最小生成树

最小生成树介绍 最小生成树(Minimum Cost Spanning Tree)是代价最小的连通网的生成树&#xff0c;即该生成树上的边的权值和最小 最小生成树的性质&#xff1a; 必须使用且仅使用连通网中的n-1条边来联结网络中的n个顶点&#xff1b; 不能使用产生回路的边&#xff1b; 各…

Linux部署幻兽帕鲁服务器,PalWorld开服联机教程,保姆级教程

------另一个号申请积分-------- Linux系统搭建PalWorld私服&#xff0c;幻兽帕鲁开服联机教程&#xff0c;保姆级教程 最近这游戏挺火&#xff0c;很多人想跟朋友联机&#xff0c;如果有专用服务器&#xff0c;就不需要房主一直开着电脑&#xff0c;稳定性也好得多。 幻兽帕…

Kubernetes operator(五)api 和 apimachinery 篇

云原生学习路线导航页&#xff08;持续更新中&#xff09; 本文是 Kubernetes operator学习 系列第五篇&#xff0c;主要对 k8s.io/api 和 k8s.io/apimachinery 两个项目 进行学习基于 kubernetes v1.24.0 代码分析Kubernetes operator学习系列 快捷链接 Kubernetes operator&a…

大数据StarRocks(九):资源隔离实战

前言 自 2.2 版本起&#xff0c;StarRocks 支持资源组管理&#xff0c;集群可以通过设置资源组&#xff08;Resource Group&#xff09;的方式限制查询对资源的消耗&#xff0c;实现多租户之间的资源隔离与合理利用。在 2.3 版本中&#xff0c;StarRocks 支持限制大查询&#…

Android配置GitLab CI/CD持续集成,Shell版本的gitlab-runner,FastLane执行,上传蒲公英

mac环境下&#xff0c; 首选需要安装gitlab-runner和fastlane brew install gitlab-runner brew install fastlane 安装完成&#xff0c;来到我们在gitlab下新建的Android项目&#xff0c;我们开始创建gitlab-runner 1、创建runner 点开runner&#xff0c;点击新建runner …

自然语言nlp学习四

5-5 BMTrain--ZeRO_哔哩哔哩_bilibili 5-6 BMTrain--Pipeline Parallel (流水线并行)_哔哩哔哩_bilibili 5-12 BMCook--背景介绍_哔哩哔哩_bilibili 5-20 BMInf--背景介绍_哔哩哔哩_bilibili 6-7 机器问答--QA介绍_哔哩哔哩_bilibili 6-8 机器问答--阅读理解_哔哩哔哩_bilibili…

常用API1 ---Math

包含用于执行基本数学运算的方法&#xff0c;如初等指数、对数、平方根和三角函数。 常用方法&#xff1a; package MyApi.a01mathdemo01;public class MathDemo01 {public static void main(String[] args) {//abs 获取参数的绝对值System.out.println(Math.abs(-88));System…

C++——new关键字

C——new关键字 介绍 在C中&#xff0c; new 关键字用于动态分配内存。它是C中处理动态内存分配的主要工具之一&#xff0c;允许在程序运行时根据需要分配内存。 基本用法 分配单个对象&#xff1a;使用 new 可以在堆上动态分配一个对象。例如&#xff0c; new int 会分配一…

江科大stm32学习笔记10——对射式红外传感器

一、接线 上电之后可以看到对射式红外传感器亮两个灯&#xff0c;如果此时用挡光片挡住两个黑色方块中间的部分&#xff0c;则只亮一个灯。 二、代码 将4-1的工程文件夹复制粘贴一份&#xff0c;重命名为“5-1 对射式红外传感器计次”&#xff0c;打开keil&#xff0c;右键添…

ChatGLM-6B在法律数据集上微调

目录 数据集 训练和推理 依赖 训练 推理 数据集 数据集&#xff1a;lawzhidao_filter.csv &#xff08;工作台 - Heywhale.com&#xff09; 处理&#xff1a; 1&#xff09;筛选is_best1的行&#xff0c;删除reply为空的行&#xff0c;在title和question中选择描述长的…

C++面试:数据库不同存储引擎的区别以及如何选择

目录 基础 具体选择原则 Mysql如何选择 创建表时指定存储引擎 修改现有表的存储引擎 查看表的存储引擎 注意事项 总结 在数据库管理系统中&#xff0c;不同的存储引擎提供了不同的存储机制、索引技术、锁定水平和其他功能。以MySQL为例&#xff0c;它支持多种存储引擎&…

认识 SYN Flood 攻击

文章目录 1.什么是 SYN Flood 攻击&#xff1f;2.半连接与全连接队列3.如何防范 SYN Flood 攻击&#xff1f;参考文献 1.什么是 SYN Flood 攻击&#xff1f; SYN Flood 是互联网上最原始、最经典的 DDoS&#xff08;Distributed Denial of Service&#xff09;攻击之一。 SYN…

【PyRestTest】进行Benchmarking测试

PyRestTest支持通过Curl请求本身收集比较差的网络环境下的性能指标。 基准测试&#xff1a;它们扩展了测试中的配置元素&#xff0c;允许你进行相似的REST调用配置。然而&#xff0c;它们不对HTTP响应情况进行验证&#xff0c;它只收集指标数据。 下列选项被指定用于benchmar…

[C#][opencvsharp]opencvsharp sift和surf特征点匹配

SIFT特征和SURF特征比较 SIFT特征基本介绍 SIFT(Scale-Invariant Feature Transform)特征检测关键特征&#xff1a; 建立尺度空间&#xff0c;寻找极值关键点定位&#xff08;寻找关键点准确位置与删除弱边缘&#xff09;关键点方向指定关键点描述子 建立尺度空间&#xff0…

SpringBoot RestTemplate 设置挡板

项目结构 代码 BaffleConfig /*** Description 记录配置信息* Author wjx* Date 2024/2/1 14:47**/ public interface BaffleConfig {// 是否开启挡板的开关public static boolean SWITCH true;// 文件根目录public static String ROOT_PATH "D:\\TIS\\mock";// …

最新2024如何解决谷歌浏览器Chrome谷歌翻译无法使用问题

快速恢复谷歌浏览器一键翻译功能在Chrome 中安装好【翻译】插件 Macbook 操作步骤&#xff1a; 1点击“前往”&#xff0c;打开“前往文件夹” 2 在对话框中输入“/etc” 囝找到“hosts”文件&#xff0c;复制粘贴到桌面 3 在复制的文件最后新起一行&#xff0c;输入并保存&am…