Skip to content

Commit

Permalink
ipinfo
Browse files Browse the repository at this point in the history
  • Loading branch information
ljxi committed Jun 10, 2024
1 parent 0fe3508 commit 3e9a9ca
Show file tree
Hide file tree
Showing 3 changed files with 112 additions and 117 deletions.
4 changes: 2 additions & 2 deletions .env
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
VITE_API_URL = //app.ljxnet.cn/network-panel/
VITE_API_URL_ = http://127.0.0.1:8000/
VITE_API_URL_ = //app.ljxnet.cn/network-panel/
VITE_API_URL = http://192.168.31.246:8000/
1 change: 0 additions & 1 deletion src/assets/CountryCode.json

This file was deleted.

224 changes: 110 additions & 114 deletions src/components/IPinfo.vue
Original file line number Diff line number Diff line change
@@ -1,176 +1,172 @@
<template>
<div class="radius card"
:style="{borderRadius:`var(--el-border-radius-round)`}">
<div class="radius card" :style="{ borderRadius: `var(--el-border-radius-round)` }">
<div style="text-align: center;">
<transition name="el-fade-in">
<div v-loading="!info.localInfo" v-if="!info.localInfo || info.localInfo['isChinaMainland']" >
<el-tooltip class="item" effect="dark" :content="info.localInfo?info.localInfo['ip']:'Loading...'" placement="top">
<div @click="copy(info.localInfo?info.localInfo['ip']:'')">
<el-tag style="width: 50px;" class="ml-2" type="success">{{ info.localLay?info.localLay+"ms":"-ms" }}</el-tag>
<el-text style="cursor: pointer;margin-left: 5px;white-space:nowrap;vertical-align: -1px;" class="font-background">{{ info.localInfo?info.localInfo['province'] + ' ' + info.localInfo['city'] + ' ' + info.localInfo['area'] + ' ' + info.localInfo['isp']:"Loading..." }}</el-text>
</div>
</el-tooltip>
</div>
</transition>
<transition name="el-fade-in">
<div v-loading="!info.globalInfo" v-if="(info.localInfo && info.localInfo['isChinaMainland'] && !info.globalInfo) || (info.globalInfo && info.globalInfo['country']!='中国')" >
<el-tooltip class="item" effect="dark" :content="info.globalInfo?info.globalInfo['ip']:'Loading...'" placement="top">
<div @click="copy(info.globalInfo?info.globalInfo['ip']:'')">
<el-tag style="width: 50px;" class="ml-2" type="success">{{ info.globalLay?info.globalLay+"ms":"-ms" }}</el-tag>
<el-text style="cursor: pointer;margin-left: 5px;white-space:nowrap;vertical-align: -3px;" class="font-background">{{ info.globalInfo?info.globalInfo['country']:"" }}</el-text>
<el-text style="cursor: pointer;margin-left: 5px;white-space:nowrap;vertical-align: -3px;" class="font-background">{{ info.globalInfo?info.globalInfo['isp']:"" }}</el-text>
</div>
</el-tooltip>
</div>
</transition>
<transition name="el-fade-in">
<div v-if="ipInfo.local && ipInfo.local.country && ipInfo.local.country.code == 'CN'">
<el-tooltip class="item" effect="dark" :content="ipInfo.local.ip" placement="top">
<div @click="copy(ipInfo.local.ip)">
<el-tag style="width: 50px;" class="ml-2" type="success">{{
ipInfo.layLocal?ipInfo.layLocal+"ms":"-ms" }}</el-tag>
<el-text style="cursor: pointer;margin-left: 5px;white-space:nowrap;vertical-align: -1px;"
class="font-background">{{ ipInfo.local.show.join(" ") }}</el-text>
</div>
</el-tooltip>
</div>
</transition>
<transition name="el-fade-in">
<div v-if="ipInfo.cloudflare && ipInfo.cloudflare.country && ipInfo.cloudflare.country.code != 'CN'">
<el-tooltip class="item" effect="dark" :content="ipInfo.cloudflare.ip" placement="top">
<div @click="copy(ipInfo.cloudflare.ip)">
<el-tag style="width: 50px;" class="ml-2" type="success">{{
ipInfo.layCloudflare?ipInfo.layCloudflare+"ms":"-ms" }}</el-tag>
<el-text style="cursor: pointer;margin-left: 5px;white-space:nowrap;vertical-align: -1px;"
class="font-background">{{ ipInfo.cloudflare.show.join(" ") }}</el-text>
</div>
</el-tooltip>
</div>
</transition>
<transition name="el-fade-in">
<div v-if="!ipInfo.local && !ipInfo.cloudflare" v-loading="true">
<el-tooltip class="item" effect="dark" content="" placement="top">
<div>
<el-text style="cursor: pointer;margin-left: 5px;white-space:nowrap;vertical-align: -1px;"
class="font-background">正在加载...</el-text>
</div>
</el-tooltip>
</div>
</transition>
</div>
</div>
</template>

