UNPKG

vue-business-date-picker

Version:

一个基于Element UI的Vue工作日日期选择器组件,支持自动禁用周末和节假日

582 lines (531 loc) 29.4 kB
import dayjs from 'dayjs'; import chineseDays from 'chinese-days'; // // // // // // // // // // // // // // // // // // var script = { name: "BusinessDatePicker", props: { value: { type: [String, Date], default: null, }, // 日期选择器类型 type: { type: String, default: "date", }, // 占位符 placeholder: { type: String, default: "请选择日期", }, // 显示格式 format: { type: String, default: "yyyy-MM-dd", }, // 值格式 valueFormat: { type: String, default: "yyyy-MM-dd", }, // 是否可清空 clearable: { type: Boolean, default: true, }, // 尺寸 size: { type: String, default: "medium", }, // 是否只读 readonly: { type: Boolean, default: false, }, // 是否可编辑 editable: { type: Boolean, default: true, }, // 是否禁用周末 disableWeekends: { type: Boolean, default: true, }, // 是否禁用节假日 disableHolidays: { type: Boolean, default: true, }, // 是否启用调休工作日(调休的周末可以选择) enableWorkDays: { type: Boolean, default: false, }, // 允许选择的日期范围(向前多少天) beforeDays: { type: Number, default: 0, }, // 允许选择的日期范围(向后多少天) afterDays: { type: Number, default: 0, }, // 基准日期(默认为当前日期) baseDate: { type: [String, Date], default: null, }, // 自定义节假日列表 customHolidays: { type: Array, default: () => [], }, }, data() { return { currentValue: this.value, }; }, computed: { // 基准日期计算 baseDateComputed() { if (this.baseDate) { return dayjs(this.baseDate); } return dayjs(); }, // 计算节假日数据获取范围(当前月±1个月) holidayDataRange() { const baseDate = this.baseDateComputed; // 计算实际的日期选择范围 let actualBeforeDays = this.beforeDays; let actualAfterDays = this.afterDays; // 如果没有设置具体的日期范围,使用固定的前后1个月范围 if (actualBeforeDays === 0 && actualAfterDays === 0) { // 获取当前月的第一天 const currentMonthStart = baseDate.startOf('month'); // 获取前一个月的第一天 const startDate = currentMonthStart.subtract(1, 'month').format('YYYY-MM-DD'); // 获取下一个月的最后一天 const endDate = baseDate.endOf('month').add(1, 'month').format('YYYY-MM-DD'); return { startDate, endDate }; } else { // 如果设置了具体范围,扩展一些缓冲区以确保覆盖完整 const bufferDays = 30; // 额外缓冲 actualBeforeDays += bufferDays; actualAfterDays += bufferDays; const startDate = baseDate.subtract(actualBeforeDays, 'day').format('YYYY-MM-DD'); const endDate = baseDate.add(actualAfterDays, 'day').format('YYYY-MM-DD'); return { startDate, endDate }; } }, // 通过chineseDays获取的节假日列表 chineseDaysHolidays() { const { startDate, endDate } = this.holidayDataRange; try { // 使用chineseDays获取节假日,包含周末节假日 return chineseDays.getHolidaysInRange(startDate, endDate, true); } catch (error) { console.warn('获取chineseDays节假日数据失败,将不禁用节假日:', error); // 如果chineseDays获取失败,返回空数组,不禁用任何节假日 return []; } }, // 合并的节假日列表(chineseDays节假日 + 自定义节假日) mergedHolidays() { return [...this.chineseDaysHolidays, ...this.customHolidays]; }, // Element UI 日期选择器配置 pickerOptions() { const options = { disabledDate: this.disabledDate, }; // 如果用户传入了额外的 pickerOptions,进行合并 if (this.$attrs["picker-options"]) { return { ...this.$attrs["picker-options"], ...options, // 如果用户也定义了 disabledDate,需要合并两个函数 disabledDate: (time) => { const userDisabled = this.$attrs["picker-options"].disabledDate; const componentDisabled = this.disabledDate(time); // 任意一个返回 true 就禁用 return componentDisabled || (userDisabled && userDisabled(time)); }, }; } return options; }, }, watch: { value(newVal) { this.currentValue = newVal; }, currentValue(newVal) { this.$emit("input", newVal); }, }, mounted() { }, methods: { /** * 禁用日期判断函数 * @param {Date} time - 要判断的日期 * @returns {boolean} - 是否禁用 */ disabledDate(time) { const date = dayjs(time); const dateString = date.format("YYYY-MM-DD"); const today = this.baseDateComputed; // 检查日期范围限制 if (this.beforeDays > 0 || this.afterDays > 0) { const minDate = today.subtract(this.beforeDays, "day"); const maxDate = today.add(this.afterDays, "day"); if (date.isBefore(minDate, "day") || date.isAfter(maxDate, "day")) { return true; } } // 检查是否为周末 if (this.disableWeekends && this.isWeekend(date)) { // 如果是周末,但这天是调休工作日,则不禁用 // 这样确保了即使设置了禁用周末,调休需要上班的周末也能被选择 if (this.isWorkDay(dateString)) { return false; } return true; } // 如果启用调休工作日功能,且当前日期是调休工作日,则不禁用 // 这个选项控制是否显示所有调休工作日(包括非周末的调休日) if (this.enableWorkDays && this.isWorkDay(dateString)) { return false; } // 检查是否为节假日 if (this.disableHolidays && this.isHolidayDate(dateString)) { return true; } return false; }, /** * 判断是否为周末 * @param {dayjs} date - dayjs日期对象 * @returns {boolean} */ isWeekend(date) { const day = date.day(); return day === 0 || day === 6; // 周日为0,周六为6 }, /** * 判断是否为节假日 * @param {string} dateString - 日期字符串 (YYYY-MM-DD) * @returns {boolean} */ isHolidayDate(dateString) { // 检查自定义节假日 if (this.customHolidays.includes(dateString)) { return true; } // 检查预获取的chineseDays节假日数据 if (this.chineseDaysHolidays.includes(dateString)) { return true; } // 如果日期不在预获取范围内,动态查询该日期 const { startDate, endDate } = this.holidayDataRange; if (dateString < startDate || dateString > endDate) { try { // 动态查询单个日期是否为节假日 return chineseDays.isHoliday(dateString); } catch (error) { console.warn(`动态查询日期 ${dateString} 节假日状态失败:`, error); return false; } } return false; }, /** * 处理日期变化 * @param {string} value - 选中的日期值 */ handleChange(value) { this.$emit("change", value); }, /** * 获取当前所有节假日列表(系统 + 自定义) * @returns {Array} */ getAllHolidaysList() { return this.mergedHolidays; }, /** * 检查指定日期是否可选择 * @param {string|Date} date - 要检查的日期 * @returns {boolean} */ isDateSelectable(date) { const mockTime = new Date(date); return !this.disabledDate(mockTime); }, /** * 获取指定日期范围内的可选日期 * @param {string} startDate - 开始日期 * @param {string} endDate - 结束日期 * @returns {Array} */ getSelectableDatesInRange(startDate, endDate) { const start = dayjs(startDate); const end = dayjs(endDate); const selectableDates = []; let current = start; while (current.isSameOrBefore(end, "day")) { if (this.isDateSelectable(current.toDate())) { selectableDates.push(current.format("YYYY-MM-DD")); } current = current.add(1, "day"); } return selectableDates; }, /** * 判断是否为调休工作日 * @param {string} dateString - 日期字符串 (YYYY-MM-DD) * @returns {boolean} */ isWorkDay(dateString) { try { return chineseDays.isWorkday(dateString); } catch (error) { console.warn('获取chineseDays工作日数据失败,将不启用调休工作日:', error); // 如果chineseDays获取失败,返回false,不启用调休工作日功能 return false; } }, /** * 重置日期选择器 */ reset() { this.currentValue = null; this.$emit("input", null); this.$emit("change", null); }, }, }; function normalizeComponent(template, style, script, scopeId, isFunctionalTemplate, moduleIdentifier /* server only */, shadowMode, createInjector, createInjectorSSR, createInjectorShadow) { if (typeof shadowMode !== 'boolean') { createInjectorSSR = createInjector; createInjector = shadowMode; shadowMode = false; } // Vue.extend constructor export interop. const options = typeof script === 'function' ? script.options : script; // render functions if (template && template.render) { options.render = template.render; options.staticRenderFns = template.staticRenderFns; options._compiled = true; // functional template if (isFunctionalTemplate) { options.functional = true; } } // scopedId if (scopeId) { options._scopeId = scopeId; } let hook; if (moduleIdentifier) { // server build hook = function (context) { // 2.3 injection context = context || // cached call (this.$vnode && this.$vnode.ssrContext) || // stateful (this.parent && this.parent.$vnode && this.parent.$vnode.ssrContext); // functional // 2.2 with runInNewContext: true if (!context && typeof __VUE_SSR_CONTEXT__ !== 'undefined') { context = __VUE_SSR_CONTEXT__; } // inject component styles if (style) { style.call(this, createInjectorSSR(context)); } // register component module identifier for async chunk inference if (context && context._registeredComponents) { context._registeredComponents.add(moduleIdentifier); } }; // used by ssr in case component is cached and beforeCreate // never gets called options._ssrRegister = hook; } else if (style) { hook = shadowMode ? function (context) { style.call(this, createInjectorShadow(context, this.$root.$options.shadowRoot)); } : function (context) { style.call(this, createInjector(context)); }; } if (hook) { if (options.functional) { // register for functional component in vue file const originalRender = options.render; options.render = function renderWithStyleInjection(h, context) { hook.call(context); return originalRender(h, context); }; } else { // inject component registration as beforeCreate hook const existing = options.beforeCreate; options.beforeCreate = existing ? [].concat(existing, hook) : [hook]; } } return script; } const isOldIE = typeof navigator !== 'undefined' && /msie [6-9]\\b/.test(navigator.userAgent.toLowerCase()); function createInjector(context) { return (id, style) => addStyle(id, style); } let HEAD; const styles = {}; function addStyle(id, css) { const group = isOldIE ? css.media || 'default' : id; const style = styles[group] || (styles[group] = { ids: new Set(), styles: [] }); if (!style.ids.has(id)) { style.ids.add(id); let code = css.source; if (css.map) { // https://developer.chrome.com/devtools/docs/javascript-debugging // this makes source maps inside style tags work properly in Chrome code += '\n/*# sourceURL=' + css.map.sources[0] + ' */'; // http://stackoverflow.com/a/26603875 code += '\n/*# sourceMappingURL=data:application/json;base64,' + btoa(unescape(encodeURIComponent(JSON.stringify(css.map)))) + ' */'; } if (!style.element) { style.element = document.createElement('style'); style.element.type = 'text/css'; if (css.media) style.element.setAttribute('media', css.media); if (HEAD === undefined) { HEAD = document.head || document.getElementsByTagName('head')[0]; } HEAD.appendChild(style.element); } if ('styleSheet' in style.element) { style.styles.push(code); style.element.styleSheet.cssText = style.styles .filter(Boolean) .join('\n'); } else { const index = style.ids.size - 1; const textNode = document.createTextNode(code); const nodes = style.element.childNodes; if (nodes[index]) style.element.removeChild(nodes[index]); if (nodes.length) style.element.insertBefore(textNode, nodes[index]); else style.element.appendChild(textNode); } } } /* script */ const __vue_script__ = script; /* template */ var __vue_render__ = function () { var _vm = this; var _h = _vm.$createElement; var _c = _vm._self._c || _h; return _c( "el-date-picker", _vm._g( _vm._b( { attrs: { type: _vm.type, placeholder: _vm.placeholder, format: _vm.format, "value-format": _vm.valueFormat, "picker-options": _vm.pickerOptions, clearable: _vm.clearable, size: _vm.size, readonly: _vm.readonly, editable: _vm.editable, }, on: { change: _vm.handleChange }, model: { value: _vm.currentValue, callback: function ($$v) { _vm.currentValue = $$v; }, expression: "currentValue", }, }, "el-date-picker", _vm.$attrs, false ), _vm.$listeners ) ) }; var __vue_staticRenderFns__ = []; __vue_render__._withStripped = true; /* style */ const __vue_inject_styles__ = function (inject) { if (!inject) return inject("data-v-4d9c7502_0", { source: "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\r\n/* 如果需要自定义样式,可以在这里添加 */\r\n", map: {"version":3,"sources":["E:\\business-date-picker-npm\\src\\BusinessDatePicker.vue"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgXA,sBAAA","file":"BusinessDatePicker.vue","sourcesContent":["<template>\r\n <el-date-picker\r\n v-model=\"currentValue\"\r\n :type=\"type\"\r\n :placeholder=\"placeholder\"\r\n :format=\"format\"\r\n :value-format=\"valueFormat\"\r\n :picker-options=\"pickerOptions\"\r\n :clearable=\"clearable\"\r\n :size=\"size\"\r\n :readonly=\"readonly\"\r\n :editable=\"editable\"\r\n v-bind=\"$attrs\"\r\n v-on=\"$listeners\"\r\n @change=\"handleChange\"\r\n />\r\n</template>\r\n\r\n<script>\r\nimport dayjs from \"dayjs\";\r\nimport chineseDays from \"chinese-days\";\r\n\r\nexport default {\r\n name: \"BusinessDatePicker\",\r\n props: {\r\n value: {\r\n type: [String, Date],\r\n default: null,\r\n },\r\n // 日期选择器类型\r\n type: {\r\n type: String,\r\n default: \"date\",\r\n },\r\n // 占位符\r\n placeholder: {\r\n type: String,\r\n default: \"请选择日期\",\r\n },\r\n // 显示格式\r\n format: {\r\n type: String,\r\n default: \"yyyy-MM-dd\",\r\n },\r\n // 值格式\r\n valueFormat: {\r\n type: String,\r\n default: \"yyyy-MM-dd\",\r\n },\r\n // 是否可清空\r\n clearable: {\r\n type: Boolean,\r\n default: true,\r\n },\r\n // 尺寸\r\n size: {\r\n type: String,\r\n default: \"medium\",\r\n },\r\n // 是否只读\r\n readonly: {\r\n type: Boolean,\r\n default: false,\r\n },\r\n // 是否可编辑\r\n editable: {\r\n type: Boolean,\r\n default: true,\r\n },\r\n // 是否禁用周末\r\n disableWeekends: {\r\n type: Boolean,\r\n default: true,\r\n },\r\n // 是否禁用节假日\r\n disableHolidays: {\r\n type: Boolean,\r\n default: true,\r\n },\r\n // 是否启用调休工作日(调休的周末可以选择)\r\n enableWorkDays: {\r\n type: Boolean,\r\n default: false,\r\n },\r\n // 允许选择的日期范围(向前多少天)\r\n beforeDays: {\r\n type: Number,\r\n default: 0,\r\n },\r\n // 允许选择的日期范围(向后多少天)\r\n afterDays: {\r\n type: Number,\r\n default: 0,\r\n },\r\n // 基准日期(默认为当前日期)\r\n baseDate: {\r\n type: [String, Date],\r\n default: null,\r\n },\r\n // 自定义节假日列表\r\n customHolidays: {\r\n type: Array,\r\n default: () => [],\r\n },\r\n\r\n },\r\n data() {\r\n return {\r\n currentValue: this.value,\r\n };\r\n },\r\n computed: {\r\n // 基准日期计算\r\n baseDateComputed() {\r\n if (this.baseDate) {\r\n return dayjs(this.baseDate);\r\n }\r\n return dayjs();\r\n },\r\n\r\n // 计算节假日数据获取范围(当前月±1个月)\r\n holidayDataRange() {\r\n const baseDate = this.baseDateComputed;\r\n\r\n // 计算实际的日期选择范围\r\n let actualBeforeDays = this.beforeDays;\r\n let actualAfterDays = this.afterDays;\r\n\r\n // 如果没有设置具体的日期范围,使用固定的前后1个月范围\r\n if (actualBeforeDays === 0 && actualAfterDays === 0) {\r\n // 获取当前月的第一天\r\n const currentMonthStart = baseDate.startOf('month');\r\n // 获取前一个月的第一天\r\n const startDate = currentMonthStart.subtract(1, 'month').format('YYYY-MM-DD');\r\n // 获取下一个月的最后一天\r\n const endDate = baseDate.endOf('month').add(1, 'month').format('YYYY-MM-DD');\r\n\r\n return { startDate, endDate };\r\n } else {\r\n // 如果设置了具体范围,扩展一些缓冲区以确保覆盖完整\r\n const bufferDays = 30; // 额外缓冲\r\n actualBeforeDays += bufferDays;\r\n actualAfterDays += bufferDays;\r\n\r\n const startDate = baseDate.subtract(actualBeforeDays, 'day').format('YYYY-MM-DD');\r\n const endDate = baseDate.add(actualAfterDays, 'day').format('YYYY-MM-DD');\r\n\r\n return { startDate, endDate };\r\n }\r\n },\r\n\r\n // 通过chineseDays获取的节假日列表\r\n chineseDaysHolidays() {\r\n const { startDate, endDate } = this.holidayDataRange;\r\n\r\n try {\r\n // 使用chineseDays获取节假日,包含周末节假日\r\n return chineseDays.getHolidaysInRange(startDate, endDate, true);\r\n } catch (error) {\r\n console.warn('获取chineseDays节假日数据失败,将不禁用节假日:', error);\r\n // 如果chineseDays获取失败,返回空数组,不禁用任何节假日\r\n return [];\r\n }\r\n },\r\n\r\n // 合并的节假日列表(chineseDays节假日 + 自定义节假日)\r\n mergedHolidays() {\r\n return [...this.chineseDaysHolidays, ...this.customHolidays];\r\n },\r\n\r\n // Element UI 日期选择器配置\r\n pickerOptions() {\r\n const options = {\r\n disabledDate: this.disabledDate,\r\n };\r\n\r\n // 如果用户传入了额外的 pickerOptions,进行合并\r\n if (this.$attrs[\"picker-options\"]) {\r\n return {\r\n ...this.$attrs[\"picker-options\"],\r\n ...options,\r\n // 如果用户也定义了 disabledDate,需要合并两个函数\r\n disabledDate: (time) => {\r\n const userDisabled = this.$attrs[\"picker-options\"].disabledDate;\r\n const componentDisabled = this.disabledDate(time);\r\n\r\n // 任意一个返回 true 就禁用\r\n return componentDisabled || (userDisabled && userDisabled(time));\r\n },\r\n };\r\n }\r\n\r\n return options;\r\n },\r\n },\r\n watch: {\r\n value(newVal) {\r\n this.currentValue = newVal;\r\n },\r\n currentValue(newVal) {\r\n this.$emit(\"input\", newVal);\r\n },\r\n },\r\n mounted() {\r\n\r\n },\r\n methods: {\r\n /**\r\n * 禁用日期判断函数\r\n * @param {Date} time - 要判断的日期\r\n * @returns {boolean} - 是否禁用\r\n */\r\n disabledDate(time) {\r\n const date = dayjs(time);\r\n const dateString = date.format(\"YYYY-MM-DD\");\r\n const today = this.baseDateComputed;\r\n\r\n // 检查日期范围限制\r\n if (this.beforeDays > 0 || this.afterDays > 0) {\r\n const minDate = today.subtract(this.beforeDays, \"day\");\r\n const maxDate = today.add(this.afterDays, \"day\");\r\n\r\n if (date.isBefore(minDate, \"day\") || date.isAfter(maxDate, \"day\")) {\r\n return true;\r\n }\r\n }\r\n\r\n // 检查是否为周末\r\n if (this.disableWeekends && this.isWeekend(date)) {\r\n // 如果是周末,但这天是调休工作日,则不禁用\r\n // 这样确保了即使设置了禁用周末,调休需要上班的周末也能被选择\r\n if (this.isWorkDay(dateString)) {\r\n return false;\r\n }\r\n return true;\r\n }\r\n\r\n // 如果启用调休工作日功能,且当前日期是调休工作日,则不禁用\r\n // 这个选项控制是否显示所有调休工作日(包括非周末的调休日)\r\n if (this.enableWorkDays && this.isWorkDay(dateString)) {\r\n return false;\r\n }\r\n\r\n // 检查是否为节假日\r\n if (this.disableHolidays && this.isHolidayDate(dateString)) {\r\n return true;\r\n }\r\n\r\n return false;\r\n },\r\n\r\n /**\r\n * 判断是否为周末\r\n * @param {dayjs} date - dayjs日期对象\r\n * @returns {boolean}\r\n */\r\n isWeekend(date) {\r\n const day = date.day();\r\n return day === 0 || day === 6; // 周日为0,周六为6\r\n },\r\n\r\n /**\r\n * 判断是否为节假日\r\n * @param {string} dateString - 日期字符串 (YYYY-MM-DD)\r\n * @returns {boolean}\r\n */\r\n isHolidayDate(dateString) {\r\n // 检查自定义节假日\r\n if (this.customHolidays.includes(dateString)) {\r\n return true;\r\n }\r\n\r\n // 检查预获取的chineseDays节假日数据\r\n if (this.chineseDaysHolidays.includes(dateString)) {\r\n return true;\r\n }\r\n\r\n // 如果日期不在预获取范围内,动态查询该日期\r\n const { startDate, endDate } = this.holidayDataRange;\r\n if (dateString < startDate || dateString > endDate) {\r\n try {\r\n // 动态查询单个日期是否为节假日\r\n return chineseDays.isHoliday(dateString);\r\n } catch (error) {\r\n console.warn(`动态查询日期 ${dateString} 节假日状态失败:`, error);\r\n return false;\r\n }\r\n }\r\n\r\n return false;\r\n },\r\n\r\n /**\r\n * 处理日期变化\r\n * @param {string} value - 选中的日期值\r\n */\r\n handleChange(value) {\r\n this.$emit(\"change\", value);\r\n },\r\n\r\n /**\r\n * 获取当前所有节假日列表(系统 + 自定义)\r\n * @returns {Array}\r\n */\r\n getAllHolidaysList() {\r\n return this.mergedHolidays;\r\n },\r\n\r\n /**\r\n * 检查指定日期是否可选择\r\n * @param {string|Date} date - 要检查的日期\r\n * @returns {boolean}\r\n */\r\n isDateSelectable(date) {\r\n const mockTime = new Date(date);\r\n return !this.disabledDate(mockTime);\r\n },\r\n\r\n /**\r\n * 获取指定日期范围内的可选日期\r\n * @param {string} startDate - 开始日期\r\n * @param {string} endDate - 结束日期\r\n * @returns {Array}\r\n */\r\n getSelectableDatesInRange(startDate, endDate) {\r\n const start = dayjs(startDate);\r\n const end = dayjs(endDate);\r\n const selectableDates = [];\r\n\r\n let current = start;\r\n while (current.isSameOrBefore(end, \"day\")) {\r\n if (this.isDateSelectable(current.toDate())) {\r\n selectableDates.push(current.format(\"YYYY-MM-DD\"));\r\n }\r\n current = current.add(1, \"day\");\r\n }\r\n\r\n return selectableDates;\r\n },\r\n\r\n /**\r\n * 判断是否为调休工作日\r\n * @param {string} dateString - 日期字符串 (YYYY-MM-DD)\r\n * @returns {boolean}\r\n */\r\n isWorkDay(dateString) {\r\n try {\r\n return chineseDays.isWorkday(dateString);\r\n } catch (error) {\r\n console.warn('获取chineseDays工作日数据失败,将不启用调休工作日:', error);\r\n // 如果chineseDays获取失败,返回false,不启用调休工作日功能\r\n return false;\r\n }\r\n },\r\n\r\n /**\r\n * 重置日期选择器\r\n */\r\n reset() {\r\n this.currentValue = null;\r\n this.$emit(\"input\", null);\r\n this.$emit(\"change\", null);\r\n },\r\n },\r\n};\r\n</script>\r\n\r\n<style scoped>\r\n/* 如果需要自定义样式,可以在这里添加 */\r\n</style>\r\n"]}, media: undefined }); }; /* scoped */ const __vue_scope_id__ = "data-v-4d9c7502"; /* module identifier */ const __vue_module_identifier__ = undefined; /* functional template */ const __vue_is_functional_template__ = false; /* style inject SSR */ /* style inject shadow dom */ const __vue_component__ = /*#__PURE__*/normalizeComponent( { render: __vue_render__, staticRenderFns: __vue_staticRenderFns__ }, __vue_inject_styles__, __vue_script__, __vue_scope_id__, __vue_is_functional_template__, __vue_module_identifier__, false, createInjector, undefined, undefined ); // 自动安装 __vue_component__.install = function (Vue) { Vue.component(__vue_component__.name, __vue_component__); }; // 支持使用标签的方式引入 if (typeof window !== 'undefined' && window.Vue) { __vue_component__.install(window.Vue); } export { __vue_component__ as default };