加入生成链接

This commit is contained in:
lingling 2023-03-20 13:54:42 +08:00
parent 68129cd5d0
commit 1880a8a135
8 changed files with 221 additions and 31 deletions

View File

@ -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 };

View File

@ -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'
}) })
}) })
} }

View File

@ -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>

80
src/pages/CreateLink.vue Normal file
View File

@ -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>

View File

@ -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 => {

View File

@ -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,

View File

@ -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!)

View File

@ -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;