sh-view 2.8.0 → 2.8.2

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.
Files changed (91) hide show
  1. package/.eslintrc.js +25 -20
  2. package/other.js +8 -8
  3. package/package.json +9 -6
  4. package/packages/components/index.js +91 -91
  5. package/packages/components/sh-alert/alert.ts +30 -0
  6. package/packages/components/sh-alert/index.vue +143 -168
  7. package/packages/components/sh-badge/index.vue +242 -242
  8. package/packages/components/sh-calendar/index.vue +650 -650
  9. package/packages/components/sh-card/index.vue +148 -148
  10. package/packages/components/sh-code-editor/index.vue +19 -19
  11. package/packages/components/sh-col/index.vue +92 -92
  12. package/packages/components/sh-corner/index.vue +230 -230
  13. package/packages/components/sh-count-to/index.vue +131 -131
  14. package/packages/components/sh-date/index.vue +301 -301
  15. package/packages/components/sh-drawer/index.vue +579 -579
  16. package/packages/components/sh-drawer/scrollbar.js +78 -78
  17. package/packages/components/sh-empty/index.vue +42 -42
  18. package/packages/components/sh-form/js/props.js +76 -76
  19. package/packages/components/sh-form/js/useForm.js +229 -229
  20. package/packages/components/sh-header/index.vue +261 -260
  21. package/packages/components/sh-icon/css/default/ionicons.svg +869 -869
  22. package/packages/components/sh-icon/css/font/iconfont.json +247 -247
  23. package/packages/components/sh-icon/index.vue +41 -41
  24. package/packages/components/sh-image/index.vue +133 -133
  25. package/packages/components/sh-list/index.vue +146 -146
  26. package/packages/components/sh-loading/index.vue +53 -53
  27. package/packages/components/sh-modal/index.vue +188 -188
  28. package/packages/components/sh-noticebar/index.vue +215 -215
  29. package/packages/components/sh-poptip/index.vue +597 -597
  30. package/packages/components/sh-progress/index.vue +276 -276
  31. package/packages/components/sh-pull-refresh/index.vue +289 -289
  32. package/packages/components/sh-result/index.vue +114 -114
  33. package/packages/components/sh-row/index.vue +66 -66
  34. package/packages/components/sh-split/components/trigger.vue +33 -33
  35. package/packages/components/sh-split/index.vue +342 -342
  36. package/packages/components/sh-table/components/importModal.vue +363 -363
  37. package/packages/components/sh-table/components/sh-column.vue +68 -68
  38. package/packages/components/sh-table/js/excel_to_json.js +313 -313
  39. package/packages/components/sh-table/js/props.js +305 -305
  40. package/packages/components/sh-table/js/tableMethods.js +167 -167
  41. package/packages/components/sh-table/js/useTable.js +636 -636
  42. package/packages/components/sh-table/table.vue +217 -217
  43. package/packages/components/sh-tabs/index.vue +426 -426
  44. package/packages/components/sh-tag/index.vue +168 -168
  45. package/packages/components/sh-toolbar/index.vue +182 -182
  46. package/packages/components/sh-tree/components/table-tree.vue +289 -289
  47. package/packages/components/sh-tree/mixin/treeProps.js +122 -122
  48. package/packages/components/sh-upload/index.vue +535 -535
  49. package/packages/components/sh-water-fall/index.vue +80 -80
  50. package/packages/components/sh-water-mark/index.vue +96 -96
  51. package/packages/css/index.js +4 -4
  52. package/packages/directive/index.js +19 -19
  53. package/packages/directive/module/click-out.js +14 -14
  54. package/packages/directive/module/draggable.js +42 -42
  55. package/packages/directive/module/line-clamp.js +22 -22
  56. package/packages/directive/module/prevent-click.js +18 -18
  57. package/packages/directive/module/resize.js +14 -14
  58. package/packages/directive/module/ripple.js +166 -166
  59. package/packages/index.js +39 -39
  60. package/packages/mixin/index.js +86 -86
  61. package/packages/other/sh-cron-modal/components/cron-content.vue +294 -294
  62. package/packages/other/sh-cron-modal/index.vue +81 -81
  63. package/packages/other/sh-cron-modal/mixin/cron-emits.js +1 -1
  64. package/packages/other/sh-cron-modal/mixin/cron-props.js +9 -9
  65. package/packages/other/sh-cron-modal/tabs/cron-week-box.vue +126 -126
  66. package/packages/other/sh-menu/index.vue +326 -326
  67. package/packages/other/sh-menu/menu-group-content.vue +136 -136
  68. package/packages/other/sh-menu/menu-item-content.vue +71 -71
  69. package/packages/other/sh-menu-card/index.vue +250 -250
  70. package/packages/other/sh-menu-card/menu-box.vue +87 -87
  71. package/packages/other/sh-preview/components/sh-excel.vue +163 -163
  72. package/packages/other/sh-preview/js/data-hook.js +41 -41
  73. package/packages/other/sh-preview/js/data-props.js +15 -15
  74. package/packages/other/sh-system-tip/index.vue +115 -115
  75. package/packages/utils/resize.js +69 -70
  76. package/packages/utils/transfer-queue.js +12 -12
  77. package/packages/vxeTable/index.js +193 -184
  78. package/packages/vxeTable/plugins/export.js +450 -450
  79. package/packages/vxeTable/render/cell/vxe-render-img.vue +27 -27
  80. package/packages/vxeTable/render/cell/vxe-render-table.vue +51 -51
  81. package/packages/vxeTable/render/cell/vxe-render-time.vue +44 -44
  82. package/packages/vxeTable/render/cell/vxe-render-tree.vue +70 -70
  83. package/packages/vxeTable/render/filters/vxe-filter-input.vue +26 -26
  84. package/packages/vxeTable/render/filters/vxe-filter-time.vue +26 -26
  85. package/packages/vxeTable/render/globalRenders.jsx +514 -514
  86. package/packages/vxeTable/render/mixin/cell-hooks.js +198 -198
  87. package/packages/vxeTable/render/mixin/cell-props.js +23 -23
  88. package/packages/vxeTable/render/mixin/filter-hooks.js +46 -46
  89. package/tsconfig.json +25 -0
  90. package/types/component.d.ts +1 -0
  91. package/types/index.ts +0 -0
