@weitutech/by-components 1.1.1 → 1.1.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.
package/package.json CHANGED
@@ -1,13 +1,8 @@
1
1
  {
2
2
  "name": "@weitutech/by-components",
3
- "version": "1.1.1",
3
+ "version": "1.1.2",
4
4
  "private": false,
5
- "main": "lib/by-components.umd.js",
6
- "module": "lib/by-components.esm.js",
7
- "files": [
8
- "lib",
9
- "dist"
10
- ],
5
+ "main": "src/index",
11
6
  "sideEffects": [
12
7
  "*.vue",
13
8
  "*.scss"
@@ -0,0 +1,394 @@
1
+ <!-- 自定义表头 -->
2
+ <template>
3
+ <div id="custom_column">
4
+ <el-dialog
5
+ :close-on-click-modal="false"
6
+ :visible="dialogVisible"
7
+ width="920px"
8
+ :append-to-body="true"
9
+ :show-close="false"
10
+ custom-class="custom_dialog_class"
11
+ @close="closeDialog"
12
+ >
13
+ <div class="el-dialog-box">
14
+ <!-- 数据指标 -->
15
+ <div class="left_box">
16
+ <div class="box_title">数据指标</div>
17
+ <div class="row" style="padding-right: 20px">
18
+ <div class="cell">
19
+ <el-input
20
+ v-model="search"
21
+ style="width: 228px; margin-bottom: 10px"
22
+ placeholder="搜索指标"
23
+ size="medium"
24
+ prefix-icon="el-icon-search"
25
+ />
26
+ </div>
27
+ <el-button type="text" @click="selectNone">全不选</el-button>
28
+ </div>
29
+ <div class="left_box_body">
30
+ <div class="left_nav">
31
+ <ul>
32
+ <li
33
+ v-for="(item, index) in checkBoxMenuBySearch"
34
+ :key="index"
35
+ :class="{ active: activeId === index }"
36
+ @click="setHighlight(index)"
37
+ >
38
+ {{ item.label }}
39
+ </li>
40
+ </ul>
41
+ </div>
42
+ <div class="left_menu">
43
+ <div
44
+ v-for="(item, index) in checkBoxMenuBySearch"
45
+ :key="index"
46
+ ref="tagItem"
47
+ >
48
+ <div class="checkbox_title">
49
+ {{ item.label }}
50
+ </div>
51
+ <el-row>
52
+ <el-col
53
+ v-for="(each, idx) in item.data"
54
+ :key="idx"
55
+ :span="12"
56
+ style="margin-bottom: 3px"
57
+ >
58
+ <el-checkbox
59
+ v-model="each.type"
60
+ @change="changeCheckbox(each.key, each.type)"
61
+ >
62
+ {{ each.label }}
63
+ </el-checkbox>
64
+ </el-col>
65
+ </el-row>
66
+ </div>
67
+ </div>
68
+ </div>
69
+ </div>
70
+ <!-- 已选指标 -->
71
+ <div class="right_box">
72
+ <div class="drag_box">
73
+ <el-row>
74
+ <div class="drag_text_box">
75
+ <span class="drag_title">{{ `已选指标(${number})` }}</span>
76
+ <span class="recover" @click="recoverDefault">恢复默认</span>
77
+ </div>
78
+ </el-row>
79
+ <div class="drag_ul">
80
+ <draggable
81
+ v-model="draggableMenu"
82
+ chosen-class="chosen"
83
+ force-fallback="true"
84
+ animation="500"
85
+ @end="onEnd"
86
+ >
87
+ <transition-group>
88
+ <div
89
+ v-for="col in draggableMenu"
90
+ v-show="col.type"
91
+ :class="
92
+ col.key === 'sort-cut-off' ? 'fixedClass' : 'drag_li_box'
93
+ "
94
+ :key="col.key"
95
+ >
96
+ <div v-if="col.key !== 'sort-cut-off'">
97
+ <i class="el-icon-rank icon-box" />
98
+ <span class="drag_li_text">{{ col.label }}</span>
99
+ </div>
100
+ <i
101
+ v-if="col.key !== 'sort-cut-off'"
102
+ class="el-icon-close remove"
103
+ @click="changeCheckbox(col.key, false)"
104
+ />
105
+ </div>
106
+ </transition-group>
107
+ </draggable>
108
+ </div>
109
+ </div>
110
+ </div>
111
+ </div>
112
+ <template #footer>
113
+ <el-row style="margin-top: 7px">
114
+ <el-button size="small" style="width: 96px" @click="closeDialog"
115
+ >取消</el-button
116
+ >
117
+ <el-button
118
+ size="small"
119
+ style="width: 96px"
120
+ type="primary"
121
+ @click="submit"
122
+ >确定</el-button
123
+ >
124
+ </el-row>
125
+ </template>
126
+ </el-dialog>
127
+ </div>
128
+ </template>
129
+
130
+ <script>
131
+ import draggable from 'vuedraggable'
132
+ import { deepClone } from '../../utils/index'
133
+ export default {
134
+ name: 'CustomColumn',
135
+ components: {
136
+ draggable
137
+ },
138
+ props: {
139
+ dialogVisible: {
140
+ type: Boolean,
141
+ default: false
142
+ },
143
+ infoMethod: {
144
+ type: Function,
145
+ required: true,
146
+ default: () => {}
147
+ },
148
+ submitMethod: {
149
+ type: Function,
150
+ required: true,
151
+ default: () => {}
152
+ }
153
+ },
154
+ data() {
155
+ return {
156
+ draggableMenu: [],
157
+ /** 勾选的主标题菜单 */
158
+ checkBoxMenu: [],
159
+ /** 选中高亮的菜单ID */
160
+ activeId: 0,
161
+ /** 表头id */
162
+ id: undefined,
163
+ /** 表格列接口路径 */
164
+ page: '',
165
+ /** 搜索字段 */
166
+ search: ''
167
+ }
168
+ },
169
+ computed: {
170
+ number() {
171
+ return this.draggableMenu.filter(
172
+ item => item.type && item.key !== 'sort-cut-off'
173
+ ).length
174
+ },
175
+ checkBoxMenuBySearch() {
176
+ if (this.search) {
177
+ return this.checkBoxMenu
178
+ .map(group => {
179
+ const filteredItems = group.data.filter(item =>
180
+ item.label.includes(this.search)
181
+ )
182
+ return {
183
+ label: group.label,
184
+ data: filteredItems
185
+ }
186
+ })
187
+ .filter(group => group.data.length > 0)
188
+ } else {
189
+ return this.checkBoxMenu
190
+ }
191
+ }
192
+ },
193
+ methods: {
194
+ deepClone,
195
+ /**
196
+ * @describe 获取自定义表头数据
197
+ * @param { string } page 表格列接口路径
198
+ * @param { object[] } column 列数据
199
+ */
200
+ async getCustomTableList(page, column) {
201
+ if (!page) {
202
+ throw new Error('缺少表格列接口路径')
203
+ } else {
204
+ // 克隆一份
205
+ this.columnList = this.deepClone(column)
206
+ this.page = page || ''
207
+ const bePreservedColumn = []
208
+ const res = await this.infoMethod({ page: page })
209
+ if (JSON.stringify(res.data) !== '[]') {
210
+ this.id = res.data.id || undefined
211
+ res.data.column.forEach(col => bePreservedColumn.push(...col.data))
212
+ }
213
+ this.initTableList(this.deepClone(column), bePreservedColumn)
214
+ }
215
+ },
216
+ /**
217
+ * @describe 第一次保存执行的函数(还未保存过的情况下)
218
+ * @param { object[] } initColumn 初始的列数据
219
+ * @param { object[] } bePreservedColumn 被保存过的列数据
220
+ */
221
+ initTableList(initColumn, bePreservedColumn = []) {
222
+ const setDraggableMenu = arr => {
223
+ const cols = []
224
+ arr.forEach(item => cols.push(...item.data))
225
+ cols.sort((a, b) => a.sort - b.sort)
226
+ if (cols.some(item => item.fixed)) {
227
+ let cutOffIndex = 0
228
+ for (let index = 0; index <= cols.length; index++) {
229
+ const col = cols[index]
230
+ const nextCol = cols[index + 1]
231
+ if (col.fixed === 'left' && (!nextCol || !nextCol.fixed)) {
232
+ cutOffIndex = index + 1
233
+ break
234
+ }
235
+ }
236
+ cols.splice(cutOffIndex, 0, {
237
+ type: true,
238
+ label: '',
239
+ key: 'sort-cut-off',
240
+ parent: ''
241
+ })
242
+ }
243
+ return cols
244
+ }
245
+ if (bePreservedColumn && bePreservedColumn.length > 0) {
246
+ // 需要处理被保存过的进行回显
247
+ initColumn.forEach(cols => {
248
+ cols.data.forEach(col => {
249
+ const beSaveCol =
250
+ bePreservedColumn.find(item => item.key === col.key) || {}
251
+ col.type =
252
+ beSaveCol.type === 'true' || beSaveCol.type === true
253
+ ? true
254
+ : false
255
+ col.sort = beSaveCol.sort
256
+ ;(col.fixed = beSaveCol.fixed ? beSaveCol.fixed : col.fixed),
257
+ (col.parent = { label: cols.label })
258
+ })
259
+ })
260
+ // 需要显示的列的数据
261
+ this.checkBoxMenu = this.deepClone(initColumn)
262
+ this.draggableMenu = setDraggableMenu(this.checkBoxMenu)
263
+ } else {
264
+ // 从未被保存过
265
+ let num = 0
266
+ initColumn.forEach(cols => {
267
+ cols.data.forEach(col => {
268
+ num++
269
+ col.type = true
270
+ ;(col.width = col.width ? +col.width : 0), (col.sort = num)
271
+ col.parent = { label: cols.label }
272
+ })
273
+ })
274
+ this.checkBoxMenu = this.deepClone(initColumn)
275
+ this.draggableMenu = setDraggableMenu(this.checkBoxMenu)
276
+ }
277
+ this.$emit(
278
+ 'changeTable',
279
+ this.draggableMenu
280
+ .filter(item => item.key !== 'sort-cut-off')
281
+ .sort((a, b) => a.sort - b.sort)
282
+ )
283
+ this.$emit('changeTableGroup', this.checkBoxMenu)
284
+ },
285
+ // 全不选
286
+ selectNone() {
287
+ this.checkBoxMenu.forEach(cols =>
288
+ cols.data.forEach(col => (col.type = false))
289
+ )
290
+ this.draggableMenu.forEach(item => {
291
+ if (item.key === 'sort-cut-off') {
292
+ item.type = true
293
+ } else {
294
+ item.type = false
295
+ }
296
+ })
297
+ },
298
+ /**
299
+ * @describe 点击高亮
300
+ * @param { number } index 索引
301
+ */
302
+ setHighlight(index) {
303
+ this.activeId = index
304
+ if (this.$refs.tagItem) {
305
+ this.$refs.tagItem[index].scrollIntoView({ behavior: 'smooth' })
306
+ }
307
+ },
308
+ /**
309
+ * @describe 勾选、关闭
310
+ * @param { string } key 唯一标识
311
+ * @param { boolean } type 是否显示
312
+ */
313
+ changeCheckbox(key, type) {
314
+ this.draggableMenu.forEach(item => {
315
+ if (item.key === key) {
316
+ item.type = type
317
+ }
318
+ })
319
+ this.checkBoxMenu.forEach(item => {
320
+ item.data.forEach(each => {
321
+ if (each.key === key) {
322
+ each.type = type
323
+ }
324
+ })
325
+ })
326
+ },
327
+ // 恢复默认
328
+ recoverDefault() {
329
+ this.initTableList(this.deepClone(this.columnList))
330
+ },
331
+ // 拖拽结束事件
332
+ onEnd() {
333
+ let isFixed = true
334
+ this.draggableMenu.forEach((item, index) => {
335
+ if (item.key === 'sort-cut-off') {
336
+ isFixed = false
337
+ }
338
+ if (isFixed) {
339
+ item.sort = index + 1
340
+ item.fixed = 'left'
341
+ } else {
342
+ item.sort = index
343
+ delete item.fixed
344
+ }
345
+ })
346
+ },
347
+ // 点击保存
348
+ async submit() {
349
+ const params = {
350
+ column: [],
351
+ id: this.id,
352
+ page: this.page
353
+ }
354
+ this.draggableMenu.forEach(item => {
355
+ if (item.key !== 'sort-cut-off') {
356
+ const { parent, ...other } = item
357
+ // 是否存在
358
+ const isExit = params.column.some(col => col.label === parent.label)
359
+ if (isExit) {
360
+ params.column.forEach(col => {
361
+ if (col.label === parent.label) {
362
+ col.data.push(other)
363
+ }
364
+ })
365
+ } else {
366
+ params.column.push({
367
+ label: parent.label,
368
+ data: [other]
369
+ })
370
+ }
371
+ }
372
+ })
373
+ await this.submitMethod(params)
374
+ const cols = []
375
+ params.column.forEach(item => {
376
+ cols.push(...item.data)
377
+ })
378
+ this.$emit(
379
+ 'changeTable',
380
+ cols.sort((a, b) => a.sort - b.sort)
381
+ )
382
+ this.$emit('changeTableGroup', params.column)
383
+ this.closeDialog()
384
+ },
385
+ // 关闭弹窗
386
+ closeDialog() {
387
+ // 重置数据
388
+ this.search = ''
389
+ this.activeId = 0
390
+ this.$emit('closeDialog')
391
+ }
392
+ }
393
+ }
394
+ </script>
@@ -0,0 +1,39 @@
1
+ <template>
2
+ <div class="drawer_query_btn b-fold-search">
3
+ <div @click="drawer">
4
+ <template v-if="show == true">
5
+ <span style="color: #3aa1ff; vertical-align: middle">收起</span>
6
+ &nbsp;&nbsp;
7
+ <img
8
+ style="vertical-align: middle"
9
+ src="data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBzdGFuZGFsb25lPSJubyI/PjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+PHN2ZyBjbGFzcz0iaWNvbiIgd2lkdGg9IjIwMHB4IiBoZWlnaHQ9IjIwMC4wMHB4IiB2aWV3Qm94PSIwIDAgMTAyNCAxMDI0IiB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZmlsbD0iIzVjYWRmZiIgZD0iTTg3Ny41IDU2NS45bC0zNjcuNi0zNDAtMzY3LjYgMzQwYy0yMi41IDE0LjUtNTIuNSAxNC41LTY3LjUgMC0xNS0yMS43LTE1LTUwLjcgMC02NS4xTDQ5NSAxMTcuNWMwLTcuMiA3LjUtNy4yIDE1LTcuMnM3LjUgMCAxNSA3LjJsNDIwLjIgMzgzLjNjMjIuNSAyMS43IDE1IDUwLjYgMCA2NS4xLTIyLjcgMTQuNS01Mi43IDE0LjUtNjcuNyAwek00OTQuOCA0NTAuMWMwLTcuMiA3LjUtNy4yIDE1LTcuMnMxNSAwIDE1IDcuMkw5NDUgODMzLjRjMjIuNSAyMS43IDE1IDUwLjYgMCA2NS4xLTIyLjUgMTQuNC01Mi41IDE0LjQtNjcuNSAwTDUwOS44IDU1OC42IDE0Mi4yIDkwNS44Yy0yMi41IDE0LjUtNTIuNSAxNC41LTY3LjUgMC0xNS0yMS43LTE1LTUwLjcgMC02NS4xbDQyMC4xLTM5MC42eiBtMCAwIiAvPjwvc3ZnPg=="
10
+ alt="收起"
11
+ />
12
+ </template>
13
+ <template v-else>
14
+ <span style="color: #3aa1ff; vertical-align: middle">展开更多</span>
15
+ &nbsp;&nbsp;
16
+ <img
17
+ style="vertical-align: middle"
18
+ src="data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBzdGFuZGFsb25lPSJubyI/PjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+PHN2ZyBjbGFzcz0iaWNvbiIgd2lkdGg9IjIwMHB4IiBoZWlnaHQ9IjIwMC4wMHB4IiB2aWV3Qm94PSIwIDAgMTAyNCAxMDI0IiB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZmlsbD0iIzVjYWRmZiIgZD0iTTE0NS40IDQ2MS4xbDM2Ny42IDM0MCAzNjcuNi0zNDBjMjIuNS0xNC41IDUyLjUtMTQuNSA2Ny41IDAgMTUgMjEuNyAxNSA1MC43IDAgNjUuMUw1MjcuOSA5MDkuNWMwIDcuMi03LjUgNy4yLTE1IDcuMnMtNy41IDAtMTUtNy4yTDc3LjcgNTI2LjJjLTIyLjUtMjEuNy0xNS01MC42IDAtNjUuMSAyMi42LTE0LjUgNTIuNi0xNC41IDY3LjcgMHpNNTI4IDU3Ni45YzAgNy4yLTcuNSA3LjItMTUgNy4ycy0xNSAwLTE1LTcuMkw3Ny44IDE5My42Yy0yMi41LTIxLjctMTUtNTAuNiAwLTY1LjEgMjIuNS0xNC40IDUyLjUtMTQuNCA2Ny41IDBMNTEzIDQ2OC40bDM2Ny42LTM0Ny4yYzIyLjUtMTQuNSA1Mi41LTE0LjUgNjcuNSAwIDE1IDIxLjcgMTUgNTAuNyAwIDY1LjFMNTI4IDU3Ni45eiBtMCAwIiAvPjwvc3ZnPg=="
19
+ alt="展开更多"
20
+ />
21
+ </template>
22
+ </div>
23
+ </div>
24
+ </template>
25
+ <script>
26
+ export default {
27
+ data() {
28
+ return {
29
+ show: false
30
+ }
31
+ },
32
+ methods: {
33
+ drawer(value) {
34
+ this.show = !this.show
35
+ this.$emit('change', this.show)
36
+ }
37
+ }
38
+ }
39
+ </script>
@@ -0,0 +1,171 @@
1
+ <template>
2
+ <div class="b-picker wrapper">
3
+ <el-date-picker
4
+ style="width: 70%"
5
+ :value="value"
6
+ v-bind="dateOptions"
7
+ @input="handleChange"
8
+ />
9
+ <div class="btn">
10
+ <span
11
+ v-for="item in shortcuts"
12
+ :key="item.key"
13
+ class="item"
14
+ :class="{ item_active: item.key === active }"
15
+ @click="handleClick(item)"
16
+ >
17
+ {{ item.label }}
18
+ </span>
19
+ </div>
20
+ </div>
21
+ </template>
22
+
23
+ <script>
24
+ import moment from 'moment'
25
+ export default {
26
+ props: {
27
+ value: {
28
+ type: [Array, String],
29
+ required: true,
30
+ default: () => []
31
+ },
32
+ otherOption: {
33
+ type: Object,
34
+ default: () => ({
35
+ startPlaceholder: '开始时间',
36
+ endPlaceholder: '结束时间',
37
+ type: 'daterange',
38
+ rangeSeparator: '-',
39
+ size: 'mini',
40
+ active: ''
41
+ })
42
+ },
43
+ startTimeField: {
44
+ type: String,
45
+ default: ''
46
+ },
47
+ endTimeField: {
48
+ type: String,
49
+ default: ''
50
+ }
51
+ },
52
+
53
+ data() {
54
+ return {
55
+ shortcuts: [
56
+ {
57
+ label: '上月',
58
+ start_time: moment()
59
+ .subtract(1, 'months')
60
+ .startOf('month')
61
+ .format('YYYY-MM-DD'),
62
+ end_time: moment()
63
+ .subtract(1, 'months')
64
+ .endOf('month')
65
+ .format('YYYY-MM-DD'),
66
+ key: 'last_month'
67
+ },
68
+ {
69
+ label: '昨天',
70
+ start_time: moment().subtract(1, 'days').format('YYYY-MM-DD'),
71
+ end_time: moment().subtract(1, 'days').format('YYYY-MM-DD'),
72
+ key: 'yesterday'
73
+ },
74
+ {
75
+ label: '今天',
76
+ start_time: moment().startOf('day').format('YYYY-MM-DD'),
77
+ end_time: moment().startOf('day').format('YYYY-MM-DD'),
78
+ key: 'today'
79
+ },
80
+ {
81
+ label: '本周',
82
+ start_time: moment().startOf('week').format('YYYY-MM-DD'),
83
+ end_time: moment().endOf('week').format('YYYY-MM-DD'),
84
+ key: 'week'
85
+ },
86
+ {
87
+ label: '本月',
88
+ start_time: moment().startOf('month').format('YYYY-MM-DD'),
89
+ end_time: moment().endOf('month').format('YYYY-MM-DD'),
90
+ key: 'month'
91
+ }
92
+ ],
93
+ active: ''
94
+ }
95
+ },
96
+
97
+ computed: {
98
+ dateOptions() {
99
+ return {
100
+ startPlaceholder: '开始时间',
101
+ endPlaceholder: '结束时间',
102
+ type: 'daterange',
103
+ rangeSeparator: '至',
104
+ size: 'mini',
105
+ active: '',
106
+ ...this.otherOption
107
+ }
108
+ }
109
+ },
110
+
111
+ watch: {
112
+ value: {
113
+ handler(newValue, oldValue) {
114
+ if (newValue && newValue.length) {
115
+ this.active = ''
116
+ this.shortcuts.forEach(item => {
117
+ if (
118
+ item.start_time === newValue[0] &&
119
+ item.end_time === newValue[1]
120
+ ) {
121
+ this.active = item.key
122
+ }
123
+ })
124
+ } else {
125
+ this.active = this.dateOptions.active
126
+ const item =
127
+ this.shortcuts.find(item => item.key === this.dateOptions.active) ||
128
+ {}
129
+ if (item.start_time && item.end_time) {
130
+ this.handleClick(item)
131
+ }
132
+ }
133
+ },
134
+ immediate: true
135
+ }
136
+ },
137
+
138
+ methods: {
139
+ handleChange(e) {
140
+ if (!e) {
141
+ this.$emit('input', [])
142
+ if (this.startTimeField && this.endTimeField) {
143
+ this.$emit('range-change', { startTime: '', endTime: '' })
144
+ }
145
+ } else {
146
+ const formattedDates = e.map(item => moment(item).format('YYYY-MM-DD'))
147
+ this.$emit('input', formattedDates)
148
+
149
+ if (this.startTimeField && this.endTimeField) {
150
+ this.$emit('range-change', {
151
+ startTime: formattedDates[0],
152
+ endTime: formattedDates[1]
153
+ })
154
+ }
155
+ }
156
+ this.active = ''
157
+ },
158
+ handleClick(item) {
159
+ this.active = item.key
160
+ this.$emit('input', [item.start_time, item.end_time])
161
+
162
+ if (this.startTimeField && this.endTimeField) {
163
+ this.$emit('range-change', {
164
+ startTime: item.start_time,
165
+ endTime: item.end_time
166
+ })
167
+ }
168
+ }
169
+ }
170
+ }
171
+ </script>