|
|
@@ -1,34 +1,32 @@
|
|
1
|
1
|
<template>
|
|
2
|
2
|
<div class="ep-topbar" @click="visible = false">
|
|
3
|
3
|
<div class="time-btns">
|
|
4
|
|
- <el-button size="small" :type="currentTime==='week'?'primary':'default'" @click="selectTime('week')">近一周</el-button>
|
|
5
|
|
- <el-button size="small" :type="currentTime==='month'?'primary':'default'" @click="selectTime('month')">近一月</el-button>
|
|
6
|
|
- <el-button size="small" :type="currentTime==='quarter'?'primary':'default'" @click="selectTime('quarter')">近三月</el-button>
|
|
7
|
|
- <el-button size="small" :type="currentTime==='year'?'primary':'default'" @click="selectTime('year')">近一年</el-button>
|
|
8
|
|
- <el-button size="small" :type="currentTime==='custom'?'primary':'default'" @click="selectTime('custom')">自定义时间范围</el-button>
|
|
9
|
|
- <el-date-picker
|
|
10
|
|
- v-if="currentTime==='custom'"
|
|
11
|
|
- v-model="dateRange"
|
|
12
|
|
- type="daterange"
|
|
13
|
|
- range-separator="至"
|
|
14
|
|
- start-placeholder="开始"
|
|
15
|
|
- end-placeholder="结束"
|
|
16
|
|
- size="small"
|
|
17
|
|
- style="margin-left:8px;width:240px"
|
|
18
|
|
- @change="() => searchHandler()" />
|
|
|
4
|
+ <div :class="currentTime==='week' ? 'primary' : 'default'" @click="selectTime('week')">近一周</div>
|
|
|
5
|
+ <div :class="currentTime==='month' ? 'primary' : 'default'" @click="selectTime('month')">近一月</div>
|
|
|
6
|
+ <div :class="currentTime==='quarter' ? 'primary' : 'default'" @click="selectTime('quarter')">近三月</div>
|
|
|
7
|
+ <div :class="currentTime==='year' ? 'primary' : 'default'" @click="selectTime('year')">近一年</div>
|
|
|
8
|
+ <div :class="currentTime==='custom' ? 'primary' : 'default'" @click="selectTime('custom')">自定义时间范围</div>
|
|
|
9
|
+ <div class="custom-style-date-picker-wrap" v-if="currentTime==='custom'">
|
|
|
10
|
+ <el-date-picker
|
|
|
11
|
+ class="custom-style-date-picker"
|
|
|
12
|
+ v-model="dateRange"
|
|
|
13
|
+ type="daterange"
|
|
|
14
|
+ range-separator="至"
|
|
|
15
|
+ start-placeholder="开始"
|
|
|
16
|
+ end-placeholder="结束"
|
|
|
17
|
+ style="width:320px"
|
|
|
18
|
+ @change="() => searchHandler()"
|
|
|
19
|
+ />
|
|
|
20
|
+ </div>
|
|
19
|
21
|
</div>
|
|
20
|
|
- <el-popover title="" :visible="visible" placement="bottom-end" trigger="click" width="60vw">
|
|
|
22
|
+ <el-popover class="popover" title="" :visible="visible" placement="bottom-start" trigger="click" width="45vw">
|
|
21
|
23
|
<template #reference>
|
|
22
|
|
- <el-button type="primary" @click.stop="visible = !visible">组织架构/模糊搜索</el-button>
|
|
|
24
|
+ <div class="primary" style="border-radius: 6px;" @click.stop="visible = !visible">组织架构/模糊搜索</div>
|
|
23
|
25
|
</template>
|
|
24
|
|
- <div style="width:100%; padding: 15px;">
|
|
|
26
|
+
|
|
|
27
|
+ <div class="custom-el-style">
|
|
25
|
28
|
<div>
|
|
26
|
|
- <el-autocomplete
|
|
27
|
|
- v-model="personName"
|
|
28
|
|
- :fetch-suggestions="queryUsers"
|
|
29
|
|
- placeholder="搜索员工/团队画像"
|
|
30
|
|
- style="width:320px"
|
|
31
|
|
- clearable>
|
|
|
29
|
+ <el-autocomplete v-model="personName" :fetch-suggestions="queryUsers" placeholder="搜索员工/团队画像" style="width:320px;" clearable>
|
|
32
|
30
|
<template #suffix
|
|
33
|
31
|
><el-icon><Search /></el-icon
|
|
34
|
32
|
></template>
|
|
|
@@ -37,10 +35,10 @@
|
|
37
|
35
|
<span v-if="item.deptName" style="font-size:12px;color:#999;margin-left:8px">{{ item.deptName }}</span>
|
|
38
|
36
|
</template>
|
|
39
|
37
|
</el-autocomplete>
|
|
40
|
|
- <el-button type="primary" style="margin-left: 30px;" @click="() => searchHandler()">模糊搜索</el-button>
|
|
|
38
|
+ <div class="primary" style="border-radius: 6px;" @click="() => searchHandler()">模糊搜索</div>
|
|
41
|
39
|
</div>
|
|
42
|
40
|
<div style="margin-top: 20px;">
|
|
43
|
|
- <el-tree :data="departments" :props="{ value: 'id', showPrefix: false }" accordion @node-click="handleNodeClick" />
|
|
|
41
|
+ <el-tree :data="departments" :default-expanded-keys="[100]" :props="{ value: 'id', showPrefix: false }" accordion @node-click="handleNodeClick" />
|
|
44
|
42
|
</div>
|
|
45
|
43
|
</div>
|
|
46
|
44
|
</el-popover>
|
|
|
@@ -48,10 +46,16 @@
|
|
48
|
46
|
</template>
|
|
49
|
47
|
|
|
50
|
48
|
<script setup>
|
|
|
49
|
+import { onMounted, onUnmounted } from 'vue'
|
|
|
50
|
+import { searchPortraitUsers } from '@/api/score/index'
|
|
|
51
|
+import { getDeptUserTree } from '@/api/item/items'
|
|
|
52
|
+
|
|
51
|
53
|
const visible = defineModel('visible', false)
|
|
52
|
54
|
const emit = defineEmits(['search'])
|
|
53
|
55
|
const currentTime = ref('year')
|
|
54
|
56
|
const personName = ref('')
|
|
|
57
|
+const departments = ref([])
|
|
|
58
|
+const dateRange = ref([])
|
|
55
|
59
|
|
|
56
|
60
|
const queryUsers = async (query, cb) => {
|
|
57
|
61
|
if (!query?.trim()) { cb([]); return }
|
|
|
@@ -76,13 +80,21 @@ const getTimeRange = () => {
|
|
76
|
80
|
return { beginTime: formatDate(begin), endTime: formatDate(end) }
|
|
77
|
81
|
}
|
|
78
|
82
|
|
|
|
83
|
+const formatDate = (d) => {
|
|
|
84
|
+ const dt = new Date(d)
|
|
|
85
|
+ return `${dt.getFullYear()}-${String(dt.getMonth()+1).padStart(2,'0')}-${String(dt.getDate()).padStart(2,'0')}`
|
|
|
86
|
+}
|
|
|
87
|
+
|
|
79
|
88
|
const selectTime = (t) => {
|
|
80
|
89
|
currentTime.value = t
|
|
81
|
90
|
if (t !== 'custom') searchHandler()
|
|
82
|
91
|
}
|
|
83
|
92
|
|
|
84
|
93
|
const searchHandler = (query = {}) => {
|
|
85
|
|
- emit('search', { ...getTimeRange(), personName: personName.value }, ...query)
|
|
|
94
|
+ const queryParams = { ...getTimeRange(), personName: personName.value, ...query }
|
|
|
95
|
+ if (queryParams.personName) {
|
|
|
96
|
+ emit('search', queryParams)
|
|
|
97
|
+ }
|
|
86
|
98
|
}
|
|
87
|
99
|
|
|
88
|
100
|
const handleNodeClick = (node) => {
|
|
|
@@ -90,6 +102,45 @@ const handleNodeClick = (node) => {
|
|
90
|
102
|
searchHandler({ personName: node.label })
|
|
91
|
103
|
}
|
|
92
|
104
|
}
|
|
|
105
|
+
|
|
|
106
|
+const setStyle = () => {
|
|
|
107
|
+ const root = document.querySelector(':root')
|
|
|
108
|
+ root.style.setProperty('--el-bg-color-overlay', '#1c1936')
|
|
|
109
|
+ root.style.setProperty('--el-border-color-extra-light', '#5c676d')
|
|
|
110
|
+ root.style.setProperty('--el-border-color-light', 'transparent')
|
|
|
111
|
+ root.style.setProperty('--el-popover-padding', '0px')
|
|
|
112
|
+ root.style.setProperty('--el-text-color-regular', '#fff')
|
|
|
113
|
+ root.style.setProperty('--el-fill-color-light', '#5c676d')
|
|
|
114
|
+}
|
|
|
115
|
+
|
|
|
116
|
+const resetStyle = () => {
|
|
|
117
|
+ const root = document.querySelector(':root')
|
|
|
118
|
+ root.style.setProperty('--el-bg-color-overlay', '#ffffff')
|
|
|
119
|
+ root.style.setProperty('--el-border-color-extra-light', '#f2f6fc')
|
|
|
120
|
+ root.style.setProperty('--el-border-color-light', '#e4e7ed')
|
|
|
121
|
+ root.style.setProperty('--el-popover-padding', '12px')
|
|
|
122
|
+ root.style.setProperty('--el-text-color-regular', '#606266')
|
|
|
123
|
+ root.style.setProperty('--el-fill-color-light', '#f5f7fa')
|
|
|
124
|
+
|
|
|
125
|
+}
|
|
|
126
|
+
|
|
|
127
|
+onMounted(async () => {
|
|
|
128
|
+ setStyle()
|
|
|
129
|
+ const res = await getDeptUserTree()
|
|
|
130
|
+ departments.value = res.data
|
|
|
131
|
+})
|
|
|
132
|
+onUnmounted(() => {
|
|
|
133
|
+ resetStyle()
|
|
|
134
|
+})
|
|
|
135
|
+
|
|
|
136
|
+defineExpose({
|
|
|
137
|
+ getDefQuery () {
|
|
|
138
|
+ return {
|
|
|
139
|
+ personName: '',
|
|
|
140
|
+ ...getTimeRange()
|
|
|
141
|
+ }
|
|
|
142
|
+ }
|
|
|
143
|
+})
|
|
93
|
144
|
</script>
|
|
94
|
145
|
|
|
95
|
146
|
<style lang="scss" scoped>
|
|
|
@@ -97,8 +148,8 @@ const handleNodeClick = (node) => {
|
|
97
|
148
|
display: flex;
|
|
98
|
149
|
align-items: center;
|
|
99
|
150
|
justify-content: flex-start;
|
|
100
|
|
- height: 90px;
|
|
101
|
|
- padding: 15px;
|
|
|
151
|
+ height: 60px;
|
|
|
152
|
+ padding: 0 15px;
|
|
102
|
153
|
box-sizing: border-box;
|
|
103
|
154
|
gap: 12px;
|
|
104
|
155
|
flex-wrap: wrap;
|
|
|
@@ -106,9 +157,103 @@ const handleNodeClick = (node) => {
|
|
106
|
157
|
.time-btns {
|
|
107
|
158
|
display: flex;
|
|
108
|
159
|
align-items: center;
|
|
109
|
|
- gap: 6px;
|
|
|
160
|
+ gap: 10px;
|
|
110
|
161
|
flex-wrap: wrap;
|
|
111
|
162
|
margin-right: 40px;
|
|
|
163
|
+ & > div {
|
|
|
164
|
+ padding: 8px 24px;
|
|
|
165
|
+ border-radius: 28px;
|
|
|
166
|
+ font-weight: 500;
|
|
|
167
|
+ }
|
|
|
168
|
+ }
|
|
|
169
|
+ .primary {
|
|
|
170
|
+ background: linear-gradient(125deg, #2AB3E6, #9605FC);
|
|
|
171
|
+ color: #fff;
|
|
|
172
|
+ padding: 8px 24px;
|
|
|
173
|
+ }
|
|
|
174
|
+ .default {
|
|
|
175
|
+ background: #1C1936;
|
|
|
176
|
+ color: #4C4C93;
|
|
|
177
|
+ position: relative;
|
|
|
178
|
+ &::before {
|
|
|
179
|
+ content: '';
|
|
|
180
|
+ position: absolute;
|
|
|
181
|
+ inset: -1px;
|
|
|
182
|
+ border-radius: 29px;
|
|
|
183
|
+ background: linear-gradient(150deg, #0f46fa 0%, #bd03fb 100%);
|
|
|
184
|
+ filter: brightness(2) contrast(150%);
|
|
|
185
|
+ z-index: -1;
|
|
|
186
|
+ opacity: 0.5;
|
|
|
187
|
+ }
|
|
|
188
|
+ }
|
|
|
189
|
+ .custom-style-date-picker-wrap {
|
|
|
190
|
+ position: relative;
|
|
|
191
|
+ border-radius: 19px;
|
|
|
192
|
+ height: 38px;
|
|
|
193
|
+ padding: 0 !important;
|
|
|
194
|
+ --el-text-color-primary: #fff;
|
|
|
195
|
+ &::before {
|
|
|
196
|
+ content: '';
|
|
|
197
|
+ position: absolute;
|
|
|
198
|
+ inset: -1px;
|
|
|
199
|
+ border-radius: 19px;
|
|
|
200
|
+ background: linear-gradient(150deg, #0f46fa 0%, #bd03fb 100%);
|
|
|
201
|
+ filter: brightness(2) contrast(150%);
|
|
|
202
|
+ z-index: -1;
|
|
|
203
|
+ opacity: 0.5;
|
|
|
204
|
+ }
|
|
112
|
205
|
}
|
|
113
|
206
|
}
|
|
114
|
207
|
</style>
|
|
|
208
|
+
|
|
|
209
|
+<style lang="scss">
|
|
|
210
|
+ .custom-el-style {
|
|
|
211
|
+ width:100%;
|
|
|
212
|
+ padding: 10px;
|
|
|
213
|
+ position: relative;
|
|
|
214
|
+ background: #1c1936;
|
|
|
215
|
+ border-radius: 8px;
|
|
|
216
|
+ --el-text-color-regular: #fff;
|
|
|
217
|
+ --el-fill-color-blank: #17122A;
|
|
|
218
|
+ --el-border-color: linear-gradient(150deg, #0f46fa 0%, #bd03fb 100%);
|
|
|
219
|
+ --el-border-color-hover: linear-gradient(150deg, #0f46fa 0%, #bd03fb 100%);
|
|
|
220
|
+ .primary {
|
|
|
221
|
+ background: linear-gradient(125deg, #2AB3E6, #9605FC);
|
|
|
222
|
+ color: #fff;
|
|
|
223
|
+ padding: 6px 20px;
|
|
|
224
|
+ display: inline-block;
|
|
|
225
|
+ margin-left: 15px;
|
|
|
226
|
+ }
|
|
|
227
|
+ &::before {
|
|
|
228
|
+ content: '';
|
|
|
229
|
+ position: absolute;
|
|
|
230
|
+ inset: -2px;
|
|
|
231
|
+ border-radius: 10px;
|
|
|
232
|
+ background: linear-gradient(150deg, #0f46fa 0%, #0f46fa 10%, #020E15, #020E15, #020E15, #bd03fb 90%, #bd03fb 100%);
|
|
|
233
|
+ filter: brightness(2) contrast(150%);
|
|
|
234
|
+ z-index: -2;
|
|
|
235
|
+ opacity: 0.5;
|
|
|
236
|
+ }
|
|
|
237
|
+ .el-input__wrapper {
|
|
|
238
|
+ }
|
|
|
239
|
+ .el-tree {
|
|
|
240
|
+ background-color: #1c1936;
|
|
|
241
|
+ color: #fff;
|
|
|
242
|
+ .el-tree-node__content {
|
|
|
243
|
+ --el-tree-node-hover-bg-color: #5c676d;
|
|
|
244
|
+ }
|
|
|
245
|
+ }
|
|
|
246
|
+ }
|
|
|
247
|
+ .el-autocomplete-suggestion {
|
|
|
248
|
+ background: #17122A;
|
|
|
249
|
+ }
|
|
|
250
|
+ .custom-style-date-picker {
|
|
|
251
|
+ background: #1C1936 !important;
|
|
|
252
|
+ box-shadow: none !important;
|
|
|
253
|
+ height: 38px !important;
|
|
|
254
|
+ border-radius: 19px;
|
|
|
255
|
+ }
|
|
|
256
|
+ .el-popper {
|
|
|
257
|
+ --el-popover-padding: 0px;
|
|
|
258
|
+ }
|
|
|
259
|
+</style>
|