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