import { defineStore } from 'pinia' import { ref } from 'vue' import { ElMessage, ElMessageBox } from 'element-plus' import { getCountryName } from '@/utils/countryUtil' export const useCountryStore = defineStore('country', () => { // 状态 const countryData = ref('') // 中文国家名 const countryDataEN = ref('') // 英文国家名 const isLoading = ref(false) // 是否正在获取 const hasInitialized = ref(false) // 是否已初始化 const lastFetchTime = ref(null) // 上次获取时间 /** * 获取 IP 国家信息 * @param {Function} t - 国际化函数 * @param {boolean} showDialog - 获取失败时是否显示弹窗(默认 true,只在第一次获取时显示) */ const fetchCountryInfo = async (t, showDialog = true) => { if (isLoading.value) return isLoading.value = true try { const response = await fetch('https://ipapi.co/json/') if (!response.ok) { throw new Error('请求失败') } const data = await response.json() countryDataEN.value = data.country_name countryData.value = getCountryName(data.country) lastFetchTime.value = Date.now() hasInitialized.value = true return { success: true } } catch (error) { console.error('获取国家信息失败:', error) // 只在允许显示弹窗且未初始化时才显示 if (showDialog && !hasInitialized.value) { showCountryInputDialog(t) } return { success: false, error } } finally { isLoading.value = false } } /** * 刷新国家信息 * @param {Function} t - 国际化函数 */ const refreshCountry = async (t) => { if (isLoading.value) return try { const result = await fetchCountryInfo(t, false) // 刷新时不自动弹窗 if (result.success) { ElMessage.success(t('workbenchesSetup.refreshSuccess') || t('hostsList.refreshSuccess') || '刷新成功') } else { // 刷新失败时,给用户选择是否手动输入 ElMessageBox.confirm( t('workbenchesSetup.refreshFailed') || t('hostsList.refreshFailed') || '刷新失败,是否手动输入国家?', t('workbenchesSetup.enterCountryTitle') || t('hostsList.enterCountryTitle') || '提示', { confirmButtonText: t('workbenchesSetup.confirm') || t('hostsList.confirm') || '手动输入', cancelButtonText: t('workbenchesSetup.cancel') || t('hostsList.cancel') || '取消', type: 'warning', } ).then(() => { showCountryInputDialog(t) }).catch(() => { // 用户取消 }) } } catch (error) { ElMessage.error(t('workbenchesSetup.refreshFailed') || t('hostsList.refreshFailed') || '刷新失败') } } /** * 显示手动输入国家的弹窗 * @param {Function} t - 国际化函数 */ const showCountryInputDialog = (t) => { ElMessageBox.prompt( t('workbenchesSetup.enterCountryPrompt') || t('hostsList.enterCountryPrompt') || '由于网络原因无法自动获取国家信息,请手动输入当前网络所在国家(中文名)', t('workbenchesSetup.enterCountryTitle') || t('hostsList.enterCountryTitle') || '获取国家失败', { confirmButtonText: t('workbenchesSetup.confirm') || t('hostsList.confirm') || '确定', cancelButtonText: t('workbenchesSetup.cancel') || t('hostsList.cancel') || '取消', inputPlaceholder: t('workbenchesSetup.countryPlaceholder') || t('hostsList.countryPlaceholder') || '例如:美国、日本、英国', inputValidator: (value) => { if (!value || value.trim() === '') { return t('workbenchesSetup.countryRequired') || t('hostsList.countryRequired') || '请输入国家名称' } return true } } ).then(({ value }) => { countryData.value = value.trim() countryDataEN.value = value.trim() hasInitialized.value = true lastFetchTime.value = Date.now() ElMessage.success(t('workbenchesSetup.countrySetSuccess') || t('hostsList.countrySetSuccess') || '国家设置成功') }).catch(() => { // 用户取消输入 if (!hasInitialized.value) { countryData.value = t('workbenchesSetup.unknown') || t('hostsList.unknown') || '未知' countryDataEN.value = 'Unknown' hasInitialized.value = true } }) } /** * 初始化国家信息(只在第一次调用时获取) * @param {Function} t - 国际化函数 */ const initCountryInfo = async (t) => { if (hasInitialized.value) { return // 已经初始化过,不再重复获取 } await fetchCountryInfo(t, true) } return { // 状态 countryData, countryDataEN, isLoading, hasInitialized, lastFetchTime, // 方法 fetchCountryInfo, refreshCountry, showCountryInputDialog, initCountryInfo, } })