@@ -1,650 +1,650 @@
1
- <template>
2
- <div class="sh-calendar">
3
- <div v-if="header" class="sh-calendar-row sh-calendar-head">
4
- <div class="info">
5
- <sh-select v-if="type !== 'year'" v-bind="yearSelectConfig" @change="onYearChange" />
6
- <sh-select v-if="!['month', 'year'].includes(type)" v-bind="monthSelectConfig" @change="onMonthChange"></sh-select>
7
- </div>
8
- <div class="extra">
9
- <template v-for="item in headerHandles" :key="item.code">
10
- <span class="sh-calendar-btn" @click="handleBtn(item)"><i :class="item.icon"></i></span>
11
- </template>
12
- </div>
13
- </div>
14
- <table class="sh-calendar-table" :class="{ 'sh-calendar-pulldown': pulldown }" v-bind="tableConfig">
15
- <thead v-if="showHeader">
16
- <tr>
17
- <template v-for="(head, headIndex) in headers" :key="headIndex">
18
- <th :style="{ textAlign: headerAlign }">{{ head.label }}</th>
19
- </template>
20
- </tr>
21
- </thead>
22
- <tbody @mouseleave="dateMouseleaveEvent">
23
- <template v-for="(row, rowIndex) in bodyDatas" :key="rowIndex">
24
- <tr>
25
- <template v-for="(item, itemIndex) in row" :key="itemIndex">
26
- <td :class="getCellClass(item)" @mouseenter="dateMouseenterEvent(item)" @click="dateSelectEvent(item)">
27
- <slot name="cell" v-bind="item">
28
- <div class="sh-calendar-cell" :style="{ textAlign: align }">
29
- <div class="sh-calendar-cell-head" :class="{ 'is-month': type === 'month' }">{{ item.label }}</div>
30
- <div v-if="note" class="sh-calendar-cell-body" :style="{ height: noteHeight }">{{ noteMethod(item) }}</div>
31
- <div v-if="festival" class="sh-calendar-cell-foot">{{ getLunarDate(item.date) }}</div>
32
- </div>
33
- </slot>
34
- </td>
35
- </template>
36
- </tr>
37
- </template>
38
- </tbody>
39
- </table>
40
- <div v-if="footer" class="sh-calendar-foot">
41
- <div class="sh-calendar-row">
42
- <div class="info">
43
- <div>{{ lunarInfo.day }}</div>
44
- <div class="sh-calendar-title">{{ lunarInfo.lunarMonth }}月 {{ lunarInfo.lunarDay }}</div>
45
- <div class="sh-calendar-title">{{ lunarInfo.jq }}</div>
46
- </div>
47
- <div class="info right">
48
- <div class="sh-calendar-title">{{ lunarInfo.yearGanZhi }}年 {{ lunarInfo.yearShengXiao }}</div>
49
- <div>{{ lunarInfo.monthGanZhi }}月 {{ lunarInfo.dayGanZhi }}</div>
50
- </div>
51
- </div>
52
- <div class="sh-calendar-row">
53
- <div class="extra"><span class="sh-calendar-tag yi">宜</span></div>
54
- <div class="info">
55
- <template v-for="(y, yIndex) in lunarInfo.yi" :key="yIndex">
56
- <span class="sh-calendar-span">{{ y }}</span>
57
- </template>
58
- </div>
59
- </div>
60
- <div class="sh-calendar-row">
61
- <div class="extra"><span class="sh-calendar-tag ji">忌</span></div>
62
- <div class="info">
63
- <template v-for="(j, jIndex) in lunarInfo.ji" :key="jIndex">
64
- <span class="sh-calendar-span">{{ j }}</span>
65
- </template>
66
- </div>
67
- </div>
68
- </div>
69
- </div>
70
- </template>
71
-
72
- <script>
73
- import { computed, defineComponent, getCurrentInstance, ref, reactive, onBeforeMount, watch } from 'vue'
74
- import { Lunar, HolidayUtil } from 'lunar-typescript'
75
- export default defineComponent({
76
- name: 'ShCalendar',
77
- props: {
78
- modelValue: [String, Number, Date],
79
- type: { type: String, default: 'day' }, // day, month, year
80
- startDay: { type: [String, Number], default: 1 },
81
- headerAlign: { type: String, default: 'center' },
82
- align: { type: String, default: 'center' },
83
- header: { type: Boolean, default: true },
84
- footer: { type: Boolean, default: false },
85
- note: { type: Boolean, default: false }, // 是否备注
86
- noteHeight: { type: String, default: '22px' }, // 备注高度
87
- noteMethod: { type: Function, default() {} },
88
- festival: { type: Boolean, default: false }, // 是否显示农历
89
- pulldown: { type: Boolean, default: false }, // 是否为下拉显示
90
- valueFormat: { type: String, default: '' },
91
- weeks: {
92
- type: Array,
93
- default() {
94
- return ['周日', '周一', '周二', '周三', '周四', '周五', '周六']
95
- }
96
- },
97
- disabledMethod: { type: Function }
98
- },
99
- emits: ['update:modelValue', 'change'],
100
- setup(props, context) {
101
- const { proxy } = getCurrentInstance()
102
- const { $vUtils } = proxy
103
- const { emit, slots } = context
104
-
105
- const yearSize = 12
106
- const monthSize = 12
107
- const headerHandles = [
108
- { code: 'prev', icon: 'vxe-icon-caret-left' },
109
- { code: 'current', icon: 'vxe-icon-dot' },
110
- { code: 'next', icon: 'vxe-icon-caret-right' }
111
- ]
112
- const reactData = reactive({
113
- inputValue: props.modelValue,
114
- panelValue: null,
115
- panelLabel: '',
116
- selectMonth: null,
117
- currentDate: null
118
- })
119
- const computeFirstDayOfWeek = computed(() => {
120
- const { startDay, startWeek } = props
121
- return $vUtils.toNumber($vUtils.isNumber(startDay) || $vUtils.isString(startDay) ? startDay : startWeek)
122
- })
123
- const computeWeekDatas = computed(() => {
124
- const weeks = []
125
- let sWeek = computeFirstDayOfWeek.value
126
- weeks.push(sWeek)
127
- for (let index = 0; index < 6; index++) {
128
- if (sWeek >= 6) {
129
- sWeek = 0
130
- } else {
131
- sWeek++
132
- }
133
- weeks.push(sWeek)
134
- }
135
- return weeks
136
- })
137
- const computeDateHMSTime = computed(() => {
138
- const dateValue = computeDateValue.value
139
- return dateValue ? (dateValue.getHours() * 3600 + dateValue.getMinutes() * 60 + dateValue.getSeconds()) * 1000 : 0
140
- })
141
-
142
- const computeYearList = computed(() => {
143
- const { selectMonth, currentDate } = reactData
144
- const years = []
145
- if (selectMonth && currentDate) {
146
- const currFullYear = currentDate.getFullYear()
147
- const selectFullYear = selectMonth.getFullYear()
148
- const startYearDate = new Date(selectFullYear - (selectFullYear % yearSize), 0, 1)
149
- for (let index = -4; index < yearSize + 4; index++) {
150
- const date = $vUtils.getWhatYear(startYearDate, index, 'first')
151
- const itemFullYear = date.getFullYear()
152
- years.push({
153
- date,
154
- isCurrent: true,
155
- isPrev: index < 0,
156
- isNow: currFullYear === itemFullYear,
157
- isNext: index >= yearSize,
158
- year: itemFullYear,
159
- label: `${itemFullYear}年`
160
- })
161
- }
162
- }
163
- return years
164
- })
165
- const computeMonthList = computed(() => {
166
- const { selectMonth, currentDate } = reactData
167
- const months = []
168
- if (selectMonth && currentDate) {
169
- const currFullYear = currentDate.getFullYear()
170
- const currMonth = currentDate.getMonth()
171
- const selFullYear = $vUtils.getWhatYear(selectMonth, 0, 'first').getFullYear()
172
- for (let index = 0; index < monthSize; index++) {
173
- const date = $vUtils.getWhatYear(selectMonth, 0, index)
174
- const itemFullYear = date.getFullYear()
175
- const itemMonth = date.getMonth()
176
- const isPrev = itemFullYear < selFullYear
177
- months.push({
178
- date,
179
- isPrev,
180
- isCurrent: itemFullYear === selFullYear,
181
- isNow: itemFullYear === currFullYear && itemMonth === currMonth,
182
- isNext: !isPrev && itemFullYear > selFullYear,
183
- month: itemMonth,
184
- label: `${itemMonth + 1}月`
185
- })
186
- }
187
- }
188
- return months
189
- })
190
- const computeDayList = computed(() => {
191
- const { selectMonth, currentDate } = reactData
192
- const days = []
193
- if (selectMonth && currentDate) {
194
- const dateHMSTime = computeDateHMSTime.value
195
- const weekDatas = computeWeekDatas.value
196
- const currFullYear = currentDate.getFullYear()
197
- const currMonth = currentDate.getMonth()
198
- const currDate = currentDate.getDate()
199
- const selFullYear = selectMonth.getFullYear()
200
- const selMonth = selectMonth.getMonth()
201
- const selDay = selectMonth.getDay()
202
- const prevOffsetDate = -weekDatas.indexOf(selDay)
203
- const startDayDate = new Date($vUtils.getWhatDay(selectMonth, prevOffsetDate).getTime() + dateHMSTime)
204
- for (let index = 0; index < 42; index++) {
205
- const date = $vUtils.getWhatDay(startDayDate, index)
206
- const itemFullYear = date.getFullYear()
207
- const itemMonth = date.getMonth()
208
- const itemDate = date.getDate()
209
- const isPrev = date < selectMonth
210
- days.push({
211
- date,
212
- isPrev,
213
- isCurrent: itemFullYear === selFullYear && itemMonth === selMonth,
214
- isNow: itemFullYear === currFullYear && itemMonth === currMonth && itemDate === currDate,
215
- isNext: !isPrev && selMonth !== itemMonth,
216
- day: itemDate,
217
- label: itemDate
218
- })
219
- }
220
- }
221
- return days
222
- })
223
- // 以下为日历需要
224
- const tableConfig = computed(() => ({ cellspacing: 0, cellpadding: 0, border: 0 }))
225
- const headers = computed(() => {
226
- const weekDatas = computeWeekDatas.value
227
- return weekDatas.map(day => {
228
- return { value: day, label: props.weeks[day] }
229
- })
230
- })
231
- const bodyDatas = computed(() => {
232
- if ('month' === props.type) {
233
- return $vUtils.chunk(computeMonthList.value, 3)
234
- } else if ('year' === props.type) {
235
- return $vUtils.chunk(computeYearList.value, 4)
236
- }
237
- return $vUtils.chunk(computeDayList.value, 7)
238
- })
239
- const computeDateValue = computed(() => {
240
- const { inputValue } = reactData
241
- let val = null
242
- if (inputValue) {
243
- const date = $vUtils.toStringDate(inputValue, props.valueFormat)
244
- if ($vUtils.isValidDate(date)) {
245
- val = date
246
- }
247
- }
248
- return val
249
- })
250
- const showHeader = computed(() => !['month', 'year'].includes(props.type))
251
- const yearValue = computed(() => $vUtils.toDateString(reactData.selectMonth, 'yyyy'))
252
- const monthValue = computed(() => $vUtils.toDateString(reactData.selectMonth, 'MM'))
253
- const dayValue = computed(() => $vUtils.toDateString(reactData.selectMonth, 'dd'))
254
- const yearSelectConfig = computed(() => {
255
- const options = []
256
- for (let index = 1880; index < 2116; index++) {
257
- options.push({
258
- value: index + '',
259
- label: `${index}年`
260
- })
261
- }
262
- return {
263
- modelValue: yearValue.value,
264
- options: options,
265
- filterable: true,
266
- style: { width: '85px' }
267
- }
268
- })
269
- const monthSelectConfig = computed(() => {
270
- const options = []
271
- for (let index = 1; index < 13; index++) {
272
- options.push({
273
- value: index + '',
274
- label: `${index}月`
275
- })
276
- }
277
- return {
278
- modelValue: monthValue.value,
279
- options: options,
280
- filterable: true,
281
- style: { width: '75px' }
282
- }
283
- })
284
- const lunarInfo = computed(() => {
285
- let dayDate = reactData.inputValue || reactData.currentDate
286
- let lunarDate = Lunar.fromDate(dayDate)
287
- return {
288
- day: $vUtils.toDateString(dayDate, 'yyyy 年 MM 月 dd 日'),
289
- lunarMonth: lunarDate.getMonthInChinese(),
290
- lunarDay: lunarDate.getDayInChinese(),
291
- yearGanZhi: lunarDate.getYearInGanZhi(),
292
- yearShengXiao: lunarDate.getYearShengXiao(),
293
- monthGanZhi: lunarDate.getMonthInGanZhi(),
294
- dayGanZhi: lunarDate.getDayInGanZhi(),
295
- yi: lunarDate.getDayYi(),
296
- ji: lunarDate.getDayJi(),
297
- jq: lunarDate.getJieQi()
298
- }
299
- })
300
- const isDateDisabled = item => {
301
- const { disabledMethod } = props
302
- return disabledMethod && disabledMethod({ type: props.type, date: item.date })
303
- }
304
- const dateChange = date => {
305
- emitValue(date)
306
- emit('change', date)
307
- }
308
- const dateSelectItem = date => {
309
- dateChange(date)
310
- }
311
- const dateCheckMonth = date => {
312
- const month = $vUtils.getWhatMonth(date, 0, 'first')
313
- if (!$vUtils.isEqual(month, reactData.selectMonth)) {
314
- reactData.selectMonth = month
315
- }
316
- }
317
- const dateMoveDay = offsetDay => {
318
- if (isDateDisabled({ date: offsetDay })) return
319
- const dayList = computeDayList.value
320
- if (!dayList.some(item => $vUtils.isDateSame(item.date, offsetDay, 'yyyyMMdd'))) {
321
- dateCheckMonth(offsetDay)
322
- }
323
- dateParseValue(offsetDay)
324
- }
325
- const dateMoveMonth = offsetMonth => {
326
- if (isDateDisabled({ date: offsetMonth })) return
327
- const monthList = computeMonthList.value
328
- if (!monthList.some(item => $vUtils.isDateSame(item.date, offsetMonth, 'yyyyMM'))) {
329
- dateCheckMonth(offsetMonth)
330
- }
331
- dateParseValue(offsetMonth)
332
- }
333
- const dateMoveYear = offsetYear => {
334
- if (isDateDisabled({ date: offsetYear })) return
335
- const yearList = computeYearList.value
336
- if (!yearList.some(item => $vUtils.isDateSame(item.date, offsetYear, 'yyyy'))) {
337
- dateCheckMonth(offsetYear)
338
- }
339
- dateParseValue(offsetYear)
340
- }
341
- const dateSelectEvent = item => {
342
- if (isDateDisabled(item)) return
343
- dateSelectItem(item.date)
344
- }
345
- const dateMouseenterEvent = item => {
346
- if (isDateDisabled(item)) return
347
- if (props.type === 'month') {
348
- dateMoveMonth(item.date)
349
- } else if (props.type === 'year') {
350
- dateMoveYear(item.date)
351
- } else {
352
- dateMoveDay(item.date)
353
- }
354
- }
355
- const dateMouseleaveEvent = () => {
356
- dateParseValue()
357
- }
358
- const dateParseValue = value => {
359
- let dValue = null
360
- if (value) {
361
- dValue = $vUtils.toStringDate(value, props.valueFormat)
362
- }
363
- if (dValue && !$vUtils.isValidDate(dValue)) {
364
- dValue = null
365
- }
366
- reactData.panelValue = dValue
367
- }
368
- const getLunarDate = day => {
369
- let lunarDate = Lunar.fromDate(day)
370
- let lunarText = lunarDate.getDayInChinese()
371
- const jq = lunarDate.getJieQi()
372
- const solarFestivals = lunarDate.getFestivals()
373
- if (jq) {
374
- lunarText = jq
375
- } else if (lunarDate.getDay() === 1) {
376
- lunarText = lunarDate.getMonthInChinese() + '月'
377
- } else if (solarFestivals.length > 0) {
378
- const f = solarFestivals[0]
379
- if (f.length < 4) {
380
- lunarText = f
381
- }
382
- }
383
- return lunarText
384
- }
385
- const getCellClass = item => {
386
- const { panelValue } = reactData
387
- const dateValue = computeDateValue.value
388
- let matchFormat = 'yyyyMMdd'
389
- if ('month' === props.type) matchFormat = 'yyyyMM'
390
- else if ('year' === props.type) matchFormat = 'yyyy'
391
- const ymd = $vUtils.toDateString(item.date, 'yyyyMMdd')
392
- const lunarDate = Lunar.fromDate(item.date)
393
- const holiday = HolidayUtil.getHoliday(ymd)
394
- let rest = false
395
- if ([0, 6].includes(lunarDate.getWeek())) {
396
- rest = true
397
- }
398
- if (holiday) rest = !holiday.isWork()
399
- return {
400
- 'is--prev': item.isPrev,
401
- 'is--current': item.isCurrent,
402
- 'is--now': item.isNow,
403
- 'is--next': item.isNext,
404
- 'is--holiday': holiday,
405
- 'is--rest': rest,
406
- 'is--disabled': isDateDisabled(item),
407
- 'is--selected': $vUtils.isDateSame(dateValue, item.date, matchFormat),
408
- 'is--hover': $vUtils.isDateSame(panelValue, item.date, matchFormat)
409
- }
410
- }
411
- const handleBtn = ({ code }) => {
412
- try {
413
- const { currentDate, selectMonth } = reactData
414
- let getName = 'getWhatMonth'
415
- let getSize = 1
416
- if (['month', 'year'].includes(props.type)) getName = 'getWhatYear'
417
- if (['year'].includes(props.type)) getSize = yearSize
418
- switch (code) {
419
- case 'prev':
420
- reactData.selectMonth = $vUtils[getName](selectMonth, getSize * -1, 'first')
421
- break
422
- case 'next':
423
- reactData.selectMonth = $vUtils[getName](selectMonth, getSize, 'first')
424
- break
425
- case 'current':
426
- reactData.selectMonth = $vUtils.getWhatMonth(currentDate, 0, 'first')
427
- break
428
- default:
429
- break
430
- }
431
- } catch (e) {
432
- proxy.msgwarning(e.message)
433
- }
434
- }
435
- const emitValue = (value, evnt) => {
436
- reactData.inputValue = value
437
- emit('update:modelValue', value)
438
- }
439
-
440
- // 初始化
441
- const initValue = () => {
442
- reactData.currentDate = $vUtils.getWhatDay(Date.now(), 0, 'first')
443
- reactData.selectMonth = $vUtils.getWhatMonth(computeDateValue.value || reactData.currentDate, 0, 'first')
444
- }
445
- // 年度切换
446
- const onYearChange = ({ value }) => {
447
- const { selectMonth } = reactData
448
- const selMonth = selectMonth.getMonth() + 1
449
- const selDate = selectMonth.getDate()
450
- const changeDate = `${value}-${selMonth}-${selDate}`
451
- reactData.selectMonth = $vUtils.toStringDate(changeDate)
452
- }
453
- // 月份切换
454
- const onMonthChange = ({ value }) => {
455
- const { selectMonth } = reactData
456
- const selYear = selectMonth.getFullYear()
457
- const selDate = selectMonth.getDate()
458
- const changeDate = `${selYear}-${value}-${selDate}`
459
- reactData.selectMonth = $vUtils.toStringDate(changeDate)
460
- }
461
-
462
- onBeforeMount(() => {
463
- initValue()
464
- })
465
-
466
- watch(
467
- () => props.modelValue,
468
- val => {
469
- reactData.inputValue = val
470
- }
471
- )
472
-
473
- return {
474
- reactData,
475
- tableConfig,
476
- yearSelectConfig,
477
- monthSelectConfig,
478
- headers,
479
- bodyDatas,
480
- lunarInfo,
481
- headerHandles,
482
- computeYearList,
483
- computeMonthList,
484
- showHeader,
485
- onYearChange,
486
- onMonthChange,
487
- getLunarDate,
488
- getCellClass,
489
- handleBtn,
490
- dateSelectEvent,
491
- dateMouseenterEvent,
492
- dateMouseleaveEvent
493
- }
494
- }
495
- })
496
- </script>
497
-
498
- <style scoped lang="scss">
499
- .sh-calendar {
500
- overflow: auto;
501
- .sh-calendar-title {
502
- font-size: 18px;
503
- font-weight: bold;
504
- }
505
- .sh-calendar-span {
506
- margin-right: 5px;
507
- }
508
- .sh-calendar-tag {
509
- border-radius: 30px;
510
- padding: 5px;
511
- display: inline-flex;
512
- vertical-align: top;
513
- line-height: 1;
514
- margin-right: 10px;
515
- &.yi {
516
- background-color: var(--vxe-success-color);
517
- color: #fff;
518
- }
519
- &.ji {
520
- background-color: var(--vxe-danger-color);
521
- color: #fff;
522
- }
523
- }
524
- .sh-calendar-row {
525
- display: flex;
526
- justify-content: space-between;
527
- align-items: center;
528
- .info {
529
- flex: 1;
530
- &.right {
531
- text-align: right;
532
- }
533
- }
534
- .extra {
535
- display: inline-flex;
536
- flex-wrap: nowrap;
537
- }
538
- & + .sh-calendar-row {
539
- margin-top: 5px;
540
- }
541
- }
542
- .sh-calendar-head,
543
- .sh-calendar-foot {
544
- padding: 8px;
545
- border: 1px solid var(--vxe-table-border-color);
546
- }
547
- .sh-calendar-head {
548
- border-bottom: none;
549
- line-height: 1;
550
- }
551
- .sh-calendar-foot {
552
- border-top: none;
553
- }
554
- .sh-calendar-btn {
555
- padding: 5px;
556
- border-radius: var(--vxe-border-radius);
557
- border: 1px solid var(--vxe-table-border-color);
558
- margin-left: 5px;
559
- &:hover {
560
- color: var(--vxe-primary-color);
561
- }
562
- }
563
- .sh-calendar-cell {
564
- display: block;
565
- &-head {
566
- padding: 3px 5px;
567
- & + .sh-calendar-cell-foot {
568
- padding-top: 0;
569
- }
570
- &.is-month {
571
- padding: 20px 5px;
572
- }
573
- }
574
- &-body {
575
- overflow: auto;
576
- }
577
- &-foot {
578
- padding: 3px 5px;
579
- font-size: 0.8em;
580
- }
581
- }
582
- .sh-calendar-table {
583
- &:not(.sh-calendar-pulldown) {
584
- td {
585
- border: 1px solid var(--vxe-table-border-color);
586
- }
587
- }
588
- &.sh-calendar-pulldown {
589
- tbody {
590
- border: 1px solid var(--vxe-table-border-color);
591
- }
592
- }
593
- }
594
- table {
595
- border: 0;
596
- width: 100%;
597
- border-spacing: 0;
598
- border-collapse: collapse;
599
- table-layout: fixed;
600
- height: 100%;
601
- }
602
- th,
603
- td {
604
- font-weight: normal;
605
- position: relative;
606
- height: 36px;
607
- }
608
- th {
609
- border: 1px solid var(--vxe-table-border-color);
610
- }
611
- td {
612
- &.is--prev,
613
- &.is--next {
614
- color: var(--vxe-font-disabled-color);
615
- }
616
- //&.is--rest {
617
- // .sh-calendar-cell-head {
618
- // color: var(--vxe-danger-color);
619
- // }
620
- //}
621
- &.is--now {
622
- &:not(.is--selected) {
623
- color: var(--vxe-primary-color);
624
- &.is--current {
625
- background-color: var(--primary-weak-color);
626
- }
627
- }
628
- }
629
- &.is--hover {
630
- background-color: var(--vxe-input-date-picker-hover-background-color);
631
- }
632
- &.is--selected {
633
- color: var(--vxe-input-date-picker-selected-color);
634
- background-color: var(--vxe-primary-color);
635
- &.is--prev,
636
- &.is--next {
637
- background-color: var(--vxe-primary-lighten-color);
638
- }
639
- }
640
- &:not(.is--disabled) {
641
- cursor: pointer;
642
- }
643
- &.is--disabled {
644
- cursor: no-drop;
645
- color: var(--vxe-input-disabled-color);
646
- background-color: var(--vxe-input-disabled-background-color);
647
- }
648
- }
649
- }
650
- </style>
1
+ <template>
2
+ <div class="sh-calendar">
3
+ <div v-if="header" class="sh-calendar-row sh-calendar-head">
4
+ <div class="info">
5
+ <sh-select v-if="type !== 'year'" v-bind="yearSelectConfig" @change="onYearChange" />
6
+ <sh-select v-if="!['month', 'year'].includes(type)" v-bind="monthSelectConfig" @change="onMonthChange"></sh-select>
7
+ </div>
8
+ <div class="extra">
9
+ <template v-for="item in headerHandles" :key="item.code">
10
+ <span class="sh-calendar-btn" @click="handleBtn(item)"><i :class="item.icon"></i></span>
11
+ </template>
12
+ </div>
13
+ </div>
14
+ <table class="sh-calendar-table" :class="{ 'sh-calendar-pulldown': pulldown }" v-bind="tableConfig">
15
+ <thead v-if="showHeader">
16
+ <tr>
17
+ <template v-for="(head, headIndex) in headers" :key="headIndex">
18
+ <th :style="{ textAlign: headerAlign }">{{ head.label }}</th>
19
+ </template>
20
+ </tr>
21
+ </thead>
22
+ <tbody @mouseleave="dateMouseleaveEvent">
23
+ <template v-for="(row, rowIndex) in bodyDatas" :key="rowIndex">
24
+ <tr>
25
+ <template v-for="(item, itemIndex) in row" :key="itemIndex">
26
+ <td :class="getCellClass(item)" @mouseenter="dateMouseenterEvent(item)" @click="dateSelectEvent(item)">
27
+ <slot name="cell" v-bind="item">
28
+ <div class="sh-calendar-cell" :style="{ textAlign: align }">
29
+ <div class="sh-calendar-cell-head" :class="{ 'is-month': type === 'month' }">{{ item.label }}</div>
30
+ <div v-if="note" class="sh-calendar-cell-body" :style="{ height: noteHeight }">{{ noteMethod(item) }}</div>
31
+ <div v-if="festival" class="sh-calendar-cell-foot">{{ getLunarDate(item.date) }}</div>
32
+ </div>
33
+ </slot>
34
+ </td>
35
+ </template>
36
+ </tr>
37
+ </template>
38
+ </tbody>
39
+ </table>
40
+ <div v-if="footer" class="sh-calendar-foot">
41
+ <div class="sh-calendar-row">
42
+ <div class="info">
43
+ <div>{{ lunarInfo.day }}</div>
44
+ <div class="sh-calendar-title">{{ lunarInfo.lunarMonth }}月 {{ lunarInfo.lunarDay }}</div>
45
+ <div class="sh-calendar-title">{{ lunarInfo.jq }}</div>
46
+ </div>
47
+ <div class="info right">
48
+ <div class="sh-calendar-title">{{ lunarInfo.yearGanZhi }}年 {{ lunarInfo.yearShengXiao }}</div>
49
+ <div>{{ lunarInfo.monthGanZhi }}月 {{ lunarInfo.dayGanZhi }}</div>
50
+ </div>
51
+ </div>
52
+ <div class="sh-calendar-row">
53
+ <div class="extra"><span class="sh-calendar-tag yi">宜</span></div>
54
+ <div class="info">
55
+ <template v-for="(y, yIndex) in lunarInfo.yi" :key="yIndex">
56
+ <span class="sh-calendar-span">{{ y }}</span>
57
+ </template>
58
+ </div>
59
+ </div>
60
+ <div class="sh-calendar-row">
61
+ <div class="extra"><span class="sh-calendar-tag ji">忌</span></div>
62
+ <div class="info">
63
+ <template v-for="(j, jIndex) in lunarInfo.ji" :key="jIndex">
64
+ <span class="sh-calendar-span">{{ j }}</span>
65
+ </template>
66
+ </div>
67
+ </div>
68
+ </div>
69
+ </div>
70
+ </template>
71
+
72
+ <script>
73
+ import { computed, defineComponent, getCurrentInstance, ref, reactive, onBeforeMount, watch } from 'vue'
74
+ import { Lunar, HolidayUtil } from 'lunar-typescript'
75
+ export default defineComponent({
76
+ name: 'ShCalendar',
77
+ props: {
78
+ modelValue: [String, Number, Date],
79
+ type: { type: String, default: 'day' }, // day, month, year
80
+ startDay: { type: [String, Number], default: 1 },
81
+ headerAlign: { type: String, default: 'center' },
82
+ align: { type: String, default: 'center' },
83
+ header: { type: Boolean, default: true },
84
+ footer: { type: Boolean, default: false },
85
+ note: { type: Boolean, default: false }, // 是否备注
86
+ noteHeight: { type: String, default: '22px' }, // 备注高度
87
+ noteMethod: { type: Function, default() {} },
88
+ festival: { type: Boolean, default: false }, // 是否显示农历
89
+ pulldown: { type: Boolean, default: false }, // 是否为下拉显示
90
+ valueFormat: { type: String, default: '' },
91
+ weeks: {
92
+ type: Array,
93
+ default() {
94
+ return ['周日', '周一', '周二', '周三', '周四', '周五', '周六']
95
+ }
96
+ },
97
+ disabledMethod: { type: Function }
98
+ },
99
+ emits: ['update:modelValue', 'change'],
100
+ setup(props, context) {
101
+ const { proxy } = getCurrentInstance()
102
+ const { $vUtils } = proxy
103
+ const { emit, slots } = context
104
+
105
+ const yearSize = 12
106
+ const monthSize = 12
107
+ const headerHandles = [
108
+ { code: 'prev', icon: 'vxe-icon-caret-left' },
109
+ { code: 'current', icon: 'vxe-icon-dot' },
110
+ { code: 'next', icon: 'vxe-icon-caret-right' }
111
+ ]
112
+ const reactData = reactive({
113
+ inputValue: props.modelValue,
114
+ panelValue: null,
115
+ panelLabel: '',
116
+ selectMonth: null,
117
+ currentDate: null
118
+ })
119
+ const computeFirstDayOfWeek = computed(() => {
120
+ const { startDay, startWeek } = props
121
+ return $vUtils.toNumber($vUtils.isNumber(startDay) || $vUtils.isString(startDay) ? startDay : startWeek)
122
+ })
123
+ const computeWeekDatas = computed(() => {
124
+ const weeks = []
125
+ let sWeek = computeFirstDayOfWeek.value
126
+ weeks.push(sWeek)
127
+ for (let index = 0; index < 6; index++) {
128
+ if (sWeek >= 6) {
129
+ sWeek = 0
130
+ } else {
131
+ sWeek++
132
+ }
133
+ weeks.push(sWeek)
134
+ }
135
+ return weeks
136
+ })
137
+ const computeDateHMSTime = computed(() => {
138
+ const dateValue = computeDateValue.value
139
+ return dateValue ? (dateValue.getHours() * 3600 + dateValue.getMinutes() * 60 + dateValue.getSeconds()) * 1000 : 0
140
+ })
141
+
142
+ const computeYearList = computed(() => {
143
+ const { selectMonth, currentDate } = reactData
144
+ const years = []
145
+ if (selectMonth && currentDate) {
146
+ const currFullYear = currentDate.getFullYear()
147
+ const selectFullYear = selectMonth.getFullYear()
148
+ const startYearDate = new Date(selectFullYear - (selectFullYear % yearSize), 0, 1)
149
+ for (let index = -4; index < yearSize + 4; index++) {
150
+ const date = $vUtils.getWhatYear(startYearDate, index, 'first')
151
+ const itemFullYear = date.getFullYear()
152
+ years.push({
153
+ date,
154
+ isCurrent: true,
155
+ isPrev: index < 0,
156
+ isNow: currFullYear === itemFullYear,
157
+ isNext: index >= yearSize,
158
+ year: itemFullYear,
159
+ label: `${itemFullYear}年`
160
+ })
161
+ }
162
+ }
163
+ return years
164
+ })
165
+ const computeMonthList = computed(() => {
166
+ const { selectMonth, currentDate } = reactData
167
+ const months = []
168
+ if (selectMonth && currentDate) {
169
+ const currFullYear = currentDate.getFullYear()
170
+ const currMonth = currentDate.getMonth()
171
+ const selFullYear = $vUtils.getWhatYear(selectMonth, 0, 'first').getFullYear()
172
+ for (let index = 0; index < monthSize; index++) {
173
+ const date = $vUtils.getWhatYear(selectMonth, 0, index)
174
+ const itemFullYear = date.getFullYear()
175
+ const itemMonth = date.getMonth()
176
+ const isPrev = itemFullYear < selFullYear
177
+ months.push({
178
+ date,
179
+ isPrev,
180
+ isCurrent: itemFullYear === selFullYear,
181
+ isNow: itemFullYear === currFullYear && itemMonth === currMonth,
182
+ isNext: !isPrev && itemFullYear > selFullYear,
183
+ month: itemMonth,
184
+ label: `${itemMonth + 1}月`
185
+ })
186
+ }
187
+ }
188
+ return months
189
+ })
190
+ const computeDayList = computed(() => {
191
+ const { selectMonth, currentDate } = reactData
192
+ const days = []
193
+ if (selectMonth && currentDate) {
194
+ const dateHMSTime = computeDateHMSTime.value
195
+ const weekDatas = computeWeekDatas.value
196
+ const currFullYear = currentDate.getFullYear()
197
+ const currMonth = currentDate.getMonth()
198
+ const currDate = currentDate.getDate()
199
+ const selFullYear = selectMonth.getFullYear()
200
+ const selMonth = selectMonth.getMonth()
201
+ const selDay = selectMonth.getDay()
202
+ const prevOffsetDate = -weekDatas.indexOf(selDay)
203
+ const startDayDate = new Date($vUtils.getWhatDay(selectMonth, prevOffsetDate).getTime() + dateHMSTime)
204
+ for (let index = 0; index < 42; index++) {
205
+ const date = $vUtils.getWhatDay(startDayDate, index)
206
+ const itemFullYear = date.getFullYear()
207
+ const itemMonth = date.getMonth()
208
+ const itemDate = date.getDate()
209
+ const isPrev = date < selectMonth
210
+ days.push({
211
+ date,
212
+ isPrev,
213
+ isCurrent: itemFullYear === selFullYear && itemMonth === selMonth,
214
+ isNow: itemFullYear === currFullYear && itemMonth === currMonth && itemDate === currDate,
215
+ isNext: !isPrev && selMonth !== itemMonth,
216
+ day: itemDate,
217
+ label: itemDate
218
+ })
219
+ }
220
+ }
221
+ return days
222
+ })
223
+ // 以下为日历需要
224
+ const tableConfig = computed(() => ({ cellspacing: 0, cellpadding: 0, border: 0 }))
225
+ const headers = computed(() => {
226
+ const weekDatas = computeWeekDatas.value
227
+ return weekDatas.map(day => {
228
+ return { value: day, label: props.weeks[day] }
229
+ })
230
+ })
231
+ const bodyDatas = computed(() => {
232
+ if ('month' === props.type) {
233
+ return $vUtils.chunk(computeMonthList.value, 3)
234
+ } else if ('year' === props.type) {
235
+ return $vUtils.chunk(computeYearList.value, 4)
236
+ }
237
+ return $vUtils.chunk(computeDayList.value, 7)
238
+ })
239
+ const computeDateValue = computed(() => {
240
+ const { inputValue } = reactData
241
+ let val = null
242
+ if (inputValue) {
243
+ const date = $vUtils.toStringDate(inputValue, props.valueFormat)
244
+ if ($vUtils.isValidDate(date)) {
245
+ val = date
246
+ }
247
+ }
248
+ return val
249
+ })
250
+ const showHeader = computed(() => !['month', 'year'].includes(props.type))
251
+ const yearValue = computed(() => $vUtils.toDateString(reactData.selectMonth, 'yyyy'))
252
+ const monthValue = computed(() => $vUtils.toDateString(reactData.selectMonth, 'MM'))
253
+ const dayValue = computed(() => $vUtils.toDateString(reactData.selectMonth, 'dd'))
254
+ const yearSelectConfig = computed(() => {
255
+ const options = []
256
+ for (let index = 1880; index < 2116; index++) {
257
+ options.push({
258
+ value: index + '',
259
+ label: `${index}年`
260
+ })
261
+ }
262
+ return {
263
+ modelValue: yearValue.value,
264
+ options: options,
265
+ filterable: true,
266
+ style: { width: '85px' }
267
+ }
268
+ })
269
+ const monthSelectConfig = computed(() => {
270
+ const options = []
271
+ for (let index = 1; index < 13; index++) {
272
+ options.push({
273
+ value: index + '',
274
+ label: `${index}月`
275
+ })
276
+ }
277
+ return {
278
+ modelValue: monthValue.value,
279
+ options: options,
280
+ filterable: true,
281
+ style: { width: '75px' }
282
+ }
283
+ })
284
+ const lunarInfo = computed(() => {
285
+ let dayDate = reactData.inputValue || reactData.currentDate
286
+ let lunarDate = Lunar.fromDate(dayDate)
287
+ return {
288
+ day: $vUtils.toDateString(dayDate, 'yyyy 年 MM 月 dd 日'),
289
+ lunarMonth: lunarDate.getMonthInChinese(),
290
+ lunarDay: lunarDate.getDayInChinese(),
291
+ yearGanZhi: lunarDate.getYearInGanZhi(),
292
+ yearShengXiao: lunarDate.getYearShengXiao(),
293
+ monthGanZhi: lunarDate.getMonthInGanZhi(),
294
+ dayGanZhi: lunarDate.getDayInGanZhi(),
295
+ yi: lunarDate.getDayYi(),
296
+ ji: lunarDate.getDayJi(),
297
+ jq: lunarDate.getJieQi()
298
+ }
299
+ })
300
+ const isDateDisabled = item => {
301
+ const { disabledMethod } = props
302
+ return disabledMethod && disabledMethod({ type: props.type, date: item.date })
303
+ }
304
+ const dateChange = date => {
305
+ emitValue(date)
306
+ emit('change', date)
307
+ }
308
+ const dateSelectItem = date => {
309
+ dateChange(date)
310
+ }
311
+ const dateCheckMonth = date => {
312
+ const month = $vUtils.getWhatMonth(date, 0, 'first')
313
+ if (!$vUtils.isEqual(month, reactData.selectMonth)) {
314
+ reactData.selectMonth = month
315
+ }
316
+ }
317
+ const dateMoveDay = offsetDay => {
318
+ if (isDateDisabled({ date: offsetDay })) return
319
+ const dayList = computeDayList.value
320
+ if (!dayList.some(item => $vUtils.isDateSame(item.date, offsetDay, 'yyyyMMdd'))) {
321
+ dateCheckMonth(offsetDay)
322
+ }
323
+ dateParseValue(offsetDay)
324
+ }
325
+ const dateMoveMonth = offsetMonth => {
326
+ if (isDateDisabled({ date: offsetMonth })) return
327
+ const monthList = computeMonthList.value
328
+ if (!monthList.some(item => $vUtils.isDateSame(item.date, offsetMonth, 'yyyyMM'))) {
329
+ dateCheckMonth(offsetMonth)
330
+ }
331
+ dateParseValue(offsetMonth)
332
+ }
333
+ const dateMoveYear = offsetYear => {
334
+ if (isDateDisabled({ date: offsetYear })) return
335
+ const yearList = computeYearList.value
336
+ if (!yearList.some(item => $vUtils.isDateSame(item.date, offsetYear, 'yyyy'))) {
337
+ dateCheckMonth(offsetYear)
338
+ }
339
+ dateParseValue(offsetYear)
340
+ }
341
+ const dateSelectEvent = item => {
342
+ if (isDateDisabled(item)) return
343
+ dateSelectItem(item.date)
344
+ }
345
+ const dateMouseenterEvent = item => {
346
+ if (isDateDisabled(item)) return
347
+ if (props.type === 'month') {
348
+ dateMoveMonth(item.date)
349
+ } else if (props.type === 'year') {
350
+ dateMoveYear(item.date)
351
+ } else {
352
+ dateMoveDay(item.date)
353
+ }
354
+ }
355
+ const dateMouseleaveEvent = () => {
356
+ dateParseValue()
357
+ }
358
+ const dateParseValue = value => {
359
+ let dValue = null
360
+ if (value) {
361
+ dValue = $vUtils.toStringDate(value, props.valueFormat)
362
+ }
363
+ if (dValue && !$vUtils.isValidDate(dValue)) {
364
+ dValue = null
365
+ }
366
+ reactData.panelValue = dValue
367
+ }
368
+ const getLunarDate = day => {
369
+ let lunarDate = Lunar.fromDate(day)
370
+ let lunarText = lunarDate.getDayInChinese()
371
+ const jq = lunarDate.getJieQi()
372
+ const solarFestivals = lunarDate.getFestivals()
373
+ if (jq) {
374
+ lunarText = jq
375
+ } else if (lunarDate.getDay() === 1) {
376
+ lunarText = lunarDate.getMonthInChinese() + '月'
377
+ } else if (solarFestivals.length > 0) {
378
+ const f = solarFestivals[0]
379
+ if (f.length < 4) {
380
+ lunarText = f
381
+ }
382
+ }
383
+ return lunarText
384
+ }
385
+ const getCellClass = item => {
386
+ const { panelValue } = reactData
387
+ const dateValue = computeDateValue.value
388
+ let matchFormat = 'yyyyMMdd'
389
+ if ('month' === props.type) matchFormat = 'yyyyMM'
390
+ else if ('year' === props.type) matchFormat = 'yyyy'
391
+ const ymd = $vUtils.toDateString(item.date, 'yyyyMMdd')
392
+ const lunarDate = Lunar.fromDate(item.date)
393
+ const holiday = HolidayUtil.getHoliday(ymd)
394
+ let rest = false
395
+ if ([0, 6].includes(lunarDate.getWeek())) {
396
+ rest = true
397
+ }
398
+ if (holiday) rest = !holiday.isWork()
399
+ return {
400
+ 'is--prev': item.isPrev,
401
+ 'is--current': item.isCurrent,
402
+ 'is--now': item.isNow,
403
+ 'is--next': item.isNext,
404
+ 'is--holiday': holiday,
405
+ 'is--rest': rest,
406
+ 'is--disabled': isDateDisabled(item),
407
+ 'is--selected': $vUtils.isDateSame(dateValue, item.date, matchFormat),
408
+ 'is--hover': $vUtils.isDateSame(panelValue, item.date, matchFormat)
409
+ }
410
+ }
411
+ const handleBtn = ({ code }) => {
412
+ try {
413
+ const { currentDate, selectMonth } = reactData
414
+ let getName = 'getWhatMonth'
415
+ let getSize = 1
416
+ if (['month', 'year'].includes(props.type)) getName = 'getWhatYear'
417
+ if (['year'].includes(props.type)) getSize = yearSize
418
+ switch (code) {
419
+ case 'prev':
420
+ reactData.selectMonth = $vUtils[getName](selectMonth, getSize * -1, 'first')
421
+ break
422
+ case 'next':
423
+ reactData.selectMonth = $vUtils[getName](selectMonth, getSize, 'first')
424
+ break
425
+ case 'current':
426
+ reactData.selectMonth = $vUtils.getWhatMonth(currentDate, 0, 'first')
427
+ break
428
+ default:
429
+ break
430
+ }
431
+ } catch (e) {
432
+ proxy.msgwarning(e.message)
433
+ }
434
+ }
435
+ const emitValue = (value, evnt) => {
436
+ reactData.inputValue = value
437
+ emit('update:modelValue', value)
438
+ }
439
+
440
+ // 初始化
441
+ const initValue = () => {
442
+ reactData.currentDate = $vUtils.getWhatDay(Date.now(), 0, 'first')
443
+ reactData.selectMonth = $vUtils.getWhatMonth(computeDateValue.value || reactData.currentDate, 0, 'first')
444
+ }
445
+ // 年度切换
446
+ const onYearChange = ({ value }) => {
447
+ const { selectMonth } = reactData
448
+ const selMonth = selectMonth.getMonth() + 1
449
+ const selDate = selectMonth.getDate()
450
+ const changeDate = `${value}-${selMonth}-${selDate}`
451
+ reactData.selectMonth = $vUtils.toStringDate(changeDate)
452
+ }
453
+ // 月份切换
454
+ const onMonthChange = ({ value }) => {
455
+ const { selectMonth } = reactData
456
+ const selYear = selectMonth.getFullYear()
457
+ const selDate = selectMonth.getDate()
458
+ const changeDate = `${selYear}-${value}-${selDate}`
459
+ reactData.selectMonth = $vUtils.toStringDate(changeDate)
460
+ }
461
+
462
+ onBeforeMount(() => {
463
+ initValue()
464
+ })
465
+
466
+ watch(
467
+ () => props.modelValue,
468
+ val => {
469
+ reactData.inputValue = val
470
+ }
471
+ )
472
+
473
+ return {
474
+ reactData,
475
+ tableConfig,
476
+ yearSelectConfig,
477
+ monthSelectConfig,
478
+ headers,
479
+ bodyDatas,
480
+ lunarInfo,
481
+ headerHandles,
482
+ computeYearList,
483
+ computeMonthList,
484
+ showHeader,
485
+ onYearChange,
486
+ onMonthChange,
487
+ getLunarDate,
488
+ getCellClass,
489
+ handleBtn,
490
+ dateSelectEvent,
491
+ dateMouseenterEvent,
492
+ dateMouseleaveEvent
493
+ }
494
+ }
495
+ })
496
+ </script>
497
+
498
+ <style scoped lang="scss">
499
+ .sh-calendar {
500
+ overflow: auto;
501
+ .sh-calendar-title {
502
+ font-size: 18px;
503
+ font-weight: bold;
504
+ }
505
+ .sh-calendar-span {
506
+ margin-right: 5px;
507
+ }
508
+ .sh-calendar-tag {
509
+ border-radius: 30px;
510
+ padding: 5px;
511
+ display: inline-flex;
512
+ vertical-align: top;
513
+ line-height: 1;
514
+ margin-right: 10px;
515
+ &.yi {
516
+ background-color: var(--vxe-success-color);
517
+ color: #fff;
518
+ }
519
+ &.ji {
520
+ background-color: var(--vxe-danger-color);
521
+ color: #fff;
522
+ }
523
+ }
524
+ .sh-calendar-row {
525
+ display: flex;
526
+ justify-content: space-between;
527
+ align-items: center;
528
+ .info {
529
+ flex: 1;
530
+ &.right {
531
+ text-align: right;
532
+ }
533
+ }
534
+ .extra {
535
+ display: inline-flex;
536
+ flex-wrap: nowrap;
537
+ }
538
+ & + .sh-calendar-row {
539
+ margin-top: 5px;
540
+ }
541
+ }
542
+ .sh-calendar-head,
543
+ .sh-calendar-foot {
544
+ padding: 8px;
545
+ border: 1px solid var(--vxe-table-border-color);
546
+ }
547
+ .sh-calendar-head {
548
+ border-bottom: none;
549
+ line-height: 1;
550
+ }
551
+ .sh-calendar-foot {
552
+ border-top: none;
553
+ }
554
+ .sh-calendar-btn {
555
+ padding: 5px;
556
+ border-radius: var(--vxe-border-radius);
557
+ border: 1px solid var(--vxe-table-border-color);
558
+ margin-left: 5px;
559
+ &:hover {
560
+ color: var(--vxe-primary-color);
561
+ }
562
+ }
563
+ .sh-calendar-cell {
564
+ display: block;
565
+ &-head {
566
+ padding: 3px 5px;
567
+ & + .sh-calendar-cell-foot {
568
+ padding-top: 0;
569
+ }
570
+ &.is-month {
571
+ padding: 20px 5px;
572
+ }
573
+ }
574
+ &-body {
575
+ overflow: auto;
576
+ }
577
+ &-foot {
578
+ padding: 3px 5px;
579
+ font-size: 0.8em;
580
+ }
581
+ }
582
+ .sh-calendar-table {
583
+ &:not(.sh-calendar-pulldown) {
584
+ td {
585
+ border: 1px solid var(--vxe-table-border-color);
586
+ }
587
+ }
588
+ &.sh-calendar-pulldown {
589
+ tbody {
590
+ border: 1px solid var(--vxe-table-border-color);
591
+ }
592
+ }
593
+ }
594
+ table {
595
+ border: 0;
596
+ width: 100%;
597
+ border-spacing: 0;
598
+ border-collapse: collapse;
599
+ table-layout: fixed;
600
+ height: 100%;
601
+ }
602
+ th,
603
+ td {
604
+ font-weight: normal;
605
+ position: relative;
606
+ height: 36px;
607
+ }
608
+ th {
609
+ border: 1px solid var(--vxe-table-border-color);
610
+ }
611
+ td {
612
+ &.is--prev,
613
+ &.is--next {
614
+ color: var(--vxe-font-disabled-color);
615
+ }
616
+ //&.is--rest {
617
+ // .sh-calendar-cell-head {
618
+ // color: var(--vxe-danger-color);
619
+ // }
620
+ //}
621
+ &.is--now {
622
+ &:not(.is--selected) {
623
+ color: var(--vxe-primary-color);
624
+ &.is--current {
625
+ background-color: var(--primary-weak-color);
626
+ }
627
+ }
628
+ }
629
+ &.is--hover {
630
+ background-color: var(--vxe-input-date-picker-hover-background-color);
631
+ }
632
+ &.is--selected {
633
+ color: var(--vxe-input-date-picker-selected-color);
634
+ background-color: var(--vxe-primary-color);
635
+ &.is--prev,
636
+ &.is--next {
637
+ background-color: var(--vxe-primary-lighten-color);
638
+ }
639
+ }
640
+ &:not(.is--disabled) {
641
+ cursor: pointer;
642
+ }
643
+ &.is--disabled {
644
+ cursor: no-drop;
645
+ color: var(--vxe-input-disabled-color);
646
+ background-color: var(--vxe-input-disabled-background-color);
647
+ }
648
+ }
649
+ }
650
+ </style>