加入生成链接
This commit is contained in:
parent
68129cd5d0
commit
1880a8a135
|
@ -6,5 +6,8 @@ class getdata {
|
||||||
async text_server(url: string) {
|
async text_server(url: string) {
|
||||||
return await api.post('http://149.129.107.38:1323/textserver', { url });
|
return await api.post('http://149.129.107.38:1323/textserver', { url });
|
||||||
}
|
}
|
||||||
|
async get_country(ip: string) {
|
||||||
|
return await api.get(`https://ip.useragentinfo.com/json?ip=${ip}`);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
export { getdata };
|
export { getdata };
|
||||||
|
|
|
@ -2,12 +2,12 @@
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-12">
|
<div class="col-12">
|
||||||
<h6 style="text-align: center;margin: 1rem;">{{ props.serve.tips }} <q-icon v-show="online" title="在线"
|
<h6 style="text-align: center;margin: 1rem;">{{ props.serve.tips }} <q-icon v-show="online" title="在线"
|
||||||
name="check_circle_outline" style="color: green;" /> <q-icon v-show="!online" title="离线" name="hide_source"
|
name="check_circle_outline" style="color: green;" /> <q-icon v-show="!online" title="离线" name="highlight_off"
|
||||||
style="color: red;" /></h6>
|
style="color: red;" /></h6>
|
||||||
<q-input v-model="outtext" filled autogrow />
|
<q-input v-model="outtext" filled autogrow />
|
||||||
<div style="text-align: center;margin-top: 1rem;">
|
<div style="text-align: center;margin-top: 1rem;display: flex;justify-content: space-around;">
|
||||||
<q-btn color="white" text-color="black" @click="copy" label="复制" />
|
<q-btn color="white" text-color="black" @click="copy('link')" label="复制" />
|
||||||
|
<q-btn color="white" text-color="black" @click="copy('sub')" label="复制订阅" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -37,6 +37,7 @@ export default defineComponent({
|
||||||
setup(props) {
|
setup(props) {
|
||||||
const online = ref(false);
|
const online = ref(false);
|
||||||
const isonline = () => {
|
const isonline = () => {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||||
let obj = JSON.parse(decode(props.text!.replace('vmess://', '')));
|
let obj = JSON.parse(decode(props.text!.replace('vmess://', '')));
|
||||||
let http = props.serve.istls == 0 ? 'http' : 'https'
|
let http = props.serve.istls == 0 ? 'http' : 'https'
|
||||||
let reg = new RegExp(/\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/);
|
let reg = new RegExp(/\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/);
|
||||||
|
@ -48,6 +49,9 @@ export default defineComponent({
|
||||||
const api = new getdata;
|
const api = new getdata;
|
||||||
const $q = useQuasar()
|
const $q = useQuasar()
|
||||||
const outtext = computed(() => {
|
const outtext = computed(() => {
|
||||||
|
// eslint-disable-next-line vue/no-side-effects-in-computed-properties
|
||||||
|
online.value = false
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||||
let obj = JSON.parse(decode(props.text!.replace('vmess://', '')));
|
let obj = JSON.parse(decode(props.text!.replace('vmess://', '')));
|
||||||
obj.add = props.serve.ip
|
obj.add = props.serve.ip
|
||||||
obj.port = props.serve.port
|
obj.port = props.serve.port
|
||||||
|
@ -58,15 +62,24 @@ export default defineComponent({
|
||||||
isonline()
|
isonline()
|
||||||
return 'vmess://' + encode(JSON.stringify(obj))
|
return 'vmess://' + encode(JSON.stringify(obj))
|
||||||
})
|
})
|
||||||
const copy = () => {
|
const copy = (type: string) => {
|
||||||
|
let tmp = ''
|
||||||
// api.text_server('http://uszz.giaogiao.uk:8080/34.125.44.195').then(res => { console.log(res.data) })
|
switch (type) {
|
||||||
copyToClipboard(outtext.value)
|
case 'sub':
|
||||||
|
tmp = `http://149.129.107.38/link.php?link=${outtext.value}`
|
||||||
|
break;
|
||||||
|
case 'link':
|
||||||
|
tmp = outtext.value
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
copyToClipboard(tmp)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
// success!
|
// success!
|
||||||
$q.notify({
|
$q.notify({
|
||||||
message: '复制成功',
|
message: '复制成功',
|
||||||
color: 'purple',
|
color: 'positive',
|
||||||
position: 'top'
|
position: 'top'
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -74,7 +87,7 @@ export default defineComponent({
|
||||||
// fail
|
// fail
|
||||||
$q.notify({
|
$q.notify({
|
||||||
message: '复制失败',
|
message: '复制失败',
|
||||||
color: 'purple'
|
color: 'negative'
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,22 +1,115 @@
|
||||||
<template>
|
<template>
|
||||||
<q-layout view="hHh lpR fFf">
|
<q-layout view="hHh lpR fFf">
|
||||||
|
|
||||||
|
<q-header reveal elevated class="bg-primary text-white" height-hint="98">
|
||||||
|
<q-toolbar>
|
||||||
|
<q-btn dense flat round icon="menu" @click="toggleLeftDrawer" />
|
||||||
|
|
||||||
|
<q-toolbar-title>
|
||||||
|
<q-avatar>
|
||||||
|
<img src="https://cdn.quasar.dev/logo-v2/svg/logo-mono-white.svg">
|
||||||
|
</q-avatar>
|
||||||
|
Title
|
||||||
|
</q-toolbar-title>
|
||||||
|
</q-toolbar>
|
||||||
|
|
||||||
|
</q-header>
|
||||||
|
|
||||||
|
<q-drawer show-if-above v-model="leftDrawerOpen" side="left" bordered>
|
||||||
|
<!-- drawer content -->
|
||||||
|
<q-scroll-area class="fit">
|
||||||
|
<q-list>
|
||||||
|
|
||||||
|
<template v-for="(menuItem, index) in menuList" :key="index">
|
||||||
|
<q-item @click="topath(menuItem.path)" clickable :active="menuItem.path == now_route.name" v-ripple>
|
||||||
|
<q-item-section avatar>
|
||||||
|
<q-icon :name="menuItem.icon" />
|
||||||
|
</q-item-section>
|
||||||
|
<q-item-section>
|
||||||
|
{{ menuItem.label }}
|
||||||
|
</q-item-section>
|
||||||
|
</q-item>
|
||||||
|
<q-separator :key="'sep' + index" v-if="menuItem.separator" />
|
||||||
|
</template>
|
||||||
|
|
||||||
|
</q-list>
|
||||||
|
</q-scroll-area>
|
||||||
|
</q-drawer>
|
||||||
|
|
||||||
<q-page-container>
|
<q-page-container>
|
||||||
<router-view />
|
<router-view />
|
||||||
</q-page-container>
|
</q-page-container>
|
||||||
|
|
||||||
</q-layout>
|
</q-layout>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script>
|
||||||
import { defineComponent } from 'vue';
|
import { ref } from 'vue'
|
||||||
|
|
||||||
export default defineComponent({
|
import { useRouter } from 'vue-router'
|
||||||
name: 'MainLayout',
|
|
||||||
|
|
||||||
|
|
||||||
|
const menuList = [
|
||||||
|
{
|
||||||
|
icon: 'swap_horiz',
|
||||||
|
label: '切换加速',
|
||||||
|
path: 'home',
|
||||||
|
separator: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'link',
|
||||||
|
label: '生成链接',
|
||||||
|
path: 'createlink',
|
||||||
|
separator: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'file_download',
|
||||||
|
label: '下载程序',
|
||||||
|
separator: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'error',
|
||||||
|
label: 'Spam',
|
||||||
|
separator: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'settings',
|
||||||
|
label: 'Settings',
|
||||||
|
separator: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'feedback',
|
||||||
|
label: 'Send Feedback',
|
||||||
|
separator: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'help_outline',
|
||||||
|
iconColor: 'primary',
|
||||||
|
label: '帮助',
|
||||||
|
separator: false
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
export default {
|
||||||
setup() {
|
setup() {
|
||||||
|
const leftDrawerOpen = ref(false)
|
||||||
|
// const route = useRoute()
|
||||||
|
// const now_route = toRaw(route)
|
||||||
|
const route_p = useRouter()
|
||||||
|
const now_route = route_p.currentRoute;
|
||||||
return {
|
return {
|
||||||
|
leftDrawerOpen,
|
||||||
|
toggleLeftDrawer() {
|
||||||
|
leftDrawerOpen.value = !leftDrawerOpen.value
|
||||||
|
},
|
||||||
|
topath(path) {
|
||||||
|
route_p.push({
|
||||||
|
name: path,
|
||||||
|
})
|
||||||
|
},
|
||||||
|
menuList,
|
||||||
|
now_route
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -0,0 +1,80 @@
|
||||||
|
<template lang="">
|
||||||
|
<div>
|
||||||
|
<div class="row" style="text-align:center">
|
||||||
|
<div class="col-xs-1 col-md-4"></div>
|
||||||
|
<div class="col-xs-10 col-md-4">
|
||||||
|
<h6 style="text-align: center;margin: 1rem;">生成链接</h6>
|
||||||
|
<q-input v-model="text" filled autogrow placeholder="IP" />
|
||||||
|
<div style="height:1rem"></div>
|
||||||
|
<q-input v-model="outlink" filled autogrow />
|
||||||
|
<q-btn color="white" text-color="black" @click="copy" label="复制" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="">
|
||||||
|
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import { defineComponent, ref, watch } from 'vue';
|
||||||
|
import { getdata } from 'src/api/api'
|
||||||
|
import { decode, encode } from 'js-base64';
|
||||||
|
import { copyToClipboard, useQuasar } from 'quasar';
|
||||||
|
export default defineComponent({
|
||||||
|
name: 'CreateLink',
|
||||||
|
setup() {
|
||||||
|
const $q = useQuasar()
|
||||||
|
const api = new getdata;
|
||||||
|
const text = ref('');
|
||||||
|
const outlink = ref('');
|
||||||
|
const def_link = 'ew0KICAidiI6ICIyIiwNCiAgInBzIjogIjAiLA0KICAiYWRkIjogIjE4NS4yMTguNi4xMDgiLA0KICAicG9ydCI6ICI5MDAwIiwNCiAgImlkIjogIjJlZTU3ODA2LWY2ZTQtNDgyYS1lZjA4LTczNjBjMDRjZDNlNSIsDQogICJhaWQiOiAiMCIsDQogICJzY3kiOiAiYXV0byIsDQogICJuZXQiOiAid3MiLA0KICAidHlwZSI6ICJub25lIiwNCiAgImhvc3QiOiAiIiwNCiAgInBhdGgiOiAiLyIsDQogICJ0bHMiOiAiIiwNCiAgInNuaSI6ICIiLA0KICAiYWxwbiI6ICIiDQp9'
|
||||||
|
const is_ip = (ip: string) => {
|
||||||
|
var reg = /^(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])$/
|
||||||
|
return reg.test(ip);
|
||||||
|
}
|
||||||
|
|
||||||
|
watch(() => text.value, (newValue, oldValue) => { //直接监听
|
||||||
|
let obj = JSON.parse(decode(def_link))
|
||||||
|
console.log(newValue)
|
||||||
|
if (!is_ip(newValue)) {
|
||||||
|
outlink.value = 'erroe ip'
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
api.get_country(newValue).then(res => {
|
||||||
|
let name = res.data.country == '中国' ? res.data.province : res.data.country
|
||||||
|
obj.ps = name + newValue
|
||||||
|
obj.add = newValue
|
||||||
|
outlink.value = 'vmess://' + encode(JSON.stringify(obj))
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
return {
|
||||||
|
|
||||||
|
text,
|
||||||
|
outlink,
|
||||||
|
copy() {
|
||||||
|
copyToClipboard(outlink.value)
|
||||||
|
.then(() => {
|
||||||
|
// success!
|
||||||
|
$q.notify({
|
||||||
|
message: '复制成功',
|
||||||
|
color: 'positive',
|
||||||
|
position: 'top'
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
// fail
|
||||||
|
$q.notify({
|
||||||
|
message: '复制失败',
|
||||||
|
color: 'negative'
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
|
@ -4,7 +4,7 @@
|
||||||
<div class="col-xs-1 col-md-4"></div>
|
<div class="col-xs-1 col-md-4"></div>
|
||||||
<div class="col-xs-10 col-md-4">
|
<div class="col-xs-10 col-md-4">
|
||||||
<h6 style="text-align: center;margin: 1rem;">节点<q-icon v-show="online" title="在线" name="check_circle_outline"
|
<h6 style="text-align: center;margin: 1rem;">节点<q-icon v-show="online" title="在线" name="check_circle_outline"
|
||||||
style="color: green;" /> <q-icon v-show="!online" title="离线" name="hide_source" style="color: red;" /></h6>
|
style="color: green;" /> <q-icon v-show="!online" title="离线" name="highlight_off" style="color: red;" /></h6>
|
||||||
<q-input v-model="text" filled autogrow />
|
<q-input v-model="text" filled autogrow />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -26,8 +26,7 @@ import { server } from 'components/models';
|
||||||
import { computed, defineComponent, onMounted, ref } from 'vue';
|
import { computed, defineComponent, onMounted, ref } from 'vue';
|
||||||
import { getdata } from 'src/api/api'
|
import { getdata } from 'src/api/api'
|
||||||
import LinkItem from 'components/LinkItem.vue';
|
import LinkItem from 'components/LinkItem.vue';
|
||||||
import { b64decode } from '@waiting/base64'
|
import { decode } from 'js-base64';
|
||||||
import { encode, decode } from 'js-base64';
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: 'IndexPage',
|
name: 'IndexPage',
|
||||||
components: { LinkItem },
|
components: { LinkItem },
|
||||||
|
@ -45,6 +44,8 @@ export default defineComponent({
|
||||||
})
|
})
|
||||||
const isobj = computed(() => {
|
const isobj = computed(() => {
|
||||||
try {
|
try {
|
||||||
|
// eslint-disable-next-line vue/no-side-effects-in-computed-properties
|
||||||
|
online.value = false
|
||||||
let obj = JSON.parse(decode(text.value.replace('vmess://', '')));
|
let obj = JSON.parse(decode(text.value.replace('vmess://', '')));
|
||||||
if (obj.id != '2ee57806-f6e4-482a-ef08-7360c04cd3e5' || obj.net != 'ws') {
|
if (obj.id != '2ee57806-f6e4-482a-ef08-7360c04cd3e5' || obj.net != 'ws') {
|
||||||
return false
|
return false
|
||||||
|
@ -58,7 +59,7 @@ export default defineComponent({
|
||||||
return true
|
return true
|
||||||
})
|
})
|
||||||
const isonline = () => {
|
const isonline = () => {
|
||||||
let obj = JSON.parse(decode(text.value!.replace('vmess://', '')));
|
let obj = JSON.parse(decode(text.value?.replace('vmess://', '')));
|
||||||
let reg = new RegExp(/\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/);
|
let reg = new RegExp(/\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/);
|
||||||
let ip = obj.ps.match(reg)[0];
|
let ip = obj.ps.match(reg)[0];
|
||||||
api.text_server(`http://${ip}:9000/`).then(res => {
|
api.text_server(`http://${ip}:9000/`).then(res => {
|
||||||
|
|
|
@ -4,7 +4,7 @@ const routes: RouteRecordRaw[] = [
|
||||||
{
|
{
|
||||||
path: '/',
|
path: '/',
|
||||||
component: () => import('layouts/MainLayout.vue'),
|
component: () => import('layouts/MainLayout.vue'),
|
||||||
children: [{ path: '', component: () => import('pages/IndexPage.vue') }],
|
children: [{ path: '', name: 'home', component: () => import('pages/IndexPage.vue') }, { path: 'createlink', name: 'createlink', component: () => import('pages/CreateLink.vue') }],
|
||||||
},
|
},
|
||||||
|
|
||||||
// Always leave this as last one,
|
// Always leave this as last one,
|
||||||
|
|
|
@ -7,7 +7,7 @@ import {
|
||||||
useStore as vuexUseStore,
|
useStore as vuexUseStore,
|
||||||
} from 'vuex'
|
} from 'vuex'
|
||||||
|
|
||||||
// import example from './module-example'
|
import example from './module-example'
|
||||||
// import { ExampleStateInterface } from './module-example/state';
|
// import { ExampleStateInterface } from './module-example/state';
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -37,16 +37,16 @@ declare module '@vue/runtime-core' {
|
||||||
export const storeKey: InjectionKey<VuexStore<StateInterface>> = Symbol('vuex-key')
|
export const storeKey: InjectionKey<VuexStore<StateInterface>> = Symbol('vuex-key')
|
||||||
|
|
||||||
// Provide typings for `this.$router` inside Vuex stores
|
// Provide typings for `this.$router` inside Vuex stores
|
||||||
declare module 'vuex' {
|
declare module 'vuex' {
|
||||||
export interface Store<S> {
|
export interface Store<S> {
|
||||||
readonly $router: Router;
|
readonly $router: Router;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default store(function (/* { ssrContext } */) {
|
export default store(function (/* { ssrContext } */) {
|
||||||
const Store = createStore<StateInterface>({
|
const Store = createStore<StateInterface>({
|
||||||
modules: {
|
modules: {
|
||||||
// example
|
example
|
||||||
},
|
},
|
||||||
|
|
||||||
// enable strict mode (adds overhead!)
|
// enable strict mode (adds overhead!)
|
||||||
|
|
|
@ -3,9 +3,9 @@ import { StateInterface } from '../index';
|
||||||
import { ExampleStateInterface } from './state';
|
import { ExampleStateInterface } from './state';
|
||||||
|
|
||||||
const getters: GetterTree<ExampleStateInterface, StateInterface> = {
|
const getters: GetterTree<ExampleStateInterface, StateInterface> = {
|
||||||
someAction (/* context */) {
|
someAction(/* context */) {
|
||||||
// your code
|
// your code
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export default getters;
|
export default getters;
|
||||||
|
|
Loading…
Reference in New Issue