sh-view 2.6.4 → 2.6.6
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 +70 -24
- package/package.json +2 -1
- package/packages/components/global-components/sh-calendar/index.vue +502 -0
- package/packages/components/global-components/sh-table/components/sh-column.vue +68 -69
- package/packages/components/global-components/sh-table/js/useTable.js +1 -1
- package/packages/components/index.js +2 -0
- package/packages/vxeTable/render/cell/vxe-render-table.vue +51 -51
package/README.md
CHANGED
|
@@ -1,39 +1,85 @@
|
|
|
1
1
|
# sh-view
|
|
2
2
|
|
|
3
3
|
#### 介绍
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
无论是个人、团队、或是企业,都能够用 Gitee 实现代码托管、项目管理、协作开发。企业项目请看 [https://gitee.com/enterprises](https://gitee.com/enterprises)}
|
|
4
|
+
1. 基于vxe-table扩展,功能更强大,配置更便捷,内置18种渲染器,灵活配置,足以满足您的业务需求!
|
|
5
|
+
2. 完全兼容vxe-table原有组件及功能,完全可以自主扩展更多的自定义组件
|
|
7
6
|
|
|
8
|
-
####
|
|
9
|
-
|
|
7
|
+
#### 组件
|
|
8
|
+
自封装组件,不依赖其他ui框架
|
|
9
|
+
1. 默认全局安装:
|
|
10
|
+
ShAlert,
|
|
11
|
+
ShBadge,
|
|
12
|
+
ShCard,
|
|
13
|
+
ShCodeEditor,
|
|
14
|
+
ShCol,
|
|
15
|
+
ShCorner,
|
|
16
|
+
ShCountTo,
|
|
17
|
+
ShDrawer,
|
|
18
|
+
ShEmpty,
|
|
19
|
+
ShForm,
|
|
20
|
+
ShHeader,
|
|
21
|
+
ShIcon,
|
|
22
|
+
ShImage,
|
|
23
|
+
ShList,
|
|
24
|
+
ShLoading,
|
|
25
|
+
ShModal,
|
|
26
|
+
ShNoticebar,
|
|
27
|
+
ShPoptip,
|
|
28
|
+
ShProgress,
|
|
29
|
+
ShPullRefresh,
|
|
30
|
+
ShQuery,
|
|
31
|
+
ShResult,
|
|
32
|
+
ShRow,
|
|
33
|
+
ShSplit,
|
|
34
|
+
ShGrid,
|
|
35
|
+
ShTable,
|
|
36
|
+
ShTabs,
|
|
37
|
+
ShTag,
|
|
38
|
+
ShToolbar,
|
|
39
|
+
ShTree,
|
|
40
|
+
ShUpload,
|
|
41
|
+
ShWaterFall,
|
|
42
|
+
ShWaterMark
|
|
10
43
|
|
|
44
|
+
2. 手动安装(业务):
|
|
45
|
+
ShCronModal(cron表达式),
|
|
46
|
+
ShMarkdown(富文本编辑),
|
|
47
|
+
ShMenu(菜单、支持竖向、横向、收起)
|
|
11
48
|
|
|
12
49
|
#### 安装教程
|
|
50
|
+
版本:[vue](https://www.npmjs.com/package/vue) 3.x
|
|
51
|
+
```shell
|
|
52
|
+
npm install sh-tools sh-view@next
|
|
53
|
+
```
|
|
54
|
+
```javascript
|
|
55
|
+
import { createApp } from 'vue'
|
|
56
|
+
import ShView from 'sh-view'
|
|
13
57
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
3. xxxx
|
|
58
|
+
createApp(App).use(ShView).mount('#app')
|
|
59
|
+
```
|
|
17
60
|
|
|
18
61
|
#### 使用说明
|
|
19
62
|
|
|
20
|
-
1.
|
|
21
|
-
2.
|
|
22
|
-
3. xxxx
|
|
63
|
+
1. 暂无文档,请参考示例或者组件api
|
|
64
|
+
2. 作者QQ:577754811
|
|
23
65
|
|
|
24
|
-
#### 参与贡献
|
|
25
66
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
4. 新建 Pull Request
|
|
67
|
+
#### 功能计划
|
|
68
|
+
* [x] v2.6.4 基于 vxe4.+,包含vxe-table所有功能,扩展更强渲染器
|
|
69
|
+
* [ ] 下一阶段:独立vxe的日历组件,独立范围选择日期渲染器;低代码配置;基础sh-view的admin系统开源(包含低代码设计模板,及系统鉴权、路由守卫等)
|
|
30
70
|
|
|
31
71
|
|
|
32
|
-
####
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
72
|
+
#### 项目预览
|
|
73
|
+
<img alt="img.png" src="examples/assets/img/img.png" width="100%"/>
|
|
74
|
+
<img alt="img_1.png" src="examples/assets/img/img_1.png" width="49%"/>
|
|
75
|
+
<img alt="img_2.png" src="examples/assets/img/img_2.png" width="49%"/>
|
|
76
|
+
<img alt="img_3.png" src="examples/assets/img/img_3.png" width="49%"/>
|
|
77
|
+
<img alt="img_4.png" src="examples/assets/img/img_4.png" width="49%"/>
|
|
78
|
+
<img alt="img_5.png" src="examples/assets/img/img_5.png" width="49%"/>
|
|
79
|
+
<img alt="img_6.png" src="examples/assets/img/img_6.png" width="49%"/>
|
|
80
|
+
<img alt="img_7.png" src="examples/assets/img/img_7.png" width="49%"/>
|
|
81
|
+
<img alt="img_8.png" src="examples/assets/img/img_8.png" width="49%"/>
|
|
82
|
+
<img alt="img_9.png" src="examples/assets/img/img_9.png" width="49%"/>
|
|
83
|
+
<img alt="img_10.png" src="examples/assets/img/img_10.png" width="49%"/>
|
|
84
|
+
<img alt="img_11.png" src="examples/assets/img/img_11.png" width="49%"/>
|
|
85
|
+
<img alt="img_12.png" src="examples/assets/img/img_12.png" width="49%"/>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sh-view",
|
|
3
|
-
"version": "2.6.
|
|
3
|
+
"version": "2.6.6",
|
|
4
4
|
"description": "基于vxe-table二次封装",
|
|
5
5
|
"main": "packages/index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -27,6 +27,7 @@
|
|
|
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
32
|
"sh-tools": "^2.1.6",
|
|
32
33
|
"tinymce": "^5.10.5",
|
|
@@ -0,0 +1,502 @@
|
|
|
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" v-bind="tableConfig">
|
|
12
|
+
<thead>
|
|
13
|
+
<tr>
|
|
14
|
+
<template v-for="(head, headIndex) in headers" :key="headIndex">
|
|
15
|
+
<th>{{ 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
|
+
align: { type: String, default: 'center' },
|
|
79
|
+
header: { type: Boolean, default: true },
|
|
80
|
+
footer: { type: Boolean, default: false },
|
|
81
|
+
note: { type: Boolean, default: false }, // 是否备注
|
|
82
|
+
noteHeight: { type: String, default: '22px' }, // 备注高度
|
|
83
|
+
noteMethod: { type: Function, default() {} },
|
|
84
|
+
festival: { type: Boolean, default: false }, // 是否显示农历
|
|
85
|
+
valueFormat: { type: String, default: '' },
|
|
86
|
+
weeks: {
|
|
87
|
+
type: Array,
|
|
88
|
+
default() {
|
|
89
|
+
return ['周日', '周一', '周二', '周三', '周四', '周五', '周六']
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
},
|
|
93
|
+
emits: ['update:modelValue', 'change'],
|
|
94
|
+
setup(props, context) {
|
|
95
|
+
const { proxy } = getCurrentInstance()
|
|
96
|
+
const { $vUtils } = proxy
|
|
97
|
+
const { emit, slots } = context
|
|
98
|
+
|
|
99
|
+
const headerHandles = [
|
|
100
|
+
{ code: 'prev', icon: 'vxe-icon-caret-left' },
|
|
101
|
+
{ code: 'current', icon: 'vxe-icon-dot' },
|
|
102
|
+
{ code: 'next', icon: 'vxe-icon-caret-right' }
|
|
103
|
+
]
|
|
104
|
+
const reactData = reactive({
|
|
105
|
+
inputValue: props.modelValue,
|
|
106
|
+
panelValue: null,
|
|
107
|
+
panelLabel: '',
|
|
108
|
+
selectMonth: null,
|
|
109
|
+
currentDate: null
|
|
110
|
+
})
|
|
111
|
+
const computeFirstDayOfWeek = computed(() => {
|
|
112
|
+
const { startDay, startWeek } = props
|
|
113
|
+
return $vUtils.toNumber($vUtils.isNumber(startDay) || $vUtils.isString(startDay) ? startDay : startWeek)
|
|
114
|
+
})
|
|
115
|
+
const computeWeekDatas = computed(() => {
|
|
116
|
+
const weeks = []
|
|
117
|
+
let sWeek = computeFirstDayOfWeek.value
|
|
118
|
+
weeks.push(sWeek)
|
|
119
|
+
for (let index = 0; index < 6; index++) {
|
|
120
|
+
if (sWeek >= 6) {
|
|
121
|
+
sWeek = 0
|
|
122
|
+
} else {
|
|
123
|
+
sWeek++
|
|
124
|
+
}
|
|
125
|
+
weeks.push(sWeek)
|
|
126
|
+
}
|
|
127
|
+
return weeks
|
|
128
|
+
})
|
|
129
|
+
const computeDateHMSTime = computed(() => {
|
|
130
|
+
const dateValue = computeDateValue.value
|
|
131
|
+
return dateValue ? (dateValue.getHours() * 3600 + dateValue.getMinutes() * 60 + dateValue.getSeconds()) * 1000 : 0
|
|
132
|
+
})
|
|
133
|
+
const computeDayList = computed(() => {
|
|
134
|
+
const { selectMonth, currentDate } = reactData
|
|
135
|
+
const days = []
|
|
136
|
+
if (selectMonth && currentDate) {
|
|
137
|
+
const dateHMSTime = computeDateHMSTime.value
|
|
138
|
+
const weekDatas = computeWeekDatas.value
|
|
139
|
+
const currFullYear = currentDate.getFullYear()
|
|
140
|
+
const currMonth = currentDate.getMonth()
|
|
141
|
+
const currDate = currentDate.getDate()
|
|
142
|
+
const selFullYear = selectMonth.getFullYear()
|
|
143
|
+
const selMonth = selectMonth.getMonth()
|
|
144
|
+
const selDay = selectMonth.getDay()
|
|
145
|
+
const prevOffsetDate = -weekDatas.indexOf(selDay)
|
|
146
|
+
const startDayDate = new Date($vUtils.getWhatDay(selectMonth, prevOffsetDate).getTime() + dateHMSTime)
|
|
147
|
+
for (let index = 0; index < 42; index++) {
|
|
148
|
+
const date = $vUtils.getWhatDay(startDayDate, index)
|
|
149
|
+
const itemFullYear = date.getFullYear()
|
|
150
|
+
const itemMonth = date.getMonth()
|
|
151
|
+
const itemDate = date.getDate()
|
|
152
|
+
const isPrev = date < selectMonth
|
|
153
|
+
days.push({
|
|
154
|
+
date,
|
|
155
|
+
isPrev,
|
|
156
|
+
isCurrent: itemFullYear === selFullYear && itemMonth === selMonth,
|
|
157
|
+
isNow: itemFullYear === currFullYear && itemMonth === currMonth && itemDate === currDate,
|
|
158
|
+
isNext: !isPrev && selMonth !== itemMonth,
|
|
159
|
+
label: itemDate
|
|
160
|
+
})
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
return days
|
|
164
|
+
})
|
|
165
|
+
|
|
166
|
+
// 以下为日历需要
|
|
167
|
+
const tableConfig = computed(() => ({ cellspacing: 0, cellpadding: 0, border: 0 }))
|
|
168
|
+
const headers = computed(() => {
|
|
169
|
+
const weekDatas = computeWeekDatas.value
|
|
170
|
+
return weekDatas.map(day => {
|
|
171
|
+
return { value: day, label: props.weeks[day] }
|
|
172
|
+
})
|
|
173
|
+
})
|
|
174
|
+
const dayDatas = computed(() => {
|
|
175
|
+
const dayList = computeDayList.value
|
|
176
|
+
return $vUtils.chunk(dayList, 7)
|
|
177
|
+
})
|
|
178
|
+
const computeDateValue = computed(() => {
|
|
179
|
+
const { inputValue } = reactData
|
|
180
|
+
let val = null
|
|
181
|
+
if (inputValue) {
|
|
182
|
+
const date = $vUtils.toStringDate(inputValue, props.valueFormat)
|
|
183
|
+
if ($vUtils.isValidDate(date)) {
|
|
184
|
+
val = date
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
return val
|
|
188
|
+
})
|
|
189
|
+
const monthInfo = computed(() => $vUtils.toDateString(reactData.selectMonth, 'yyyy 年 MM 月'))
|
|
190
|
+
const dayInfo = computed(() => $vUtils.toDateString(reactData.currentDate, 'yyyyMMdd'))
|
|
191
|
+
const lunarInfo = computed(() => {
|
|
192
|
+
let dayDate = reactData.inputValue || reactData.currentDate
|
|
193
|
+
let lunarDate = Lunar.fromDate(dayDate)
|
|
194
|
+
return {
|
|
195
|
+
day: $vUtils.toDateString(dayDate, 'yyyy 年 MM 月 dd 日'),
|
|
196
|
+
lunarMonth: lunarDate.getMonthInChinese(),
|
|
197
|
+
lunarDay: lunarDate.getDayInChinese(),
|
|
198
|
+
yearGanZhi: lunarDate.getYearInGanZhi(),
|
|
199
|
+
yearShengXiao: lunarDate.getYearShengXiao(),
|
|
200
|
+
monthGanZhi: lunarDate.getMonthInGanZhi(),
|
|
201
|
+
dayGanZhi: lunarDate.getDayInGanZhi(),
|
|
202
|
+
yi: lunarDate.getDayYi(),
|
|
203
|
+
ji: lunarDate.getDayJi(),
|
|
204
|
+
jq: lunarDate.getJieQi()
|
|
205
|
+
}
|
|
206
|
+
})
|
|
207
|
+
const isDateDisabled = item => {
|
|
208
|
+
const { disabledMethod } = props
|
|
209
|
+
return disabledMethod && disabledMethod({ type: props.type, date: item.date })
|
|
210
|
+
}
|
|
211
|
+
const dateChange = date => {
|
|
212
|
+
emitValue(date)
|
|
213
|
+
emit('change', date)
|
|
214
|
+
}
|
|
215
|
+
const dateSelectItem = date => {
|
|
216
|
+
const { type } = props
|
|
217
|
+
if (type === 'month') {
|
|
218
|
+
} else if (type === 'year') {
|
|
219
|
+
} else {
|
|
220
|
+
dateChange(date)
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
const dateCheckMonth = date => {
|
|
224
|
+
const month = $vUtils.getWhatMonth(date, 0, 'first')
|
|
225
|
+
if (!$vUtils.isEqual(month, reactData.selectMonth)) {
|
|
226
|
+
reactData.selectMonth = month
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
const dateMoveDay = date => {
|
|
230
|
+
if (isDateDisabled(date)) return
|
|
231
|
+
const dayList = computeDayList.value
|
|
232
|
+
if (!dayList.some(item => $vUtils.isDateSame(item.date, date.date, 'yyyyMMdd'))) {
|
|
233
|
+
dateCheckMonth(date.date)
|
|
234
|
+
}
|
|
235
|
+
dateParseValue(date.date)
|
|
236
|
+
}
|
|
237
|
+
const dateSelectEvent = item => {
|
|
238
|
+
if (isDateDisabled(item)) return
|
|
239
|
+
dateSelectItem(item.date)
|
|
240
|
+
}
|
|
241
|
+
const dateMouseenterEvent = item => {
|
|
242
|
+
if (isDateDisabled(item)) return
|
|
243
|
+
const { datePanelType } = reactData
|
|
244
|
+
if (datePanelType === 'month') {
|
|
245
|
+
// dateMoveMonth(item.date)
|
|
246
|
+
} else if (datePanelType === 'year') {
|
|
247
|
+
// dateMoveYear(item.date)
|
|
248
|
+
} else {
|
|
249
|
+
dateMoveDay(item)
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
const dateMouseleaveEvent = () => {
|
|
253
|
+
dateParseValue()
|
|
254
|
+
}
|
|
255
|
+
const dateParseValue = value => {
|
|
256
|
+
let dValue = null
|
|
257
|
+
if (value) {
|
|
258
|
+
dValue = $vUtils.toStringDate(value, props.valueFormat)
|
|
259
|
+
}
|
|
260
|
+
if (dValue && !$vUtils.isValidDate(dValue)) {
|
|
261
|
+
dValue = null
|
|
262
|
+
}
|
|
263
|
+
reactData.panelValue = dValue
|
|
264
|
+
}
|
|
265
|
+
const getLunarDate = day => {
|
|
266
|
+
let lunarDate = Lunar.fromDate(day)
|
|
267
|
+
let lunarText = lunarDate.getDayInChinese()
|
|
268
|
+
const jq = lunarDate.getJieQi()
|
|
269
|
+
const solarFestivals = lunarDate.getFestivals()
|
|
270
|
+
if (jq) {
|
|
271
|
+
lunarText = jq
|
|
272
|
+
} else if (lunarDate.getDay() === 1) {
|
|
273
|
+
lunarText = lunarDate.getMonthInChinese() + '月'
|
|
274
|
+
} else if (solarFestivals.length > 0) {
|
|
275
|
+
const f = solarFestivals[0]
|
|
276
|
+
if (f.length < 4) {
|
|
277
|
+
lunarText = f
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
return lunarText
|
|
281
|
+
}
|
|
282
|
+
const getCellClass = item => {
|
|
283
|
+
const { panelValue } = reactData
|
|
284
|
+
const dateValue = computeDateValue.value
|
|
285
|
+
const matchFormat = 'yyyyMMdd'
|
|
286
|
+
const ymd = $vUtils.toDateString(item.date, matchFormat)
|
|
287
|
+
const lunarDate = Lunar.fromDate(item.date)
|
|
288
|
+
const holiday = HolidayUtil.getHoliday(ymd)
|
|
289
|
+
let rest = false
|
|
290
|
+
if ([0, 6].includes(lunarDate.getWeek())) {
|
|
291
|
+
rest = true
|
|
292
|
+
}
|
|
293
|
+
if (holiday) rest = !holiday.isWork()
|
|
294
|
+
return {
|
|
295
|
+
'is--prev': item.isPrev,
|
|
296
|
+
'is--current': item.isCurrent,
|
|
297
|
+
'is--now': item.isNow,
|
|
298
|
+
'is--next': item.isNext,
|
|
299
|
+
'is--holiday': holiday,
|
|
300
|
+
'is--rest': rest,
|
|
301
|
+
'is--disabled': isDateDisabled(item),
|
|
302
|
+
'is--selected': $vUtils.isDateSame(dateValue, item.date, matchFormat),
|
|
303
|
+
'is--hover': $vUtils.isDateSame(panelValue, item.date, matchFormat)
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
const handleBtn = ({ code }) => {
|
|
307
|
+
try {
|
|
308
|
+
const { currentDate, selectMonth } = reactData
|
|
309
|
+
switch (code) {
|
|
310
|
+
case 'prev':
|
|
311
|
+
reactData.selectMonth = $vUtils.getWhatMonth(selectMonth, -1, 'first')
|
|
312
|
+
break
|
|
313
|
+
case 'next':
|
|
314
|
+
reactData.selectMonth = $vUtils.getWhatMonth(selectMonth, 1, 'first')
|
|
315
|
+
break
|
|
316
|
+
case 'current':
|
|
317
|
+
reactData.selectMonth = $vUtils.getWhatMonth(currentDate, 0, 'first')
|
|
318
|
+
break
|
|
319
|
+
default:
|
|
320
|
+
break
|
|
321
|
+
}
|
|
322
|
+
} catch (e) {
|
|
323
|
+
proxy.msgwarning(e.message)
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
const emitValue = (value, evnt) => {
|
|
327
|
+
reactData.inputValue = value
|
|
328
|
+
emit('update:modelValue', value)
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
// 初始化
|
|
332
|
+
const initValue = () => {
|
|
333
|
+
reactData.currentDate = $vUtils.getWhatDay(Date.now(), 0, 'first')
|
|
334
|
+
reactData.selectMonth = $vUtils.getWhatMonth(reactData.currentDate, 0, 'first')
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
onBeforeMount(() => {
|
|
338
|
+
initValue()
|
|
339
|
+
})
|
|
340
|
+
|
|
341
|
+
watch(
|
|
342
|
+
() => props.modelValue,
|
|
343
|
+
val => {
|
|
344
|
+
reactData.inputValue = val
|
|
345
|
+
}
|
|
346
|
+
)
|
|
347
|
+
|
|
348
|
+
return {
|
|
349
|
+
tableConfig,
|
|
350
|
+
headers,
|
|
351
|
+
dayDatas,
|
|
352
|
+
monthInfo,
|
|
353
|
+
dayInfo,
|
|
354
|
+
lunarInfo,
|
|
355
|
+
headerHandles,
|
|
356
|
+
getLunarDate,
|
|
357
|
+
getCellClass,
|
|
358
|
+
handleBtn,
|
|
359
|
+
dateSelectEvent,
|
|
360
|
+
dateMouseenterEvent,
|
|
361
|
+
dateMouseleaveEvent
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
})
|
|
365
|
+
</script>
|
|
366
|
+
|
|
367
|
+
<style scoped lang="scss">
|
|
368
|
+
.sh-calendar {
|
|
369
|
+
overflow: auto;
|
|
370
|
+
.sh-calendar-title {
|
|
371
|
+
font-size: 18px;
|
|
372
|
+
font-weight: bold;
|
|
373
|
+
}
|
|
374
|
+
.sh-calendar-span {
|
|
375
|
+
margin-right: 5px;
|
|
376
|
+
}
|
|
377
|
+
.sh-calendar-tag {
|
|
378
|
+
border-radius: 30px;
|
|
379
|
+
padding: 5px;
|
|
380
|
+
display: inline-flex;
|
|
381
|
+
vertical-align: top;
|
|
382
|
+
line-height: 1;
|
|
383
|
+
margin-right: 10px;
|
|
384
|
+
&.yi {
|
|
385
|
+
background-color: var(--vxe-success-color);
|
|
386
|
+
color: #fff;
|
|
387
|
+
}
|
|
388
|
+
&.ji {
|
|
389
|
+
background-color: var(--vxe-danger-color);
|
|
390
|
+
color: #fff;
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
.sh-calendar-row {
|
|
394
|
+
display: flex;
|
|
395
|
+
justify-content: space-between;
|
|
396
|
+
align-items: center;
|
|
397
|
+
.info {
|
|
398
|
+
flex: 1;
|
|
399
|
+
&.right {
|
|
400
|
+
text-align: right;
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
.extra {
|
|
404
|
+
display: inline-flex;
|
|
405
|
+
flex-wrap: nowrap;
|
|
406
|
+
}
|
|
407
|
+
& + .sh-calendar-row {
|
|
408
|
+
margin-top: 5px;
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
.sh-calendar-head,
|
|
412
|
+
.sh-calendar-foot {
|
|
413
|
+
padding: 8px;
|
|
414
|
+
border: 1px solid var(--vxe-table-border-color);
|
|
415
|
+
}
|
|
416
|
+
.sh-calendar-head {
|
|
417
|
+
border-bottom: none;
|
|
418
|
+
line-height: 1;
|
|
419
|
+
}
|
|
420
|
+
.sh-calendar-foot {
|
|
421
|
+
border-top: none;
|
|
422
|
+
}
|
|
423
|
+
.sh-calendar-btn {
|
|
424
|
+
padding: 5px;
|
|
425
|
+
border-radius: var(--vxe-border-radius);
|
|
426
|
+
border: 1px solid var(--vxe-table-border-color);
|
|
427
|
+
margin-left: 5px;
|
|
428
|
+
&:hover {
|
|
429
|
+
color: var(--vxe-primary-color);
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
.sh-calendar-cell {
|
|
433
|
+
display: block;
|
|
434
|
+
&-head {
|
|
435
|
+
padding: 3px 5px;
|
|
436
|
+
& + .sh-calendar-cell-foot {
|
|
437
|
+
padding-top: 0;
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
&-body {
|
|
441
|
+
overflow: auto;
|
|
442
|
+
}
|
|
443
|
+
&-foot {
|
|
444
|
+
padding: 3px 5px;
|
|
445
|
+
font-size: 0.8em;
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
table {
|
|
449
|
+
border: 0;
|
|
450
|
+
width: 100%;
|
|
451
|
+
border-spacing: 0;
|
|
452
|
+
border-collapse: collapse;
|
|
453
|
+
table-layout: fixed;
|
|
454
|
+
height: 100%;
|
|
455
|
+
}
|
|
456
|
+
th,
|
|
457
|
+
td {
|
|
458
|
+
font-weight: normal;
|
|
459
|
+
position: relative;
|
|
460
|
+
border: 1px solid var(--vxe-table-border-color);
|
|
461
|
+
height: 36px;
|
|
462
|
+
}
|
|
463
|
+
td {
|
|
464
|
+
&.is--prev,
|
|
465
|
+
&.is--next {
|
|
466
|
+
color: var(--vxe-font-disabled-color);
|
|
467
|
+
}
|
|
468
|
+
//&.is--rest {
|
|
469
|
+
// .sh-calendar-cell-head {
|
|
470
|
+
// color: var(--vxe-danger-color);
|
|
471
|
+
// }
|
|
472
|
+
//}
|
|
473
|
+
&.is--now {
|
|
474
|
+
&:not(.is--selected) {
|
|
475
|
+
color: var(--vxe-primary-color);
|
|
476
|
+
&.is--current {
|
|
477
|
+
background-color: var(--primary-weak-color);
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
&.is--hover {
|
|
482
|
+
background-color: var(--vxe-input-date-picker-hover-background-color);
|
|
483
|
+
}
|
|
484
|
+
&.is--selected {
|
|
485
|
+
color: var(--vxe-input-date-picker-selected-color);
|
|
486
|
+
background-color: var(--vxe-primary-color);
|
|
487
|
+
&.is--prev,
|
|
488
|
+
&.is--next {
|
|
489
|
+
background-color: var(--vxe-primary-lighten-color);
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
&:not(.is--disabled) {
|
|
493
|
+
cursor: pointer;
|
|
494
|
+
}
|
|
495
|
+
&.is--disabled {
|
|
496
|
+
cursor: no-drop;
|
|
497
|
+
color: var(--vxe-input-disabled-color);
|
|
498
|
+
background-color: var(--vxe-input-disabled-background-color);
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
</style>
|
|
@@ -1,69 +1,68 @@
|
|
|
1
|
-
<script>
|
|
2
|
-
import { computed, defineComponent, getCurrentInstance, h, inject, ref, resolveComponent, renderSlot } from 'vue'
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
const {
|
|
13
|
-
const
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
let
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
config.
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
<style scoped lang="scss"></style>
|
|
1
|
+
<script>
|
|
2
|
+
import { computed, defineComponent, getCurrentInstance, h, inject, ref, resolveComponent, renderSlot } from 'vue'
|
|
3
|
+
export default defineComponent({
|
|
4
|
+
name: 'ShColumn',
|
|
5
|
+
props: {
|
|
6
|
+
column: {
|
|
7
|
+
type: Object
|
|
8
|
+
}
|
|
9
|
+
},
|
|
10
|
+
setup(props, context) {
|
|
11
|
+
const { proxy } = getCurrentInstance()
|
|
12
|
+
const { $vUtils } = proxy
|
|
13
|
+
const shTable = inject('ShTableInstance')
|
|
14
|
+
|
|
15
|
+
const isGroup = computed(() => {
|
|
16
|
+
return proxy.hasChildren(props.column)
|
|
17
|
+
})
|
|
18
|
+
const columnConfig = computed(() => {
|
|
19
|
+
let renderObj = { name: props.column.renderName, props: props.column.renderProps }
|
|
20
|
+
let config = Object.assign({}, shTable.columnObjConfig, props.column)
|
|
21
|
+
if (props.column.readonly) {
|
|
22
|
+
config.cellRender = config.cellRender || renderObj
|
|
23
|
+
} else {
|
|
24
|
+
config.editRender = config.editRender || renderObj
|
|
25
|
+
}
|
|
26
|
+
if (config.renderName === '$vMoney' && props.column.renderProps.bill) {
|
|
27
|
+
config.filter = false
|
|
28
|
+
config.headerClassName += ' header-bill-cell'
|
|
29
|
+
}
|
|
30
|
+
if (config.filter === true || Number(config.filter) === 1) {
|
|
31
|
+
shTable.turnColumnItemFilters(config, renderObj.props)
|
|
32
|
+
}
|
|
33
|
+
return $vUtils.omit(config, ['children', 'renderName', 'renderProps', 'renderRequire', 'requireProps'])
|
|
34
|
+
})
|
|
35
|
+
const groupConfig = computed(() => {
|
|
36
|
+
return $vUtils.omit(columnConfig.value, ['cellRender', 'editRender'])
|
|
37
|
+
})
|
|
38
|
+
const renderVN = () => {
|
|
39
|
+
let columnSlots = {}
|
|
40
|
+
if (props.column.slots) {
|
|
41
|
+
Object.keys(props.column.slots).map(key => {
|
|
42
|
+
columnSlots[key] = shTable.slots[props.column.slots[key]]
|
|
43
|
+
})
|
|
44
|
+
}
|
|
45
|
+
if (isGroup.value) {
|
|
46
|
+
let childrenList = props.column.children.map(child => {
|
|
47
|
+
return h(resolveComponent('sh-column'), { column: child })
|
|
48
|
+
})
|
|
49
|
+
columnSlots.default = () => childrenList
|
|
50
|
+
return h(resolveComponent('vxe-colgroup'), { ...groupConfig.value }, columnSlots)
|
|
51
|
+
}
|
|
52
|
+
return h(resolveComponent('vxe-column'), { ...columnConfig.value }, columnSlots)
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
return {
|
|
56
|
+
isGroup,
|
|
57
|
+
columnConfig,
|
|
58
|
+
groupConfig,
|
|
59
|
+
renderVN
|
|
60
|
+
}
|
|
61
|
+
},
|
|
62
|
+
render() {
|
|
63
|
+
return this.renderVN()
|
|
64
|
+
}
|
|
65
|
+
})
|
|
66
|
+
</script>
|
|
67
|
+
|
|
68
|
+
<style scoped lang="scss"></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(() => {
|
|
@@ -1,6 +1,7 @@
|
|
|
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'
|
|
@@ -37,6 +38,7 @@ import { VxeButton, VxeInput, VxeTextarea, VxeSelect } from 'vxe-table'
|
|
|
37
38
|
const components = {
|
|
38
39
|
ShAlert,
|
|
39
40
|
ShBadge,
|
|
41
|
+
ShCalendar,
|
|
40
42
|
ShCard,
|
|
41
43
|
ShCodeEditor,
|
|
42
44
|
ShCol,
|
|
@@ -1,51 +1,51 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<span class="vxe-render--inner" style="display: inline-grid; width: 100%">
|
|
3
|
-
<sh-table
|
|
4
|
-
ref="shTableRef"
|
|
5
|
-
:disabled="!redit && !isEditAll"
|
|
6
|
-
v-bind="rprops"
|
|
7
|
-
:size="rsize"
|
|
8
|
-
:data-sourse="renderValue"
|
|
9
|
-
@edit-closed="vxeInputCallback"
|
|
10
|
-
@toolbaroption="onToolbaroption"></sh-table>
|
|
11
|
-
</span>
|
|
12
|
-
</template>
|
|
13
|
-
|
|
14
|
-
<script>
|
|
15
|
-
import { defineComponent, getCurrentInstance, ref } from 'vue'
|
|
16
|
-
import cellProps from '../mixin/cell-props'
|
|
17
|
-
import cellHooks from '../mixin/cell-hooks'
|
|
18
|
-
export default defineComponent({
|
|
19
|
-
name: 'VxeRenderTable',
|
|
20
|
-
props: cellProps,
|
|
21
|
-
setup(props, context) {
|
|
22
|
-
const { proxy } = getCurrentInstance()
|
|
23
|
-
const useCell = cellHooks(props, context, proxy)
|
|
24
|
-
const shTableRef = ref()
|
|
25
|
-
|
|
26
|
-
const fullData = () => {
|
|
27
|
-
return shTableRef.value.getFullData()
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
// 输入框回调
|
|
31
|
-
const vxeInputCallback = ({ $table, row }) => {
|
|
32
|
-
driveBackData()
|
|
33
|
-
}
|
|
34
|
-
// 新增、删除行回调
|
|
35
|
-
const onToolbaroption = (code, data, $table) => {
|
|
36
|
-
driveBackData()
|
|
37
|
-
}
|
|
38
|
-
// 回填数据
|
|
39
|
-
const driveBackData = value => {
|
|
40
|
-
useCell.setRenderValue(fullData(), true)
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
return {
|
|
44
|
-
...useCell,
|
|
45
|
-
shTableRef,
|
|
46
|
-
vxeInputCallback,
|
|
47
|
-
onToolbaroption
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
})
|
|
51
|
-
</script>
|
|
1
|
+
<template>
|
|
2
|
+
<span class="vxe-render--inner" style="display: inline-grid; width: 100%">
|
|
3
|
+
<sh-table
|
|
4
|
+
ref="shTableRef"
|
|
5
|
+
:disabled="!redit && !isEditAll"
|
|
6
|
+
v-bind="rprops"
|
|
7
|
+
:size="rsize"
|
|
8
|
+
:data-sourse="renderValue"
|
|
9
|
+
@edit-closed="vxeInputCallback"
|
|
10
|
+
@toolbaroption="onToolbaroption"></sh-table>
|
|
11
|
+
</span>
|
|
12
|
+
</template>
|
|
13
|
+
|
|
14
|
+
<script>
|
|
15
|
+
import { defineComponent, getCurrentInstance, ref } from 'vue'
|
|
16
|
+
import cellProps from '../mixin/cell-props'
|
|
17
|
+
import cellHooks from '../mixin/cell-hooks'
|
|
18
|
+
export default defineComponent({
|
|
19
|
+
name: 'VxeRenderTable',
|
|
20
|
+
props: cellProps,
|
|
21
|
+
setup(props, context) {
|
|
22
|
+
const { proxy } = getCurrentInstance()
|
|
23
|
+
const useCell = cellHooks(props, context, proxy)
|
|
24
|
+
const shTableRef = ref()
|
|
25
|
+
|
|
26
|
+
const fullData = () => {
|
|
27
|
+
return shTableRef.value.getFullData({ deleteXid: true })
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// 输入框回调
|
|
31
|
+
const vxeInputCallback = ({ $table, row }) => {
|
|
32
|
+
driveBackData()
|
|
33
|
+
}
|
|
34
|
+
// 新增、删除行回调
|
|
35
|
+
const onToolbaroption = (code, data, $table) => {
|
|
36
|
+
driveBackData()
|
|
37
|
+
}
|
|
38
|
+
// 回填数据
|
|
39
|
+
const driveBackData = value => {
|
|
40
|
+
useCell.setRenderValue(fullData(), true)
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return {
|
|
44
|
+
...useCell,
|
|
45
|
+
shTableRef,
|
|
46
|
+
vxeInputCallback,
|
|
47
|
+
onToolbaroption
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
})
|
|
51
|
+
</script>
|