实现思路:
1、将日历分为四个部分:
1)日历中要显示的上个月日期部分
2)当月到当天的日期部分
3)当月当前之后的部分(为了实现点击无操作)
4)日历中要显示的下个月日期部分
2、日历的操作:
1)点击上个月日期进入到上个月日历。
2)(当月)点击到当前日期之前的显示当天的报工信息、
(当月之前)点击任意七日都可显示当天的报工信息
3)当月之后不可操作。
4)节假日、休息日点击显示休息日。
**注意:不支持年切换,只允许对当前年份进行操作
<template>
<div class="container">
<div class="calendar-container">
<div class="year" style="display: flex;justify-content: space-between;">
<div>
每日统计
<span>({{ nowDate.year }}年{{ nowDate.month + 1 }}月)</span>
</div>
<el-button
type="text"
style="margin-right: 15px;"
@click="clickToIndex()"
>返回首页</el-button
>
</div>
<ul class="week">
<li v-for="(o, index) in 7" :key="o">{{ formatWeek(index) }}</li>
</ul>
<ul class="date">
<li class="none-week last" v-for="o in lastMonthDays" :key="o + 50" @click="lastClickEvent">
{{ lastMonthStartDay + o - 1 }}
</li>
<li @click="handleClick(item)"
v-for=" item in showList" :key="item.daySn"
:class="[item.holType !== '1' ? 'holidayActiv': item.appFlag? (item.appFlag === 'Y' || item.appFlag === 'F') ? 'normalActiv': 'unormalActiv' : ((item.daySn - 0) === nowDate.date && isNowMonth) ? 'notActiv' : 'unormalActiv', isClickDay === (item.daySn - 0) ? 'clickActiv': '']">
{{ item.daySn }}
</li>
<!-- 当前日期后,不做点击处理 -->
<li v-for="day in nowMonthDays - nowDate.date" :key="day + nowDate.date" v-if="isNowMonth">
{{ day + nowDate.date }}
</li>
<li class="none-week next" @click="nextClickEvent"
v-for="day in 42 - lastMonthDays - nowMonthDays"
:key="day + 100">
{{ day }}
</li>
</ul>
<div class="explain">
<div class="info"><p class="normal"></p>正常</div>
<div class="info"><p class="unormal"></p>异常</div>
<div class="info"><p class="holiday"></p>节假日</div>
<div class="info"><p class="not"></p>待报工</div>
</div>
</div>
<div class="body" v-if="showForm">
<div style="margin: 0 15px;color: rgb(158, 155, 155);
display: flex;align-items: center;
justify-content: space-between;">
<span>每日报工信息</span>
<span v-show="form.appFlag === 'B' ">驳回</span>
<span v-show="form.appFlag === 'A' ">未审核</span>
</div>
<el-form ref="form" :model="form" label-width="125px" :disabled="form.state !== 'Y' ">
<el-form-item label="报工日期" required>
<el-input v-model="form.jobDate" required readonly></el-input>
</el-form-item>
<el-form-item label="项目编号" required>
<el-select v-model="projectValue" placeholder="请选择项目编号"
@change="currentSel"
value-key="xmIncode" :disabled="!ifShowButton">
<el-option :label="item.xmbh" :value="item"
v-for="item in projectList" :key="item.xmIncode">
<span style="float: left;display: inline-block;
max-width: 240px;overflow: hidden;
text-overflow: ellipsis;padding-left: 10px;
white-space: nowrap;">{{ item.xmmc }}</span>
<span style="float: right; color: #8492a6; font-size: 13px;padding-right: 10px;">{{ item.xmbh }}</span>
</el-option>
<el-option :label="uchose.xmbh"
:value="uchose"
:key="uchose.xmIncode"
disabled v-if="uchose.xmIncode !== 0"
>
<span style="float: left;display: inline-block;
max-width: 240px;overflow: hidden;
text-overflow: ellipsis;padding-left: 10px;
white-space: nowrap;">{{ uchose.xmmc }}</span>
<span style="float: right; color: #8492a6; font-size: 13px;padding-right: 10px;">{{ uchose.xmbh }}</span>
</el-option>
</el-select>
</el-form-item>
<el-form-item label="项目部门" required>
<el-input v-model="form.groupName" placeholder="请输入" readonly></el-input>
</el-form-item>
<el-form-item label="工作内容简述">
<el-input type="textarea"
:rows="3"
v-model="form.remark"
placeholder="请输入工作内容简述" :readonly="!ifShowButton"></el-input>
</el-form-item>
<el-form-item v-if="form.state === 'Y' && ifShowButton"
style="border-radius: 0px;padding: 0px;margin: 10px;background-color:transparent;">
<el-button type="primary" @click="onSubmit" :disabled="isSubmit">提交</el-button>
</el-form-item>
</el-form>
</div>
<div v-else class="body"
style="height: calc(100% - 405.5px);background-color: rgb(255, 255, 255);
margin: 10px;color: #9e9b9b;
display: flex;
flex-direction: column;
align-items: center;
border-radius: 15px;
justify-content: center;">
<i class="el-icon-hot-water" style="font-size: 80px"></i>
<span style="margin-top: 12px;letter-spacing: 2px;">今日休息</span>
</div>
</div>
</template>
默认进入当前页面,选中当天进行报工,也可传入指定日期。
export default {
name: "AddBooking",
data() {
return {
showList: [],//展示日历信息
projectList:[],//项目列表
selectDate: [], //选择日期列表
nowDate: this.getDate(new Date()), //当前设置时间 默认为当前系统时间
form:{
incode: 0,
xmIncode: 0,
groupName: "",
remark: "",
xmbh: "",
xmmc: "",
state: "Y",
appFlag: null
},
showForm: false,
isNowMonth: true,
projectValue: {
xmIncode: 0,
xmbh: "",
xmmc: "",
groupName: ""
},// 选中的项目信息
uchose: {
xmIncode: 0,
xmbh: "",
xmmc: "",
groupName: ""
},
isDisabled: false,
isClickDay: new Date().getDate(),
isSubmit: false,//是否提交
ifAllowSubmit:true,//是否允许上个月报工
ifShowButton: true,//是否显示提交按钮
listColumn: 30,//允许报工天数
};
},
computed: {
lastMonthDays() {//日历中上个月需显示的天数
return this.startWeek();
},
lastMonthStartDay() {//计算日历中需要显示的上个月的开始日期
//上个月天数
let lastMonthMonthDays = this.calcLastMonthDays(this.nowDate.year, this.nowDate.month);
// 需要显示的天数
let days = this.startWeek() - 1;
return lastMonthMonthDays - days;
},
nowMonthDays() {//当月天数
return this.calcDays(this.nowDate.year, this.nowDate.month);
}
},
created() {
let that = this;
let jobDate = that.$route.params.jobDate;
let day = that.$route.params.day;
if(!jobDate){//如果没有传递日期
let date = new Date();
let month = date.getMonth();
month = month + 1;
if(month < 10){
month = "0" + month;
}
jobDate = date.getFullYear() + month;
day = date.getDate();
}
let nowMonth = that.nowDate.month + 1;
let jobMonth = jobDate.substring(jobDate.length-2);
if (jobMonth[0] == '0') {
jobMonth = jobMonth.slice(1) - 0;
}
if(nowMonth !== jobMonth){
let jobyear = jobDate.substring(0,4);
that.nowDate = that.getDate(new Date(jobyear,jobMonth - 1))
}
// 获取当前月份日历
that.getList(jobDate, day);
},
methods: {
getList(jobDate, day){//获取当前月报工日期
let that = this;
that.showList = [];
var p1 = new Promise((resolve, reject) => {
let data = {
"jobDate": jobDate,
"day": day
};
postAction('/project/getJobCalendar', data).then(res => {
if (res.status === 200) {
resolve(res.data.rtnData.list)
}else{
reject(res.data.rtnMsg)
}
})
})
var p2 = new Promise((resolve,reject)=>{
postAction('/project/getCollection', null).then(res=>{
if (res.status === 200) {
resolve(res.data.rtnData.list)
}else{
reject(res.data.rtnMsg)
}
})
})
Promise.all([p1,p2]).then(res=>{
let jobClenderList = res[0];
that.listColumn = jobClenderList[0].listColumn;
if(that.listColumn > 30){
that.ifAllowSubmit = true;
}else{
that.ifAllowSubmit = false;
}
let collectionProjectList = res[1];
let jobMonth = jobDate.substring(jobDate.length-2);
let month = new Date().getMonth() + 1;
let today = new Date().getDate();
if(month < 10){
month = "0" + month;
}
// 处理展示的列表
if(jobMonth === month){//当月截取当天之前日历数据
that.isNowMonth = true;
let nowDay = new Date().getDate();
jobClenderList = jobClenderList.slice(0,nowDay)
// 处理是否是当天
if(that.listColumn > 30){
that.ifShowButton = true;
}else{
if(day !== today && (day - today) > that.listColumn){
that.ifShowButton = false;
}else{
that.ifShowButton = true;
}
}
}else{//非本月处理逻辑
that.isNowMonth = false;
if(that.listColumn > 30){
that.ifShowButton = true
}else{
that.ifShowButton = false
}
}
that.showList = jobClenderList;
that.projectList = collectionProjectList;
// 处理form表单显示
that.isShowForm(day);
}).catch(err => {
that.$message({
message: err,
type: 'warning'
});
})
},
isShowForm(day){
let that = this;
that.isClickDay = day;
let today = new Date().getDate();
if(that.isNowMonth && day > today){//当月
day = today;
}
let item = that.showList[day - 1];
if(item.holType && item.holType === "1"){//工作日
that.showForm = true;
that.form = {
incode: item.incode,
appFlag: item.appFlag,
jobDate: that.nowDateFormat(that.nowDate.year, that.nowDate.month, day),
groupName: item.groupName,
xmIncode: item.xmIncode,
xmbh: item.xmbh,
xmmc: item.xmmc,
remark: item.remark,
state: item.appFlag? ((item.appFlag === 'Y' || item.appFlag === 'F')? 'N': 'Y') : 'Y'
};
if(item.appFlag){
that.projectValue = {
xmIncode: item.xmIncode,
xmbh: item.xmbh,
xmmc: item.xmmc,
groupName: item.groupName
}
that.uchose = {
xmIncode: item.xmIncode,
xmbh: item.xmbh,
xmmc: item.xmmc,
groupName: item.groupName
};
}
}else{
this.showForm = false;
}
},
nowDateFormat(year, month, day) {//当天日期YYYY-MM-DD
let date = new Date(year, month, day);
month = month + 1;
if(month < 10){
month = "0" + month;
}
if(day < 10){
day = "0" + day;
}
return date.getFullYear() + "-" + month + "-" + day;
},
getDate(date) {
return {
year: date.getFullYear(),
month: date.getMonth(),
day: date.getDay(),
date: date.getDate(),
};
},
formatWeek(day) {//排序星期
switch (day) {
case 0:
return "日";
case 1:
return "一";
case 2:
return "二";
case 3:
return "三";
case 4:
return "四";
case 5:
return "五";
case 6:
return "六";
}
},
isLeapYear(year) {//判断闰年
return year % 4 == 0 && (year % 100 != 0 || year % 400 == 0);
},
calcWeekend(year, month, day) {//根据日子计算星期
return new Date(year, month, day).getDay();
},
calcDays(year, month) {//计算某年某月的天数
const monthDay = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
// 是闰年2月返回29天
if (this.isLeapYear(year) && month === 1) return 29;
else return monthDay[month];
},
//计算上个月天数
calcLastMonthDays(year, month) {
if (month === 0) {//1月返回去年12月天数
return this.calcDays(year - 1, 11);
} else {
return this.calcDays(year, month - 1);
}
},
//计算当月开始星期
startWeek() {
return this.calcWeekend(this.nowDate.year, this.nowDate.month, 1);
},
//点击事件
handleClick(item) {
this.isClickDay = item.daySn - 0;
if(item.holType !== "1"){//非工作日
this.showForm = false;
return
}
if(this.isNowMonth && !this.ifAllowSubmit){//不允许上个月提交
let nowDay = new Date().getDate();
let clickDay = item.daySn - 0;
if((nowDay - clickDay) < this.listColumn){
this.ifShowButton = true
}else{
this.ifShowButton = false
}
}
this.showForm = true;
if(item.appFlag){//有报工信息
this.form.incode = item.incode;
this.form.groupName = item.groupName;
this.form.remark = item.remark;
this.form.xmbh = item.xmbh;
this.form.xmmc = item.xmmc;
this.form.xmIncode = item.xmIncode;
this.form.appFlag = item.appFlag;
this.form.state = (item.appFlag === 'Y' || item.appFlag === 'F')? 'N': 'Y'
this.projectValue = {
xmIncode: item.xmIncode,
xmbh: item.xmbh,
xmmc: item.xmmc,
groupName: item.groupName
}
let list = this.projectList;
let xmIncode = item.xmIncode;
list.forEach(e => {
if(e.xmIncode === xmIncode){
return;
}
})
this.uchose = {
xmIncode: item.xmIncode,
xmbh: item.xmbh,
xmmc: item.xmmc,
groupName: item.groupName
};
}else{
this.form.appFlag = null;
this.form.incode = 0;
this.form.xmIncode = 0,
this.form.groupName = "";
this.form.remark = "";
this.form.xmbh = "";
this.form.xmmc = "";
this.form.state = "Y";
// 清空
this.projectValue = {
xmIncode: 0,
xmbh: "",
xmmc: "",
groupName: ""
}
this.uchose = {
xmIncode: 0,
xmbh: "",
xmmc: "",
groupName: ""
};
}
// let date = this.getDate(new Date());
let month = this.nowDate.month + 1;
let day = item.daySn;
if(month < 10){
month = "0" + month;
}
if(day < 10){
day = "0" + day;
}
this.form.jobDate = this.nowDate.year + "-" +month + "-" + day;
},
onSubmit(){//提交或修改报工
let that = this;
if(that.form.xmIncode === 0){
that.$message({
message: "请选择项目编号",
type: 'warning'
})
return
}
if(that.form.remark !== null && that.form.remark.length > 100){
that.$message({
message: "工作内容简述长度不得超过100",
type: 'warning'
})
return
}
const loading = that.$loading({
lock: true,
text: '正在提交报工'
});
that.isSubmit = true;
new Promise((resolve, reject) => {
let data = {
partyId: 10012,
incode: that.form.incode,
xmsbDate: that.form.jobDate,
groupName: that.form.groupName,
xmIncode: that.form.xmIncode,
xmbh: that.form.xmbh,
xmmc: that.form.xmmc,
remark: that.form.remark,
};
let url = "/project/createJob";
if(data.incode !== 0){
url = "/project/alterJob"
}
postAction(url, data).then(result => {
loading.close();
if (result.status === 200) {
let type = 'success';
if(result.data.rtnCode === -1){
type = 'warning'
}
that.$message({
message: result.data.rtnMsg,
type: type,
onClose:()=>{//此处写提示关闭后需要执行的函数
that.isSubmit = false;
}
})
if(result.data.rtnCode !== -1){
that.$router.push({name:'Index'})
}
} else {
that.$message({
message: result.data.rtnMsg,
type: 'warning'
})
}
})
})
},
lastClickEvent(e){//上个月
let nowMonth = new Date().getMonth();
// let nowDay = new Date().getDate();
if (this.nowDate.month === 0) {
return
}
this.nowDate.month--;
if(nowMonth === this.nowDate.month){//当前月
this.isNowMonth = true;
}else{
this.isNowMonth = false;
if(this.ifAllowSubmit){//允许上个月提交
this.ifShowButton = true
}else{
this.ifShowButton = false
}
}
let month = this.nowDate.month;
month = month + 1;
if(month < 10){
month = "0" + month;
}
let jobDate = this.nowDate.year + "" + month
let day = Number(e.target.innerText)
this.getList(jobDate, day);
},
nextClickEvent(e){//下个月
let nowMonth = new Date().getMonth();
let day = Number(e.target.innerText);
if(nowMonth === this.nowDate.month){
return
}
if (this.nowDate.month === 11) {
this.nowDate.month = 0;
this.nowDate.year++;
} else {
this.nowDate.month++;
}
if(nowMonth === this.nowDate.month){
this.isNowMonth = true;
this.ifShowButton = true;
let today = new Date().getDate();
if(day >= today){
day = today;
}
}else{
this.isNowMonth = false;
if(this.ifAllowSubmit){//允许上个月提交
this.ifShowButton = true
}else{
this.ifShowButton = false
}
}
let month = this.nowDate.month;
month = month + 1;
if(month < 10){
month = "0" + month;
}
let jobDate = this.nowDate.year + "" + month
this.getList(jobDate, day);
},
currentSel(selVal) {
this.form.xmbh = selVal.xmbh;
this.form.xmmc = selVal.xmmc;
this.form.xmIncode = selVal.xmIncode;
this.form.groupName = selVal.groupName;
},
clickToIndex(){//返回首页
this.$router.push({
path: '/Index',
query:{}
})
}
效果图