144 lines
4.9 KiB
JavaScript
144 lines
4.9 KiB
JavaScript
|
|
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,
|
|||
|
|
}
|
|||
|
|
})
|