更新记录
1.0.3(2025-09-12) 下载此版本
支持工作日报 周计划审核配置 needSate false 提交后直接通过, true 需要审核(展示待审核)
1.0.2(2025-09-11) 下载此版本
修复bug
1.0.1(2025-09-11) 下载此版本
修复 bug
查看更多平台兼容性
uni-app(4.07)
Vue2 | Vue3 | Chrome | Safari | app-vue | app-nvue | Android | iOS | 鸿蒙 |
---|---|---|---|---|---|---|---|---|
√ | √ | √ | √ | √ | √ | √ | √ | √ |
微信小程序 | 支付宝小程序 | 抖音小程序 | 百度小程序 | 快手小程序 | 京东小程序 | 鸿蒙元服务 | QQ小程序 | 飞书小程序 | 快应用-华为 | 快应用-联盟 |
---|---|---|---|---|---|---|---|---|---|---|
√ | √ | - | - | - | - | - | - | - | - | - |
uni-app x(4.07)
Chrome | Safari | Android | iOS | 鸿蒙 | 微信小程序 |
---|---|---|---|---|---|
√ | √ | √ | √ | √ | √ |
Work-calendar
介绍
基于uni-calendar做的定制化开发,主要功能为工作日历展示和提报组件
1.支持周计划日报状态展示且可配置
2.支持农历展示配置,回到当日,月份切换
3.日历,周报,日报等点击事件封装
4.支持休假展示
使用说明
1.下载插件到工程中,并在业务代码中引入
import Calendar from '@/components/calendar-zhikuany/calendar.vue'
2.布局中引入插件,并配置所需要的展示信息
<template>
<view>
<calendar ref="calendar" :date="date" @monthSwitch="monthSwitch" @change="handleSelect"
@weekPlanClick="weekPlanClick" @datePlanClick="datePlanClick" lunar :showDay="prop.showDay"
:showPlan="prop.showPlan" :showMonth="prop.showMonth" :needState="prop.needState" />
</view>
</template>
/**
* Calendar 日历
* @property {String} date 自定义当前时间,默认为今天
* @property {String} text.size 文字大小
* @property {String} text.color 文字颜色
* @property {Boolean} lunar 显示农历
* @property {Boolean} showPlan 展示周计划
* @property {Boolean} showDay 展示日报
* @property {String} startDate 日期选择范围-开始日期
* @property {String} endDate 日期选择范围-结束日期
* @property {Boolean} range 范围选择
* @property {Boolean} showMonth 是否选择月份为背景
* @property {Boolean} needState 周计划日报是否需要审核
* @event {Function} change 日期改变,
* @event {Function} monthSwitch 切换月份时触发
*/
3.设置本月周报日报假期数据
/**
* 设置数据
*/
const setDate = (year : number, month : number) => {
// 获取当月第一天和最后一天
// const firstDay = new Date(year, month, 1);
// const lastDay = new Date(year, month + 1, 0); // 下个月第0天 = 本月最后一天
uni.showLoading({
title: ''
})
//仿照调用接口 设置工作日历数据
setTimeout(() => {
uni.hideLoading()
//测试周报和日报数据 为 9月12号
date.value = '2025-09-12'
calendar.value.setPlanList(planList)
}, 1000)
}
4.核心数据设置逻辑
/**
* 获取每周数据
* @param {Object} dateData
*/
_getWeek(dateData) {
const {
year,
month
} = this.getDate(dateData)
let firstDay = new Date(year, month - 1, 1).getDay()
// 调整为周一作为第一天(0=周一,6=周日)
let adjustedFirstDay = firstDay === 0 ? 6 : firstDay - 1;
let currentDay = new Date(year, month, 0).getDate()
let dates = {
lastMonthDays: this._getLastMonthDays(adjustedFirstDay, this.getDate(dateData)), // 上个月末尾几天
currentMonthDys: this._currentMonthDys(currentDay, this.getDate(dateData)), // 本月天数
nextMonthDays: [], // 下个月开始几天
weeks: []
}
let canlender = []
const surplus = 42 - (dates.lastMonthDays.length + dates.currentMonthDys.length)
dates.nextMonthDays = this._getNextMonthDays(surplus, this.getDate(dateData))
canlender = canlender.concat(dates.lastMonthDays, dates.currentMonthDys, dates.nextMonthDays)
this.canlender = canlender
let weekTemp = {}
let weekplan = {} //每周的周计划
// 拼接数组 上个月开始几天 + 本月天数+ 下个月开始几天
for (let i = 0; i < canlender.length; i++) {
//获取本周的周计划数据
if (i % 7 === 0) {
//本周开始日期
const weekBeginDate = canlender[i].fullDate
// console.log('开始',weekBeginDate)
//获取计划状态
weekplan = {}
for (let i = 0; i < this.planList.length; i++) {
if (this.planList[i]) {
const item = this.planList[i]
// console.log(item.monday)
if (item.beginDate == weekBeginDate) {
weekplan = item
// console.log('weekplan', weekplan)
break
}
}
}
let weekDataState = 0 //周计划状态K
if (this.needSate) {
weekDataState = weekplan.dataState //周计划 状态
} else {
weekDataState = this.isEmpty(weekplan.dataState) ? weekplan.dataState : 1 //状态不用审核
}
weekTemp[parseInt(i / 7)] = {
weeks: new Array(7),
planCode: weekplan.planCode,
planId: weekplan.planId,
dataState: weekDataState,
attachIds: weekplan.attachIds,
// fileUrl: weekplan.fileUrl,
weekWorkPlan: weekplan.weekWorkPlan,
workSummary: weekplan.workSummary,
coordinateHelp: weekplan.coordinateHelp,
}
}
//每天的计划状态
var dayPlan = {}
switch (i % 7) {
case 0: //周一
if (this.needSate) {
dayPlan.dayStatus = weekplan.mondayStatus
} else {
dayPlan.dayStatus = this.isEmptyWithZero(weekplan.mondayStatus) ? weekplan.mondayStatus : 2
}
dayPlan.isHoliday = weekplan.mondayIsHoliday
break;
case 1:
if (this.needSate) {
dayPlan.dayStatus = weekplan.tuesdayStatus
} else {
dayPlan.dayStatus = this.isEmptyWithZero(weekplan.tuesdayStatus) ? weekplan.tuesdayStatus :
2
}
dayPlan.isHoliday = weekplan.tuesdayIsHoliday
break;
case 2:
if (this.needSate) {
dayPlan.dayStatus = weekplan.wednesdayStatus
} else {
dayPlan.dayStatus = this.isEmptyWithZero(weekplan.wednesdayStatus) ? weekplan
.wednesdayStatus : 2
}
dayPlan.isHoliday = weekplan.wednesdayIsHoliday
break;
case 3:
if (this.needSate) {
dayPlan.dayStatus = weekplan.thursdayStatus
} else {
dayPlan.dayStatus = this.isEmptyWithZero(weekplan.thursdayStatus) ? weekplan
.thursdayStatus : 2
}
dayPlan.isHoliday = weekplan.thursdayIsHoliday
break;
case 4:
if (this.needSate) {
dayPlan.dayStatus = weekplan.fridayStatus
} else {
dayPlan.dayStatus = this.isEmptyWithZero(weekplan.fridayStatus) ? weekplan.fridayStatus : 2
}
dayPlan.isHoliday = weekplan.fridayIsHoliday
break;
case 5:
if (this.needSate) {
dayPlan.dayStatus = weekplan.saturdayStatus
} else {
dayPlan.dayStatus = this.isEmptyWithZero(weekplan.saturdayStatus) ? weekplan
.saturdayStatus : 2
}
dayPlan.isHoliday = weekplan.saturdayIsHoliday
break;
case 6:
if (this.needSate) {
dayPlan.dayStatus = weekplan.sundayStatus
} else {
dayPlan.dayStatus = this.isEmptyWithZero(weekplan.sundayStatus) ? weekplan.sundayStatus : 2
}
dayPlan.isHoliday = weekplan.sundayIsHoliday
break;
}
// console.log('swich',dayPlan)
weekTemp[parseInt(i / 7)].weeks[i % 7] = {
...canlender[i],
...dayPlan
}
}
this.weeks = weekTemp
// console.log(this.weeks)
}
完整示例
<template>
<view>
<calendar ref="calendar" :date="date" @monthSwitch="monthSwitch" @change="handleSelect"
@weekPlanClick="weekPlanClick" @datePlanClick="datePlanClick" lunar :showDay="prop.showDay"
:showPlan="prop.showPlan" :showMonth="prop.showMonth" :needState="prop.needState" />
</view>
</template>
<script setup lang="ts">
import { ref, onMounted } from 'vue'
import { onLoad, onShow } from '@dcloudio/uni-app'
import { planList } from './data.js'
import Calendar from '@/components/calendar-zhikuany/calendar.vue'
/**
* 本组件是基于uni-calendar(V1.5.5)之上增加了一些个性化功能点,如打卡日历,日历日程,日历排班,打卡排班等功能
* 小点的位置 point.position [1, 2, 3, 4, 5, 6] 红点位置,[左上角, 右上角, 右下角, 左下角, 上中间, 下中间]
* 小点的颜色 point.color 如 #000 #fff
* 日期数字下方的自定义文本 info
* text.size 自定义文本字体大小 如 12 14 16
* text.color 自定义文本颜色 如 #000 #fff
*/
const calendar = ref({})
const date = ref('')
const query = defineProps<{ prop : string }>()
const prop : any = ref({})
//页面加载
onLoad(() => {
//解析配置参数
prop.value = JSON.parse(query.prop)
})
onShow(() => {
initDate()
})
//获取当月所有日期的数组 初始化数据
const initDate = () => {
const now = new Date();
const year = now.getFullYear();
const month = now.getMonth() + 1; // 月份从 0 开始(0=1月)
setDate(year, month);
}
/**
* 设置数据
*/
const setDate = (year : number, month : number) => {
// 获取当月第一天和最后一天
// const firstDay = new Date(year, month, 1);
// const lastDay = new Date(year, month + 1, 0); // 下个月第0天 = 本月最后一天
uni.showLoading({
title: ''
})
//仿照调用接口 设置工作日历数据
setTimeout(() => {
uni.hideLoading()
//测试周报和日报数据 为 9月12号
date.value = '2025-09-12'
calendar.value.setPlanList(planList)
}, 1000)
}
/**
* 选中
*/
const handleSelect = (e : any) => {
console.log(e)
if (e.extraInfo.date) {
// do something
}
}
//周计划点击
const weekPlanClick = (item : any) => {
console.log(item)
if (item.dataState == 1 || item.dataState == 0) {//审核中或者审核通过
uni.showToast({
title: JSON.stringify(item),
icon: 'none',
duration: 2000
})
} else {
if (!checkWeekRange(item.beginDate, item.endDate)) {
uni.showToast({
title: '只能提交当本周或下周的周计划',
icon: 'none'
})
return
}
uni.showToast({
title: '跳转周计划填报页面',
icon: 'none',
duration: 2000
})
}
}
/**
* 判断给定的日期范围是否属于本周或下周
* @param {string} beginDate - 开始日期,格式为 "YYYY-MM-DD"
* @param {string} endDate - 结束日期,格式为 "YYYY-MM-DD"
* @returns {string} - 返回 "本周"、"下周" 或 "不在本周或下周"
*/
function checkWeekRange(beginDate : any, endDate : any) : Boolean {
// 将字符串日期转换为Date对象
const begin = new Date(beginDate);
const end = new Date(endDate);
begin.setHours(0, 0, 0, 0)
end.setHours(0, 0, 0, 0)
console.log(begin + ' ' + end)
// 获取当前日期
const today = new Date();
today.setHours(0, 0, 0, 0); // 清除时间部分
// 计算当前周的起始和结束日期(周一至周日)
const currentWeekStart = new Date(today);
const dayOfWeek = today.getDay(); // 0是周日,1是周一,...,6是周六
const diffToMonday = dayOfWeek === 0 ? -6 : 1 - dayOfWeek; // 调整为周一作为一周的第一天
currentWeekStart.setDate(today.getDate() + diffToMonday);
currentWeekStart.setHours(0, 0, 0, 0);
const currentWeekEnd = new Date(currentWeekStart);
currentWeekEnd.setDate(currentWeekStart.getDate() + 6);
// 计算下周的起始和结束日期
const nextWeekStart = new Date(currentWeekStart);
nextWeekStart.setDate(currentWeekStart.getDate() + 7);
const nextWeekEnd = new Date(currentWeekEnd);
nextWeekEnd.setDate(currentWeekEnd.getDate() + 7);
console.log(currentWeekStart + ' ' + currentWeekEnd)
// 检查日期范围是否完全在本周内
const isCurrentWeek = begin >= currentWeekStart && end <= currentWeekEnd;
console.log(nextWeekStart + ' ' + nextWeekEnd)
// 检查日期范围是否完全在下周内
const isNextWeek = begin >= nextWeekStart && end <= nextWeekEnd;
// 检查日期范围是否跨越本周和下周(部分在本周,部分在下周)
const isOverlapping = (begin <= currentWeekEnd && end >= nextWeekStart);
if (isCurrentWeek) {
console.log('本周')
return true;
} else if (isNextWeek || isOverlapping) {
console.log('下周')
return true;
} else {
console.log('非本周或下周')
return false;
}
}
//是否属于当前周
const isInRange = (bengin : any, end : any) => {
const benginDate = new Date(bengin)
const endDate = new Date(end)
const currentDate = new Date()
return currentDate >= benginDate && currentDate <= endDate
}
//日报点击
const datePlanClick = (item : any) => {
console.log(item)
//展示周计划的时候需要校验周计划状态
if (prop.showPlan) {
if (item.dataState == null || item.dataState == 'undefined') {
uni.showToast({
title: '请先提交周计划',
icon: 'none'
})
return
}
if (item.dataState == 0) {
uni.showToast({
title: '周计划审核中...',
icon: 'none'
})
return
}
}
//审批中 已通过
if (item.dayStatus == 1 || item.dayStatus == 2) {
uni.showToast({
title: '跳转日报详情页面',
icon: 'none',
duration: 2000
})
} else {//未提交或者驳回
if (!isDateInCurrentWeek(item.fullDate)) {
uni.showToast({
title: '只能提交本周内的日报',
icon: 'none'
})
return
}
uni.showToast({
title: '跳转日报填写页面',
icon: 'none',
duration: 2000
})
}
}
/**
* 判断某个日期是否属于本周
* @param {Date|string} targetDate - 目标日期(Date 对象或 "YYYY-MM-DD" 字符串)
* @returns {boolean} - 是否属于本周
*/
function isDateInCurrentWeek(targetDate : any) : Boolean {
// 如果传入的是字符串,转换为 Date 对象
const date = typeof targetDate === 'string' ? new Date(targetDate) : new Date(targetDate);
// 获取当前日期
const today = new Date();
// 计算本周一的日期(以周一作为一周的第一天)
const currentWeekMonday = new Date(today);
currentWeekMonday.setDate(today.getDate() - today.getDay() + 1); // getDay() 周日是 0,周一是 1,...,周六是 6
currentWeekMonday.setHours(0, 0, 0, 0); // 清除时间部分,确保比较的是日期
// 计算本周日的日期
const currentWeekSunday = new Date(currentWeekMonday);
currentWeekSunday.setDate(currentWeekMonday.getDate() + 6);
currentWeekSunday.setHours(23, 59, 59, 999); // 设置为周日最后一刻
// 判断目标日期是否在本周范围内
return date >= currentWeekMonday && date <= currentWeekSunday;
}
//月份切换
const monthSwitch = (e : any) => {
console.log(e)
setDate(e.year, e.month)
}
//日期转字符串格式
const dateToStr = (date : any) => {
var year = date.getFullYear() //年
var month = date.getMonth() //月
var day = date.getDate() //日
var hours = date.getHours() //时
var min = date.getMinutes() //分
var second = date.getSeconds() //秒
return year + "-" +
((month + 1) > 9 ? (month + 1) : "0" + (month + 1)) + "-" +
(day > 9 ? day : ("0" + day)) + " " +
(hours > 9 ? hours : ("0" + hours)) + ":" +
(min > 9 ? min : ("0" + min))
}
//字符串转日期
const strToDate = (str : string) => {
var date = new Date(str)
return date.getTime()
}
</script>
<style>
</style>
周计划日报数据示例
含用户信息 ,周计划信息和状态,日报信息和状态,是否休假
const planList = [{
//计划编码和id
"planId": 58,
"planCode": "1015297758478274563",
//本周开始 截止时间
"beginDate": "2025-09-08",
"endDate": "2025-09-14",
"planPeriod": "2025-09-08~2025-09-14",
//用户信息
"userCode": "1009761934881456147",
"username": "员工001",
"departCode": "951784785749401608",
"departName": "xx***公司",
//周一到周日状态信息
"monday": "2025-09-08",
"mondayStatus": 0,
"tuesday": "2025-09-09",
"tuesdayStatus": 1,
"wednesday": "2025-09-10",
"wednesdayStatus": 1,
"thursday": "2025-09-11",
"thursdayStatus": 0,
"friday": "2025-09-12",
"fridayStatus": 0,
"saturday": "2025-09-13",
"saturdayStatus": 0,
"sunday": "2025-09-14",
"sundayStatus": 0,
//
"weekWorkPlan": "工作计划",
"workSummary": '跟最后工作总结',
"coordinateHelp": "需要协调需帮助",
//附件列表 字符串 逗号分隔
"attachIds": "",
//创建更新时间
"gmtCreate": "2025-09-03 08:27:25",
"gmtModified": "2025-09-03 08:27:25",
//周计划状态
"dataState": 0,
//是否请假 周一到周五
"mondayIsHoliday": null,
"tuesdayIsHoliday": 1,
"wednesdayIsHoliday": 0,
"thursdayIsHoliday": null,
"fridayIsHoliday": null,
"saturdayIsHoliday": null,
"sundayIsHoliday": null
}]