提交 | 用户 | age
|
74a35f
|
1 |
<!-- TooltipAndDropdown.vue --> |
H |
2 |
<template> |
|
3 |
<div style="display: flex; justify-content: space-around"> |
|
4 |
<!-- Tooltip --> |
|
5 |
|
|
6 |
<!-- Dropdown --> |
|
7 |
<a-dropdown v-model:open="dropdownOpen" :trigger="['click']" placement="bottomLeft"> |
|
8 |
<a-tooltip v-if="showTooltip" v-model:open="tooltipOpen" placement="bottomLeft"> |
|
9 |
<template #title> |
|
10 |
<div class="p-1" style="width: 210px"> |
|
11 |
<span>{{ tooltipTitle }}</span> |
|
12 |
<div class="p-2" style="font-size: 18px; font-weight: 600">{{ formattedTime }}</div> |
|
13 |
<div class="p-2" style="text-align: center"> |
|
14 |
<CButton size="small" shape="round" type="success" @click="onUpdate">修改</CButton> |
|
15 |
<a-button |
|
16 |
style="margin-left: 10px" |
|
17 |
size="small" |
|
18 |
shape="round" |
|
19 |
type="primary" |
|
20 |
@click="onComplete" |
|
21 |
>完成</a-button |
|
22 |
> |
|
23 |
</div> |
|
24 |
</div> |
|
25 |
</template> |
|
26 |
<FieldTimeOutlined v-if="showTooltip" class="color-handle" /> |
|
27 |
</a-tooltip> |
|
28 |
<FieldTimeOutlined v-else @click.stop="toggleDropdown" /> |
|
29 |
<template #overlay> |
|
30 |
<a-card title="选择稍后处理时间:" style="width: 250px" size="small"> |
|
31 |
<div |
|
32 |
class="date p-1" |
|
33 |
v-for="item in dateList" |
|
34 |
:key="item.key" |
|
35 |
@click="fnSelectDate(item)" |
|
36 |
> |
|
37 |
<div class="date-left">{{ item.name }}</div> |
|
38 |
<div class="date-right"> |
|
39 |
<span v-if="item.key !== 'today'">{{ item.dayOfWeek }}</span> |
|
40 |
<span style="margin-left: 5px">{{ item.time }}</span> |
|
41 |
</div> |
|
42 |
</div> |
|
43 |
<a-divider style="margin: 5px 0" /> |
|
44 |
<div class="date p-1"> |
|
45 |
<a-popover |
db42d0
|
46 |
:trigger="trigger" |
74a35f
|
47 |
title="自定义时间" |
H |
48 |
v-model:open="customTimeDropdownOpen" |
|
49 |
@confirm="onSubmitCustomTime" |
|
50 |
> |
|
51 |
<template #content> |
|
52 |
<a-form :model="form" ref="formRef"> |
|
53 |
<a-form-item |
|
54 |
label="日期" |
|
55 |
name="date" |
|
56 |
:rules="[{ required: true, message: '请选择日期' }]" |
|
57 |
> |
|
58 |
<a-date-picker |
|
59 |
format="YYYY/MM/DD" |
|
60 |
:disabledDate="disabledDate" |
|
61 |
v-model:value="form.date" |
|
62 |
/> |
|
63 |
</a-form-item> |
|
64 |
<a-form-item |
|
65 |
label="时间" |
|
66 |
name="time" |
|
67 |
:rules="[{ required: true, message: '请选择时间' }]" |
|
68 |
> |
|
69 |
<a-time-picker v-model:value="form.time" /> |
|
70 |
</a-form-item> |
|
71 |
<a-form-item> |
|
72 |
<a-button @click="cancelCustomTime">取消</a-button> |
|
73 |
<a-button style="margin-left: 10px" type="primary" @click="submitCustomTime" |
|
74 |
>确定</a-button |
|
75 |
> |
|
76 |
</a-form-item> |
|
77 |
</a-form> |
|
78 |
</template> |
|
79 |
<div class="date-left" @click="toggleCustomTime">自定义时间</div> |
|
80 |
</a-popover> |
|
81 |
</div> |
|
82 |
</a-card> |
|
83 |
</template> |
|
84 |
</a-dropdown> |
|
85 |
</div> |
|
86 |
</template> |
|
87 |
|
|
88 |
<script lang="ts" setup> |
|
89 |
import { ref, reactive, defineProps, defineEmits, computed, inject, nextTick } from 'vue'; |
|
90 |
import { FieldTimeOutlined, PushpinOutlined } from '@ant-design/icons-vue'; |
|
91 |
import dayjs from 'dayjs'; |
|
92 |
import CButton from '@/components/CButton/index.vue'; |
|
93 |
const getDataList = inject('getDataList'); |
|
94 |
|
|
95 |
function processDateList() { |
|
96 |
const dateList = [ |
|
97 |
{ name: '今天稍晚', key: 'today' }, |
|
98 |
{ name: '明天', key: 'tomorrow' }, |
|
99 |
{ name: '本周稍晚', key: 'thisWeek' }, |
|
100 |
{ name: '本周末', key: 'thisWeekend' }, |
|
101 |
{ name: '下周', key: 'nextWeek' }, |
|
102 |
]; |
|
103 |
|
|
104 |
const now = new Date(); |
|
105 |
|
|
106 |
const dateArray = dateList.map((item) => { |
|
107 |
let date = new Date(); // 初始化当前日期 |
|
108 |
let dayOfWeekString = ''; // 初始化星期几 |
|
109 |
let timeString = ''; // 初始化时间 |
|
110 |
|
|
111 |
switch (item.key) { |
|
112 |
case 'today': |
|
113 |
// 今天稍晚是今天的 16:00 |
|
114 |
date.setHours(16, 0, 0, 0); |
|
115 |
break; |
|
116 |
case 'tomorrow': |
|
117 |
// 明天 08:00 |
|
118 |
date.setDate(now.getDate() + 1); |
|
119 |
date.setHours(8, 0, 0, 0); |
|
120 |
break; |
|
121 |
case 'thisWeek': |
|
122 |
// 本周稍晚:周五 08:00 |
|
123 |
const dayOfWeek = now.getDay(); |
|
124 |
const daysUntilFriday = (5 - dayOfWeek + 7) % 7; // 计算到周五的天数 |
|
125 |
date.setDate(now.getDate() + daysUntilFriday); |
|
126 |
date.setHours(8, 0, 0, 0); |
|
127 |
break; |
|
128 |
case 'thisWeekend': |
|
129 |
// 本周末:周日 08:00 |
|
130 |
const daysUntilSunday = (7 - now.getDay()) % 7; // 计算到周日的天数 |
|
131 |
date.setDate(now.getDate() + daysUntilSunday); |
|
132 |
date.setHours(8, 0, 0, 0); |
|
133 |
break; |
|
134 |
case 'nextWeek': |
|
135 |
// 下周一 08:00 |
|
136 |
const daysUntilNextMonday = ((1 - now.getDay() + 7) % 7) + 7; // 计算到下周一的天数 |
|
137 |
date.setDate(now.getDate() + daysUntilNextMonday); |
|
138 |
date.setHours(8, 0, 0, 0); |
|
139 |
break; |
|
140 |
default: |
|
141 |
break; |
|
142 |
} |
|
143 |
|
|
144 |
// 获取星期几的字符串表示 |
|
145 |
dayOfWeekString = date.toLocaleDateString('zh-CN', { weekday: 'long' }); |
|
146 |
|
|
147 |
// 获取仅时间部分 |
|
148 |
timeString = date.toLocaleTimeString('zh-CN', { hour: '2-digit', minute: '2-digit' }); |
|
149 |
|
|
150 |
// 返回日期、星期几和时间信息 |
|
151 |
return { |
|
152 |
name: item.name, |
|
153 |
key: item.key, |
|
154 |
date: date, |
|
155 |
dayOfWeek: dayOfWeekString, |
|
156 |
time: timeString, // 保存仅时间部分 |
|
157 |
}; |
|
158 |
}); |
|
159 |
|
|
160 |
return dateArray; |
|
161 |
} |
|
162 |
const dateList = processDateList(); |
|
163 |
const props = defineProps({ |
|
164 |
tooltipTitle: String, // Tooltip 标题 |
|
165 |
initialDropdownOpen: Boolean, // Dropdown 初始打开状态 |
|
166 |
showTooltip: Boolean, // 是否展示 Tooltip |
|
167 |
initialTooltipOpen: Boolean, // Tooltip 初始打开状态 |
|
168 |
row: Object, // 当前行对象 |
|
169 |
docCodeS: Array, |
db42d0
|
170 |
trigger: { |
H |
171 |
type: String, |
|
172 |
default: 'click', |
|
173 |
}, |
74a35f
|
174 |
}); |
H |
175 |
|
|
176 |
const emit = defineEmits(['updateHandleTime', 'completeAction', 'customTimeSubmit', 'tagRow']); |
|
177 |
|
|
178 |
import { useMessage } from '@/hooks/web/useMessage'; |
|
179 |
import { formatToDateDay } from '@/utils/dateUtil'; |
|
180 |
import { updateHandleAPi } from '@/api/email/userList'; |
|
181 |
|
|
182 |
const { createMessage } = useMessage(); |
|
183 |
function fnSelectDate(item) { |
|
184 |
dropdownOpen.value = false; |
|
185 |
const date = formatToDateDay(new Date(item.date)); |
|
186 |
const data = { |
|
187 |
handleTime: date, |
|
188 |
docCode: props.docCodeS, |
|
189 |
}; |
db42d0
|
190 |
|
74a35f
|
191 |
pushUpdateHandle(data); |
H |
192 |
} |
|
193 |
function pushUpdateHandle(data) { |
|
194 |
updateHandleAPi(data) |
|
195 |
.then((res) => { |
|
196 |
if (res.code == 0) { |
|
197 |
createMessage.success(res.msg); |
|
198 |
getDataList({}); |
|
199 |
} |
|
200 |
}) |
|
201 |
.catch((err) => {}); |
|
202 |
} |
|
203 |
|
|
204 |
// Dropdown 和 Tooltip 状态管理 |
|
205 |
const dropdownOpen = ref(props.initialDropdownOpen); |
|
206 |
const tooltipOpen = ref(props.initialTooltipOpen); |
|
207 |
const customTimeDropdownOpen = ref(false); |
|
208 |
|
|
209 |
// 表单数据 |
|
210 |
const form = reactive({ |
|
211 |
date: '', |
|
212 |
time: '', |
|
213 |
}); |
|
214 |
const onUpdate = () => { |
|
215 |
dropdownOpen.value = true; |
|
216 |
tooltipOpen.value = false; |
|
217 |
}; |
|
218 |
// 事件处理 |
|
219 |
const toggleDropdown = () => { |
|
220 |
dropdownOpen.value = !dropdownOpen.value; |
|
221 |
}; |
|
222 |
|
|
223 |
const toggleTooltip = () => { |
|
224 |
tooltipOpen.value = !tooltipOpen.value; |
|
225 |
}; |
|
226 |
|
|
227 |
const toggleCustomTime = () => { |
|
228 |
customTimeDropdownOpen.value = !customTimeDropdownOpen.value; |
|
229 |
dropdownOpen.value = false; |
|
230 |
}; |
|
231 |
|
|
232 |
const onComplete = () => { |
|
233 |
const data = { |
|
234 |
docCode: props.docCodeS, |
|
235 |
}; |
|
236 |
pushUpdateHandle(data); |
|
237 |
}; |
|
238 |
const formRef = ref(); |
|
239 |
const submitCustomTime = () => { |
db42d0
|
240 |
formRef.value.validate().then((valid) => { |
H |
241 |
if (valid) { |
|
242 |
customTimeDropdownOpen.value = false; |
|
243 |
const date = form.date ? dayjs(form.date).format('YYYY-MM-DD') : ''; |
|
244 |
const time = form.time ? dayjs(form.time).format('HH:mm') : ''; |
|
245 |
const data = { |
|
246 |
handleTime: date + ' ' + time, |
|
247 |
docCode: props.docCodeS, |
|
248 |
}; |
|
249 |
pushUpdateHandle(data); |
|
250 |
} else { |
|
251 |
return false; |
|
252 |
} |
|
253 |
}); |
74a35f
|
254 |
}; |
H |
255 |
|
|
256 |
const cancelCustomTime = () => { |
|
257 |
customTimeDropdownOpen.value = false; |
|
258 |
dropdownOpen.value = true; |
|
259 |
}; |
|
260 |
|
|
261 |
// 处理时间格式化 |
|
262 |
const formattedTime = computed(() => |
|
263 |
props.row.handleTime ? dayjs(props.row.handleTime).format('YYYY-MM-DD HH:mm') : '', |
|
264 |
); |
|
265 |
|
|
266 |
// 日期禁用处理 |
|
267 |
const disabledDate = (currentDate) => { |
|
268 |
return currentDate && currentDate < dayjs().startOf('day'); |
|
269 |
}; |
|
270 |
|
|
271 |
function TooltipAndDropdown() {} |
|
272 |
|
|
273 |
function onSubmitCustomTime() { |
|
274 |
customTimeDropdownOpen.value = true; |
|
275 |
} |
|
276 |
</script> |
|
277 |
|
|
278 |
<style scoped lang="less"> |
|
279 |
.display-flex { |
|
280 |
display: flex; |
|
281 |
align-items: center; |
|
282 |
justify-content: space-between; |
|
283 |
} |
|
284 |
|
|
285 |
.date { |
|
286 |
display: flex; |
|
287 |
align-items: center; |
|
288 |
justify-content: space-between; |
|
289 |
} |
|
290 |
|
|
291 |
.date-left { |
|
292 |
flex-grow: 1; |
|
293 |
} |
|
294 |
|
|
295 |
.color-handle { |
|
296 |
cursor: pointer; |
|
297 |
} |
|
298 |
|
|
299 |
.date:hover { |
|
300 |
transition: all 0.2s; |
|
301 |
background-color: #0000000a; |
|
302 |
} |
|
303 |
|
|
304 |
.color-handle { |
|
305 |
color: #0a6aff; |
|
306 |
} |
|
307 |
</style> |