sh-view 2.6.5 → 2.6.7

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/README.md CHANGED
@@ -66,7 +66,8 @@ createApp(App).use(ShView).mount('#app')
66
66
 
67
67
  #### 功能计划
68
68
  * [x] v2.6.4 基于 vxe4.+,包含vxe-table所有功能,扩展更强渲染器
69
- * [ ] 下一阶段:独立vxe的日历组件,独立范围选择日期渲染器;低代码配置;基础sh-view的admin系统开源(包含低代码设计模板,及系统鉴权、路由守卫等)
69
+ * [x] v2.6.7:独立日历组件,扩展日期选择组件(支持日期的单选,范围选择,多日期选择等);
70
+ * [ ] 下一阶段:基础sh-view的admin系统开源(包含低代码设计模板,及系统鉴权、路由守卫等)
70
71
 
71
72
 
72
73
  #### 项目预览
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sh-view",
3
- "version": "2.6.5",
3
+ "version": "2.6.7",
4
4
  "description": "基于vxe-table二次封装",
5
5
  "main": "packages/index.js",
6
6
  "scripts": {
@@ -27,13 +27,14 @@
27
27
  "exceljs": "^4.3.0",
28
28
  "jspdf": "^2.5.1",
29
29
  "jszip": "^3.10.1",
30
+ "lunar-javascript": "^1.6.4",
30
31
  "popper.js": "^1.16.1",
31
- "sh-tools": "^2.1.6",
32
+ "sh-tools": "^2.1.7",
32
33
  "tinymce": "^5.10.5",
33
34
  "vue": "^3.3.4",
34
35
  "vue-masonry": "^0.16.0",
35
36
  "vue-router": "^4.2.4",
36
- "vxe-table": "^4.5.11",
37
+ "vxe-table": "^4.5.12",
37
38
  "vxe-table-plugin-export-pdf": "^3.0.4",
38
39
  "vxe-table-plugin-export-xlsx": "^3.0.5",
39
40
  "xe-clipboard": "^1.10.2",
@@ -8,7 +8,7 @@
8
8
  </div>
9
9
  <div class="sh-alert-content">
10
10
  <slot>{{ title }}</slot>
11
- <div class="sh-alert-desc">
11
+ <div v-if="content || $slots.content" class="sh-alert-desc">
12
12
  <slot name="content">{{ content }}</slot>
13
13
  </div>
14
14
  </div>
@@ -0,0 +1,519 @@
1
+ <template>
2
+ <div class="sh-calendar">
3
+ <div v-if="header" class="sh-calendar-row sh-calendar-head">
4
+ <div class="info">{{ monthInfo }}</div>
5
+ <div class="extra">
6
+ <template v-for="item in headerHandles" :key="item.code">
7
+ <span class="sh-calendar-btn" @click="handleBtn(item)"><i :class="item.icon"></i></span>
8
+ </template>
9
+ </div>
10
+ </div>
11
+ <table class="sh-calendar-table" :class="{ 'sh-calendar-pulldown': pulldown }" v-bind="tableConfig">
12
+ <thead>
13
+ <tr>
14
+ <template v-for="(head, headIndex) in headers" :key="headIndex">
15
+ <th :style="{ textAlign: headerAlign }">{{ head.label }}</th>
16
+ </template>
17
+ </tr>
18
+ </thead>
19
+ <tbody @mouseleave="dateMouseleaveEvent">
20
+ <template v-for="(row, rowIndex) in dayDatas" :key="rowIndex">
21
+ <tr>
22
+ <template v-for="(item, itemIndex) in row" :key="itemIndex">
23
+ <td :class="getCellClass(item)" @mouseenter="dateMouseenterEvent(item)" @click="dateSelectEvent(item)">
24
+ <slot name="cell" v-bind="item">
25
+ <div class="sh-calendar-cell" :style="{ textAlign: align }">
26
+ <div class="sh-calendar-cell-head">{{ item.label }}</div>
27
+ <div v-if="note" class="sh-calendar-cell-body" :style="{ height: noteHeight }">{{ noteMethod(item) }}</div>
28
+ <div v-if="festival" class="sh-calendar-cell-foot">{{ getLunarDate(item.date) }}</div>
29
+ </div>
30
+ </slot>
31
+ </td>
32
+ </template>
33
+ </tr>
34
+ </template>
35
+ </tbody>
36
+ </table>
37
+ <div v-if="footer" class="sh-calendar-foot">
38
+ <div class="sh-calendar-row">
39
+ <div class="info">
40
+ <div>{{ lunarInfo.day }}</div>
41
+ <div class="sh-calendar-title">{{ lunarInfo.lunarMonth }}月 {{ lunarInfo.lunarDay }}</div>
42
+ <div class="sh-calendar-title">{{ lunarInfo.jq }}</div>
43
+ </div>
44
+ <div class="info right">
45
+ <div class="sh-calendar-title">{{ lunarInfo.yearGanZhi }}年 {{ lunarInfo.yearShengXiao }}</div>
46
+ <div>{{ lunarInfo.monthGanZhi }}月 {{ lunarInfo.dayGanZhi }}</div>
47
+ </div>
48
+ </div>
49
+ <div class="sh-calendar-row">
50
+ <div class="extra"><span class="sh-calendar-tag yi">宜</span></div>
51
+ <div class="info">
52
+ <template v-for="(y, yIndex) in lunarInfo.yi" :key="yIndex">
53
+ <span class="sh-calendar-span">{{ y }}</span>
54
+ </template>
55
+ </div>
56
+ </div>
57
+ <div class="sh-calendar-row">
58
+ <div class="extra"><span class="sh-calendar-tag ji">忌</span></div>
59
+ <div class="info">
60
+ <template v-for="(j, jIndex) in lunarInfo.ji" :key="jIndex">
61
+ <span class="sh-calendar-span">{{ j }}</span>
62
+ </template>
63
+ </div>
64
+ </div>
65
+ </div>
66
+ </div>
67
+ </template>
68
+
69
+ <script>
70
+ import { computed, defineComponent, getCurrentInstance, ref, reactive, onBeforeMount, PropType, watch } from 'vue'
71
+ import { Lunar, HolidayUtil } from 'lunar-javascript'
72
+ export default defineComponent({
73
+ name: 'ShCalendar',
74
+ props: {
75
+ modelValue: [String, Number, Date],
76
+ type: { type: String, default: 'day' }, // day, month, year 暂时只支持day
77
+ startDay: { type: [String, Number], default: 1 },
78
+ headerAlign: { type: String, default: 'center' },
79
+ align: { type: String, default: 'center' },
80
+ header: { type: Boolean, default: true },
81
+ footer: { type: Boolean, default: false },
82
+ note: { type: Boolean, default: false }, // 是否备注
83
+ noteHeight: { type: String, default: '22px' }, // 备注高度
84
+ noteMethod: { type: Function, default() {} },
85
+ festival: { type: Boolean, default: false }, // 是否显示农历
86
+ pulldown: { type: Boolean, default: false }, // 是否为下拉显示
87
+ valueFormat: { type: String, default: '' },
88
+ weeks: {
89
+ type: Array,
90
+ default() {
91
+ return ['周日', '周一', '周二', '周三', '周四', '周五', '周六']
92
+ }
93
+ },
94
+ disabledMethod: { type: Function }
95
+ },
96
+ emits: ['update:modelValue', 'change'],
97
+ setup(props, context) {
98
+ const { proxy } = getCurrentInstance()
99
+ const { $vUtils } = proxy
100
+ const { emit, slots } = context
101
+
102
+ const headerHandles = [
103
+ { code: 'prev', icon: 'vxe-icon-caret-left' },
104
+ { code: 'current', icon: 'vxe-icon-dot' },
105
+ { code: 'next', icon: 'vxe-icon-caret-right' }
106
+ ]
107
+ const reactData = reactive({
108
+ inputValue: props.modelValue,
109
+ panelValue: null,
110
+ panelLabel: '',
111
+ selectMonth: null,
112
+ currentDate: null
113
+ })
114
+ const computeFirstDayOfWeek = computed(() => {
115
+ const { startDay, startWeek } = props
116
+ return $vUtils.toNumber($vUtils.isNumber(startDay) || $vUtils.isString(startDay) ? startDay : startWeek)
117
+ })
118
+ const computeWeekDatas = computed(() => {
119
+ const weeks = []
120
+ let sWeek = computeFirstDayOfWeek.value
121
+ weeks.push(sWeek)
122
+ for (let index = 0; index < 6; index++) {
123
+ if (sWeek >= 6) {
124
+ sWeek = 0
125
+ } else {
126
+ sWeek++
127
+ }
128
+ weeks.push(sWeek)
129
+ }
130
+ return weeks
131
+ })
132
+ const computeDateHMSTime = computed(() => {
133
+ const dateValue = computeDateValue.value
134
+ return dateValue ? (dateValue.getHours() * 3600 + dateValue.getMinutes() * 60 + dateValue.getSeconds()) * 1000 : 0
135
+ })
136
+ const computeDayList = computed(() => {
137
+ const { selectMonth, currentDate } = reactData
138
+ const days = []
139
+ if (selectMonth && currentDate) {
140
+ const dateHMSTime = computeDateHMSTime.value
141
+ const weekDatas = computeWeekDatas.value
142
+ const currFullYear = currentDate.getFullYear()
143
+ const currMonth = currentDate.getMonth()
144
+ const currDate = currentDate.getDate()
145
+ const selFullYear = selectMonth.getFullYear()
146
+ const selMonth = selectMonth.getMonth()
147
+ const selDay = selectMonth.getDay()
148
+ const prevOffsetDate = -weekDatas.indexOf(selDay)
149
+ const startDayDate = new Date($vUtils.getWhatDay(selectMonth, prevOffsetDate).getTime() + dateHMSTime)
150
+ for (let index = 0; index < 42; index++) {
151
+ const date = $vUtils.getWhatDay(startDayDate, index)
152
+ const itemFullYear = date.getFullYear()
153
+ const itemMonth = date.getMonth()
154
+ const itemDate = date.getDate()
155
+ const isPrev = date < selectMonth
156
+ days.push({
157
+ date,
158
+ isPrev,
159
+ isCurrent: itemFullYear === selFullYear && itemMonth === selMonth,
160
+ isNow: itemFullYear === currFullYear && itemMonth === currMonth && itemDate === currDate,
161
+ isNext: !isPrev && selMonth !== itemMonth,
162
+ label: itemDate
163
+ })
164
+ }
165
+ }
166
+ return days
167
+ })
168
+
169
+ // 以下为日历需要
170
+ const tableConfig = computed(() => ({ cellspacing: 0, cellpadding: 0, border: 0 }))
171
+ const headers = computed(() => {
172
+ const weekDatas = computeWeekDatas.value
173
+ return weekDatas.map(day => {
174
+ return { value: day, label: props.weeks[day] }
175
+ })
176
+ })
177
+ const dayDatas = computed(() => {
178
+ const dayList = computeDayList.value
179
+ return $vUtils.chunk(dayList, 7)
180
+ })
181
+ const computeDateValue = computed(() => {
182
+ const { inputValue } = reactData
183
+ let val = null
184
+ if (inputValue) {
185
+ const date = $vUtils.toStringDate(inputValue, props.valueFormat)
186
+ if ($vUtils.isValidDate(date)) {
187
+ val = date
188
+ }
189
+ }
190
+ return val
191
+ })
192
+ const monthInfo = computed(() => $vUtils.toDateString(reactData.selectMonth, 'yyyy 年 MM 月'))
193
+ const dayInfo = computed(() => $vUtils.toDateString(reactData.currentDate, 'yyyyMMdd'))
194
+ const lunarInfo = computed(() => {
195
+ let dayDate = reactData.inputValue || reactData.currentDate
196
+ let lunarDate = Lunar.fromDate(dayDate)
197
+ return {
198
+ day: $vUtils.toDateString(dayDate, 'yyyy 年 MM 月 dd 日'),
199
+ lunarMonth: lunarDate.getMonthInChinese(),
200
+ lunarDay: lunarDate.getDayInChinese(),
201
+ yearGanZhi: lunarDate.getYearInGanZhi(),
202
+ yearShengXiao: lunarDate.getYearShengXiao(),
203
+ monthGanZhi: lunarDate.getMonthInGanZhi(),
204
+ dayGanZhi: lunarDate.getDayInGanZhi(),
205
+ yi: lunarDate.getDayYi(),
206
+ ji: lunarDate.getDayJi(),
207
+ jq: lunarDate.getJieQi()
208
+ }
209
+ })
210
+ const isDateDisabled = item => {
211
+ const { disabledMethod } = props
212
+ return disabledMethod && disabledMethod({ type: props.type, date: item.date })
213
+ }
214
+ const dateChange = date => {
215
+ emitValue(date)
216
+ emit('change', date)
217
+ }
218
+ const dateSelectItem = date => {
219
+ const { type } = props
220
+ if (type === 'month') {
221
+ } else if (type === 'year') {
222
+ } else {
223
+ dateChange(date)
224
+ }
225
+ }
226
+ const dateCheckMonth = date => {
227
+ const month = $vUtils.getWhatMonth(date, 0, 'first')
228
+ if (!$vUtils.isEqual(month, reactData.selectMonth)) {
229
+ reactData.selectMonth = month
230
+ }
231
+ }
232
+ const dateMoveDay = date => {
233
+ if (isDateDisabled(date)) return
234
+ const dayList = computeDayList.value
235
+ if (!dayList.some(item => $vUtils.isDateSame(item.date, date.date, 'yyyyMMdd'))) {
236
+ dateCheckMonth(date.date)
237
+ }
238
+ dateParseValue(date.date)
239
+ }
240
+ const dateSelectEvent = item => {
241
+ if (isDateDisabled(item)) return
242
+ dateSelectItem(item.date)
243
+ }
244
+ const dateMouseenterEvent = item => {
245
+ if (isDateDisabled(item)) return
246
+ const { datePanelType } = reactData
247
+ if (datePanelType === 'month') {
248
+ // dateMoveMonth(item.date)
249
+ } else if (datePanelType === 'year') {
250
+ // dateMoveYear(item.date)
251
+ } else {
252
+ dateMoveDay(item)
253
+ }
254
+ }
255
+ const dateMouseleaveEvent = () => {
256
+ dateParseValue()
257
+ }
258
+ const dateParseValue = value => {
259
+ let dValue = null
260
+ if (value) {
261
+ dValue = $vUtils.toStringDate(value, props.valueFormat)
262
+ }
263
+ if (dValue && !$vUtils.isValidDate(dValue)) {
264
+ dValue = null
265
+ }
266
+ reactData.panelValue = dValue
267
+ }
268
+ const getLunarDate = day => {
269
+ let lunarDate = Lunar.fromDate(day)
270
+ let lunarText = lunarDate.getDayInChinese()
271
+ const jq = lunarDate.getJieQi()
272
+ const solarFestivals = lunarDate.getFestivals()
273
+ if (jq) {
274
+ lunarText = jq
275
+ } else if (lunarDate.getDay() === 1) {
276
+ lunarText = lunarDate.getMonthInChinese() + '月'
277
+ } else if (solarFestivals.length > 0) {
278
+ const f = solarFestivals[0]
279
+ if (f.length < 4) {
280
+ lunarText = f
281
+ }
282
+ }
283
+ return lunarText
284
+ }
285
+ const getCellClass = item => {
286
+ const { panelValue } = reactData
287
+ const dateValue = computeDateValue.value
288
+ const matchFormat = 'yyyyMMdd'
289
+ const ymd = $vUtils.toDateString(item.date, matchFormat)
290
+ const lunarDate = Lunar.fromDate(item.date)
291
+ const holiday = HolidayUtil.getHoliday(ymd)
292
+ let rest = false
293
+ if ([0, 6].includes(lunarDate.getWeek())) {
294
+ rest = true
295
+ }
296
+ if (holiday) rest = !holiday.isWork()
297
+ return {
298
+ 'is--prev': item.isPrev,
299
+ 'is--current': item.isCurrent,
300
+ 'is--now': item.isNow,
301
+ 'is--next': item.isNext,
302
+ 'is--holiday': holiday,
303
+ 'is--rest': rest,
304
+ 'is--disabled': isDateDisabled(item),
305
+ 'is--selected': $vUtils.isDateSame(dateValue, item.date, matchFormat),
306
+ 'is--hover': $vUtils.isDateSame(panelValue, item.date, matchFormat)
307
+ }
308
+ }
309
+ const handleBtn = ({ code }) => {
310
+ try {
311
+ const { currentDate, selectMonth } = reactData
312
+ switch (code) {
313
+ case 'prev':
314
+ reactData.selectMonth = $vUtils.getWhatMonth(selectMonth, -1, 'first')
315
+ break
316
+ case 'next':
317
+ reactData.selectMonth = $vUtils.getWhatMonth(selectMonth, 1, 'first')
318
+ break
319
+ case 'current':
320
+ reactData.selectMonth = $vUtils.getWhatMonth(currentDate, 0, 'first')
321
+ break
322
+ default:
323
+ break
324
+ }
325
+ } catch (e) {
326
+ proxy.msgwarning(e.message)
327
+ }
328
+ }
329
+ const emitValue = (value, evnt) => {
330
+ reactData.inputValue = value
331
+ emit('update:modelValue', value)
332
+ }
333
+
334
+ // 初始化
335
+ const initValue = () => {
336
+ reactData.currentDate = $vUtils.getWhatDay(Date.now(), 0, 'first')
337
+ reactData.selectMonth = $vUtils.getWhatMonth(reactData.currentDate, 0, 'first')
338
+ }
339
+
340
+ onBeforeMount(() => {
341
+ initValue()
342
+ })
343
+
344
+ watch(
345
+ () => props.modelValue,
346
+ val => {
347
+ reactData.inputValue = val
348
+ }
349
+ )
350
+
351
+ return {
352
+ tableConfig,
353
+ headers,
354
+ dayDatas,
355
+ monthInfo,
356
+ dayInfo,
357
+ lunarInfo,
358
+ headerHandles,
359
+ getLunarDate,
360
+ getCellClass,
361
+ handleBtn,
362
+ dateSelectEvent,
363
+ dateMouseenterEvent,
364
+ dateMouseleaveEvent
365
+ }
366
+ }
367
+ })
368
+ </script>
369
+
370
+ <style scoped lang="scss">
371
+ .sh-calendar {
372
+ overflow: auto;
373
+ .sh-calendar-title {
374
+ font-size: 18px;
375
+ font-weight: bold;
376
+ }
377
+ .sh-calendar-span {
378
+ margin-right: 5px;
379
+ }
380
+ .sh-calendar-tag {
381
+ border-radius: 30px;
382
+ padding: 5px;
383
+ display: inline-flex;
384
+ vertical-align: top;
385
+ line-height: 1;
386
+ margin-right: 10px;
387
+ &.yi {
388
+ background-color: var(--vxe-success-color);
389
+ color: #fff;
390
+ }
391
+ &.ji {
392
+ background-color: var(--vxe-danger-color);
393
+ color: #fff;
394
+ }
395
+ }
396
+ .sh-calendar-row {
397
+ display: flex;
398
+ justify-content: space-between;
399
+ align-items: center;
400
+ .info {
401
+ flex: 1;
402
+ &.right {
403
+ text-align: right;
404
+ }
405
+ }
406
+ .extra {
407
+ display: inline-flex;
408
+ flex-wrap: nowrap;
409
+ }
410
+ & + .sh-calendar-row {
411
+ margin-top: 5px;
412
+ }
413
+ }
414
+ .sh-calendar-head,
415
+ .sh-calendar-foot {
416
+ padding: 8px;
417
+ border: 1px solid var(--vxe-table-border-color);
418
+ }
419
+ .sh-calendar-head {
420
+ border-bottom: none;
421
+ line-height: 1;
422
+ }
423
+ .sh-calendar-foot {
424
+ border-top: none;
425
+ }
426
+ .sh-calendar-btn {
427
+ padding: 5px;
428
+ border-radius: var(--vxe-border-radius);
429
+ border: 1px solid var(--vxe-table-border-color);
430
+ margin-left: 5px;
431
+ &:hover {
432
+ color: var(--vxe-primary-color);
433
+ }
434
+ }
435
+ .sh-calendar-cell {
436
+ display: block;
437
+ &-head {
438
+ padding: 3px 5px;
439
+ & + .sh-calendar-cell-foot {
440
+ padding-top: 0;
441
+ }
442
+ }
443
+ &-body {
444
+ overflow: auto;
445
+ }
446
+ &-foot {
447
+ padding: 3px 5px;
448
+ font-size: 0.8em;
449
+ }
450
+ }
451
+ .sh-calendar-table {
452
+ &:not(.sh-calendar-pulldown) {
453
+ td {
454
+ border: 1px solid var(--vxe-table-border-color);
455
+ }
456
+ }
457
+ &.sh-calendar-pulldown {
458
+ tbody {
459
+ border: 1px solid var(--vxe-table-border-color);
460
+ }
461
+ }
462
+ }
463
+ table {
464
+ border: 0;
465
+ width: 100%;
466
+ border-spacing: 0;
467
+ border-collapse: collapse;
468
+ table-layout: fixed;
469
+ height: 100%;
470
+ }
471
+ th,
472
+ td {
473
+ font-weight: normal;
474
+ position: relative;
475
+ height: 36px;
476
+ }
477
+ th {
478
+ border: 1px solid var(--vxe-table-border-color);
479
+ }
480
+ td {
481
+ &.is--prev,
482
+ &.is--next {
483
+ color: var(--vxe-font-disabled-color);
484
+ }
485
+ //&.is--rest {
486
+ // .sh-calendar-cell-head {
487
+ // color: var(--vxe-danger-color);
488
+ // }
489
+ //}
490
+ &.is--now {
491
+ &:not(.is--selected) {
492
+ color: var(--vxe-primary-color);
493
+ &.is--current {
494
+ background-color: var(--primary-weak-color);
495
+ }
496
+ }
497
+ }
498
+ &.is--hover {
499
+ background-color: var(--vxe-input-date-picker-hover-background-color);
500
+ }
501
+ &.is--selected {
502
+ color: var(--vxe-input-date-picker-selected-color);
503
+ background-color: var(--vxe-primary-color);
504
+ &.is--prev,
505
+ &.is--next {
506
+ background-color: var(--vxe-primary-lighten-color);
507
+ }
508
+ }
509
+ &:not(.is--disabled) {
510
+ cursor: pointer;
511
+ }
512
+ &.is--disabled {
513
+ cursor: no-drop;
514
+ color: var(--vxe-input-disabled-color);
515
+ background-color: var(--vxe-input-disabled-background-color);
516
+ }
517
+ }
518
+ }
519
+ </style>
@@ -0,0 +1,273 @@
1
+ <template>
2
+ <div class="sh-date">
3
+ <template v-if="range">
4
+ <vxe-pulldown v-model="pulldownValue" v-bind="pulldownConfig" @hide-panel="onHidePanel">
5
+ <template #default>
6
+ <div class="sh-date-range-input" @click="onRangeFocus">
7
+ <input class="vxe-input vxe-input--inner" v-bind="startInputConfig" />
8
+ <span>{{ separator }}</span>
9
+ <input class="vxe-input vxe-input--inner" v-bind="endInputConfig" />
10
+ <span class="sh-date-range-suffix sh-date-clear" @click.stop="onRangeClear"><i class="vxe-icon-error-circle-fill"></i></span>
11
+ <span class="sh-date-range-suffix"><i class="vxe-icon-calendar"></i></span>
12
+ </div>
13
+ </template>
14
+ <template #dropdown>
15
+ <div class="sh-date-content">
16
+ <sh-calendar v-model="rangeValue[0]" v-bind="startCalendarConfig"></sh-calendar>
17
+ <div style="min-width: 10px"></div>
18
+ <sh-calendar v-model="rangeValue[1]" v-bind="endCalendarConfig"></sh-calendar>
19
+ </div>
20
+ </template>
21
+ </vxe-pulldown>
22
+ </template>
23
+ <template v-else>
24
+ <vxe-input
25
+ v-model="inputValue"
26
+ v-bind="inputConfig"
27
+ @input="dispatch('input', $event)"
28
+ @change="dispatch('change', $event)"
29
+ @keydown="dispatch('keydown', $event)"
30
+ @keyup="dispatch('keyup', $event)"
31
+ @click="dispatch('click', $event)"
32
+ @focus="dispatch('focus', $event)"
33
+ @blur="dispatch('blur', $event)"
34
+ @clear="dispatch('clear', $event)"
35
+ @search-click="dispatch('search-click', $event)"
36
+ @toggle-visible="dispatch('toggle-visible', $event)"
37
+ @prefix-click="dispatch('prefix-click', $event)"
38
+ @suffix-click="dispatch('suffix-click', $event)"
39
+ @date-prev="dispatch('date-prev', $event)"
40
+ @date-today="dispatch('date-today', $event)"
41
+ @date-next="dispatch('date-next', $event)"></vxe-input>
42
+ </template>
43
+ </div>
44
+ </template>
45
+
46
+ <script>
47
+ // 记录自定义参数,传给vxe要过滤掉
48
+ let omitProps = ['range', 'separator', 'startPlaceholder', 'endPlaceholder', 'pulldown']
49
+ import { computed, defineComponent, getCurrentInstance, ref, reactive, onBeforeMount, PropType, watch } from 'vue'
50
+ export default defineComponent({
51
+ name: 'ShDate',
52
+ props: {
53
+ modelValue: [String, Number, Date, Array],
54
+ type: { type: String, default: 'date' },
55
+ clearable: { type: Boolean },
56
+ readonly: Boolean,
57
+ disabled: Boolean,
58
+ placeholder: String,
59
+ className: String,
60
+ size: String,
61
+ multiple: Boolean,
62
+ // date、week、month、quarter、year
63
+ startDate: { type: [String, Number, Date] },
64
+ endDate: { type: [String, Number, Date] },
65
+ minDate: [String, Number, Date],
66
+ maxDate: [String, Number, Date],
67
+ startDay: { type: [String, Number] },
68
+ labelFormat: { type: String, default: 'yyyy-MM-dd' },
69
+ valueFormat: { type: String, default: 'yyyy-MM-dd' },
70
+ editable: { type: Boolean, default: true },
71
+ festivalMethod: { type: Function },
72
+ disabledMethod: { type: Function },
73
+ // week
74
+ selectDay: { type: [String, Number] },
75
+ prefixIcon: String,
76
+ suffixIcon: String,
77
+ placement: String,
78
+ transfer: Boolean,
79
+ // 个性化参数
80
+ range: Boolean,
81
+ separator: { type: String, default: '至' },
82
+ startPlaceholder: { type: String, default: '起始日期' },
83
+ endPlaceholder: { type: String, default: '截止日期' },
84
+ pulldown: Object
85
+ },
86
+ emits: [
87
+ 'update:modelValue',
88
+ 'focus',
89
+ 'change',
90
+ 'blur',
91
+ 'input',
92
+ 'keydown',
93
+ 'keyup',
94
+ 'click',
95
+ 'clear',
96
+ 'search-click',
97
+ 'toggle-visible',
98
+ 'prefix-click',
99
+ 'suffix-click',
100
+ 'date-prev',
101
+ 'date-today',
102
+ 'date-next'
103
+ ],
104
+ setup(props, context) {
105
+ const { proxy } = getCurrentInstance()
106
+ const { $vUtils } = proxy
107
+ const { emit, slots } = context
108
+
109
+ const pulldownValue = ref(false)
110
+ const inputValue = ref(props.modelValue)
111
+ const rangeValue = ref(props.modelValue || [])
112
+
113
+ const inputConfig = computed(() => {
114
+ let defaultProps = {}
115
+ let vxeProps = $vUtils.omit(props, (val, key) => {
116
+ return omitProps.includes(key) || $vUtils.isNone(val)
117
+ })
118
+ let shProps = {}
119
+ return Object.assign(defaultProps, vxeProps, shProps)
120
+ })
121
+ const pulldownConfig = computed(() => {
122
+ return Object.assign({ transfer: true }, props.pulldown)
123
+ })
124
+ const rangeInputConfig = computed(() => ({ type: 'text', readonly: true }))
125
+ const startInputConfig = computed(() => {
126
+ let startValue = rangeValue.value[0] || ''
127
+ let startLabel = $vUtils.toDateString(startValue, props.labelFormat)
128
+ return { ...rangeInputConfig.value, value: startLabel, placeholder: props.startPlaceholder }
129
+ })
130
+ const endInputConfig = computed(() => {
131
+ let endValue = rangeValue.value[1] || ''
132
+ let endLabel = $vUtils.toDateString(endValue, props.labelFormat)
133
+ return { ...rangeInputConfig.value, value: endLabel, placeholder: props.endPlaceholder }
134
+ })
135
+ const calendarConfig = computed(() => ({ pulldown: true, style: { height: '100%' }, align: 'center', valueFormat: props.valueFormat }))
136
+ const startCalendarConfig = computed(() => {
137
+ let startValue = rangeValue.value[0] || ''
138
+ return {
139
+ ...calendarConfig.value,
140
+ modelValue: startValue,
141
+ disabledMethod: ({ date, viewType }) => {
142
+ let endTime = rangeValue.value[1]
143
+ let { done, time } = $vUtils.getDateDiff(endTime, date)
144
+ return done
145
+ }
146
+ }
147
+ })
148
+ const endCalendarConfig = computed(() => {
149
+ let endValue = rangeValue.value[1] || ''
150
+ return {
151
+ ...calendarConfig.value,
152
+ modelValue: endValue,
153
+ disabledMethod: ({ date, viewType }) => {
154
+ let startTime = rangeValue.value[0]
155
+ let { done, time } = $vUtils.getDateDiff(startTime, date)
156
+ return startTime ? !done : false
157
+ }
158
+ }
159
+ })
160
+
161
+ const onRangeFocus = async e => {
162
+ pulldownValue.value = !pulldownValue.value
163
+ if (pulldownValue.value) {
164
+ dispatch('focus', e)
165
+ }
166
+ }
167
+ const onRangeClear = () => {
168
+ pulldownValue.value = false
169
+ rangeValue.value = []
170
+ onHidePanel()
171
+ }
172
+ const onHidePanel = () => {
173
+ dispatch('value')
174
+ dispatch('change')
175
+ dispatch('blur')
176
+ }
177
+
178
+ // 回调事件
179
+ const dispatch = (code, params) => {
180
+ if (code === 'value') {
181
+ emit('update:modelValue', rangeValue.value)
182
+ } else if (props.range) {
183
+ emit(code, { value: rangeValue.value, params })
184
+ } else {
185
+ if (code === 'change') {
186
+ emit('update:modelValue', params.value)
187
+ }
188
+ emit(code, params)
189
+ }
190
+ }
191
+
192
+ watch(
193
+ () => props.modelValue,
194
+ (value, oldValue) => {
195
+ if (props.range) {
196
+ rangeValue.value = value
197
+ } else {
198
+ inputValue.value = value
199
+ }
200
+ }
201
+ )
202
+
203
+ return {
204
+ pulldownValue,
205
+ inputValue,
206
+ rangeValue,
207
+ inputConfig,
208
+ pulldownConfig,
209
+ startInputConfig,
210
+ endInputConfig,
211
+ startCalendarConfig,
212
+ endCalendarConfig,
213
+ onRangeFocus,
214
+ onHidePanel,
215
+ onRangeClear,
216
+ dispatch
217
+ }
218
+ }
219
+ })
220
+ </script>
221
+
222
+ <style scoped lang="scss">
223
+ .sh-date {
224
+ display: inline-block;
225
+ position: relative;
226
+ }
227
+ .sh-date-range-input {
228
+ display: flex;
229
+ justify-content: space-between;
230
+ align-items: center;
231
+ border-radius: var(--vxe-border-radius);
232
+ color: var(--vxe-font-color);
233
+ border: 1px solid var(--vxe-input-border-color);
234
+ background-color: var(--vxe-input-background-color);
235
+ box-shadow: none;
236
+ &:hover {
237
+ .sh-date-clear {
238
+ display: flex;
239
+ }
240
+ }
241
+ input {
242
+ width: 100%;
243
+ border: none;
244
+ color: inherit;
245
+ text-align: center;
246
+ }
247
+ .sh-date-range-suffix {
248
+ color: var(--vxe-table-column-icon-border-color);
249
+ height: 100%;
250
+ display: inline-flex;
251
+ margin-right: 8px;
252
+ }
253
+ .sh-date-clear {
254
+ cursor: pointer;
255
+ display: none;
256
+ position: absolute;
257
+ right: 0;
258
+ height: 100%;
259
+ justify-content: center;
260
+ align-items: center;
261
+ &:hover {
262
+ color: inherit;
263
+ }
264
+ }
265
+ }
266
+ .sh-date-content {
267
+ display: flex;
268
+ justify-content: space-between;
269
+ padding: 12px;
270
+ width: 600px;
271
+ max-width: 100%;
272
+ }
273
+ </style>
@@ -86,8 +86,8 @@ export default function (props, context, proxy, isGrid) {
86
86
  const tablePrevColumns = computed(() => {
87
87
  let prevColumns = []
88
88
  const { seq, selectType } = tableGlobalConfig.value
89
- if (seq) prevColumns.push(columnsMapDefault.seq)
90
89
  if (selectType) prevColumns.push(columnsMapDefault[selectType])
90
+ if (seq) prevColumns.push(columnsMapDefault.seq)
91
91
  return prevColumns
92
92
  })
93
93
  const tableColumns = computed(() => {
@@ -162,7 +162,7 @@ export default defineComponent({
162
162
  const onDataCall = datas => {
163
163
  treeData.value = datas
164
164
  }
165
- // 回调fouces事件
165
+ // 回调focus事件
166
166
  const emitFocus = obj => {
167
167
  emit('focus', obj)
168
168
  }
@@ -171,7 +171,7 @@ export default defineComponent({
171
171
  emitValue()
172
172
  emit('change', selectedKeys.value, selectedData.value)
173
173
  }
174
- // 回调fouces事件
174
+ // 回调blur事件
175
175
  const emitBlur = () => {
176
176
  emit('blur', selectedKeys.value, selectedData.value)
177
177
  }
@@ -1,11 +1,13 @@
1
1
  // 全局公共封装组件
2
2
  import ShAlert from './global-components/sh-alert/index.vue'
3
3
  import ShBadge from './global-components/sh-badge/index.vue'
4
+ import ShCalendar from './global-components/sh-calendar/index.vue'
4
5
  import ShCard from './global-components/sh-card/index.vue'
5
6
  import ShCodeEditor from './global-components/sh-code-editor/index.vue'
6
7
  import ShCol from './global-components/sh-col/index.vue'
7
8
  import ShCorner from './global-components/sh-corner/index.vue'
8
9
  import ShCountTo from './global-components/sh-count-to/index.vue'
10
+ import ShDate from './global-components/sh-date/index.vue'
9
11
  import ShDrawer from './global-components/sh-drawer/index.vue'
10
12
  import ShEmpty from './global-components/sh-empty/index.vue'
11
13
  import ShForm from './global-components/sh-form/form.vue'
@@ -37,11 +39,13 @@ import { VxeButton, VxeInput, VxeTextarea, VxeSelect } from 'vxe-table'
37
39
  const components = {
38
40
  ShAlert,
39
41
  ShBadge,
42
+ ShCalendar,
40
43
  ShCard,
41
44
  ShCodeEditor,
42
45
  ShCol,
43
46
  ShCorner,
44
47
  ShCountTo,
48
+ ShDate,
45
49
  ShDrawer,
46
50
  ShEmpty,
47
51
  ShForm,
@@ -1,44 +1,44 @@
1
- <template>
2
- <span class="vxe-render--inner" :class="{ 'form-render': rform, 'td-render': !rform }">
3
- <template v-if="redit || isEditAll">
4
- <vxe-input v-model="renderValue" v-bind="rprops" :size="rsize" :disabled-method="vxeDisabledMethod" @change="vxeChangeCallBack"></vxe-input>
5
- </template>
6
- <template v-else>
7
- <span v-html="renderText"></span>
8
- </template>
9
- </span>
10
- </template>
11
-
12
- <script>
13
- import { defineComponent, getCurrentInstance } from 'vue'
14
- import cellProps from '../mixin/cell-props'
15
- import cellHooks from '../mixin/cell-hooks'
16
- export default defineComponent({
17
- name: 'VxeRenderTime',
18
- props: cellProps,
19
- setup(props, context) {
20
- const { proxy } = getCurrentInstance()
21
- const { $vUtils } = proxy
22
- const useCell = cellHooks(props, context, proxy)
23
-
24
- // 禁用事件
25
- const vxeDisabledMethod = ({ date, viewType }) => {
26
- let { startTime, endTime } = props.rprops
27
- if (startTime) {
28
- startTime = $vUtils.format(startTime, props.rdata)
29
- let { done, time } = $vUtils.getDateDiff(startTime, date)
30
- return startTime ? !done : false
31
- } else if (endTime) {
32
- endTime = $vUtils.format(endTime, props.rdata)
33
- let { done, time } = $vUtils.getDateDiff(endTime, date)
34
- return done
35
- }
36
- }
37
-
38
- return {
39
- ...useCell,
40
- vxeDisabledMethod
41
- }
42
- }
43
- })
44
- </script>
1
+ <template>
2
+ <span class="vxe-render--inner" :class="{ 'form-render': rform, 'td-render': !rform }">
3
+ <template v-if="redit || isEditAll">
4
+ <sh-date v-model="renderValue" v-bind="rprops" :size="rsize" :disabled-method="vxeDisabledMethod" @change="vxeChangeCallBack"></sh-date>
5
+ </template>
6
+ <template v-else>
7
+ <span v-html="renderText"></span>
8
+ </template>
9
+ </span>
10
+ </template>
11
+
12
+ <script>
13
+ import { defineComponent, getCurrentInstance } from 'vue'
14
+ import cellProps from '../mixin/cell-props'
15
+ import cellHooks from '../mixin/cell-hooks'
16
+ export default defineComponent({
17
+ name: 'VxeRenderTime',
18
+ props: cellProps,
19
+ setup(props, context) {
20
+ const { proxy } = getCurrentInstance()
21
+ const { $vUtils } = proxy
22
+ const useCell = cellHooks(props, context, proxy)
23
+
24
+ // 禁用事件
25
+ const vxeDisabledMethod = ({ date, viewType }) => {
26
+ let { startTime, endTime } = props.rprops
27
+ if (startTime) {
28
+ startTime = $vUtils.format(startTime, props.rdata)
29
+ let { done, time } = $vUtils.getDateDiff(startTime, date)
30
+ return startTime ? !done : false
31
+ } else if (endTime) {
32
+ endTime = $vUtils.format(endTime, props.rdata)
33
+ let { done, time } = $vUtils.getDateDiff(endTime, date)
34
+ return done
35
+ }
36
+ }
37
+
38
+ return {
39
+ ...useCell,
40
+ vxeDisabledMethod
41
+ }
42
+ }
43
+ })
44
+ </script>
@@ -35,7 +35,7 @@ export default function (props, context, proxy) {
35
35
  const rform = computed(() => !!props.rparams.$form)
36
36
  const reditmode = computed(() => props.rparams.$table?.props?.editConfig?.mode)
37
37
  const isEditAll = computed(() => {
38
- return props.rparams.$table?.props?.editConfig?.enabled && reditmode.value === 'all'
38
+ return props.rparams.$table?.props?.editConfig?.enabled && reditmode.value === 'all' && props.rparams.column.editRender
39
39
  })
40
40
  const moneyUnitText = computed(() => {
41
41
  let moneyConstant = moneyUnitConstants.find(item => item.value === props.rprops.moneyUnit)
package/README.en.md DELETED
@@ -1,36 +0,0 @@
1
- # sh-view
2
-
3
- #### Description
4
- {**When you're done, you can delete the content in this README and update the file with details for others getting started with your repository**}
5
-
6
- #### Software Architecture
7
- Software architecture description
8
-
9
- #### Installation
10
-
11
- 1. xxxx
12
- 2. xxxx
13
- 3. xxxx
14
-
15
- #### Instructions
16
-
17
- 1. xxxx
18
- 2. xxxx
19
- 3. xxxx
20
-
21
- #### Contribution
22
-
23
- 1. Fork the repository
24
- 2. Create Feat_xxx branch
25
- 3. Commit your code
26
- 4. Create Pull Request
27
-
28
-
29
- #### Gitee Feature
30
-
31
- 1. You can use Readme\_XXX.md to support different languages, such as Readme\_en.md, Readme\_zh.md
32
- 2. Gitee blog [blog.gitee.com](https://blog.gitee.com)
33
- 3. Explore open source project [https://gitee.com/explore](https://gitee.com/explore)
34
- 4. The most valuable open source project [GVP](https://gitee.com/gvp)
35
- 5. The manual of Gitee [https://gitee.com/help](https://gitee.com/help)
36
- 6. The most popular members [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/)