Skip to content

Commit 9536e53

Browse files
author
Taois
committed
feat: 设置界面增加更多地址配置
包括直播地址和各种代理地址
1 parent 8506466 commit 9536e53

File tree

2 files changed

+909
-82
lines changed

2 files changed

+909
-82
lines changed
Lines changed: 354 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,354 @@
1+
<template>
2+
<a-popover
3+
v-model:popup-visible="visible"
4+
trigger="click"
5+
position="bottom"
6+
:content-style="{ padding: 0, maxWidth: '400px' }"
7+
>
8+
<template #content>
9+
<div class="address-history-content">
10+
<div class="history-header">
11+
<span class="history-title">历史配置</span>
12+
<span class="history-count">{{ histories.length }}/10</span>
13+
</div>
14+
15+
<div v-if="histories.length === 0" class="empty-state">
16+
<icon-history class="empty-icon" />
17+
<span class="empty-text">暂无历史配置</span>
18+
</div>
19+
20+
<div v-else class="history-list">
21+
<div
22+
v-for="(item, index) in histories"
23+
:key="index"
24+
class="history-item"
25+
@click="selectHistory(item)"
26+
>
27+
<div class="history-content">
28+
<div class="history-url">{{ item.url }}</div>
29+
<div class="history-time">{{ formatTime(item.timestamp) }}</div>
30+
</div>
31+
<a-button
32+
type="text"
33+
size="mini"
34+
class="delete-btn"
35+
@click.stop="deleteHistory(index)"
36+
>
37+
<template #icon>
38+
<icon-delete />
39+
</template>
40+
</a-button>
41+
</div>
42+
</div>
43+
44+
<div v-if="histories.length > 0" class="history-footer">
45+
<a-button
46+
type="text"
47+
size="small"
48+
@click="clearAllHistories"
49+
class="clear-all-btn"
50+
>
51+
<template #icon>
52+
<icon-delete />
53+
</template>
54+
清空全部
55+
</a-button>
56+
</div>
57+
</div>
58+
</template>
59+
60+
<a-button type="text" size="small" class="history-trigger-btn">
61+
<template #icon>
62+
<icon-history />
63+
</template>
64+
</a-button>
65+
</a-popover>
66+
</template>
67+
68+
<script setup>
69+
import { ref, computed, watch } from 'vue'
70+
import { Message } from '@arco-design/web-vue'
71+
import {
72+
IconHistory,
73+
IconDelete
74+
} from '@arco-design/web-vue/es/icon'
75+
76+
const props = defineProps({
77+
configKey: {
78+
type: String,
79+
required: true
80+
},
81+
currentValue: {
82+
type: String,
83+
default: ''
84+
}
85+
})
86+
87+
const emit = defineEmits(['select'])
88+
89+
const visible = ref(false)
90+
const histories = ref([])
91+
92+
// 获取存储键名
93+
const storageKey = computed(() => `address-history-${props.configKey}`)
94+
95+
// 加载历史记录
96+
const loadHistories = () => {
97+
try {
98+
const stored = localStorage.getItem(storageKey.value)
99+
if (stored) {
100+
histories.value = JSON.parse(stored)
101+
}
102+
} catch (error) {
103+
console.error('加载历史记录失败:', error)
104+
histories.value = []
105+
}
106+
}
107+
108+
// 保存历史记录
109+
const saveHistories = () => {
110+
try {
111+
localStorage.setItem(storageKey.value, JSON.stringify(histories.value))
112+
} catch (error) {
113+
console.error('保存历史记录失败:', error)
114+
}
115+
}
116+
117+
// 添加历史记录
118+
const addHistory = (url) => {
119+
if (!url || !url.trim()) return
120+
121+
const trimmedUrl = url.trim()
122+
123+
// 检查是否已存在
124+
const existingIndex = histories.value.findIndex(item => item.url === trimmedUrl)
125+
if (existingIndex !== -1) {
126+
// 如果已存在,移到最前面并更新时间
127+
const existing = histories.value.splice(existingIndex, 1)[0]
128+
existing.timestamp = Date.now()
129+
histories.value.unshift(existing)
130+
} else {
131+
// 添加新记录
132+
histories.value.unshift({
133+
url: trimmedUrl,
134+
timestamp: Date.now()
135+
})
136+
}
137+
138+
// 保持最多10条记录
139+
if (histories.value.length > 10) {
140+
histories.value = histories.value.slice(0, 10)
141+
}
142+
143+
saveHistories()
144+
}
145+
146+
// 选择历史记录
147+
const selectHistory = (item) => {
148+
emit('select', item.url)
149+
visible.value = false
150+
Message.success('已填充历史配置')
151+
}
152+
153+
// 删除单个历史记录
154+
const deleteHistory = (index) => {
155+
histories.value.splice(index, 1)
156+
saveHistories()
157+
Message.success('已删除历史记录')
158+
}
159+
160+
// 清空所有历史记录
161+
const clearAllHistories = () => {
162+
histories.value = []
163+
saveHistories()
164+
visible.value = false
165+
Message.success('已清空所有历史记录')
166+
}
167+
168+
// 格式化时间
169+
const formatTime = (timestamp) => {
170+
const date = new Date(timestamp)
171+
const now = new Date()
172+
const diff = now - date
173+
174+
if (diff < 60000) { // 1分钟内
175+
return '刚刚'
176+
} else if (diff < 3600000) { // 1小时内
177+
return `${Math.floor(diff / 60000)}分钟前`
178+
} else if (diff < 86400000) { // 1天内
179+
return `${Math.floor(diff / 3600000)}小时前`
180+
} else if (diff < 604800000) { // 1周内
181+
return `${Math.floor(diff / 86400000)}天前`
182+
} else {
183+
return date.toLocaleDateString()
184+
}
185+
}
186+
187+
// 监听当前值变化,自动保存到历史记录
188+
watch(() => props.currentValue, (newValue, oldValue) => {
189+
if (oldValue && oldValue.trim() && newValue !== oldValue) {
190+
addHistory(oldValue)
191+
}
192+
}, { flush: 'post' })
193+
194+
// 暴露添加历史记录的方法
195+
defineExpose({
196+
addHistory
197+
})
198+
199+
// 初始化
200+
loadHistories()
201+
</script>
202+
203+
<style scoped>
204+
.history-trigger-btn {
205+
color: var(--color-text-3);
206+
transition: all 0.3s ease;
207+
}
208+
209+
.history-trigger-btn:hover {
210+
color: var(--color-primary-6);
211+
background-color: var(--color-primary-light-1);
212+
}
213+
214+
.address-history-content {
215+
width: 380px;
216+
max-height: 400px;
217+
background: white;
218+
border-radius: 8px;
219+
overflow: hidden;
220+
}
221+
222+
.history-header {
223+
display: flex;
224+
align-items: center;
225+
justify-content: space-between;
226+
padding: 12px 16px;
227+
background: var(--color-bg-2);
228+
border-bottom: 1px solid var(--color-border-2);
229+
}
230+
231+
.history-title {
232+
font-size: 14px;
233+
font-weight: 500;
234+
color: var(--color-text-1);
235+
}
236+
237+
.history-count {
238+
font-size: 12px;
239+
color: var(--color-text-3);
240+
background: var(--color-fill-2);
241+
padding: 2px 6px;
242+
border-radius: 4px;
243+
}
244+
245+
.empty-state {
246+
display: flex;
247+
flex-direction: column;
248+
align-items: center;
249+
justify-content: center;
250+
padding: 40px 20px;
251+
color: var(--color-text-3);
252+
}
253+
254+
.empty-icon {
255+
font-size: 32px;
256+
margin-bottom: 8px;
257+
opacity: 0.5;
258+
}
259+
260+
.empty-text {
261+
font-size: 14px;
262+
}
263+
264+
.history-list {
265+
max-height: 300px;
266+
overflow-y: auto;
267+
}
268+
269+
.history-item {
270+
display: flex;
271+
align-items: center;
272+
padding: 12px 16px;
273+
cursor: pointer;
274+
transition: all 0.2s ease;
275+
border-bottom: 1px solid var(--color-border-3);
276+
}
277+
278+
.history-item:hover {
279+
background: var(--color-bg-2);
280+
}
281+
282+
.history-item:last-child {
283+
border-bottom: none;
284+
}
285+
286+
.history-content {
287+
flex: 1;
288+
min-width: 0;
289+
margin-right: 8px;
290+
}
291+
292+
.history-url {
293+
font-size: 13px;
294+
color: var(--color-text-1);
295+
word-break: break-all;
296+
line-height: 1.4;
297+
margin-bottom: 4px;
298+
}
299+
300+
.history-time {
301+
font-size: 11px;
302+
color: var(--color-text-3);
303+
}
304+
305+
.delete-btn {
306+
color: var(--color-text-4);
307+
opacity: 0;
308+
transition: all 0.2s ease;
309+
}
310+
311+
.history-item:hover .delete-btn {
312+
opacity: 1;
313+
}
314+
315+
.delete-btn:hover {
316+
color: var(--color-danger-6);
317+
background-color: var(--color-danger-light-1);
318+
}
319+
320+
.history-footer {
321+
padding: 8px 16px;
322+
background: var(--color-bg-1);
323+
border-top: 1px solid var(--color-border-2);
324+
text-align: center;
325+
}
326+
327+
.clear-all-btn {
328+
color: var(--color-text-3);
329+
font-size: 12px;
330+
}
331+
332+
.clear-all-btn:hover {
333+
color: var(--color-danger-6);
334+
background-color: var(--color-danger-light-1);
335+
}
336+
337+
/* 滚动条样式 */
338+
.history-list::-webkit-scrollbar {
339+
width: 4px;
340+
}
341+
342+
.history-list::-webkit-scrollbar-track {
343+
background: var(--color-bg-2);
344+
}
345+
346+
.history-list::-webkit-scrollbar-thumb {
347+
background: var(--color-border-3);
348+
border-radius: 2px;
349+
}
350+
351+
.history-list::-webkit-scrollbar-thumb:hover {
352+
background: var(--color-border-2);
353+
}
354+
</style>

0 commit comments

Comments
 (0)