目录
1.日历页面
2.工作日查询、自然日查询 js
3.修改工作日配置
4.数据库,表结构
5.初始化数据
因系统需要,需要制作一个功能--工作日配置。
需要的业务有:
1.初始化与国家放假情况一致,之后支持手动进行工作日配置;
2.展示12个月的放假/工作日情况;
3.一些特殊的日期,如调休、春节等需要进行展示。
页面展示:
修改页面:
1.日历页面
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head th:include="include/header_css::header('工作日维护')"></head>
<style type="text/css">
.calendar-box * {margin: 0;padding: 0;box-sizing: border-box;
}
.calendar-box {border: 1px solid #d2d2d2;box-shadow: 0 2px 4px rgba(0,0,0,.12);background-color: #fff;color: #666;position: relative;z-index: 0;display: inline-block;width: 272px;border-radius: 2px;font-size: 14px;
}
.calendar-content {position: relative;padding: 10px;-moz-user-select: none;-webkit-user-select: none;-ms-user-select: none;
}
.calendar-content table {border-collapse: collapse;border-spacing: 0;
}
.calendar-content th, .calendar-content td {border: 1px solid #d3d3d3;width: 36px;height: 30px;padding: 5px;text-align: center;
}
.calendar-content th {font-weight: 400;color: #333;
}
.calendar-content td {position: relative;cursor: pointer;transition-duration: .3s;-webkit-transition-duration: .3s;
}
.calendar-content td:hover {background-color: #eaeaea;color: #333;
}
.calendar-content .calendar-day-mark-td {height: 33px;
}
.calendar-day-mark {position: absolute;left: 0;top: 0;width: 100%;height: 100%;line-height: 33px;font-size: 12px;overflow: hidden;
}
.calendar-content .weekend {color: red;
}
.calendar-disabled {background: 0 0!important;cursor: not-allowed !important;-moz-user-select: none;-webkit-user-select: none;-ms-user-select: none;
}
.calendar-workday {color: white;background-color: #080101;
}
.calendar-workday:hover {background-color: #080101b3;
}
.calendar-holiday {color: white;background-color: #f08a8a;
}
.calendar-holiday:hover {background-color: #f08a8aab;
}
</style>
<body>
<div id="dpLTE"><div class="row form-row"><div class="col-md-2 text-center text-muted"></div><div class="col-md-3 text-right text-muted">请选择年份:</div><div class="col-md-3 text-center text-muted"><select class="form-control" id="yearSelect"> </select></div><div class="col-md-4 text-center text-muted"><a onclick="initDataByYear()" class="btn btn-default"><i class="fa fa-refresh"></i> 初始工作日数据</a></div></div><div class="row"><div class="col-md-3 text-center text-muted">一月</div><div class="col-md-3 text-center text-muted">二月</div><div class="col-md-3 text-center text-muted">三月</div><div class="col-md-3 text-center text-muted">四月</div></div><div class="row"><div class="col-md-3 text-center text-muted"><div id="month1"></div></div><div class="col-md-3 text-center text-muted"><div id="month2"></div></div><div class="col-md-3 text-center text-muted"><div id="month3"></div></div><div class="col-md-3 text-center text-muted"><div id="month4"></div></div></div><div class="row"><div class="col-md-3 text-center text-muted">五月</div><div class="col-md-3 text-center text-muted">六月</div><div class="col-md-3 text-center text-muted">七月</div><div class="col-md-3 text-center text-muted">八月</div></div><div class="row"><div class="col-md-3 text-center text-muted"><div id="month5"></div></div><div class="col-md-3 text-center text-muted"><div id="month6"></div></div><div class="col-md-3 text-center text-muted"><div id="month7"></div></div><div class="col-md-3 text-center text-muted"><div id="month8"></div></div></div><div class="row"><div class="col-md-3 text-center text-muted">九月</div><div class="col-md-3 text-center text-muted">十月</div><div class="col-md-3 text-center text-muted">十一月</div><div class="col-md-3 text-center text-muted">十二月</div></div><div class="row"><div class="col-md-3 text-center text-muted"><div id="month9"></div></div><div class="col-md-3 text-center text-muted"><div id="month10"></div></div><div class="col-md-3 text-center text-muted"><div id="month11"></div></div><div class="col-md-3 text-center text-muted"><div id="month12"></div></div></div><div class="row form-row" style="margin-top: 50px;"><div class="col-md-12 text-center text-muted">工作日查询</div></div><div class="row form-row"><div class="col-md-2 text-right text-muted">请选择日期:</div><div class="col-md-2 text-center text-muted"><input class="form-control" id="dateSelect" type="text"/></div><div class="col-md-2 text-right text-muted">请输入工作日偏移天数:</div><div class="col-md-2 text-right text-muted"><input class="form-control" id="days" type="number"/></div><div class="col-md-1 text-left text-muted"><a href="javascript:inputChange();" class="btn btn-primary">查询</a></div><div class="col-md-2 text-right text-muted"><input class="form-control" id="result" type="text" readonly="readonly"/></div></div><div class="row form-row" style="margin-top: 50px;"><div class="col-md-12 text-center text-muted">自然日查询</div></div><div class="row form-row"><div class="col-md-2 text-right text-muted">请选择日期:</div><div class="col-md-2 text-center text-muted"><input class="form-control" id="natureDateSelect" type="text"/></div><div class="col-md-2 text-right text-muted">请输入自然日偏移天数:</div><div class="col-md-2 text-right text-muted"><input class="form-control" id="natureDays" type="number"/></div><div class="col-md-1 text-left text-muted"><a href="javascript:natureInputChange();" class="btn btn-primary">查询</a></div><div class="col-md-2 text-right text-muted"><input class="form-control" id="natureResult" type="text" readonly="readonly"/></div></div><div class="row" style="margin-top: 50px;"></div>
</div><div th:include="include/footer_js::footer"></div><script type="text/javascript">$(function() {var year = formatDate(new Date(), 'yyyy');var data = {};var nextYear = year * 1 + 1;//下拉框范围:从2024年开始,到当前年份+1for (var i = 2024; i <= nextYear; i++) {data[i] = i;}// 初始化系统参数,选择年$('#yearSelect').selectBindEx({data: data,placeholder: '请选择年份',value: 'stringValue',text: 'name',allowClear: false,selected: [year],change: function (data) {initByYear(data);}});initByYear(year);laydate.render({elem: '#dateSelect',trigger: 'click',position: 'fixed',type: 'date',value: new Date(),format: 'yyyy-MM-dd'});laydate.render({elem: '#natureDateSelect',trigger: 'click',position: 'fixed',type: 'date',value: new Date(),format: 'yyyy-MM-dd'});});function initByYear(year) {var markDayData = [];$.SetForm({url: '../../system/workDay/listByYear?year=' + year + '&_=' + $.now(),param: {},async: false,success: function (data) {markDayData = data;}});// 月份for(var i = 1; i <= 12; i++) {// 渲染月份html结构renderMonthHtml(i);// 表格中显示日期showCalendarData(year, i, markDayData);}}/*** 渲染月份html结构*/function renderMonthHtml(month) {var calendar = $('#month' + month);calendar.empty();// 设置表格区的html结构var _theadHtml = '<thead>' +'<tr>' +'<th class="weekend">日</th>' +'<th>一</th>' +'<th>二</th>' +'<th>三</th>' +'<th>四</th>' +'<th>五</th>' +'<th class="weekend">六</th>' +'</tr>' +'</thead>';// 一个月最多31天,所以一个月最多占6行表格var _tbodyHtml = '<tbody>';for(var i = 0; i < 6; i++) {_tbodyHtml += '<tr>' +'<td></td>' +'<td></td>' +'<td></td>' +'<td></td>' +'<td></td>' +'<td></td>' +'<td></td>' +'</tr>';}_tbodyHtml += '</tbody>';// 表格divvar _boxHtml = '<div class="calendar-box">' +'<div class="calendar-content">' +'<table>' +_theadHtml +_tbodyHtml +'</table>' +'</div>' +'</div>';// 添加到节点中calendar.html(_boxHtml);}/*** 表格中显示数据,并设置类名*/function showCalendarData(year, month, markDayData) {// 设置表格中的日期数据var _table = $('#month' + month + ' table');var _tds = _table.find("td");var _firstDate = new Date(year, month - 1, 1); // 当前月第一天for(var i = 0; i < _tds.length; i++) {var _td = $(_tds[i]);var _markHtml = '<span> </span>';// 日期编号// < 0,代表是上个月的日期// > 0,代表是这个月的日期// > 31,代表是下个月的日期,如1月有31天,超过31号的,是下个月2月var dayNumber = i + 1 - _firstDate.getDay();var _thisDate = new Date(year, month - 1, dayNumber); // 当前日期var _thisDateStr = formatDate(_thisDate, 'yyyy-MM-dd'); // 格式化,年月日var day = _thisDate.getDate(); // 当前日期,几号// 不可点击(默认)_td.addClass("calendar-disabled");_td.html(_markHtml);// 只显示当前月if (_thisDate.getMonth() == month - 1) {_markHtml = '<span>' + day + '</span>';_td.html(_markHtml);_td.removeClass("calendar-disabled"); //可点击_td.attr('id', _thisDateStr); // id,年月日_td.attr('title', _thisDateStr);_td.attr('year', year); // 年_td.attr('month', month); // 月_td.attr('day', day); // 日_td.attr('onclick', 'editDay(this)');// 特殊日期for (var j = 0; j < markDayData.length; j++) {var mItem = markDayData[j];var mdate = mItem.year + '-' + mItem.month + '-' + mItem.day;// 日期一致if (_thisDateStr == mdate) {_td.addClass("calendar-day-mark-td");// 存在特殊日期名称if (mItem.name) {if (mItem.type == 1) {// 工作日_markHtml = '<span class="calendar-day-mark calendar-workday">' + mItem.name + '</span>';_td.html(_markHtml);} else if (mItem.type == 2) {// 节假日_markHtml = '<span class="calendar-day-mark calendar-holiday">' + mItem.name + '</span>';_td.html(_markHtml);}}break;}}}}}function editDay(obj) {var id = $(obj).attr('id');var year = $(obj).attr('year');dialogOpen({title: '修改工作日配置',url: 'system/workDay/workDayEdit.html?_' + $.now(),width: '600px',height: '400px',scroll : true,success: function(iframeId){top.frames[iframeId].vm.workDay.id = id;top.frames[iframeId].vm.setForm();},yes : function(iframeId) {// 子页面传值到父页面var result = top.frames[iframeId].vm.acceptClick();if (result) {var temp = {};Object.assign(temp, result);$.ConfirmForm({url: '../../system/workDay/saveWorkDay?_=' + $.now(),param: temp,close : false,success: function(data) {initByYear(year);dialogCloseById(iframeId);}});}}});}function initDataByYear() {var year = $('#yearSelect').val();$.ConfirmForm({msg: '您是否要初始'+year+'年工作日数据?',url: '../../system/workDay/initDataByYear?year=' + year + '&_=' + $.now(),param: {},async: false,success: function (data) {initByYear(year);}});}function inputChange() {var result = getWorkDayAfterByDate($("#dateSelect").val(), $("#days").val());$("#result").val(result);}function natureInputChange() {var result = dateAddDays($("#natureDateSelect").val(), $("#natureDays").val());$("#natureResult").val(result);}</script>
</body>
</html>
2.工作日查询、自然日查询 js
/*** [dateAddDays 从某个日期增加n天后的日期]* @param {[string]} dateStr [日期字符串]* @param {[int]} dayCount [增加的天数]* @return {[string]}[增加n天后的日期字符串]*/
function dateAddDays(dateStr,dayCount) {var tempDate=new Date(dateStr.replace(/-/g,"/"));//把日期字符串转换成日期格式var resultDate=new Date((tempDate/1000+(86400*dayCount))*1000);//增加n天后的日期return formatDate(resultDate, "yyyy-MM-dd");
}/*** 查询工作日* @param date 时间,格式:yyyy-MM-dd,为空将使用当前时间* @param days 偏移量,整数,为正向后偏移,为负向前偏移* @returns {*}*/
function getWorkDayAfterByDate(date, days) {if (isNullOrEmpty(date)) {date = formatDate(new Date(), 'yyyy-MM-dd');}if (isNullOrEmpty(days)) {return;}var result;$.SetForm({url: '../../system/workDay/getWorkDayAfterByDate?date=' + date + '&days=' + days + '&_=' + $.now(),param: {},async: false,success: function (data) {result = data;}});return result;
}
3.修改工作日配置
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head th:include="include/header_css::header('编辑-工作日配置')"></head>
<body><div id="dpLTE" class="container-fluid" v-cloak><table class="form" id="form"><colgroup><col width="20%" /></colgroup><tr><td class="formTitle">日期</td><td class="formValue">{{ workDay.year }}-{{ workDay.month }}-{{ workDay.day }}</td></tr><tr><td class="formTitle">工作日名称</td><td class="formValue"><input v-model.trim="workDay.name" type="text" class="form-control" placeholder="请输入工作日名称" errormsg="工作日名称" /></td></tr><tr><td class="formTitle">备注</td><td class="formValue"><input v-model.trim="workDay.descn" type="text" class="form-control" placeholder="请输入备注" errormsg="备注" /></td></tr><tr><td class="formTitle">工作日类型</td><td class="formValue"><label class="radio-inline"><input type="radio" name="holidayType" value="0" v-model="workDay.holidayType" isvalid="yes" checkexpession="NotNull"/> 工作日</label> <label class="radio-inline"><input type="radio" name="holidayType" value="1" v-model="workDay.holidayType" isvalid="yes" checkexpession="NotNull"/> 周末</label> <label class="radio-inline"><input type="radio" name="holidayType" value="2" v-model="workDay.holidayType" isvalid="yes" checkexpession="NotNull"/> 节日</label><label class="radio-inline"><input type="radio" name="holidayType" value="3" v-model="workDay.holidayType" isvalid="yes" checkexpession="NotNull"/> 调休</label></td></tr></table></div><div th:include="include/footer_js::footer"></div><script type="text/javascript">var vm = new Vue({el:'#dpLTE',data: {workDay: {id: null,year: null,month: null,day: null,holidayType: 0,}},methods : {setForm: function() {var param = {id: vm.workDay.id};$.SetForm({url: '../../system/workDay/getInfoByDate?_' + $.now(),param: param,success: function(data) {if (data) {vm.workDay = data;}}});},acceptClick: function() {if (!$('#form').Validform()) {return false;}return vm.workDay;}}})</script>
</body>
</html>
4.数据库,表结构
字段名 | 类型 | 长度 | 主键 | 注释 |
---|---|---|---|---|
id | varchar | 36 | 是 | 主键id 年月日拼接 如:2024-01-01 |
year | varchar | 10 | 否 | 年份 |
month | varchar | 2 | 否 | 月份 |
day | varchar | 2 | 否 | 天 |
name | varchar | 200 | 否 | 名称 |
week | int | 2 | 否 | 星期几(1-7) |
week_mean | varchar | 20 | 否 | 星期几(1-7) 文本,如:星期一 |
type | int | 2 | 否 | 类型 1:工作日 2:非工作日/节假日 默认为工作日 |
holiday_type | int | 2 | 否 | 节假日类型: 0:工作日 1:周末 2:节日 3:调休 |
oper_user_id | varchar | 36 | 否 | 操作用户id |
descn | varchar | 200 | 否 | 备注 |
cdate | datetime | 0 | 否 | 创建时间 |
ldate | datetime | 0 | 否 | 修改时间 |
status | int | 2 | 否 | 状态: 1:有效 0:无效 |
sql脚本:
CREATE TABLE `t_work_day` (`id` varchar(36) NOT NULL COMMENT '主键id',`year` varchar(10) DEFAULT NULL COMMENT '年份',`month` varchar(2) DEFAULT NULL COMMENT '月份',`day` varchar(2) DEFAULT NULL COMMENT '天',`name` varchar(200) DEFAULT NULL COMMENT '名称',`week` int(2) DEFAULT NULL COMMENT '星期几(1-7)',`week_mean` varchar(20) DEFAULT NULL COMMENT '星期几(1-7)',`type` int(2) DEFAULT NULL COMMENT '类型(1:工作日;2:非工作日/节假日;默认为工作日)',`holiday_type` int(2) DEFAULT NULL COMMENT '节假日类型:0工作日、1周末、2节日、3调休',`oper_user_id` varchar(36) DEFAULT NULL COMMENT '操作用户id',`descn` varchar(200) DEFAULT NULL COMMENT '备注',`cdate` datetime DEFAULT NULL COMMENT '创建时间',`ldate` datetime DEFAULT NULL COMMENT '修改时间',`status` int(2) DEFAULT NULL COMMENT '状态',PRIMARY KEY (`id`) USING BTREE,UNIQUE KEY `year_month_day` (`year`,`month`,`day`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='工作日配置表';
数据如下:
5.初始化数据
工作日数据由第三方初始化获取 ,参考:
工作日API文档:http://timor.tech/api/holiday