1+ <template >
2+ <div class =" live-proxy-selector" >
3+ <svg class =" selector-icon" viewBox =" 0 0 24 24" fill =" none" xmlns =" http://www.w3.org/2000/svg" >
4+ <path d =" M12 2L2 7l10 5 10-5-10-5z" stroke =" currentColor" stroke-width =" 2" stroke-linecap =" round" stroke-linejoin =" round" />
5+ <path d =" M2 17l10 5 10-5" stroke =" currentColor" stroke-width =" 2" stroke-linecap =" round" stroke-linejoin =" round" />
6+ <path d =" M2 12l10 5 10-5" stroke =" currentColor" stroke-width =" 2" stroke-linecap =" round" stroke-linejoin =" round" />
7+ </svg >
8+ <a-select
9+ :model-value =" currentSelection"
10+ @change =" handleSelectionChange"
11+ class =" proxy-select"
12+ size =" small"
13+ placeholder =" 选择代理播放地址"
14+ >
15+ <a-option value =" disabled" title =" 关闭代理播放功能" >代理播放:关闭</a-option >
16+ <a-option
17+ v-for =" option in proxyOptions"
18+ :key =" option.value"
19+ :value =" option.value"
20+ :title =" `${option.label}\n完整链接: ${option.url || option.value}`"
21+ >
22+ 代理播放:{{ option.label }}
23+ </a-option >
24+ </a-select >
25+ </div >
26+ </template >
27+
28+ <script setup>
29+ import { ref , onMounted , onUnmounted } from ' vue'
30+
31+ // Props
32+ const props = defineProps ({
33+ // 可以传入初始值,但组件会使用自己的存储
34+ initialValue: {
35+ type: String ,
36+ default: ' disabled'
37+ }
38+ })
39+
40+ // Emits
41+ const emit = defineEmits ([' change' ])
42+
43+ // 响应式数据
44+ const currentSelection = ref (' disabled' )
45+ const proxyOptions = ref ([])
46+
47+ // 存储键名 - 直播界面专用
48+ const LIVE_PROXY_STORAGE_KEY = ' live-proxy-selection'
49+ const GLOBAL_PROXY_HISTORY_KEY = ' address-history-proxy-play'
50+
51+ // 获取代理配置名称
52+ const getProxyName = (url ) => {
53+ if (! url) return ' 未知'
54+ const hashIndex = url .indexOf (' #' )
55+ if (hashIndex !== - 1 && hashIndex < url .length - 1 ) {
56+ return url .substring (hashIndex + 1 )
57+ }
58+ return ' 默认代理'
59+ }
60+
61+ // 加载全局代理播放地址历史记录作为选项
62+ const loadProxyOptions = () => {
63+ try {
64+ // 从全局历史记录中加载选项
65+ const addressHistory = JSON .parse (localStorage .getItem (GLOBAL_PROXY_HISTORY_KEY ) || ' []' )
66+
67+ // 清空选项
68+ proxyOptions .value = []
69+
70+ // 添加历史记录到选项中
71+ addressHistory .forEach (item => {
72+ const url = item .url || item .value || ' '
73+ if (! url) return
74+
75+ const proxyName = getProxyName (url)
76+ proxyOptions .value .push ({
77+ value: url,
78+ label: proxyName,
79+ url: url
80+ })
81+ })
82+
83+ console .log (' 直播代理选项加载完成:' , proxyOptions .value .length , ' 个选项' )
84+ } catch (error) {
85+ console .error (' 加载直播代理选项失败:' , error)
86+ }
87+ }
88+
89+ // 加载直播界面的独立选择状态
90+ const loadLiveProxySelection = () => {
91+ try {
92+ const savedSelection = localStorage .getItem (LIVE_PROXY_STORAGE_KEY )
93+ if (savedSelection && savedSelection !== ' null' ) {
94+ currentSelection .value = savedSelection
95+ } else {
96+ currentSelection .value = ' disabled'
97+ }
98+
99+ console .log (' 直播代理选择状态加载:' , currentSelection .value )
100+ } catch (error) {
101+ console .error (' 加载直播代理选择状态失败:' , error)
102+ currentSelection .value = ' disabled'
103+ }
104+ }
105+
106+ // 保存直播界面的独立选择状态
107+ const saveLiveProxySelection = (value ) => {
108+ try {
109+ localStorage .setItem (LIVE_PROXY_STORAGE_KEY , value)
110+ console .log (' 直播代理选择状态已保存:' , value)
111+ } catch (error) {
112+ console .error (' 保存直播代理选择状态失败:' , error)
113+ }
114+ }
115+
116+ // 处理选择变更
117+ const handleSelectionChange = (value ) => {
118+ currentSelection .value = value
119+
120+ // 保存到独立存储
121+ saveLiveProxySelection (value)
122+
123+ // 发送事件给父组件
124+ emit (' change' , {
125+ value: value,
126+ enabled: value !== ' disabled' ,
127+ url: value === ' disabled' ? ' ' : value
128+ })
129+
130+ console .log (' 直播代理选择已变更:' , {
131+ value: value,
132+ enabled: value !== ' disabled'
133+ })
134+ }
135+
136+ // 监听全局代理历史变化,更新选项
137+ const handleGlobalProxyHistoryChange = (event ) => {
138+ if (event .key === GLOBAL_PROXY_HISTORY_KEY ) {
139+ loadProxyOptions ()
140+ }
141+ }
142+
143+ // 监听自定义事件(用于同一页面内的历史变化)
144+ const handleAddressHistoryChanged = () => {
145+ loadProxyOptions ()
146+ }
147+
148+ // 组件挂载时初始化
149+ onMounted (() => {
150+ loadProxyOptions ()
151+ loadLiveProxySelection ()
152+
153+ // 监听localStorage变化
154+ window .addEventListener (' storage' , handleGlobalProxyHistoryChange)
155+
156+ // 监听自定义事件
157+ window .addEventListener (' addressHistoryChanged' , handleAddressHistoryChanged)
158+ })
159+
160+ // 组件卸载时清理监听器
161+ onUnmounted (() => {
162+ window .removeEventListener (' storage' , handleGlobalProxyHistoryChange)
163+ window .removeEventListener (' addressHistoryChanged' , handleAddressHistoryChanged)
164+ })
165+
166+ // 暴露方法给父组件
167+ defineExpose ({
168+ getCurrentSelection : () => currentSelection .value ,
169+ isEnabled : () => currentSelection .value !== ' disabled' ,
170+ getProxyUrl : () => currentSelection .value === ' disabled' ? ' ' : currentSelection .value ,
171+ refreshOptions: loadProxyOptions
172+ })
173+ </script >
174+
175+ <style scoped>
176+ .live-proxy-selector {
177+ display : flex ;
178+ align-items : center ;
179+ gap : 4px ;
180+ padding : 6px 10px ;
181+ border-radius : 4px ;
182+ cursor : pointer ;
183+ transition : all 0.2s ease ;
184+ background : transparent ;
185+ border : none ;
186+ font-size : 12px ;
187+ font-weight : 500 ;
188+ color : #495057 ;
189+ min-height : 28px ;
190+ position : relative ;
191+ }
192+
193+ .live-proxy-selector :hover {
194+ background : #e9ecef ;
195+ color : #212529 ;
196+ transform : translateY (-1px );
197+ }
198+
199+ .selector-icon {
200+ width : 14px ;
201+ height : 14px ;
202+ flex-shrink : 0 ;
203+ }
204+
205+ .proxy-select {
206+ border : none !important ;
207+ background : transparent !important ;
208+ box-shadow : none !important ;
209+ min-width : 120px ;
210+ }
211+
212+ .proxy-select :deep(.arco-select-view ) {
213+ border : none !important ;
214+ background : transparent !important ;
215+ padding : 0 ;
216+ font-size : 11px ;
217+ font-weight : 500 ;
218+ }
219+
220+ .proxy-select :deep(.arco-select-view-suffix ) {
221+ color : currentColor ;
222+ }
223+
224+ .proxy-select :deep(.arco-select-view-value ) {
225+ color : currentColor ;
226+ }
227+ </style >
0 commit comments