<script lang="ts" setup>
const props = defineProps({
isVisible: Boolean
})
import CountryCode from "../assets/CountryCode.json"
import { reactive,watchEffect } from 'vue'
import { reactive } from 'vue'
import { ElMessage } from 'element-plus'
import { toClipboard } from '@soerenmartius/vue3-clipboard'
const info=reactive({
localInfo:null,
globalInfo:null,
localLay:0,
globalLay:0,
})
const ip_cache=reactive(JSON.parse(localStorage.getItem("ip_cache")||"{}"))
watchEffect(()=>{
localStorage.setItem("ip_cache",JSON.stringify(ip_cache))
})
const copy=(ip:string)=>{
const ipInfo: {local:any, cloudflare:any,layLocal:any,layCloudflare:any} = reactive({local:null, cloudflare:null,layLocal:null,layCloudflare:null})
const copy = (ip: string) => {
toClipboard(ip)
ElMessage.success({
dangerouslyUseHTMLString: true,
message: `已经复制IP地址:<br><strong>${ip}</strong>`,
})
}
const provinceMatch=(str:string)=>{
const ChinaMainland=['内蒙古','黑龙江','河北','山西','吉林','辽宁','江苏','浙江','安徽','福建','江西','山东','河南','湖北','湖南','广东','海南','四川','贵州','云南','陕西','甘肃','青海','广西','西藏','宁夏','新疆','北京','天津','上海','重庆']
for(let i in ChinaMainland)if(str.includes(ChinaMainland[i]))return ChinaMainland[i]
return null
}
async function getLocalIp() {
async function queryIp(ip: string) {
try {
const rsp = await fetch(import.meta.env.VITE_API_URL+"ip.ajax", {
const rsp = await fetch(import.meta.env.VITE_API_URL + "ip.ajax?ip=" + ip, {
method: "GET",
mode: "cors",
redirect: "follow",
referrerPolicy: "no-referrer"
});
let resp = await rsp.json();
let localInfo:any={
ip:resp['data']['ip'],
isp:resp['data']['isp'],
isChinaMainland:provinceMatch(resp['data']['province'])?true:false,
province:provinceMatch(resp['data']['province']),
city:resp['data']['city'].replace(/$/, ""),
area:resp['data']['districts'],
}
return localInfo
return resp['data']
} catch (error) {
throw "获取本地IP失败"
throw "查询IP信息失败"
}
}
async function cacheCtr(ip_addr:string){
let ret=ip_cache[ip_addr]
if(!ret || new Date().getTime()/1000-ret['time']>60*60*24*30){
ret=await getLocalIp()
ret['time']=new Date().getTime()/1000
ip_cache[ip_addr]=ret
async function cachedQuery(ip: string) {
let ret = JSON.parse(localStorage.getItem("cache_ip_"+ip) || "{}")
if (!ret.ip || new Date().getTime() / 1000 - ret.time > 60 * 60 * 24){
ret = await queryIp(ip)
ret['time'] = new Date().getTime() / 1000
localStorage.setItem("cache_ip_"+ip, JSON.stringify(ret))
}
return ret
}
const nullInfo:any={
"ip": "127.0.0.1",
"isp": "获取失败",
"isChinaMainland": true,
"province": "",
"city": "",
"area": ""
}
async function watchLocalIp() {
if(props.isVisible){
async function handleIP(ip: string) {
const info = await cachedQuery(ip)
info.show = info.regions_short || info.regions || []
if (info.country && info.country.code != "CN") {
info.show = [info.country.name, ...info.show]
}
if (info.as) {
info.show.push(info.as.info || info.as.name)
}
if (info.type) {
info.show.push(info.type)
}
return info
}
(async function watchLocalIp() {
if (props.isVisible) {
try {
const response = await fetch('https://forge.speedtest.cn/api/location/info', { referrerPolicy: 'no-referrer' });
let resp = await response.json();
let localInfo:any=await cacheCtr(resp['ip'])
info['localInfo']=localInfo
ipInfo.local = await handleIP(resp['ip'])
} catch (error) {
if(error=='获取本地IP失败'){
info['localInfo']=nullInfo
return
}
console.log(error)
info['localInfo']=null
}
}
setTimeout(watchLocalIp,info['localInfo']?5000:1000)
}
async function getGlobalIp() {
if(props.isVisible){
setTimeout(watchLocalIp, 5000)
})();
const watchCloudflare = async(host: string) => {
if (props.isVisible) {
try {
const response = await fetch('https://api-ipv4.ip.sb/geoip', { referrerPolicy: 'no-referrer' });
let resp = await response.json();
let globalInfo:any={
ip:resp['ip'],
isp:resp['isp'],
country:CountryCode[resp['country_code'] as keyof typeof CountryCode],
var start_timestamp = new Date().getTime();
const response = await fetch(`https://${host}/cdn-cgi/trace`, { referrerPolicy: 'no-referrer' });
const lay = new Date().getTime() - start_timestamp;
let resp = await response.text();
let ip = resp.match(/ip=([0-9a-f.:]+)/);
if (ip) {
ipInfo.cloudflare = await handleIP(ip[1])
ipInfo.layCloudflare = lay
}
info['globalInfo']=globalInfo
} catch (error) {
info['globalInfo']=null
console.log(error)
}
}
setTimeout(getGlobalIp, info['globalInfo']?5000:1000)
setTimeout(watchCloudflare, 1000, host)
}
watchLocalIp()
getGlobalIp()
async function get_lay(url:string,type:'localLay'|'globalLay') {
if(props.isVisible){
watchCloudflare("cp.cloudflare.com")
// watchCloudflare("chat.openai.com")
;(async function getCNLay() {
if (props.isVisible) {
try {
var start_timestamp = new Date().getTime();
await fetch(url, { method: "HEAD", cache: "no-store", mode: 'no-cors', referrerPolicy: 'no-referrer' });
info[type] = new Date().getTime() - start_timestamp;
await fetch("https://connectivitycheck.platform.hicloud.com/generate_204",
{ method: "HEAD", cache: "no-store", mode: 'no-cors', referrerPolicy: 'no-referrer' });
ipInfo.layLocal = new Date().getTime() - start_timestamp
} catch (error) {
info[type]=0
ipInfo.layLocal = 0
}
}
setTimeout(get_lay, 1000,url,type)
}
get_lay('https://connectivitycheck.platform.hicloud.com/generate_204','localLay')
get_lay('https://cp.cloudflare.com/','globalLay')
setTimeout(getCNLay, 1000)
})();
</script>

<style scoped>
.font-background{
color: #344357;
font-size: 14px;
.font-background {
color: #344357;
font-size: 14px;
}
.card{
.card {
max-width: 800px;
height:fit-content;
height: fit-content;
display: block;
margin:0 auto;
background-color:#ffffff;
padding:2%
margin: 0 auto;
background-color: #ffffff;
padding: 2%
}
@media (prefers-color-scheme: dark) {
.card {
background-color:rgb(18,18,18);
background-color: rgb(18, 18, 18);
}
.font-background{
color: rgb(193,206,230);
.font-background {
color: rgb(193, 206, 230);
}
}
</style>

0 comments on commit 3e9a9ca

Please sign in to comment.