ci-plus 1.0.8 → 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/index.ts +2 -0
- package/package.json +1 -1
- package/src/assets/icons/exportExcel.svg +19 -0
- 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 +249 -115
- package/src/selectSuffix/types copy.ts +30 -0
- package/src/selectSuffix/types.ts +20 -5
- package/src/sortableTable/headButtons.vue +2 -3
package/index.ts
CHANGED
package/package.json
CHANGED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
<!-- 导出excel -->
|
|
2
|
+
<svg
|
|
3
|
+
t="1705566058206" class="icon" viewBox="0 0 1024 1024"
|
|
4
|
+
version="1.1" xmlns="http://www.w3.org/2000/svg"
|
|
5
|
+
p-id="7831" width="200" height="200"
|
|
6
|
+
>
|
|
7
|
+
<path
|
|
8
|
+
d="M595.2 755.2h128v88.32L954.88 710.4 723.2 576v89.6h-128zM266.24 134.4c0-6.4 6.4-12.8 12.8-12.8H652.8c3.84 0 7.68 0 12.8 1.28v198.4H864c1.28 5.12 1.28 29.44 1.28 33.28v252.16l49.92 30.72v-281.6c0-34.56-20.48-102.4-43.52-126.72L760.32 117.76C736 93.44 688.64 74.24 654.08 74.24H279.04c-34.56 0-62.72 28.16-62.72 62.72V262.4h49.92v-128z m449.28 10.24c3.84 2.56 6.4 5.12 8.96 7.68l111.36 111.36c2.56 2.56 5.12 5.12 7.68 8.96h-128v-128z"
|
|
9
|
+
fill="#22975D"
|
|
10
|
+
p-id="7832"
|
|
11
|
+
>
|
|
12
|
+
</path>
|
|
13
|
+
<path
|
|
14
|
+
d="M595.2 385.28H800v58.88H595.2z m270.08 503.04c0 6.4-6.4 12.8-12.8 12.8H279.04c-6.4 0-12.8-6.4-12.8-12.8v-42.24h-49.92v42.24c0 34.56 28.16 62.72 62.72 62.72h574.72c34.56 0 62.72-28.16 62.72-62.72V783.36l-49.92 29.44v75.52zM537.6 320H69.12v468.48H537.6V320zM367.36 687.36l-64-94.72-28.16 43.52h28.16v52.48H160l104.96-153.6L172.8 396.8h76.8l55.04 80.64 55.04-80.64h76.8l-92.16 138.24 104.96 153.6h-81.92z m227.84-185.6H800v58.88H595.2z"
|
|
15
|
+
fill="#22975D"
|
|
16
|
+
p-id="7833"
|
|
17
|
+
>
|
|
18
|
+
</path>
|
|
19
|
+
</svg>
|
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,35 +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) {
|
|
123
175
|
emits('update:modelValue', row[props.prop.value])
|
|
124
|
-
|
|
125
176
|
emits('change', row[props.prop.value], row)
|
|
126
177
|
tagLabel.value = row[props.prop.label]
|
|
127
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()
|
|
128
188
|
}
|
|
129
189
|
}
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
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)
|
|
134
211
|
}
|
|
135
212
|
const openTable = () => {
|
|
136
213
|
basic.is_dialogTable = true
|
|
137
214
|
if (!tableData.value.length) getTableData()
|
|
138
215
|
let searchObj: AnyO = {}
|
|
139
216
|
searchObj[props.searchKey ? props.searchKey : 'search'] = props.modelValue
|
|
140
|
-
if (props.modelValue)
|
|
141
|
-
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) => {
|
|
142
219
|
if (res.code == 200 && res.data.length) {
|
|
143
|
-
|
|
144
|
-
|
|
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
|
+
}
|
|
145
226
|
setCurrent()
|
|
146
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
|
|
147
240
|
}
|
|
148
241
|
const getTableData = (obj = {}, page1 = false) => {
|
|
149
242
|
getAxios(obj, page1).then((res) => {
|
|
@@ -153,12 +246,23 @@ const getTableData = (obj = {}, page1 = false) => {
|
|
|
153
246
|
setCurrent()
|
|
154
247
|
})
|
|
155
248
|
}
|
|
156
|
-
const setCurrent = (
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
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
|
+
}
|
|
160
265
|
}
|
|
161
|
-
//获取数据
|
|
162
266
|
const getAxios = async (obj = {}, page1 = false): Promise<any> => {
|
|
163
267
|
basic.loading = true
|
|
164
268
|
if (page1) basic.page = 1
|
|
@@ -185,6 +289,27 @@ const getAxios = async (obj = {}, page1 = false): Promise<any> => {
|
|
|
185
289
|
})
|
|
186
290
|
return data
|
|
187
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
|
+
}
|
|
188
313
|
</script>
|
|
189
314
|
|
|
190
315
|
<style lang="scss">
|
|
@@ -197,5 +322,14 @@ const getAxios = async (obj = {}, page1 = false): Promise<any> => {
|
|
|
197
322
|
.el-table__body tr.current-row > td.el-table__cell {
|
|
198
323
|
background-color: #bbe7ff !important;
|
|
199
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;
|
|
200
334
|
}
|
|
201
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
|
}
|
|
@@ -5,9 +5,8 @@
|
|
|
5
5
|
* @version : 1.0.0
|
|
6
6
|
* @since : 创建时间 2023-12-26 14:18:14
|
|
7
7
|
*/ -->
|
|
8
|
-
|
|
9
8
|
<template>
|
|
10
|
-
<div class="
|
|
9
|
+
<div class="ciheadbtns">
|
|
11
10
|
<div>
|
|
12
11
|
<slot name="left"></slot>
|
|
13
12
|
</div>
|
|
@@ -20,7 +19,7 @@
|
|
|
20
19
|
defineOptions({ name: 'ci-headbtns' })
|
|
21
20
|
</script>
|
|
22
21
|
<style lang="scss">
|
|
23
|
-
.
|
|
22
|
+
.ciheadbtns {
|
|
24
23
|
display: flex;
|
|
25
24
|
justify-content: space-between;
|
|
26
25
|
padding: 5px 10px;
|