@ql-web/view-report 1.0.2 → 1.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/view-report.css +223 -1
- package/view-report.es.js +449 -232
- package/view-report.umd.js +578 -1
package/view-report.es.js
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
|
-
import { defineComponent
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
|
|
1
|
+
import { defineComponent, ref, computed, watch, onMounted, onUnmounted, isVue2 } from "vue-demi";
|
|
2
|
+
import { createElementBlock, openBlock, normalizeStyle, renderSlot, createTextVNode, toDisplayString, createElementVNode, withDirectives, createCommentVNode, vShow, createStaticVNode, Fragment, renderList, normalizeClass } from "vue";
|
|
3
|
+
const _export_sfc = (sfc, props) => {
|
|
4
|
+
const target = sfc.__vccOpts || sfc;
|
|
5
|
+
for (const [key, val] of props) {
|
|
6
|
+
target[key] = val;
|
|
7
|
+
}
|
|
8
|
+
return target;
|
|
9
|
+
};
|
|
10
|
+
const _sfc_main$1 = defineComponent({
|
|
10
11
|
name: "MyButton",
|
|
11
12
|
// 必须声明 name,用于全局注册
|
|
12
13
|
props: {
|
|
@@ -19,126 +20,133 @@ const G = M({
|
|
|
19
20
|
default: "#409eff"
|
|
20
21
|
}
|
|
21
22
|
},
|
|
22
|
-
setup(
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
}
|
|
23
|
+
setup(props, { emit }) {
|
|
24
|
+
const handleClick = () => {
|
|
25
|
+
emit("click", "按钮被点击");
|
|
26
|
+
};
|
|
27
|
+
return { handleClick };
|
|
26
28
|
}
|
|
27
29
|
});
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
},
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
const Q = K.exports;
|
|
42
|
-
class v {
|
|
30
|
+
function _sfc_render$1(_ctx, _cache, $props, $setup, $data, $options) {
|
|
31
|
+
return openBlock(), createElementBlock("button", {
|
|
32
|
+
class: "my-button",
|
|
33
|
+
style: normalizeStyle({ background: _ctx.color }),
|
|
34
|
+
onClick: _cache[0] || (_cache[0] = (...args) => _ctx.handleClick && _ctx.handleClick(...args))
|
|
35
|
+
}, [
|
|
36
|
+
renderSlot(_ctx.$slots, "default", {}, () => [
|
|
37
|
+
createTextVNode(toDisplayString(_ctx.text), 1)
|
|
38
|
+
], true)
|
|
39
|
+
], 4);
|
|
40
|
+
}
|
|
41
|
+
const MyButton = /* @__PURE__ */ _export_sfc(_sfc_main$1, [["render", _sfc_render$1], ["__scopeId", "data-v-d19bd5c3"]]);
|
|
42
|
+
class DateUtils {
|
|
43
43
|
/**
|
|
44
44
|
* 格式化日期为 YYYY-MM-DD 格式
|
|
45
45
|
* @param {Date} date 日期对象
|
|
46
46
|
* @returns {string} 格式化后的日期字符串
|
|
47
47
|
*/
|
|
48
|
-
static formatDate(
|
|
49
|
-
if (!
|
|
50
|
-
const
|
|
51
|
-
|
|
48
|
+
static formatDate(date) {
|
|
49
|
+
if (!date || !(date instanceof Date) || isNaN(date.getTime())) return "";
|
|
50
|
+
const year = date.getFullYear();
|
|
51
|
+
const month = String(date.getMonth() + 1).padStart(2, "0");
|
|
52
|
+
const day = String(date.getDate()).padStart(2, "0");
|
|
53
|
+
return `${year}-${month}-${day}`;
|
|
52
54
|
}
|
|
53
55
|
/**
|
|
54
56
|
* 获取指定日期所在月份的第一天
|
|
55
57
|
* @param {Date} date 基准日期
|
|
56
58
|
* @returns {Date} 月份第一天
|
|
57
59
|
*/
|
|
58
|
-
static getFirstDayOfMonth(
|
|
59
|
-
return new Date(
|
|
60
|
+
static getFirstDayOfMonth(date) {
|
|
61
|
+
return new Date(date.getFullYear(), date.getMonth(), 1);
|
|
60
62
|
}
|
|
61
63
|
/**
|
|
62
64
|
* 获取指定日期所在月份的最后一天
|
|
63
65
|
* @param {Date} date 基准日期
|
|
64
66
|
* @returns {Date} 月份最后一天
|
|
65
67
|
*/
|
|
66
|
-
static getLastDayOfMonth(
|
|
67
|
-
return new Date(
|
|
68
|
+
static getLastDayOfMonth(date) {
|
|
69
|
+
return new Date(date.getFullYear(), date.getMonth() + 1, 0);
|
|
68
70
|
}
|
|
69
71
|
/**
|
|
70
72
|
* 获取日期对应的星期数(周日=0,周六=6)
|
|
71
73
|
* @returns {number} 星期数
|
|
72
74
|
*/
|
|
73
|
-
static getDayOfWeek(
|
|
74
|
-
return
|
|
75
|
+
static getDayOfWeek(date) {
|
|
76
|
+
return date.getDay();
|
|
75
77
|
}
|
|
76
78
|
/**
|
|
77
79
|
* 上一个月(支持跨年,如2026-01 → 2025-12)
|
|
78
80
|
* @returns {Date} 上月日期
|
|
79
81
|
*/
|
|
80
|
-
static getPrevMonth(
|
|
81
|
-
const
|
|
82
|
-
|
|
82
|
+
static getPrevMonth(date) {
|
|
83
|
+
const year = date.getMonth() === 0 ? date.getFullYear() - 1 : date.getFullYear();
|
|
84
|
+
const month = date.getMonth() === 0 ? 11 : date.getMonth() - 1;
|
|
85
|
+
return new Date(year, month, 1);
|
|
83
86
|
}
|
|
84
87
|
/**
|
|
85
88
|
* 下一个月(支持跨年,如2025-12 → 2026-01)
|
|
86
89
|
* @returns {Date} 下月日期
|
|
87
90
|
*/
|
|
88
|
-
static getNextMonth(
|
|
89
|
-
const
|
|
90
|
-
|
|
91
|
+
static getNextMonth(date) {
|
|
92
|
+
const year = date.getMonth() === 11 ? date.getFullYear() + 1 : date.getFullYear();
|
|
93
|
+
const month = date.getMonth() === 11 ? 0 : date.getMonth() + 1;
|
|
94
|
+
return new Date(year, month, 1);
|
|
91
95
|
}
|
|
92
96
|
/**
|
|
93
97
|
* 上一年(直接切换年份,如2026 → 2025)
|
|
94
98
|
* @returns {Date} 上年同月日期
|
|
95
99
|
*/
|
|
96
|
-
static getPrevYear(
|
|
97
|
-
return new Date(
|
|
100
|
+
static getPrevYear(date) {
|
|
101
|
+
return new Date(date.getFullYear() - 1, date.getMonth(), 1);
|
|
98
102
|
}
|
|
99
103
|
/**
|
|
100
104
|
* 下一年(直接切换年份,如2025 → 2026)
|
|
101
105
|
* @returns {Date} 下年同月日期
|
|
102
106
|
*/
|
|
103
|
-
static getNextYear(
|
|
104
|
-
return new Date(
|
|
107
|
+
static getNextYear(date) {
|
|
108
|
+
return new Date(date.getFullYear() + 1, date.getMonth(), 1);
|
|
105
109
|
}
|
|
106
110
|
/**
|
|
107
111
|
* 生成6行7列的日期面板数据(42个,自动补充跨月/跨年日期)
|
|
108
112
|
* @returns {Array} 42个日期对象的数组(6*7)
|
|
109
113
|
*/
|
|
110
|
-
static generateMonthPanel(
|
|
111
|
-
const
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
114
|
+
static generateMonthPanel(currentDate, selectedDate = "") {
|
|
115
|
+
const panel = [];
|
|
116
|
+
const firstDay = this.getFirstDayOfMonth(currentDate);
|
|
117
|
+
const lastDay = this.getLastDayOfMonth(currentDate);
|
|
118
|
+
const firstDayWeek = this.getDayOfWeek(firstDay);
|
|
119
|
+
const prevMonthDaysCount = firstDayWeek;
|
|
120
|
+
for (let i = prevMonthDaysCount; i > 0; i--) {
|
|
121
|
+
const prevDay = new Date(firstDay.getTime() - i * 24 * 60 * 60 * 1e3);
|
|
122
|
+
panel.push({
|
|
123
|
+
date: prevDay,
|
|
124
|
+
formatDate: this.formatDate(prevDay),
|
|
125
|
+
isCurrentMonth: false,
|
|
126
|
+
isSelected: this.formatDate(prevDay) === selectedDate
|
|
119
127
|
});
|
|
120
128
|
}
|
|
121
|
-
const
|
|
122
|
-
for (let
|
|
123
|
-
const
|
|
124
|
-
|
|
125
|
-
date:
|
|
126
|
-
formatDate: this.formatDate(
|
|
127
|
-
isCurrentMonth:
|
|
128
|
-
isSelected: this.formatDate(
|
|
129
|
+
const currentMonthDays = lastDay.getDate();
|
|
130
|
+
for (let i = 1; i <= currentMonthDays; i++) {
|
|
131
|
+
const currentDay = new Date(currentDate.getFullYear(), currentDate.getMonth(), i);
|
|
132
|
+
panel.push({
|
|
133
|
+
date: currentDay,
|
|
134
|
+
formatDate: this.formatDate(currentDay),
|
|
135
|
+
isCurrentMonth: true,
|
|
136
|
+
isSelected: this.formatDate(currentDay) === selectedDate
|
|
129
137
|
});
|
|
130
138
|
}
|
|
131
|
-
const
|
|
132
|
-
for (let
|
|
133
|
-
const
|
|
134
|
-
|
|
135
|
-
date:
|
|
136
|
-
formatDate: this.formatDate(
|
|
137
|
-
isCurrentMonth:
|
|
138
|
-
isSelected: this.formatDate(
|
|
139
|
+
const needNextDays = 42 - panel.length;
|
|
140
|
+
for (let i = 1; i <= needNextDays; i++) {
|
|
141
|
+
const nextDay = new Date(lastDay.getTime() + i * 24 * 60 * 60 * 1e3);
|
|
142
|
+
panel.push({
|
|
143
|
+
date: nextDay,
|
|
144
|
+
formatDate: this.formatDate(nextDay),
|
|
145
|
+
isCurrentMonth: false,
|
|
146
|
+
isSelected: this.formatDate(nextDay) === selectedDate
|
|
139
147
|
});
|
|
140
148
|
}
|
|
141
|
-
return
|
|
149
|
+
return panel;
|
|
142
150
|
}
|
|
143
151
|
// ========== 新增十年跨度相关方法(不改动原有逻辑) ==========
|
|
144
152
|
/**
|
|
@@ -146,214 +154,423 @@ class v {
|
|
|
146
154
|
* @param {Date} date 基准日期
|
|
147
155
|
* @returns {number} 十年起始年份(如2026 → 2020)
|
|
148
156
|
*/
|
|
149
|
-
static getDecadeStart(
|
|
150
|
-
const
|
|
151
|
-
return Math.floor(
|
|
157
|
+
static getDecadeStart(date) {
|
|
158
|
+
const year = date.getFullYear();
|
|
159
|
+
return Math.floor(year / 10) * 10;
|
|
152
160
|
}
|
|
153
161
|
/**
|
|
154
162
|
* 获取下一个十年区间起始年份
|
|
155
163
|
* @param {number} decadeStart 当前十年起始年份
|
|
156
164
|
* @returns {number} 下一个十年起始年份(如2020 → 2030)
|
|
157
165
|
*/
|
|
158
|
-
static getNextDecade(
|
|
159
|
-
return
|
|
166
|
+
static getNextDecade(decadeStart) {
|
|
167
|
+
return decadeStart + 10;
|
|
160
168
|
}
|
|
161
169
|
/**
|
|
162
170
|
* 获取上一个十年区间起始年份
|
|
163
171
|
* @param {number} decadeStart 当前十年起始年份
|
|
164
172
|
* @returns {number} 上一个十年起始年份(如2020 → 2010)
|
|
165
173
|
*/
|
|
166
|
-
static getPrevDecade(
|
|
167
|
-
return
|
|
174
|
+
static getPrevDecade(decadeStart) {
|
|
175
|
+
return decadeStart - 10;
|
|
168
176
|
}
|
|
169
177
|
/**
|
|
170
178
|
* 生成十年跨度的年份数组(如2020-2029)
|
|
171
179
|
* @param {number} decadeStart 十年起始年份
|
|
172
180
|
* @returns {Array} 十年年份数组
|
|
173
181
|
*/
|
|
174
|
-
static generateDecadeYears(
|
|
175
|
-
return Array.from({ length: 10 }, (
|
|
182
|
+
static generateDecadeYears(decadeStart) {
|
|
183
|
+
return Array.from({ length: 10 }, (_, i) => decadeStart + i);
|
|
176
184
|
}
|
|
177
185
|
}
|
|
178
|
-
const
|
|
186
|
+
const _sfc_main = defineComponent({
|
|
179
187
|
name: "ViewDatePicker",
|
|
180
188
|
// Vue2兼容:props定义(vue-demi已适配)
|
|
181
189
|
props: {
|
|
182
190
|
value: {
|
|
183
191
|
// Vue2的v-model绑定值(兼容Vue3的modelValue)
|
|
184
192
|
type: String,
|
|
185
|
-
default: () =>
|
|
193
|
+
default: () => DateUtils.formatDate(/* @__PURE__ */ new Date())
|
|
186
194
|
},
|
|
187
195
|
modelValue: {
|
|
188
196
|
// Vue3的v-model绑定值
|
|
189
197
|
type: String,
|
|
190
|
-
default: () =>
|
|
198
|
+
default: () => DateUtils.formatDate(/* @__PURE__ */ new Date())
|
|
191
199
|
}
|
|
192
200
|
},
|
|
193
201
|
// Vue2/Vue3兼容:emits定义
|
|
194
202
|
emits: ["input", "update:modelValue", "change"],
|
|
195
|
-
setup(
|
|
196
|
-
const
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
203
|
+
setup(props, { emit }) {
|
|
204
|
+
const pickerWrapper = ref(null);
|
|
205
|
+
const dateInput = ref(null);
|
|
206
|
+
const datePanel = ref(null);
|
|
207
|
+
const panelVisible = ref(false);
|
|
208
|
+
const panelStyle = ref({});
|
|
209
|
+
const currentYear = ref((/* @__PURE__ */ new Date()).getFullYear());
|
|
210
|
+
const currentMonth = ref((/* @__PURE__ */ new Date()).getMonth() + 1);
|
|
211
|
+
const hoverDate = ref("");
|
|
212
|
+
const displayDate = ref("");
|
|
213
|
+
const panelType = ref("date");
|
|
214
|
+
const decadeStart = ref(DateUtils.getDecadeStart(new Date(currentYear.value, currentMonth.value - 1)));
|
|
215
|
+
const decadeYears = computed(() => {
|
|
216
|
+
const years = DateUtils.generateDecadeYears(decadeStart.value);
|
|
217
|
+
return Array.isArray(years) ? years : [];
|
|
218
|
+
});
|
|
219
|
+
const getDecadeStartAndEnd = computed(() => {
|
|
220
|
+
const start = decadeStart.value;
|
|
221
|
+
const end = start + 9;
|
|
222
|
+
return `${start}年-${end}年`;
|
|
223
|
+
});
|
|
224
|
+
const panelDates = computed(() => {
|
|
225
|
+
const currentDateTemp = new Date(currentYear.value, currentMonth.value - 1, 1);
|
|
226
|
+
const dates = DateUtils.generateMonthPanel(currentDateTemp, displayDate.value);
|
|
227
|
+
return Array.isArray(dates) ? dates : [];
|
|
228
|
+
});
|
|
229
|
+
const initDisplayDate = () => {
|
|
230
|
+
const initValue = isVue2 ? props.value : props.modelValue;
|
|
231
|
+
if (initValue) {
|
|
232
|
+
displayDate.value = initValue;
|
|
233
|
+
const date = new Date(initValue);
|
|
234
|
+
if (!isNaN(date.getTime())) {
|
|
235
|
+
currentYear.value = date.getFullYear();
|
|
236
|
+
currentMonth.value = date.getMonth() + 1;
|
|
237
|
+
decadeStart.value = DateUtils.getDecadeStart(date);
|
|
238
|
+
}
|
|
211
239
|
} else {
|
|
212
|
-
const
|
|
213
|
-
|
|
240
|
+
const now = /* @__PURE__ */ new Date();
|
|
241
|
+
displayDate.value = DateUtils.formatDate(now);
|
|
242
|
+
currentYear.value = now.getFullYear();
|
|
243
|
+
currentMonth.value = now.getMonth() + 1;
|
|
244
|
+
decadeStart.value = DateUtils.getDecadeStart(now);
|
|
214
245
|
}
|
|
215
246
|
};
|
|
216
|
-
|
|
217
|
-
() => [
|
|
247
|
+
watch(
|
|
248
|
+
() => [props.value, props.modelValue],
|
|
218
249
|
() => {
|
|
219
|
-
|
|
250
|
+
initDisplayDate();
|
|
220
251
|
},
|
|
221
|
-
{ immediate:
|
|
252
|
+
{ immediate: true, deep: true }
|
|
222
253
|
);
|
|
223
|
-
const
|
|
224
|
-
if (!
|
|
225
|
-
const
|
|
226
|
-
|
|
254
|
+
const calcPanelPosition = () => {
|
|
255
|
+
if (!dateInput.value || !datePanel.value) return;
|
|
256
|
+
const inputRect = dateInput.value.getBoundingClientRect();
|
|
257
|
+
const wrapperRect = pickerWrapper.value.getBoundingClientRect();
|
|
258
|
+
panelStyle.value = {
|
|
227
259
|
position: "absolute",
|
|
228
|
-
top: `${
|
|
229
|
-
left: `${
|
|
260
|
+
top: `${inputRect.bottom - wrapperRect.top + 4}px`,
|
|
261
|
+
left: `${inputRect.left - wrapperRect.left}px`,
|
|
230
262
|
zIndex: 9999,
|
|
231
|
-
width:
|
|
263
|
+
width: `322px`
|
|
232
264
|
};
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
265
|
+
};
|
|
266
|
+
const togglePanel = () => {
|
|
267
|
+
panelVisible.value = !panelVisible.value;
|
|
268
|
+
if (panelVisible.value) {
|
|
269
|
+
setTimeout(() => calcPanelPosition(), 0);
|
|
270
|
+
panelType.value = "date";
|
|
271
|
+
}
|
|
272
|
+
};
|
|
273
|
+
const openYearPanel = () => {
|
|
274
|
+
decadeStart.value = DateUtils.getDecadeStart(new Date(currentYear.value, currentMonth.value - 1));
|
|
275
|
+
panelType.value = "year";
|
|
276
|
+
};
|
|
277
|
+
const openMonthPanel = () => {
|
|
278
|
+
panelType.value = "month";
|
|
279
|
+
};
|
|
280
|
+
const selectDecadeYear = (year) => {
|
|
281
|
+
currentYear.value = year;
|
|
282
|
+
panelType.value = "month";
|
|
283
|
+
};
|
|
284
|
+
const selectTargetMonth = (month) => {
|
|
285
|
+
currentMonth.value = month;
|
|
286
|
+
panelType.value = "date";
|
|
287
|
+
};
|
|
288
|
+
const selectDate = (item) => {
|
|
289
|
+
displayDate.value = item.formatDate;
|
|
290
|
+
currentYear.value = item.date.getFullYear();
|
|
291
|
+
currentMonth.value = item.date.getMonth() + 1;
|
|
292
|
+
if (isVue2) {
|
|
293
|
+
emit("input", displayDate.value);
|
|
294
|
+
} else {
|
|
295
|
+
emit("update:modelValue", displayDate.value);
|
|
296
|
+
}
|
|
297
|
+
emit("change", {
|
|
298
|
+
date: item.date,
|
|
299
|
+
formatDate: displayDate.value
|
|
300
|
+
});
|
|
301
|
+
panelVisible.value = false;
|
|
302
|
+
};
|
|
303
|
+
const switchToPrevYear = () => {
|
|
304
|
+
currentYear.value -= 1;
|
|
305
|
+
decadeStart.value = DateUtils.getDecadeStart(new Date(currentYear.value, currentMonth.value - 1));
|
|
306
|
+
};
|
|
307
|
+
const switchToPrevMonth = () => {
|
|
308
|
+
if (currentMonth.value === 1) {
|
|
309
|
+
currentMonth.value = 12;
|
|
310
|
+
currentYear.value -= 1;
|
|
311
|
+
} else {
|
|
312
|
+
currentMonth.value -= 1;
|
|
270
313
|
}
|
|
271
|
-
|
|
272
|
-
}, k = (n) => {
|
|
273
|
-
const l = B(n.target, t.value);
|
|
274
|
-
u.value && t.value && !l && (u.value = !1, i.value = "date");
|
|
275
|
-
}, m = () => {
|
|
276
|
-
u.value && y();
|
|
314
|
+
decadeStart.value = DateUtils.getDecadeStart(new Date(currentYear.value, currentMonth.value - 1));
|
|
277
315
|
};
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
currentYear
|
|
316
|
+
const switchToNextMonth = () => {
|
|
317
|
+
if (currentMonth.value === 12) {
|
|
318
|
+
currentMonth.value = 1;
|
|
319
|
+
currentYear.value += 1;
|
|
320
|
+
} else {
|
|
321
|
+
currentMonth.value += 1;
|
|
322
|
+
}
|
|
323
|
+
decadeStart.value = DateUtils.getDecadeStart(new Date(currentYear.value, currentMonth.value - 1));
|
|
324
|
+
};
|
|
325
|
+
const switchToNextYear = () => {
|
|
326
|
+
currentYear.value += 1;
|
|
327
|
+
decadeStart.value = DateUtils.getDecadeStart(new Date(currentYear.value, currentMonth.value - 1));
|
|
328
|
+
};
|
|
329
|
+
const switchToNextTenYears = () => {
|
|
330
|
+
decadeStart.value = DateUtils.getNextDecade(decadeStart.value);
|
|
331
|
+
};
|
|
332
|
+
const switchToPrevTenYears = () => {
|
|
333
|
+
decadeStart.value = DateUtils.getPrevDecade(decadeStart.value);
|
|
334
|
+
};
|
|
335
|
+
const handleInput = (e) => {
|
|
336
|
+
displayDate.value = e.target.value;
|
|
337
|
+
};
|
|
338
|
+
const isElementInContainer = (el, container) => {
|
|
339
|
+
if (!el || !container) return false;
|
|
340
|
+
if (container.contains(el)) return true;
|
|
341
|
+
if (el.classList.contains("year-item")) return true;
|
|
342
|
+
if (el.classList.contains("month-item")) return true;
|
|
343
|
+
let currentEl = el;
|
|
344
|
+
while (currentEl.parentElement) {
|
|
345
|
+
currentEl = currentEl.parentElement;
|
|
346
|
+
if (currentEl === container) {
|
|
347
|
+
return true;
|
|
348
|
+
}
|
|
349
|
+
if (currentEl.tagName === "BODY") break;
|
|
350
|
+
}
|
|
351
|
+
return false;
|
|
352
|
+
};
|
|
353
|
+
const handleViewReportClickOutside = (e) => {
|
|
354
|
+
const isInWrapper = isElementInContainer(e.target, pickerWrapper.value);
|
|
355
|
+
if (panelVisible.value && pickerWrapper.value && !isInWrapper) {
|
|
356
|
+
panelVisible.value = false;
|
|
357
|
+
panelType.value = "date";
|
|
358
|
+
}
|
|
359
|
+
};
|
|
360
|
+
const handleViewReportResizes = () => {
|
|
361
|
+
if (panelVisible.value) calcPanelPosition();
|
|
362
|
+
};
|
|
363
|
+
onMounted(() => {
|
|
364
|
+
initDisplayDate();
|
|
365
|
+
document.addEventListener("click", handleViewReportClickOutside);
|
|
366
|
+
window.addEventListener("scroll", handleViewReportResizes, true);
|
|
367
|
+
window.addEventListener("resize", handleViewReportResizes);
|
|
368
|
+
});
|
|
369
|
+
onUnmounted(() => {
|
|
370
|
+
document.removeEventListener("click", handleViewReportClickOutside);
|
|
371
|
+
window.removeEventListener("scroll", handleViewReportResizes, true);
|
|
372
|
+
window.removeEventListener("resize", handleViewReportResizes);
|
|
373
|
+
});
|
|
374
|
+
return {
|
|
375
|
+
pickerWrapper,
|
|
376
|
+
dateInput,
|
|
377
|
+
datePanel,
|
|
378
|
+
panelVisible,
|
|
379
|
+
panelStyle,
|
|
380
|
+
currentYear,
|
|
289
381
|
// 仅暴露currentYear/currentMonth
|
|
290
|
-
currentMonth
|
|
291
|
-
hoverDate
|
|
292
|
-
displayDate
|
|
293
|
-
panelType
|
|
294
|
-
decadeYears
|
|
295
|
-
panelDates
|
|
296
|
-
togglePanel
|
|
297
|
-
openYearPanel
|
|
298
|
-
openMonthPanel
|
|
299
|
-
selectDecadeYear
|
|
300
|
-
selectTargetMonth
|
|
301
|
-
selectDate
|
|
302
|
-
switchToPrevYear
|
|
303
|
-
switchToPrevMonth
|
|
304
|
-
switchToNextMonth
|
|
305
|
-
switchToNextYear
|
|
306
|
-
handleInput
|
|
307
|
-
getDecadeStartAndEnd
|
|
308
|
-
switchToPrevTenYears
|
|
309
|
-
switchToNextTenYears
|
|
382
|
+
currentMonth,
|
|
383
|
+
hoverDate,
|
|
384
|
+
displayDate,
|
|
385
|
+
panelType,
|
|
386
|
+
decadeYears,
|
|
387
|
+
panelDates,
|
|
388
|
+
togglePanel,
|
|
389
|
+
openYearPanel,
|
|
390
|
+
openMonthPanel,
|
|
391
|
+
selectDecadeYear,
|
|
392
|
+
selectTargetMonth,
|
|
393
|
+
selectDate,
|
|
394
|
+
switchToPrevYear,
|
|
395
|
+
switchToPrevMonth,
|
|
396
|
+
switchToNextMonth,
|
|
397
|
+
switchToNextYear,
|
|
398
|
+
handleInput,
|
|
399
|
+
getDecadeStartAndEnd,
|
|
400
|
+
switchToPrevTenYears,
|
|
401
|
+
switchToNextTenYears
|
|
310
402
|
};
|
|
311
403
|
}
|
|
312
404
|
});
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
"
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
405
|
+
const _hoisted_1 = {
|
|
406
|
+
class: "view-date-picker-wrapper",
|
|
407
|
+
ref: "pickerWrapper"
|
|
408
|
+
};
|
|
409
|
+
const _hoisted_2 = { class: "native-input-wrapper" };
|
|
410
|
+
const _hoisted_3 = ["value"];
|
|
411
|
+
const _hoisted_4 = { class: "date-picker-panel" };
|
|
412
|
+
const _hoisted_5 = { class: "picker-header" };
|
|
413
|
+
const _hoisted_6 = { class: "current-month" };
|
|
414
|
+
const _hoisted_7 = { class: "picker-header" };
|
|
415
|
+
const _hoisted_8 = { class: "current-month" };
|
|
416
|
+
const _hoisted_9 = { class: "clickable-year" };
|
|
417
|
+
const _hoisted_10 = { class: "picker-header" };
|
|
418
|
+
const _hoisted_11 = { class: "current-month" };
|
|
419
|
+
const _hoisted_12 = { class: "clickable-year" };
|
|
420
|
+
const _hoisted_13 = {
|
|
421
|
+
key: 0,
|
|
422
|
+
class: "bod-mb"
|
|
423
|
+
};
|
|
424
|
+
const _hoisted_14 = { class: "picker-panel" };
|
|
425
|
+
const _hoisted_15 = ["onClick", "onMouseenter"];
|
|
426
|
+
const _hoisted_16 = {
|
|
427
|
+
key: 1,
|
|
428
|
+
class: "bod-mb"
|
|
429
|
+
};
|
|
430
|
+
const _hoisted_17 = ["onClick"];
|
|
431
|
+
const _hoisted_18 = {
|
|
432
|
+
key: 2,
|
|
433
|
+
class: "bod-mb"
|
|
434
|
+
};
|
|
435
|
+
const _hoisted_19 = ["onClick"];
|
|
436
|
+
function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
|
|
437
|
+
return openBlock(), createElementBlock("div", _hoisted_1, [
|
|
438
|
+
createElementVNode("div", _hoisted_2, [
|
|
439
|
+
createElementVNode("input", {
|
|
440
|
+
ref: "dateInput",
|
|
441
|
+
type: "text",
|
|
442
|
+
value: _ctx.displayDate,
|
|
443
|
+
onInput: _cache[0] || (_cache[0] = (...args) => _ctx.handleInput && _ctx.handleInput(...args)),
|
|
444
|
+
placeholder: "请选择日期",
|
|
445
|
+
readonly: "",
|
|
446
|
+
class: "native-input",
|
|
447
|
+
onClick: _cache[1] || (_cache[1] = (...args) => _ctx.togglePanel && _ctx.togglePanel(...args))
|
|
448
|
+
}, null, 40, _hoisted_3),
|
|
449
|
+
createElementVNode("span", {
|
|
450
|
+
class: "date-icon",
|
|
451
|
+
onClick: _cache[2] || (_cache[2] = (...args) => _ctx.togglePanel && _ctx.togglePanel(...args))
|
|
452
|
+
}, "📅")
|
|
453
|
+
]),
|
|
454
|
+
withDirectives(createElementVNode("div", {
|
|
455
|
+
ref: "datePanel",
|
|
456
|
+
class: "date-picker-dropdown",
|
|
457
|
+
style: normalizeStyle(_ctx.panelStyle)
|
|
458
|
+
}, [
|
|
459
|
+
createElementVNode("div", _hoisted_4, [
|
|
460
|
+
withDirectives(createElementVNode("div", _hoisted_5, [
|
|
461
|
+
createElementVNode("button", {
|
|
462
|
+
class: "toggle-btn year-btn prev-year",
|
|
463
|
+
onClick: _cache[3] || (_cache[3] = (...args) => _ctx.switchToPrevYear && _ctx.switchToPrevYear(...args))
|
|
464
|
+
}, "«"),
|
|
465
|
+
createElementVNode("button", {
|
|
466
|
+
class: "toggle-btn month-btn prev-month",
|
|
467
|
+
onClick: _cache[4] || (_cache[4] = (...args) => _ctx.switchToPrevMonth && _ctx.switchToPrevMonth(...args))
|
|
468
|
+
}, " < "),
|
|
469
|
+
createElementVNode("div", _hoisted_6, [
|
|
470
|
+
createElementVNode("span", {
|
|
471
|
+
onClick: _cache[5] || (_cache[5] = (...args) => _ctx.openYearPanel && _ctx.openYearPanel(...args)),
|
|
472
|
+
class: "clickable-year"
|
|
473
|
+
}, toDisplayString(_ctx.currentYear) + "年", 1),
|
|
474
|
+
createElementVNode("span", {
|
|
475
|
+
onClick: _cache[6] || (_cache[6] = (...args) => _ctx.openMonthPanel && _ctx.openMonthPanel(...args)),
|
|
476
|
+
class: "clickable-month"
|
|
477
|
+
}, toDisplayString(_ctx.currentMonth) + "月", 1)
|
|
478
|
+
]),
|
|
479
|
+
createElementVNode("button", {
|
|
480
|
+
class: "toggle-btn month-btn next-month",
|
|
481
|
+
onClick: _cache[7] || (_cache[7] = (...args) => _ctx.switchToNextMonth && _ctx.switchToNextMonth(...args))
|
|
482
|
+
}, ">"),
|
|
483
|
+
createElementVNode("button", {
|
|
484
|
+
class: "toggle-btn year-btn next-year",
|
|
485
|
+
onClick: _cache[8] || (_cache[8] = (...args) => _ctx.switchToNextYear && _ctx.switchToNextYear(...args))
|
|
486
|
+
}, "»")
|
|
487
|
+
], 512), [
|
|
488
|
+
[vShow, _ctx.panelType == "date"]
|
|
489
|
+
]),
|
|
490
|
+
withDirectives(createElementVNode("div", _hoisted_7, [
|
|
491
|
+
createElementVNode("button", {
|
|
492
|
+
class: "toggle-btn month-btn prev-month",
|
|
493
|
+
onClick: _cache[9] || (_cache[9] = (...args) => _ctx.switchToPrevTenYears && _ctx.switchToPrevTenYears(...args))
|
|
494
|
+
}, " < "),
|
|
495
|
+
createElementVNode("div", _hoisted_8, [
|
|
496
|
+
createElementVNode("span", _hoisted_9, toDisplayString(_ctx.getDecadeStartAndEnd) + "年", 1)
|
|
497
|
+
]),
|
|
498
|
+
createElementVNode("button", {
|
|
499
|
+
class: "toggle-btn month-btn next-month",
|
|
500
|
+
onClick: _cache[10] || (_cache[10] = (...args) => _ctx.switchToNextTenYears && _ctx.switchToNextTenYears(...args))
|
|
501
|
+
}, ">")
|
|
502
|
+
], 512), [
|
|
503
|
+
[vShow, _ctx.panelType == "year"]
|
|
504
|
+
]),
|
|
505
|
+
withDirectives(createElementVNode("div", _hoisted_10, [
|
|
506
|
+
createElementVNode("button", {
|
|
507
|
+
class: "toggle-btn month-btn prev-month",
|
|
508
|
+
onClick: _cache[11] || (_cache[11] = (...args) => _ctx.switchToPrevYear && _ctx.switchToPrevYear(...args))
|
|
509
|
+
}, " < "),
|
|
510
|
+
createElementVNode("div", _hoisted_11, [
|
|
511
|
+
createElementVNode("span", _hoisted_12, toDisplayString(_ctx.currentYear) + "年", 1)
|
|
512
|
+
]),
|
|
513
|
+
createElementVNode("button", {
|
|
514
|
+
class: "toggle-btn month-btn next-month",
|
|
515
|
+
onClick: _cache[12] || (_cache[12] = (...args) => _ctx.switchToNextYear && _ctx.switchToNextYear(...args))
|
|
516
|
+
}, ">")
|
|
517
|
+
], 512), [
|
|
518
|
+
[vShow, _ctx.panelType == "month"]
|
|
519
|
+
]),
|
|
520
|
+
_ctx.panelType === "date" ? (openBlock(), createElementBlock("div", _hoisted_13, [
|
|
521
|
+
_cache[14] || (_cache[14] = createStaticVNode('<div class="picker-week-header" data-v-e6885493><div class="week-item" data-v-e6885493>日</div><div class="week-item" data-v-e6885493>一</div><div class="week-item" data-v-e6885493>二</div><div class="week-item" data-v-e6885493>三</div><div class="week-item" data-v-e6885493>四</div><div class="week-item" data-v-e6885493>五</div><div class="week-item" data-v-e6885493>六</div></div>', 1)),
|
|
522
|
+
createElementVNode("div", _hoisted_14, [
|
|
523
|
+
(openBlock(true), createElementBlock(Fragment, null, renderList(_ctx.panelDates, (item, index2) => {
|
|
524
|
+
return openBlock(), createElementBlock("div", {
|
|
525
|
+
class: normalizeClass(["date-item", {
|
|
526
|
+
"not-current-month": !item.isCurrentMonth,
|
|
527
|
+
"selected": item.formatDate === _ctx.displayDate,
|
|
528
|
+
"hover": _ctx.hoverDate === item.formatDate && item.formatDate !== _ctx.displayDate
|
|
529
|
+
}]),
|
|
530
|
+
key: index2,
|
|
531
|
+
onClick: ($event) => _ctx.selectDate(item),
|
|
532
|
+
onMouseenter: ($event) => _ctx.hoverDate = item.formatDate,
|
|
533
|
+
onMouseleave: _cache[13] || (_cache[13] = ($event) => _ctx.hoverDate = "")
|
|
534
|
+
}, toDisplayString(item.date.getDate()), 43, _hoisted_15);
|
|
535
|
+
}), 128))
|
|
536
|
+
])
|
|
537
|
+
])) : _ctx.panelType === "year" ? (openBlock(), createElementBlock("div", _hoisted_16, [
|
|
538
|
+
(openBlock(true), createElementBlock(Fragment, null, renderList(_ctx.decadeYears, (year) => {
|
|
539
|
+
return openBlock(), createElementBlock("div", {
|
|
540
|
+
class: normalizeClass(["year-item", { "selected": year === _ctx.currentYear }]),
|
|
541
|
+
key: year,
|
|
542
|
+
onClick: ($event) => _ctx.selectDecadeYear(year)
|
|
543
|
+
}, toDisplayString(year) + "年 ", 11, _hoisted_17);
|
|
544
|
+
}), 128))
|
|
545
|
+
])) : _ctx.panelType === "month" ? (openBlock(), createElementBlock("div", _hoisted_18, [
|
|
546
|
+
(openBlock(), createElementBlock(Fragment, null, renderList(12, (month) => {
|
|
547
|
+
return createElementVNode("div", {
|
|
548
|
+
class: normalizeClass(["month-item", { "selected": month === _ctx.currentMonth }]),
|
|
549
|
+
key: month,
|
|
550
|
+
onClick: ($event) => _ctx.selectTargetMonth(month)
|
|
551
|
+
}, toDisplayString(month) + "月 ", 11, _hoisted_19);
|
|
552
|
+
}), 64))
|
|
553
|
+
])) : createCommentVNode("", true)
|
|
554
|
+
])
|
|
555
|
+
], 4), [
|
|
556
|
+
[vShow, _ctx.panelVisible]
|
|
557
|
+
])
|
|
558
|
+
], 512);
|
|
559
|
+
}
|
|
560
|
+
const ViewDatePicker = /* @__PURE__ */ _export_sfc(_sfc_main, [["render", _sfc_render], ["__scopeId", "data-v-e6885493"]]);
|
|
561
|
+
const components = [MyButton, ViewDatePicker];
|
|
562
|
+
const install = (app) => {
|
|
563
|
+
components.forEach((component) => {
|
|
564
|
+
app.component(component.name, component);
|
|
350
565
|
});
|
|
351
566
|
};
|
|
352
|
-
typeof window
|
|
353
|
-
|
|
567
|
+
if (typeof window !== "undefined" && window.Vue) {
|
|
568
|
+
install(window.Vue);
|
|
569
|
+
}
|
|
570
|
+
const index = { install };
|
|
354
571
|
export {
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
572
|
+
MyButton,
|
|
573
|
+
ViewDatePicker,
|
|
574
|
+
index as default,
|
|
575
|
+
install
|
|
359
576
|
};
|