ci-plus 1.0.9 → 1.1.0
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 +250 -117
- package/src/selectSuffix/types copy.ts +30 -0
- package/src/selectSuffix/types.ts +20 -5
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,156 @@
|
|
|
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
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
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
|
+
v-bind="$attrs"
|
|
21
|
+
>
|
|
22
|
+
<template #prefix>
|
|
23
|
+
<span class="el-input-number__increase" @click.stop="openTable">
|
|
24
|
+
<el-icon>
|
|
25
|
+
<Operation />
|
|
26
|
+
</el-icon>
|
|
27
|
+
</span>
|
|
28
|
+
</template>
|
|
29
|
+
</el-select-v2>
|
|
30
|
+
<el-dialog
|
|
31
|
+
class="L-dialog"
|
|
32
|
+
v-model="basic.is_dialogTable"
|
|
33
|
+
:title="title ? title : '请选择'"
|
|
34
|
+
append-to-body
|
|
35
|
+
style="height: 60%; width: 800px"
|
|
36
|
+
draggable
|
|
37
|
+
>
|
|
38
|
+
<div style="display: flex; flex-direction: column; height: 100%" v-loading="basic.loading">
|
|
39
|
+
<el-row style="margin-bottom: 3px">
|
|
40
|
+
<el-col v-if="mul && Array.isArray(props.modelValue)" :span="16" class="flex">
|
|
41
|
+
<template v-for="(v, i) in chooseRow">
|
|
42
|
+
<el-tag
|
|
43
|
+
v-if="i < 3"
|
|
44
|
+
:key="v[props.prop.value]"
|
|
45
|
+
closable
|
|
46
|
+
style="width: 120px"
|
|
47
|
+
@close="closeTag(v)"
|
|
48
|
+
>
|
|
49
|
+
{{ v[props.prop.label] }}
|
|
50
|
+
</el-tag>
|
|
51
|
+
<el-tag v-else-if="i == 3" style="width: 60px; font-weight: bold">
|
|
52
|
+
{{ `+${chooseRow.length - 3}` }}
|
|
53
|
+
</el-tag>
|
|
54
54
|
</template>
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
55
|
+
<el-button-group>
|
|
56
|
+
<el-tooltip
|
|
57
|
+
v-if="aim && chooseRow.length"
|
|
58
|
+
effect="dark"
|
|
59
|
+
content="清空选项"
|
|
60
|
+
placement="top-start"
|
|
61
|
+
>
|
|
62
|
+
<el-button
|
|
63
|
+
type="info"
|
|
64
|
+
plain
|
|
65
|
+
size="small"
|
|
66
|
+
icon="CloseBold"
|
|
67
|
+
style="padding: 5px 7px"
|
|
68
|
+
@click="empty"
|
|
69
|
+
></el-button>
|
|
70
|
+
</el-tooltip>
|
|
71
|
+
<el-tooltip
|
|
72
|
+
v-if="chooseRow.length"
|
|
73
|
+
effect="dark"
|
|
74
|
+
:content="is_aim ? '取消查询' : '查询已选中信息'"
|
|
75
|
+
placement="top-start"
|
|
76
|
+
>
|
|
77
|
+
<el-button
|
|
78
|
+
:type="is_aim ? 'primary' : ''"
|
|
79
|
+
size="small"
|
|
80
|
+
:icon="is_aim ? 'RefreshLeft' : 'Aim'"
|
|
81
|
+
style="padding: 5px 7px"
|
|
82
|
+
@click="appointGet"
|
|
83
|
+
></el-button>
|
|
84
|
+
</el-tooltip>
|
|
85
|
+
</el-button-group>
|
|
86
|
+
</el-col>
|
|
87
|
+
<el-col v-else :span="16" class="flex">
|
|
88
|
+
<el-tag v-if="props.modelValue && props.modelValue.length" closable @close="closeTag">
|
|
89
|
+
{{ tagLabel }}</el-tag
|
|
90
|
+
>
|
|
91
|
+
</el-col>
|
|
92
|
+
<el-col :span="8">
|
|
93
|
+
<el-input
|
|
94
|
+
v-model="basic.search"
|
|
95
|
+
placeholder="模糊搜索"
|
|
96
|
+
@keyup.enter="getTableData({}, true)"
|
|
97
|
+
@change="getTableData({}, true)"
|
|
98
|
+
>
|
|
99
|
+
<template #append>
|
|
100
|
+
<el-button icon="Search" @click="getTableData({}, true)" />
|
|
101
|
+
</template>
|
|
102
|
+
</el-input>
|
|
103
|
+
</el-col>
|
|
104
|
+
</el-row>
|
|
105
|
+
<el-table
|
|
106
|
+
:data="tableData"
|
|
107
|
+
size="small"
|
|
108
|
+
@row-click="rowClick"
|
|
109
|
+
ref="tableRef"
|
|
110
|
+
style="width: 100%; flex: 1"
|
|
111
|
+
:row-class-name="tableRowColor"
|
|
112
|
+
:highlight-current-row="!mul"
|
|
113
|
+
>
|
|
114
|
+
<!-- <el-table-column v-if="props.mul" type="selection" align="center" /> -->
|
|
115
|
+
<template v-for="column in columns">
|
|
116
|
+
<el-table-column v-if="column.component" v-bind="column.col">
|
|
117
|
+
<template #default="scope">
|
|
118
|
+
<component :is="column.component(h, scope)" :scope="scope"></component>
|
|
119
|
+
</template>
|
|
120
|
+
</el-table-column>
|
|
121
|
+
<el-table-column v-else v-bind="column.col" />
|
|
122
|
+
</template>
|
|
123
|
+
</el-table>
|
|
124
|
+
<el-pagination
|
|
125
|
+
background
|
|
126
|
+
layout="total,sizes, prev, pager, next,jumper"
|
|
127
|
+
:pager-count="5"
|
|
128
|
+
:total="basic.count"
|
|
129
|
+
small
|
|
130
|
+
:page-sizes="[30, 100, 200]"
|
|
131
|
+
v-model:current-page="basic.page"
|
|
132
|
+
v-model:page-size="basic.limit"
|
|
133
|
+
@size-change="getTableData()"
|
|
134
|
+
@current-change="getTableData()"
|
|
135
|
+
@prev-click="getTableData()"
|
|
136
|
+
@next-click="getTableData()"
|
|
137
|
+
style="margin-top: 3px"
|
|
138
|
+
/>
|
|
139
|
+
</div>
|
|
140
|
+
</el-dialog>
|
|
141
|
+
</div>
|
|
76
142
|
</template>
|
|
77
143
|
|
|
78
144
|
<script setup lang="ts">
|
|
79
|
-
|
|
80
|
-
import { reactive, h, ref } from 'vue'
|
|
145
|
+
import { reactive, h, ref, onMounted, toRef, watch } from 'vue'
|
|
81
146
|
import { ElMessage, ElTable } from 'element-plus'
|
|
82
147
|
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
|
|
148
|
+
import { SelectSuffix, Basic, AnyO } from './types'
|
|
149
|
+
defineOptions({
|
|
150
|
+
inheritAttrs: false
|
|
106
151
|
})
|
|
107
|
-
|
|
108
|
-
|
|
152
|
+
const tableRef = ref<InstanceType<typeof ElTable>>()
|
|
153
|
+
const props = defineProps<SelectSuffix>()
|
|
109
154
|
const emits = defineEmits(['update:modelValue', 'change'])
|
|
110
155
|
const basic = reactive<Basic>({
|
|
111
156
|
page: 1,
|
|
@@ -115,36 +160,83 @@ const basic = reactive<Basic>({
|
|
|
115
160
|
is_dialogTable: false,
|
|
116
161
|
search: ''
|
|
117
162
|
})
|
|
163
|
+
const is_aim = ref(false)
|
|
118
164
|
const tagLabel = ref('')
|
|
119
165
|
const tableData = ref<AnyO[]>([])
|
|
166
|
+
const temporary_options = ref<AnyO[]>([])
|
|
167
|
+
const chooseRow = ref<AnyO[]>([])
|
|
168
|
+
const tableRowColor = ({ row, rowIndex }: { row: AnyO; rowIndex: number }) => {
|
|
169
|
+
if (chooseRow.value.find((v) => v[props.prop.value] === row[props.prop.value]))
|
|
170
|
+
return 'success-row'
|
|
171
|
+
return ''
|
|
172
|
+
}
|
|
120
173
|
const rowClick = (row: AnyO) => {
|
|
121
|
-
console.log('row', row)
|
|
122
174
|
if (!props.mul) {
|
|
175
|
+
emits('update:modelValue', row[props.prop.value])
|
|
123
176
|
emits('change', row[props.prop.value], row)
|
|
124
|
-
setTimeout(() => {
|
|
125
|
-
emits('update:modelValue', row[props.prop.value])
|
|
126
|
-
}, 100)
|
|
127
177
|
tagLabel.value = row[props.prop.label]
|
|
128
178
|
if (!props.isExist) basic.is_dialogTable = false
|
|
179
|
+
} else {
|
|
180
|
+
if (chooseRow.value.find((v) => v[props.prop.value] == row[props.prop.value]))
|
|
181
|
+
chooseRow.value.splice(
|
|
182
|
+
chooseRow.value.findIndex((v) => v[props.prop.value] == row[props.prop.value]),
|
|
183
|
+
1
|
|
184
|
+
)
|
|
185
|
+
else chooseRow.value.push(row)
|
|
186
|
+
// tableRef.value.toggleRowSelection(row, undefined)
|
|
187
|
+
sendMulValue()
|
|
129
188
|
}
|
|
130
189
|
}
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
190
|
+
const closeTag = (row?: AnyO) => {
|
|
191
|
+
if (!props.mul) {
|
|
192
|
+
emits('update:modelValue', '')
|
|
193
|
+
emits('change', '', null)
|
|
194
|
+
tableRef.value!.setCurrentRow(null)
|
|
195
|
+
} else {
|
|
196
|
+
chooseRow.value.splice(
|
|
197
|
+
chooseRow.value.findIndex((v) => v == row),
|
|
198
|
+
1
|
|
199
|
+
)
|
|
200
|
+
sendMulValue()
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
const empty = () => {
|
|
204
|
+
chooseRow.value = []
|
|
205
|
+
sendMulValue()
|
|
206
|
+
}
|
|
207
|
+
const sendMulValue = () => {
|
|
208
|
+
let values = chooseRow.value.map((v) => v[props.prop.value])
|
|
209
|
+
emits('update:modelValue', values)
|
|
210
|
+
emits('change', values, chooseRow.value)
|
|
135
211
|
}
|
|
136
212
|
const openTable = () => {
|
|
137
213
|
basic.is_dialogTable = true
|
|
138
214
|
if (!tableData.value.length) getTableData()
|
|
139
215
|
let searchObj: AnyO = {}
|
|
140
216
|
searchObj[props.searchKey ? props.searchKey : 'search'] = props.modelValue
|
|
141
|
-
if (props.modelValue)
|
|
142
|
-
getAxios(props.where ? props.where : searchObj).then((res) => {
|
|
217
|
+
if (props.modelValue && props.modelValue.length)
|
|
218
|
+
getAxios(props.where ? props.where : searchObj, true).then((res) => {
|
|
143
219
|
if (res.code == 200 && res.data.length) {
|
|
144
|
-
|
|
145
|
-
|
|
220
|
+
if (props.mul) chooseRow.value = res.data
|
|
221
|
+
else tagLabel.value = res.data[0]?.[props.prop.label]
|
|
222
|
+
} else {
|
|
223
|
+
tagLabel.value = ''
|
|
224
|
+
chooseRow.value = []
|
|
225
|
+
}
|
|
146
226
|
setCurrent()
|
|
147
227
|
})
|
|
228
|
+
else {
|
|
229
|
+
tagLabel.value = ''
|
|
230
|
+
chooseRow.value = []
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
const appointGet = () => {
|
|
234
|
+
if (!is_aim.value) {
|
|
235
|
+
let params: AnyO = {}
|
|
236
|
+
params[props.where ? Object.keys(props.where)[0] : 'search'] = JSON.stringify(props.modelValue)
|
|
237
|
+
getTableData(params, true)
|
|
238
|
+
} else getTableData()
|
|
239
|
+
is_aim.value = !is_aim.value
|
|
148
240
|
}
|
|
149
241
|
const getTableData = (obj = {}, page1 = false) => {
|
|
150
242
|
getAxios(obj, page1).then((res) => {
|
|
@@ -154,12 +246,23 @@ const getTableData = (obj = {}, page1 = false) => {
|
|
|
154
246
|
setCurrent()
|
|
155
247
|
})
|
|
156
248
|
}
|
|
157
|
-
const setCurrent = (
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
249
|
+
const setCurrent = () => {
|
|
250
|
+
if (props.mul) {
|
|
251
|
+
let clickRows = tableData.value.filter((v) =>
|
|
252
|
+
(props.modelValue || []).includes(v[props.prop.value])
|
|
253
|
+
)
|
|
254
|
+
clickRows.forEach((v) => {
|
|
255
|
+
if (!chooseRow.value.find((x) => x[props.prop.value] == v[props.prop.value])) {
|
|
256
|
+
chooseRow.value.push(v)
|
|
257
|
+
// tableRef.value!.toggleRowSelection(v,true)
|
|
258
|
+
}
|
|
259
|
+
})
|
|
260
|
+
} else {
|
|
261
|
+
let clickRow = tableData.value.find((v) => v[props.prop.value] === props.modelValue)
|
|
262
|
+
if (clickRow) tableRef.value!.setCurrentRow(clickRow)
|
|
263
|
+
else tableRef.value!.setCurrentRow(null)
|
|
264
|
+
}
|
|
161
265
|
}
|
|
162
|
-
//获取数据
|
|
163
266
|
const getAxios = async (obj = {}, page1 = false): Promise<any> => {
|
|
164
267
|
basic.loading = true
|
|
165
268
|
if (page1) basic.page = 1
|
|
@@ -186,6 +289,27 @@ const getAxios = async (obj = {}, page1 = false): Promise<any> => {
|
|
|
186
289
|
})
|
|
187
290
|
return data
|
|
188
291
|
}
|
|
292
|
+
const getOptions = (val: string) => {
|
|
293
|
+
if (!val) return
|
|
294
|
+
let searchObj: AnyO = {}
|
|
295
|
+
searchObj[props.searchKey ? props.searchKey : 'search'] = val
|
|
296
|
+
axios({
|
|
297
|
+
...props.axiosConfig,
|
|
298
|
+
params: {
|
|
299
|
+
page: 1,
|
|
300
|
+
...searchObj,
|
|
301
|
+
...props.axiosConfig.params
|
|
302
|
+
}
|
|
303
|
+
})
|
|
304
|
+
.then((res_) => {
|
|
305
|
+
let res = res_.data
|
|
306
|
+
if (res.code !== 200) return ElMessage.warning(res.msg)
|
|
307
|
+
temporary_options.value = res.data
|
|
308
|
+
})
|
|
309
|
+
.catch((err) => {
|
|
310
|
+
ElMessage.error(err.code)
|
|
311
|
+
})
|
|
312
|
+
}
|
|
189
313
|
</script>
|
|
190
314
|
|
|
191
315
|
<style lang="scss">
|
|
@@ -198,5 +322,14 @@ const getAxios = async (obj = {}, page1 = false): Promise<any> => {
|
|
|
198
322
|
.el-table__body tr.current-row > td.el-table__cell {
|
|
199
323
|
background-color: #bbe7ff !important;
|
|
200
324
|
}
|
|
325
|
+
|
|
326
|
+
.el-tag__content {
|
|
327
|
+
overflow: hidden;
|
|
328
|
+
text-overflow: ellipsis;
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
.el-table .success-row {
|
|
333
|
+
--el-table-tr-bg-color: #cdedff;
|
|
201
334
|
}
|
|
202
335
|
</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
|
+
}
|
|
@@ -7,6 +7,9 @@ export interface Scope<T> {
|
|
|
7
7
|
$index: number,
|
|
8
8
|
column: ColumnCls<T>
|
|
9
9
|
}
|
|
10
|
+
export interface AnyO {
|
|
11
|
+
[key: string]: any
|
|
12
|
+
}
|
|
10
13
|
export interface SelectColumn {
|
|
11
14
|
col: Props<TableColumnInstance>
|
|
12
15
|
scope?(props: any): string
|
|
@@ -14,17 +17,29 @@ export interface SelectColumn {
|
|
|
14
17
|
}
|
|
15
18
|
export interface SelectSuffix {
|
|
16
19
|
title?: string //弹出层标题
|
|
17
|
-
modelValue
|
|
20
|
+
modelValue?: string | string[] //下拉框value
|
|
18
21
|
columns: SelectColumn[] // 表格列配置
|
|
19
|
-
mul?: boolean
|
|
22
|
+
mul?: boolean //多选
|
|
23
|
+
aim?: boolean
|
|
24
|
+
disabled?: boolean
|
|
25
|
+
size?: "" | "default" | "small" | "large"
|
|
20
26
|
prop: { //下拉框字段
|
|
21
27
|
label: string
|
|
22
28
|
value: string
|
|
23
29
|
}
|
|
24
|
-
where?: { //弹出层打开需要展示Label
|
|
30
|
+
where?: { //弹出层打开需要展示Label的请求的params
|
|
25
31
|
[key: string]: string
|
|
26
32
|
}
|
|
27
33
|
axiosConfig: AxiosRequestConfig //Axios请求配置
|
|
28
|
-
isExist?: boolean
|
|
29
|
-
searchKey?: string // 模糊搜索字段,默认search
|
|
34
|
+
isExist?: boolean // 是否选中关闭,单选默认true,多选默认false
|
|
35
|
+
searchKey?: string // 模糊搜索字段,默认search,
|
|
36
|
+
// selectConfig?:Props<ISelectV2Props>
|
|
37
|
+
}
|
|
38
|
+
export interface Basic {
|
|
39
|
+
page: number
|
|
40
|
+
limit: number
|
|
41
|
+
count: number
|
|
42
|
+
is_dialogTable: boolean
|
|
43
|
+
loading: boolean
|
|
44
|
+
search: string
|
|
30
45
|
}
|