MUI 万年历的前端实现
前言
根据业务需要,开发一个万年历。注(本项目只有前端,后端需自己编写,遇到问题可以私信我。)
功能描述:
- 初始化时高亮显示当前日期
- 可以显示每天打卡的状态
- 正常 => 用绿色标记
- 异常 => 用红色标记
- 点击有标记的日期
- 可以显示一天的打卡次数,以及具体的打卡时间
实现的UI效果
关键JavaScript代码
var z;
function ajaxTonzghi(x) {
$.ajax({
type: 'get',
url: 'url',//prod
success: function (data) {
var y = data.data; // 后端数据格式 {daycount: 1, user_id: "e34d7daaa934425586d807fc1f0085b3", location_time: "2020-07-01T11:10:31.000+0000"}
console.log(y)
var list = [];
var jbCount = 0;
for(var i in y){
if(compareTime(y[i].location_time,shapeTime(y[i].location_time,3)) === 1){
console.log(y[i].location_time,shapeTime(y[i].location_time,3))
jbCount++;
}
list.push({"time": y[i].location_time,"type": y[i].daycount});
}
console.log("list:",list)
$("#Overtime").html(jbCount)
$("#ShouldAttend").html(22);
$("#HaiShoulde").html(22 - y.length);
$("#ActualAttendance").html(y.length);
$('.calendar-box').html('');
$('.calendar-box').calendar({
ele: '.demo-box' //依附
})
$(".calendar-box").find(".ht-rili-td ").each(function(){
var el = $(this);
// console.log(el.attr("data-date"));
setMark(el, list);
})
}
});
}
(function () {
var calendarDate = {};
var riliHtml = '';
calendarDate.today = new Date();
calendarDate.year = calendarDate.today.getFullYear();//当前年
calendarDate.month = calendarDate.today.getMonth() + 1;//当前月
calendarDate.date = calendarDate.today.getDate();//当前日
calendarDate.day = calendarDate.today.getDay();//当前周几
z = calendarDate.year + '-' + calendarDate.month;
ajaxTonzghi(z);
//绘制
function getIndexDay() {
isLeapYear();
getDays();
riliHtml = '';
//本月一号周几
calendarDate.monthStart = new Date(calendarDate.year + "/" + calendarDate.month + "/1").getDay();
//上个月所占空格数
if (calendarDate.monthStart == 0) {//独占一行
calendarDate.monthStart = 7;
}
//上月数据
for (var i = calendarDate.monthStart; i > 0; i--) {
var dataDateStr = calendarDate.lastYear + "-" + calendarDate.lastMonth + "-" + (calendarDate.lastDays - i + 1);
riliHtml += '<div class="ht-rili-td ht-rili-td-disabled" data-date="' + dataDateStr + '"><span' +
' class="ht-rili-day moren">' + (calendarDate.lastDays - i + 1) + '</span></div>'
}
//本月数据
for (var k = 0; k < calendarDate.days; k++) {
var dataDateStr = calendarDate.year + "-" + calendarDate.month + "-" + (k + 1);
if(k === new Date().getDate()){ //当天日期高亮显示
riliHtml += '<div class="ht-rili-td ht-rili-td-active ht-rili-onclick" data-date="' + dataDateStr + '"><span' +
' class="ht-rili-da">' + k + '</span></div>';
continue;
}
riliHtml += '<div class="ht-rili-td ht-rili-onclick" data-date="' + dataDateStr + '"><span' +
' class="ht-rili-da">' + (k + 1) + '</span></div>';
}
//下月数据
if ((calendarDate.days + calendarDate.monthStart) >= 35) {
for (var j = 0; j < (42 - calendarDate.days - calendarDate.monthStart); j++) {//42-已占用表格数=剩余表格数
var dataDateStr = calendarDate.nextYear + "-" + calendarDate.nextMonth + "-" + (j + 1);
riliHtml += '<div class="ht-rili-td ht-rili-td-disabled" data-date="' + dataDateStr + '"><span class="ht-rili-day">' + (j + 1) + '</span><span class="ht-rili-money"></span></div>';
}
} else {
for (var j = 0; j < (35 - calendarDate.days - calendarDate.monthStart); j++) {//36-已占用表格数=剩余表格数
var dataDateStr = calendarDate.nextYear + "-" + calendarDate.nextMonth + "-" + (j + 1);
riliHtml += '<div class="ht-rili-td ht-rili-td-disabled" data-date="' + dataDateStr + '"><span' +
' class="ht-rili-day moren">' + (j + 1) + '</span></div>';
}
}
$('.ht-rili-body').append(riliHtml);
$('.ht-rili-onclick').on('click', function () {
dateClick(this);
})
}
//是否是闰年
function isLeapYear() {
if ((calendarDate.year % 4 == 0) && (calendarDate.year % 100 != 0 || calendarDate.year % 400 == 0)) {
calendarDate.isLeapYear = true;
} else {
calendarDate.isLeapYear = false;
}
}
//日期点击事件
function dateClick(obj) {
$(obj).siblings().each(function () {
$(this).removeClass('ht-rili-td-active');
});
$(obj).addClass('ht-rili-td-active');
}
//获取上个月份,本月,下个月份信息
function getDays() {
//上月天数
if (parseInt(calendarDate.month) == 1) {
calendarDate.lastDays = new Date(calendarDate.year - 1, 12, 0).getDate();
calendarDate.lastMonth = new Date(calendarDate.year - 1, 12, 0).getMonth() + 1;
calendarDate.lastYear = new Date(calendarDate.year - 1, 12, 0).getFullYear();
} else {
calendarDate.lastDays = new Date(calendarDate.year, calendarDate.month - 1, 0).getDate();
calendarDate.lastMonth = new Date(calendarDate.year, calendarDate.month - 1, 0).getMonth() + 1;
calendarDate.lastYear = new Date(calendarDate.year, calendarDate.month - 1, 0).getFullYear();
}
//下个月天数
if (parseInt(calendarDate.month) == 12) {
calendarDate.nextDays = new Date(calendarDate.year + 1, 1, 0).getDate();
calendarDate.nextMonth = new Date(calendarDate.year + 1, 1, 0).getMonth() + 1;
calendarDate.nextYear = new Date(calendarDate.year + 1, 1, 0).getFullYear();
} else {
calendarDate.nextDays = new Date(calendarDate.year, calendarDate.month + 1, 0).getDate();
calendarDate.nextMonth = new Date(calendarDate.year, calendarDate.month + 1, 0).getMonth() + 1;
calendarDate.nextYear = new Date(calendarDate.year, calendarDate.month + 1, 0).getFullYear();
}
//本月天数
calendarDate.days = new Date(calendarDate.year, calendarDate.month, 0).getDate();
}
//检测时间是否一致
function checkDate(dateStr1, dateStr2) {
var date1 = dateStr1.split("-"); //[0]year,[1]month,[2]date;
var date2 = dateStr2.split("-"); //[0]year,[1]month,[2]date;
if (date1[1] < 10 && date1[1].length < 2) {
date1[1] = "0" + date1[1];
}
if (date1[2] < 10 && date1[2].length < 2) {
date1[2] = "0" + date1[2];
}
if (date2[1] < 10 && date2[1].length < 2) {
date2[1] = "0" + date2[1];
}
if (date2[2] < 10 && date2[2].length < 2) {
date2[2] = "0" + date2[2];
}
date1 = date1.join("-");
date2 = date2.join("-");
return date1 == date2;
}
$.fn.extend({
calendar: function (opt) {
//加载容器
calendarDate.container = '<div class="ht-rili-querybox"><div class="ht-rili-datebox"><span class="ht-rili-leftarr"></span><span class="ht-rili-date"></span><span' +
' class="ht-rili-rightarr"></span></div></div><div class="ht-rili-head"><div class="ht-rili-th">日</div><div class="ht-rili-th">一</div><div class="ht-rili-th">二</div><div class="ht-rili-th">三</div><div class="ht-rili-th">四</div><div class="ht-rili-th">五</div><div class="ht-rili-th">六</div></div><div class="ht-rili-body"><!--<div class="ht-rili-td"><span class="ht-rili-day">1</span><span class="ht-rili-money">¥100</span></div>--></div>'
$(opt.ele).append(calendarDate.container);
$('.ht-rili-date').html(calendarDate.year + '年 ' + calendarDate.month + '月');
getIndexDay();
$('.ht-rili-leftarr').on('click', function () {
$('.ht-rili-body').html('');
if (calendarDate.month == 1) {
calendarDate.year -= 1;
calendarDate.month = 12;
} else {
calendarDate.month -= 1;
}
$('.ht-rili-date').html(calendarDate.year + '年 ' + calendarDate.month + '月');
var x = calendarDate.year + '-' + calendarDate.month;
ajaxTonzghi(x);
getIndexDay();
})
$('.ht-rili-rightarr').on('click', function () {
$('.ht-rili-body').html('');
if (calendarDate.month == 12) {
calendarDate.year += 1;
calendarDate.month = 1;
} else {
calendarDate.month += 1;
}
$('.ht-rili-date').html(calendarDate.year + '年 ' + calendarDate.month + '月');
var y = calendarDate.year + '-' + calendarDate.month;
ajaxTonzghi(y);
getIndexDay();
})
},
});
})(jQuery)
//格式化时间 "2020-07-01T11:10:31.000+0000" => "2020-07-01 11:10:31"
function formartTime(str){
var json_date = new Date(str).toJSON();
return new Date(new Date(json_date) + 8 * 3600 * 1000).toISOString().replace(/T/g, ' ').replace(/\.[\d]{3}Z/, '')
}
// 制作每天打卡的截止时间 包括早、晚、加班
function shapeTime(dateStr,type){
var date = new Date(dateStr);
var result;
switch (type){
case 1:
//console.log("早");
result = date.getFullYear() + "-" + (date.getMonth() + 1) + "-" + date.getDate() + " " + "09:00"
break;
case 2:
//console.log("晚");
result = date.getFullYear() + "-" + (date.getMonth() + 1) + "-" + date.getDate() + " " + "17:00"
break;
case 3:
//console.log("加")
result = date.getFullYear() + "-" + (date.getMonth() + 1) + "-" + date.getDate() + " " + "19:00"
break;
default:
console.log("没有这个类型!")
}
return result;
}
// 日期比较
function compareTime(date1,date2){
var oDate1 = new Date(date1);
var oDate2 = new Date(date2);
if(oDate1.getTime() > oDate2.getTime()){
return 1;
} else {
return 2;
}
}
// 用于为天数个性化颜色显示 打卡正常 打卡异常
function clockStatus(el, date1, type){
var date2 = shapeTime(date1,type);
//console.log(date1, date2);
var comTmp = compareTime(date1, date2);
var ht;
var popMessage='';
switch(type){
case 1:
//console.log("早打卡")
if(comTmp === 1){
//console.log("异常 》》》 迟到")
ht = 'weikaoqing';
}else{
//console.log("正常")
ht = 'kaoqing'
}
popMessage += '<span class="tip" style="font-size: 12px; color: black; display: block;">早打卡:'+ formartTime(date1) +'</span>'
el.find(".ht-rili-da").addClass(ht);
break;
case 2:
//console.log("晚打卡")
if(comTmp === 1){
//console.log("正常")
ht = 'kaoqing'
}else{
//console.log("异常 》》》 早退")
ht = 'weikaoqing'
}
popMessage += '<span class="tip" style="font-size: 12px; color: black; display: block;">晚打卡:'+ formartTime(date1) +'</span>'
el.find(".ht-rili-da").addClass(ht);
break;
case 3:
//console.log("加班打卡")
if(comTmp === 1){
//console.log("正常")
ht = 'kaoqing'
}else{
//console.log("异常 》》》 早退")
ht = 'weikaoqing'
}
popMessage += '<span class="tip" style="font-size: 12px; color: black; display: block;">加班打卡:'+ formartTime(date1) +'</span>'
el.find(".ht-rili-da").addClass(ht);
break;
default:
console.log("没有这个类型")
}
return {"tip":ht,"message":popMessage};
}
// 设置天数 下面的 正常 与 异常, 并为天数绑定点击弹窗事件
function setMark(el, list){
var compareCount = 0;
var message = '';
var retObj;
var arr = new Array();
var n = '<span class="tip" style="font-size: 12px; color: black; display: block;">正常</span>'
var an = '<span class="tip" style="font-size: 12px; color: black; display: block;">异常</span>'
list.forEach(function(value, key){
var time = list[key].time;
var date = time.split("T")[0];
var type =list[key].type;
var ymd = date.split("-");
var newDate = "" + ymd[0] + "-" + parseInt(ymd[1]) + "-" + parseInt(ymd[2]);
//console.log(date, newDate, el.attr("data-date"))
if(newDate === el.attr("data-date")){
//console.log(date,value)
//console.log(el.find("span").html())
switch(type)
{
case 1:
retObj = clockStatus(el, time, 1)
el.on('click', function () {
//console.log(popMessage)
mui.alert(retObj.message,"打卡详情");
})
if(retObj.tip === "kaoqing"){
el.append(n)
}else{
el.append(an)
}
break;
case 2:
compareCount +=1;
if(compareCount === 1){
retObj = clockStatus(el, time, 1);
message += retObj.message;
if(retObj.tip === "kaoqing"){
arr.push(true);
}else{
arr.push(false);
}
}
if(compareCount === 2){
retObj = clockStatus(el, time, 2);
message += retObj.message;
el.on('click', function () {
//console.log(popMessage)
mui.alert(message,"打卡详情");
})
if(retObj.tip === "kaoqing"){
arr.push(true);
}else{
arr.push(false);
}
if(arr.includes(false)){
el.append(an);
}else{
el.append(n);
}
compareCount = 0;
}
break;
default:
compareCount += 1;
if(compareCount === 1){
retObj = clockStatus(el, time, 1);
message += retObj.message;
if(retObj.tip === "kaoqing"){
arr.push(true)
}else{
arr.push(false)
}
}
if(compareCount === 2){
retObj = clockStatus(el, time, 2)
message += retObj.message;
if(retObj.tip === "kaoqing"){
arr.push(true)
}else{
arr.push(false)
}
}
if(compareCount === 3){
retObj = clockStatus(el, time, 3)
message += retObj.message;
el.on('click', function () {
//console.log(popMessage)
mui.alert(message,"打卡详情");
})
if(retObj.tip === "kaoqing"){
arr.push(true)
}else{
arr.push(false)
}
if(arr.includes(false)){
el.append(an);
}else{
el.append(n);
}
compareCount = 0;
}
break;
}
}
})
}
前端源码包
前端源码包
资源审核已通过,需要的童鞋可以随意取用,不需要积分。