更新记录

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
}]

隐私、权限声明

1. 本插件需要申请的系统权限列表:

2. 本插件采集的数据、发送的服务器地址、以及数据用途说明:

3. 本插件是否包含广告,如包含需详细说明广告表达方式、展示频率:

许可协议

MIT协议