ci-plus 1.0.9 → 1.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/dailog/dialog.vue +2 -1
- package/src/dailog/read.md +74 -0
- package/src/dailog/style/index.less +66 -0
- package/src/selectSuffix/selectSuffix copy.vue +202 -0
- package/src/selectSuffix/selectSuffix.vue +281 -118
- package/src/selectSuffix/types copy.ts +30 -0
- package/src/selectSuffix/types.ts +36 -20
- package/src/sortableTable/utils/interface.ts +2 -2
package/package.json
CHANGED
package/src/dailog/dialog.vue
CHANGED
|
@@ -68,7 +68,7 @@ if (!MyFullscreen.value) {
|
|
|
68
68
|
|
|
69
69
|
// 根据传递搜全屏给调整最大高度:如果为不全屏立马给一个最大高度
|
|
70
70
|
if (props.fullscreen == false) {
|
|
71
|
-
console.log('判断进来没222')
|
|
71
|
+
// console.log('判断进来没222')
|
|
72
72
|
MyStyle.value =
|
|
73
73
|
props.style + `max-height: calc( ${windowHeight.value}px - ${dTop.value});translate(59px, 4px)`
|
|
74
74
|
}
|
|
@@ -191,6 +191,7 @@ const onTdMousedown = (e: MouseEvent) => {
|
|
|
191
191
|
:style="MyStyle"
|
|
192
192
|
:top="dTop"
|
|
193
193
|
ref="MyDialogRef"
|
|
194
|
+
v-bind="$attrs"
|
|
194
195
|
>
|
|
195
196
|
<template #header="{ close, titleId, titleClass }">
|
|
196
197
|
<div class="my-header">
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
## 注意
|
|
2
|
+
|
|
3
|
+
如果组件使用了append-to-body 属性将 弹窗提高到了body 的子项时,在本组件中的样式将不在生效,需要在App.vue或者其他高层级中设置 如下样式:
|
|
4
|
+
|
|
5
|
+
```css
|
|
6
|
+
body {
|
|
7
|
+
.el-overlay {
|
|
8
|
+
.el-overlay-dialog {
|
|
9
|
+
.el-dialog {
|
|
10
|
+
padding: 0 !important;
|
|
11
|
+
.el-dialog__header {
|
|
12
|
+
height: 35px !important;
|
|
13
|
+
line-height: 35px !important;
|
|
14
|
+
margin: 0 !important;
|
|
15
|
+
padding: 0px !important;
|
|
16
|
+
background-color: rgba(0, 0, 0, 0.1) !important;
|
|
17
|
+
|
|
18
|
+
.my-header {
|
|
19
|
+
display: flex;
|
|
20
|
+
height: 35px;
|
|
21
|
+
line-height: 35px;
|
|
22
|
+
margin: 0 10px;
|
|
23
|
+
.title {
|
|
24
|
+
flex: 1;
|
|
25
|
+
.el-dialog__title {
|
|
26
|
+
margin: 0px !important;
|
|
27
|
+
padding: 0px !important;
|
|
28
|
+
height: 35px !important;
|
|
29
|
+
line-height: 35px;
|
|
30
|
+
margin: 0 !important;
|
|
31
|
+
padding: 0 !important;
|
|
32
|
+
text-align: left !important;
|
|
33
|
+
font-weight: 700;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
.btn {
|
|
37
|
+
max-width: 100px;
|
|
38
|
+
display: flex;
|
|
39
|
+
justify-content: flex-end;
|
|
40
|
+
height: 35px;
|
|
41
|
+
line-height: 35px;
|
|
42
|
+
align-items: center;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// 内容区域
|
|
48
|
+
.el-dialog__body {
|
|
49
|
+
height: calc(100% - 65px);
|
|
50
|
+
overflow: auto;
|
|
51
|
+
.my-body {
|
|
52
|
+
text-align: left;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
.drag {
|
|
57
|
+
position: absolute;
|
|
58
|
+
width: 16px;
|
|
59
|
+
height: 16px;
|
|
60
|
+
bottom: 3px;
|
|
61
|
+
// background: red;
|
|
62
|
+
right: 3px;
|
|
63
|
+
z-index: 999;
|
|
64
|
+
border-radius: inherit;
|
|
65
|
+
box-shadow: 2px 2px 0px -1px red;
|
|
66
|
+
cursor: se-resize; // move:十字
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
}
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
或者将本组件的样式文件中的#dia 去掉让样式变成全局样式
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
#dia {
|
|
2
2
|
.el-dialog {
|
|
3
|
+
padding: 0 !important;
|
|
3
4
|
// height: 100% !important;
|
|
4
5
|
// max-height: calc(100% - 10vh);
|
|
5
6
|
.el-dialog__header {
|
|
@@ -41,6 +42,7 @@
|
|
|
41
42
|
// 内容区域
|
|
42
43
|
.el-dialog__body {
|
|
43
44
|
height: calc(100% - 65px);
|
|
45
|
+
padding-bottom: 0px !important;
|
|
44
46
|
overflow: auto;
|
|
45
47
|
.my-body {
|
|
46
48
|
text-align: left;
|
|
@@ -67,3 +69,67 @@
|
|
|
67
69
|
// position: relative;
|
|
68
70
|
// }
|
|
69
71
|
}
|
|
72
|
+
|
|
73
|
+
// 此处样式会全局生效
|
|
74
|
+
.el-dialog {
|
|
75
|
+
padding: 0 !important;
|
|
76
|
+
// height: 100% !important;
|
|
77
|
+
// max-height: calc(100% - 10vh);
|
|
78
|
+
.el-dialog__header {
|
|
79
|
+
height: 35px !important;
|
|
80
|
+
line-height: 35px !important;
|
|
81
|
+
margin: 0 !important;
|
|
82
|
+
padding: 0px !important;
|
|
83
|
+
background-color: rgba(0, 0, 0, 0.1) !important;
|
|
84
|
+
|
|
85
|
+
.my-header {
|
|
86
|
+
display: flex;
|
|
87
|
+
height: 35px;
|
|
88
|
+
line-height: 35px;
|
|
89
|
+
margin: 0 10px;
|
|
90
|
+
.title {
|
|
91
|
+
flex: 1;
|
|
92
|
+
.el-dialog__title {
|
|
93
|
+
margin: 0px !important;
|
|
94
|
+
padding: 0px !important;
|
|
95
|
+
height: 35px !important;
|
|
96
|
+
line-height: 35px;
|
|
97
|
+
margin: 0 !important;
|
|
98
|
+
padding: 0 !important;
|
|
99
|
+
text-align: left !important;
|
|
100
|
+
font-weight: 700;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
.btn {
|
|
104
|
+
max-width: 100px;
|
|
105
|
+
display: flex;
|
|
106
|
+
justify-content: flex-end;
|
|
107
|
+
height: 35px;
|
|
108
|
+
line-height: 35px;
|
|
109
|
+
align-items: center;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// 内容区域
|
|
115
|
+
.el-dialog__body {
|
|
116
|
+
height: calc(100% - 65px);
|
|
117
|
+
padding-bottom: 0px !important;
|
|
118
|
+
overflow: auto;
|
|
119
|
+
.my-body {
|
|
120
|
+
text-align: left;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
.drag {
|
|
125
|
+
position: absolute;
|
|
126
|
+
width: 16px;
|
|
127
|
+
height: 16px;
|
|
128
|
+
bottom: 3px;
|
|
129
|
+
// background: red;
|
|
130
|
+
right: 3px;
|
|
131
|
+
z-index: 999;
|
|
132
|
+
border-radius: inherit;
|
|
133
|
+
box-shadow: 2px 2px 0px -1px red;
|
|
134
|
+
cursor: se-resize; // move:十字
|
|
135
|
+
}
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<span class="el-input-number__increase" @click.stop="openTable">
|
|
3
|
+
<el-icon>
|
|
4
|
+
<Operation />
|
|
5
|
+
</el-icon>
|
|
6
|
+
</span>
|
|
7
|
+
<el-dialog
|
|
8
|
+
class="L-dialog"
|
|
9
|
+
v-model="basic.is_dialogTable"
|
|
10
|
+
:title="title ? title : '请选择'"
|
|
11
|
+
append-to-body
|
|
12
|
+
style="height: 60%; width: 800px"
|
|
13
|
+
draggable
|
|
14
|
+
>
|
|
15
|
+
<div style="display: flex; flex-direction: column; height: 100%" v-loading="basic.loading">
|
|
16
|
+
<el-row style="margin-bottom: 3px">
|
|
17
|
+
<el-col v-if="mul && Array.isArray(props.modelValue)" :span="14">
|
|
18
|
+
<template v-for="(v, i) in props.modelValue">
|
|
19
|
+
<el-tag v-if="i <= 2" :key="v" closable type="" style="width: 70px">
|
|
20
|
+
{{ v }}
|
|
21
|
+
</el-tag>
|
|
22
|
+
</template>
|
|
23
|
+
</el-col>
|
|
24
|
+
<el-col v-else :span="14" class="flex">
|
|
25
|
+
<el-tag v-if="props.modelValue?.length" closable type="" @close="closeTag">
|
|
26
|
+
{{ tagLabel }}
|
|
27
|
+
</el-tag>
|
|
28
|
+
</el-col>
|
|
29
|
+
<el-col :span="10">
|
|
30
|
+
<el-input
|
|
31
|
+
v-model="basic.search"
|
|
32
|
+
placeholder="模糊搜索"
|
|
33
|
+
@keyup.enter="getTableData({}, true)"
|
|
34
|
+
@change="getTableData({}, true)"
|
|
35
|
+
>
|
|
36
|
+
<template #append>
|
|
37
|
+
<el-button icon="Search" @click="getTableData({}, true)" />
|
|
38
|
+
</template>
|
|
39
|
+
</el-input>
|
|
40
|
+
</el-col>
|
|
41
|
+
</el-row>
|
|
42
|
+
<el-table
|
|
43
|
+
:data="tableData"
|
|
44
|
+
size="small"
|
|
45
|
+
@row-click="rowClick"
|
|
46
|
+
ref="tableRef"
|
|
47
|
+
style="width: 100%; flex: 1"
|
|
48
|
+
:highlight-current-row="!mul"
|
|
49
|
+
>
|
|
50
|
+
<template v-for="column in columns">
|
|
51
|
+
<el-table-column v-if="column.component" v-bind="column.col">
|
|
52
|
+
<template #default="scope">
|
|
53
|
+
<component :is="column.component(h, scope)" :scope="scope"></component>
|
|
54
|
+
</template>
|
|
55
|
+
</el-table-column>
|
|
56
|
+
<el-table-column v-else v-bind="column.col" />
|
|
57
|
+
</template>
|
|
58
|
+
</el-table>
|
|
59
|
+
<el-pagination
|
|
60
|
+
background
|
|
61
|
+
layout="total,sizes, prev, pager, next,jumper"
|
|
62
|
+
:pager-count="5"
|
|
63
|
+
:total="basic.count"
|
|
64
|
+
small
|
|
65
|
+
:page-sizes="[30, 100, 200]"
|
|
66
|
+
v-model:current-page="basic.page"
|
|
67
|
+
v-model:page-size="basic.limit"
|
|
68
|
+
@size-change="getTableData()"
|
|
69
|
+
@current-change="getTableData()"
|
|
70
|
+
@prev-click="getTableData()"
|
|
71
|
+
@next-click="getTableData()"
|
|
72
|
+
style="margin-top: 3px"
|
|
73
|
+
/>
|
|
74
|
+
</div>
|
|
75
|
+
</el-dialog>
|
|
76
|
+
</template>
|
|
77
|
+
|
|
78
|
+
<script setup lang="ts">
|
|
79
|
+
defineOptions({ name: 'ci-suffix' })
|
|
80
|
+
import { reactive, h, ref } from 'vue'
|
|
81
|
+
import { ElMessage, ElTable } from 'element-plus'
|
|
82
|
+
import axios from 'axios'
|
|
83
|
+
import { SelectSuffix } from './types'
|
|
84
|
+
interface AnyO {
|
|
85
|
+
[key: string]: any
|
|
86
|
+
}
|
|
87
|
+
interface Basic {
|
|
88
|
+
page: number
|
|
89
|
+
limit: number
|
|
90
|
+
count: number
|
|
91
|
+
is_dialogTable: boolean
|
|
92
|
+
loading: boolean
|
|
93
|
+
search: string
|
|
94
|
+
}
|
|
95
|
+
const tableRef = ref<InstanceType<typeof ElTable>>()
|
|
96
|
+
const props = withDefaults(defineProps<SelectSuffix>(), {
|
|
97
|
+
title: '', //弹出层标题
|
|
98
|
+
modelValue: '', //下拉框value
|
|
99
|
+
columns: () => [], // 表格列配置
|
|
100
|
+
mul: false, // 是否多选
|
|
101
|
+
prop: () => ({ label: '', value: '' }), //下拉框字段对象
|
|
102
|
+
where: () => ({}), //弹出层打开需要展示Label的请求对象
|
|
103
|
+
axiosConfig: () => ({}), //Axios请求配置对象
|
|
104
|
+
isExist: false, // 是否选中关闭,单选默认true,多选默认false
|
|
105
|
+
searchKey: 'search' // 模糊搜索字段,默认search
|
|
106
|
+
})
|
|
107
|
+
console.log('props', props)
|
|
108
|
+
|
|
109
|
+
const emits = defineEmits(['update:modelValue', 'change'])
|
|
110
|
+
const basic = reactive<Basic>({
|
|
111
|
+
page: 1,
|
|
112
|
+
limit: 30,
|
|
113
|
+
count: 0,
|
|
114
|
+
loading: false,
|
|
115
|
+
is_dialogTable: false,
|
|
116
|
+
search: ''
|
|
117
|
+
})
|
|
118
|
+
const tagLabel = ref('')
|
|
119
|
+
const tableData = ref<AnyO[]>([])
|
|
120
|
+
const rowClick = (row: AnyO) => {
|
|
121
|
+
console.log('row', row)
|
|
122
|
+
if (!props.mul) {
|
|
123
|
+
emits('change', row[props.prop.value], row)
|
|
124
|
+
setTimeout(() => {
|
|
125
|
+
emits('update:modelValue', row[props.prop.value])
|
|
126
|
+
}, 100)
|
|
127
|
+
tagLabel.value = row[props.prop.label]
|
|
128
|
+
if (!props.isExist) basic.is_dialogTable = false
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
const closeTag = () => {
|
|
133
|
+
emits('update:modelValue', '')
|
|
134
|
+
tableRef.value!.setCurrentRow(null)
|
|
135
|
+
}
|
|
136
|
+
const openTable = () => {
|
|
137
|
+
basic.is_dialogTable = true
|
|
138
|
+
if (!tableData.value.length) getTableData()
|
|
139
|
+
let searchObj: AnyO = {}
|
|
140
|
+
searchObj[props.searchKey ? props.searchKey : 'search'] = props.modelValue
|
|
141
|
+
if (props.modelValue)
|
|
142
|
+
getAxios(props.where ? props.where : searchObj).then((res) => {
|
|
143
|
+
if (res.code == 200 && res.data.length) {
|
|
144
|
+
tagLabel.value = res.data[0]?.[props.prop.label]
|
|
145
|
+
} else tagLabel.value = ''
|
|
146
|
+
setCurrent()
|
|
147
|
+
})
|
|
148
|
+
}
|
|
149
|
+
const getTableData = (obj = {}, page1 = false) => {
|
|
150
|
+
getAxios(obj, page1).then((res) => {
|
|
151
|
+
if (res.code !== 200) return ElMessage.warning(res.msg)
|
|
152
|
+
basic.count = res.count
|
|
153
|
+
tableData.value = res.data
|
|
154
|
+
setCurrent()
|
|
155
|
+
})
|
|
156
|
+
}
|
|
157
|
+
const setCurrent = (row?: AnyO) => {
|
|
158
|
+
let chooseRow = tableData.value.find((v) => v[props.prop.value] === props.modelValue)
|
|
159
|
+
if (chooseRow) tableRef.value!.setCurrentRow(chooseRow)
|
|
160
|
+
else tableRef.value!.setCurrentRow(null)
|
|
161
|
+
}
|
|
162
|
+
//获取数据
|
|
163
|
+
const getAxios = async (obj = {}, page1 = false): Promise<any> => {
|
|
164
|
+
basic.loading = true
|
|
165
|
+
if (page1) basic.page = 1
|
|
166
|
+
let data,
|
|
167
|
+
searchObj: AnyO = {}
|
|
168
|
+
searchObj[props.searchKey ? props.searchKey : 'search'] = basic.search
|
|
169
|
+
await axios({
|
|
170
|
+
...props.axiosConfig,
|
|
171
|
+
params: {
|
|
172
|
+
page: basic.page,
|
|
173
|
+
limit: basic.limit,
|
|
174
|
+
...searchObj,
|
|
175
|
+
...props.axiosConfig.params,
|
|
176
|
+
...obj
|
|
177
|
+
}
|
|
178
|
+
})
|
|
179
|
+
.then((res) => {
|
|
180
|
+
basic.loading = false
|
|
181
|
+
data = res.data
|
|
182
|
+
})
|
|
183
|
+
.catch((err) => {
|
|
184
|
+
ElMessage.error(err.code)
|
|
185
|
+
basic.loading = false
|
|
186
|
+
})
|
|
187
|
+
return data
|
|
188
|
+
}
|
|
189
|
+
</script>
|
|
190
|
+
|
|
191
|
+
<style lang="scss">
|
|
192
|
+
.L-dialog {
|
|
193
|
+
.flex {
|
|
194
|
+
display: flex;
|
|
195
|
+
align-items: center;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
.el-table__body tr.current-row > td.el-table__cell {
|
|
199
|
+
background-color: #bbe7ff !important;
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
</style>
|
|
@@ -1,111 +1,162 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<
|
|
3
|
-
<el-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
<el-
|
|
25
|
-
<el-
|
|
26
|
-
|
|
27
|
-
</el-
|
|
28
|
-
</
|
|
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
|
-
|
|
2
|
+
<div style="width: 100%">
|
|
3
|
+
<el-select-v2
|
|
4
|
+
:size="props.size ?? 'small'"
|
|
5
|
+
placeholder="请选择"
|
|
6
|
+
:model-value="props.modelValue"
|
|
7
|
+
@update:model-value="(val) => emits('update:modelValue', val)"
|
|
8
|
+
:options="temporary_options"
|
|
9
|
+
@change="
|
|
10
|
+
(val) =>
|
|
11
|
+
emits('change', val, temporary_options.find((v) => v[props.prop.value] == val) ?? null)
|
|
12
|
+
"
|
|
13
|
+
filterable
|
|
14
|
+
style="width: 100%"
|
|
15
|
+
remote
|
|
16
|
+
:remote-method="getOptions"
|
|
17
|
+
:props="props.prop"
|
|
18
|
+
:height="200"
|
|
19
|
+
:disabled="props.disabled"
|
|
20
|
+
:loading="select_loading"
|
|
21
|
+
v-bind="$attrs"
|
|
22
|
+
>
|
|
23
|
+
<template #prefix>
|
|
24
|
+
<span class="el-input-number__increase" @click.stop="openTable">
|
|
25
|
+
<el-icon>
|
|
26
|
+
<Operation />
|
|
27
|
+
</el-icon>
|
|
28
|
+
</span>
|
|
29
|
+
</template>
|
|
30
|
+
<template #loading>
|
|
31
|
+
<svg class="circular" viewBox="0 0 50 50">
|
|
32
|
+
<circle class="path" cx="25" cy="25" r="20" fill="none" />
|
|
33
|
+
</svg>
|
|
34
|
+
</template>
|
|
35
|
+
</el-select-v2>
|
|
36
|
+
<el-dialog
|
|
37
|
+
class="L-dialog"
|
|
38
|
+
v-model="basic.is_dialogTable"
|
|
39
|
+
:title="title ? title : '请选择'"
|
|
40
|
+
append-to-body
|
|
41
|
+
style="height: 60%; width: 800px"
|
|
42
|
+
draggable
|
|
43
|
+
>
|
|
44
|
+
<div style="display: flex; flex-direction: column; height: 100%" v-loading="basic.loading">
|
|
45
|
+
<el-row style="margin-bottom: 3px">
|
|
46
|
+
<el-col v-if="mul && Array.isArray(props.modelValue)" :span="16" class="flex">
|
|
47
|
+
<template v-for="(v, i) in chooseRow">
|
|
48
|
+
<el-tag
|
|
49
|
+
v-if="i < 3"
|
|
50
|
+
:key="v[props.prop.value]"
|
|
51
|
+
closable
|
|
52
|
+
style="width: 120px"
|
|
53
|
+
@close="closeTag(v)"
|
|
54
|
+
>
|
|
55
|
+
{{ v[props.prop.label] }}
|
|
56
|
+
</el-tag>
|
|
57
|
+
<el-tag v-else-if="i == 3" style="width: 60px; font-weight: bold">
|
|
58
|
+
{{ `+${chooseRow.length - 3}` }}
|
|
59
|
+
</el-tag>
|
|
54
60
|
</template>
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
61
|
+
<el-button-group>
|
|
62
|
+
<el-tooltip
|
|
63
|
+
v-if="aim && chooseRow.length"
|
|
64
|
+
effect="dark"
|
|
65
|
+
content="清空选项"
|
|
66
|
+
placement="top-start"
|
|
67
|
+
>
|
|
68
|
+
<el-button
|
|
69
|
+
type="info"
|
|
70
|
+
plain
|
|
71
|
+
size="small"
|
|
72
|
+
icon="CloseBold"
|
|
73
|
+
style="padding: 5px 7px"
|
|
74
|
+
@click="empty"
|
|
75
|
+
></el-button>
|
|
76
|
+
</el-tooltip>
|
|
77
|
+
<el-tooltip
|
|
78
|
+
v-if="chooseRow.length"
|
|
79
|
+
effect="dark"
|
|
80
|
+
:content="is_aim ? '取消查询' : '查询已选中信息'"
|
|
81
|
+
placement="top-start"
|
|
82
|
+
>
|
|
83
|
+
<el-button
|
|
84
|
+
:type="is_aim ? 'primary' : ''"
|
|
85
|
+
size="small"
|
|
86
|
+
:icon="is_aim ? 'RefreshLeft' : 'Aim'"
|
|
87
|
+
style="padding: 5px 7px"
|
|
88
|
+
@click="appointGet"
|
|
89
|
+
></el-button>
|
|
90
|
+
</el-tooltip>
|
|
91
|
+
</el-button-group>
|
|
92
|
+
</el-col>
|
|
93
|
+
<el-col v-else :span="16" class="flex">
|
|
94
|
+
<el-tag v-if="props.modelValue && props.modelValue.length" closable @close="closeTag">
|
|
95
|
+
{{ tagLabel }}</el-tag
|
|
96
|
+
>
|
|
97
|
+
</el-col>
|
|
98
|
+
<el-col :span="8">
|
|
99
|
+
<el-input
|
|
100
|
+
v-model="basic.search"
|
|
101
|
+
placeholder="模糊搜索"
|
|
102
|
+
@keyup.enter="getTableData({}, true)"
|
|
103
|
+
@change="getTableData({}, true)"
|
|
104
|
+
>
|
|
105
|
+
<template #append>
|
|
106
|
+
<el-button icon="Search" @click="getTableData({}, true)" />
|
|
107
|
+
</template>
|
|
108
|
+
</el-input>
|
|
109
|
+
</el-col>
|
|
110
|
+
</el-row>
|
|
111
|
+
<el-table
|
|
112
|
+
:data="tableData"
|
|
113
|
+
size="small"
|
|
114
|
+
@row-click="rowClick"
|
|
115
|
+
ref="tableRef"
|
|
116
|
+
style="width: 100%; flex: 1"
|
|
117
|
+
:row-class-name="tableRowColor"
|
|
118
|
+
:highlight-current-row="!mul"
|
|
119
|
+
>
|
|
120
|
+
<!-- <el-table-column v-if="props.mul" type="selection" align="center" /> -->
|
|
121
|
+
<template v-for="column in columns">
|
|
122
|
+
<el-table-column v-if="column.component" v-bind="column.col">
|
|
123
|
+
<template #default="scope">
|
|
124
|
+
<component :is="column.component(h, scope)" :scope="scope"></component>
|
|
125
|
+
</template>
|
|
126
|
+
</el-table-column>
|
|
127
|
+
<el-table-column v-else v-bind="column.col" />
|
|
128
|
+
</template>
|
|
129
|
+
</el-table>
|
|
130
|
+
<el-pagination
|
|
131
|
+
background
|
|
132
|
+
layout="total,sizes, prev, pager, next,jumper"
|
|
133
|
+
:pager-count="5"
|
|
134
|
+
:total="basic.count"
|
|
135
|
+
small
|
|
136
|
+
:page-sizes="[30, 100, 200]"
|
|
137
|
+
v-model:current-page="basic.page"
|
|
138
|
+
v-model:page-size="basic.limit"
|
|
139
|
+
@size-change="getTableData()"
|
|
140
|
+
@current-change="getTableData()"
|
|
141
|
+
@prev-click="getTableData()"
|
|
142
|
+
@next-click="getTableData()"
|
|
143
|
+
style="margin-top: 3px"
|
|
144
|
+
/>
|
|
145
|
+
</div>
|
|
146
|
+
</el-dialog>
|
|
147
|
+
</div>
|
|
76
148
|
</template>
|
|
77
149
|
|
|
78
150
|
<script setup lang="ts">
|
|
79
|
-
|
|
80
|
-
import { reactive, h, ref } from 'vue'
|
|
151
|
+
import { reactive, h, ref, onMounted, toRef, watch } from 'vue'
|
|
81
152
|
import { ElMessage, ElTable } from 'element-plus'
|
|
82
153
|
import axios from 'axios'
|
|
83
|
-
import { SelectSuffix } from './types'
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
}
|
|
87
|
-
interface Basic {
|
|
88
|
-
page: number
|
|
89
|
-
limit: number
|
|
90
|
-
count: number
|
|
91
|
-
is_dialogTable: boolean
|
|
92
|
-
loading: boolean
|
|
93
|
-
search: string
|
|
94
|
-
}
|
|
95
|
-
const tableRef = ref<InstanceType<typeof ElTable>>()
|
|
96
|
-
const props = withDefaults(defineProps<SelectSuffix>(), {
|
|
97
|
-
title: '', //弹出层标题
|
|
98
|
-
modelValue: '', //下拉框value
|
|
99
|
-
columns: () => [], // 表格列配置
|
|
100
|
-
mul: false, // 是否多选
|
|
101
|
-
prop: () => ({ label: '', value: '' }), //下拉框字段对象
|
|
102
|
-
where: () => ({}), //弹出层打开需要展示Label的请求对象
|
|
103
|
-
axiosConfig: () => ({}), //Axios请求配置对象
|
|
104
|
-
isExist: false, // 是否选中关闭,单选默认true,多选默认false
|
|
105
|
-
searchKey: 'search' // 模糊搜索字段,默认search
|
|
154
|
+
import { SelectSuffix, Basic, AnyO } from './types'
|
|
155
|
+
defineOptions({
|
|
156
|
+
inheritAttrs: false
|
|
106
157
|
})
|
|
107
|
-
|
|
108
|
-
|
|
158
|
+
const tableRef = ref<InstanceType<typeof ElTable>>()
|
|
159
|
+
const props = defineProps<SelectSuffix>()
|
|
109
160
|
const emits = defineEmits(['update:modelValue', 'change'])
|
|
110
161
|
const basic = reactive<Basic>({
|
|
111
162
|
page: 1,
|
|
@@ -115,51 +166,111 @@ const basic = reactive<Basic>({
|
|
|
115
166
|
is_dialogTable: false,
|
|
116
167
|
search: ''
|
|
117
168
|
})
|
|
169
|
+
const select_loading = ref(false)
|
|
170
|
+
const is_aim = ref(false)
|
|
118
171
|
const tagLabel = ref('')
|
|
119
172
|
const tableData = ref<AnyO[]>([])
|
|
173
|
+
const temporary_options = ref<AnyO[]>([])
|
|
174
|
+
const chooseRow = ref<AnyO[]>([])
|
|
175
|
+
const tableRowColor = ({ row, rowIndex }: { row: AnyO; rowIndex: number }) => {
|
|
176
|
+
if (chooseRow.value.find((v) => v[props.prop.value] === row[props.prop.value]))
|
|
177
|
+
return 'success-row'
|
|
178
|
+
return ''
|
|
179
|
+
}
|
|
120
180
|
const rowClick = (row: AnyO) => {
|
|
121
|
-
console.log('row', row)
|
|
122
181
|
if (!props.mul) {
|
|
182
|
+
emits('update:modelValue', row[props.prop.value])
|
|
123
183
|
emits('change', row[props.prop.value], row)
|
|
124
|
-
setTimeout(() => {
|
|
125
|
-
emits('update:modelValue', row[props.prop.value])
|
|
126
|
-
}, 100)
|
|
127
184
|
tagLabel.value = row[props.prop.label]
|
|
128
185
|
if (!props.isExist) basic.is_dialogTable = false
|
|
186
|
+
} else {
|
|
187
|
+
if (chooseRow.value.find((v) => v[props.prop.value] == row[props.prop.value]))
|
|
188
|
+
chooseRow.value.splice(
|
|
189
|
+
chooseRow.value.findIndex((v) => v[props.prop.value] == row[props.prop.value]),
|
|
190
|
+
1
|
|
191
|
+
)
|
|
192
|
+
else chooseRow.value.push(row)
|
|
193
|
+
// tableRef.value.toggleRowSelection(row, undefined)
|
|
194
|
+
sendMulValue()
|
|
129
195
|
}
|
|
130
196
|
}
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
197
|
+
const closeTag = (row?: AnyO) => {
|
|
198
|
+
if (!props.mul) {
|
|
199
|
+
emits('update:modelValue', '')
|
|
200
|
+
emits('change', '', null)
|
|
201
|
+
tableRef.value!.setCurrentRow(null)
|
|
202
|
+
} else {
|
|
203
|
+
chooseRow.value.splice(
|
|
204
|
+
chooseRow.value.findIndex((v) => v == row),
|
|
205
|
+
1
|
|
206
|
+
)
|
|
207
|
+
sendMulValue()
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
const empty = () => {
|
|
211
|
+
chooseRow.value = []
|
|
212
|
+
sendMulValue()
|
|
213
|
+
}
|
|
214
|
+
const sendMulValue = () => {
|
|
215
|
+
let values = chooseRow.value.map((v) => v[props.prop.value])
|
|
216
|
+
emits('update:modelValue', values)
|
|
217
|
+
emits('change', values, chooseRow.value)
|
|
135
218
|
}
|
|
136
219
|
const openTable = () => {
|
|
137
220
|
basic.is_dialogTable = true
|
|
138
221
|
if (!tableData.value.length) getTableData()
|
|
139
222
|
let searchObj: AnyO = {}
|
|
140
223
|
searchObj[props.searchKey ? props.searchKey : 'search'] = props.modelValue
|
|
141
|
-
if (props.modelValue)
|
|
142
|
-
getAxios(props.where ? props.where : searchObj).then((res) => {
|
|
224
|
+
if (props.modelValue && props.modelValue.length)
|
|
225
|
+
getAxios(props.where ? props.where : searchObj, true).then((res) => {
|
|
143
226
|
if (res.code == 200 && res.data.length) {
|
|
144
|
-
|
|
145
|
-
|
|
227
|
+
if (props.mul) chooseRow.value = res.data
|
|
228
|
+
else tagLabel.value = res.data[0]?.[props.prop.label]
|
|
229
|
+
} else {
|
|
230
|
+
tagLabel.value = ''
|
|
231
|
+
chooseRow.value = []
|
|
232
|
+
}
|
|
146
233
|
setCurrent()
|
|
147
234
|
})
|
|
235
|
+
else {
|
|
236
|
+
tagLabel.value = ''
|
|
237
|
+
chooseRow.value = []
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
const appointGet = () => {
|
|
241
|
+
if (!is_aim.value) {
|
|
242
|
+
let params: AnyO = {}
|
|
243
|
+
params[props.where ? Object.keys(props.where)[0] : 'search'] = JSON.stringify(props.modelValue)
|
|
244
|
+
getTableData(params, true)
|
|
245
|
+
} else getTableData()
|
|
246
|
+
is_aim.value = !is_aim.value
|
|
148
247
|
}
|
|
149
248
|
const getTableData = (obj = {}, page1 = false) => {
|
|
150
249
|
getAxios(obj, page1).then((res) => {
|
|
151
250
|
if (res.code !== 200) return ElMessage.warning(res.msg)
|
|
152
251
|
basic.count = res.count
|
|
153
|
-
tableData.value = res.data
|
|
252
|
+
if (props.getData) tableData.value = props.getData(res.data) || []
|
|
253
|
+
else tableData.value = res.data || []
|
|
154
254
|
setCurrent()
|
|
155
255
|
})
|
|
156
256
|
}
|
|
157
|
-
const setCurrent = (
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
257
|
+
const setCurrent = () => {
|
|
258
|
+
if (props.mul) {
|
|
259
|
+
let clickRows = tableData.value.filter((v) =>
|
|
260
|
+
(props.modelValue || []).includes(v[props.prop.value])
|
|
261
|
+
)
|
|
262
|
+
clickRows.forEach((v) => {
|
|
263
|
+
if (!chooseRow.value.find((x) => x[props.prop.value] == v[props.prop.value])) {
|
|
264
|
+
chooseRow.value.push(v)
|
|
265
|
+
// tableRef.value!.toggleRowSelection(v,true)
|
|
266
|
+
}
|
|
267
|
+
})
|
|
268
|
+
} else {
|
|
269
|
+
let clickRow = tableData.value.find((v) => v[props.prop.value] === props.modelValue)
|
|
270
|
+
if (clickRow) tableRef.value!.setCurrentRow(clickRow)
|
|
271
|
+
else tableRef.value!.setCurrentRow(null)
|
|
272
|
+
}
|
|
161
273
|
}
|
|
162
|
-
//获取数据
|
|
163
274
|
const getAxios = async (obj = {}, page1 = false): Promise<any> => {
|
|
164
275
|
basic.loading = true
|
|
165
276
|
if (page1) basic.page = 1
|
|
@@ -186,6 +297,32 @@ const getAxios = async (obj = {}, page1 = false): Promise<any> => {
|
|
|
186
297
|
})
|
|
187
298
|
return data
|
|
188
299
|
}
|
|
300
|
+
const getOptions = (val: string) => {
|
|
301
|
+
if (!val) return
|
|
302
|
+
select_loading.value = true
|
|
303
|
+
let searchObj: AnyO = {}
|
|
304
|
+
searchObj[props.searchKey ? props.searchKey : 'search'] = val
|
|
305
|
+
axios({
|
|
306
|
+
...props.axiosConfig,
|
|
307
|
+
params: {
|
|
308
|
+
page: 1,
|
|
309
|
+
...searchObj,
|
|
310
|
+
...props.axiosConfig.params
|
|
311
|
+
}
|
|
312
|
+
})
|
|
313
|
+
.then((res_) => {
|
|
314
|
+
let res = res_.data
|
|
315
|
+
select_loading.value = false
|
|
316
|
+
if (res.code !== 200) return ElMessage.warning(res.msg)
|
|
317
|
+
if (props.getData) temporary_options.value = props.getData(res.data) || []
|
|
318
|
+
else temporary_options.value = res.data || []
|
|
319
|
+
temporary_options.value = res.data
|
|
320
|
+
})
|
|
321
|
+
.catch((err) => {
|
|
322
|
+
select_loading.value = false
|
|
323
|
+
ElMessage.error(err.code)
|
|
324
|
+
})
|
|
325
|
+
}
|
|
189
326
|
</script>
|
|
190
327
|
|
|
191
328
|
<style lang="scss">
|
|
@@ -198,5 +335,31 @@ const getAxios = async (obj = {}, page1 = false): Promise<any> => {
|
|
|
198
335
|
.el-table__body tr.current-row > td.el-table__cell {
|
|
199
336
|
background-color: #bbe7ff !important;
|
|
200
337
|
}
|
|
338
|
+
|
|
339
|
+
.el-tag__content {
|
|
340
|
+
overflow: hidden;
|
|
341
|
+
text-overflow: ellipsis;
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
.el-table .success-row {
|
|
346
|
+
--el-table-tr-bg-color: #cdedff;
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
.circular {
|
|
350
|
+
margin-top: 5px;
|
|
351
|
+
display: inline;
|
|
352
|
+
height: 30px;
|
|
353
|
+
width: 30px;
|
|
354
|
+
animation: loading-rotate 2s linear infinite;
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
.path {
|
|
358
|
+
animation: loading-dash 1.5s ease-in-out infinite;
|
|
359
|
+
stroke-dasharray: 90, 150;
|
|
360
|
+
stroke-dashoffset: 0;
|
|
361
|
+
stroke-width: 2;
|
|
362
|
+
stroke: var(--el-color-primary);
|
|
363
|
+
stroke-linecap: round;
|
|
201
364
|
}
|
|
202
365
|
</style>
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { Component as ComponentIns, h } from 'vue'
|
|
2
|
+
import { TableColumnInstance, ColumnCls } from 'element-plus'
|
|
3
|
+
import { AxiosRequestConfig } from 'axios';
|
|
4
|
+
export type Props<T> = Partial<Omit<T, `$${string}` | `_${string}` | '$' | '_'>>
|
|
5
|
+
export interface Scope<T> {
|
|
6
|
+
row: T,
|
|
7
|
+
$index: number,
|
|
8
|
+
column: ColumnCls<T>
|
|
9
|
+
}
|
|
10
|
+
export interface SelectColumn {
|
|
11
|
+
col: Props<TableColumnInstance>
|
|
12
|
+
scope?(props: any): string
|
|
13
|
+
component?: (createVNode: typeof h, data: Scope<any>) => ComponentIns
|
|
14
|
+
}
|
|
15
|
+
export interface SelectSuffix {
|
|
16
|
+
title?: string //弹出层标题
|
|
17
|
+
modelValue: string | string[] //下拉框value
|
|
18
|
+
columns: SelectColumn[] // 表格列配置
|
|
19
|
+
mul?: boolean, //多选
|
|
20
|
+
prop: { //下拉框字段
|
|
21
|
+
label: string
|
|
22
|
+
value: string
|
|
23
|
+
}
|
|
24
|
+
where?: { //弹出层打开需要展示Label的请求
|
|
25
|
+
[key: string]: string
|
|
26
|
+
}
|
|
27
|
+
axiosConfig: AxiosRequestConfig //Axios请求配置
|
|
28
|
+
isExist?: boolean, // 是否选中关闭,单选默认true,多选默认false
|
|
29
|
+
searchKey?: string // 模糊搜索字段,默认search
|
|
30
|
+
}
|
|
@@ -3,28 +3,44 @@ import { TableColumnInstance, ColumnCls } from 'element-plus'
|
|
|
3
3
|
import { AxiosRequestConfig } from 'axios';
|
|
4
4
|
export type Props<T> = Partial<Omit<T, `$${string}` | `_${string}` | '$' | '_'>>
|
|
5
5
|
export interface Scope<T> {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
row: T,
|
|
7
|
+
$index: number,
|
|
8
|
+
column: ColumnCls<T>
|
|
9
|
+
}
|
|
10
|
+
export interface AnyO {
|
|
11
|
+
[key: string]: any
|
|
9
12
|
}
|
|
10
13
|
export interface SelectColumn {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
+
col: Props<TableColumnInstance>
|
|
15
|
+
scope?(props: any): string
|
|
16
|
+
component?: (createVNode: typeof h, data: Scope<any>) => ComponentIns
|
|
14
17
|
}
|
|
15
18
|
export interface SelectSuffix {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
19
|
+
title?: string //弹出层标题
|
|
20
|
+
modelValue?: string | string[] //下拉框value
|
|
21
|
+
columns: SelectColumn[] // 表格列配置
|
|
22
|
+
mul?: boolean //多选
|
|
23
|
+
aim?: boolean
|
|
24
|
+
disabled?: boolean
|
|
25
|
+
size?: "" | "default" | "small" | "large"
|
|
26
|
+
prop: { //下拉框字段
|
|
27
|
+
label: string
|
|
28
|
+
value: string
|
|
29
|
+
}
|
|
30
|
+
where?: { //弹出层打开需要展示Label的请求的params
|
|
31
|
+
[key: string]: string
|
|
32
|
+
}
|
|
33
|
+
axiosConfig: AxiosRequestConfig //Axios请求配置
|
|
34
|
+
isExist?: boolean // 是否选中关闭,单选默认true,多选默认false
|
|
35
|
+
searchKey?: string // 模糊搜索字段,默认search,
|
|
36
|
+
// selectConfig?:Props<ISelectV2Props>
|
|
37
|
+
getData?: (params: any) => any[] // 获取数据的方法::getData="(data: any) => data.data"
|
|
38
|
+
}
|
|
39
|
+
export interface Basic {
|
|
40
|
+
page: number
|
|
41
|
+
limit: number
|
|
42
|
+
count: number
|
|
43
|
+
is_dialogTable: boolean
|
|
44
|
+
loading: boolean
|
|
45
|
+
search: string
|
|
30
46
|
}
|
|
@@ -15,7 +15,7 @@ export type Props<T> = Mutable<
|
|
|
15
15
|
>
|
|
16
16
|
export type anyObj = { [key: string | number | symbol]: any }
|
|
17
17
|
export interface SortColumn {
|
|
18
|
-
hide?: boolean
|
|
18
|
+
hide?: boolean //是否显示列
|
|
19
19
|
ban?: boolean
|
|
20
20
|
id?: number
|
|
21
21
|
key?: string
|
|
@@ -47,6 +47,6 @@ export interface SortableTableIns
|
|
|
47
47
|
export interface SortableTableDialog {
|
|
48
48
|
config?: /* @vue-ignore */
|
|
49
49
|
| Props<InstanceType<typeof ElDialog>>
|
|
50
|
-
|
|
50
|
+
| /* @vue-ignore */ Ref<Props<InstanceType<typeof ElDialog>>>['value']
|
|
51
51
|
modelValue: SortColumn[] | Ref<SortColumn[]>['value']
|
|
52
52
|
}
|