vue-business-date-picker
Version:
一个基于Element UI的Vue工作日日期选择器组件,支持自动禁用周末和节假日
587 lines (535 loc) • 30.8 kB
JavaScript
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('dayjs'), require('chinese-days')) :
typeof define === 'function' && define.amd ? define(['dayjs', 'chinese-days'], factory) :
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.BusinessDatePicker = factory(global.dayjs, global.chineseDays));
})(this, (function (dayjs, chineseDays) { 'use strict';
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
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);
}
return __vue_component__;
}));