🔥 添加自定义后缀
This commit is contained in:
parent
168013cb27
commit
4c6250b1f9
@ -1,6 +1,6 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import {SupportedTLDs} from "~/utils/domain";
|
const domainStore = useDomainStore();
|
||||||
|
const SupportedTLDs = new Set(Object.keys(domainStore.SupportedTLDs));
|
||||||
const isOpen = ref(false)
|
const isOpen = ref(false)
|
||||||
const {t} = useI18n()
|
const {t} = useI18n()
|
||||||
</script>
|
</script>
|
||||||
|
53
components/domain/Editor.vue
Normal file
53
components/domain/Editor.vue
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
<template>
|
||||||
|
<div class="px-4 space-y-4">
|
||||||
|
<div class="flex gap-2 items-center">
|
||||||
|
<UInput v-model="newDomainSuffix" @input="searchSuffix" placeholder="域名后缀,如 .cn" class="flex-grow rounded shadow transition duration-200 ease-in-out" />
|
||||||
|
<UInput v-model="newWhoisServer" placeholder="Whois服务器,如 whois.cnnic.net.cn" class="flex-grow border-gray-300 rounded shadow transition duration-200 ease-in-out" />
|
||||||
|
<UButton @click="addSuffix" type="button" :disabled="suffixExists" class="p-2 bg-blue-500 text-white rounded hover:bg-blue-700 shadow disabled:bg-gray-400 disabled:cursor-not-allowed transition duration-200 ease-in-out">添加</UButton>
|
||||||
|
</div>
|
||||||
|
<div class="text-sm" v-if="suffixExists">
|
||||||
|
<span class="text-red-500">后缀已存在</span>
|
||||||
|
</div>
|
||||||
|
<div class="overflow-auto h-64 mt-4 bg-gray-50 rounded shadow">
|
||||||
|
<div v-for="(server, suffix) in domainStore.SupportedTLDs" :key="suffix" class="flex items-center justify-between p-2 border-b border-gray-200 last:border-b-0">
|
||||||
|
<div>{{ suffix }}: {{ server }}</div>
|
||||||
|
<UButton @click="removeSuffix(suffix)" type="button" class="bg-red-500 hover:bg-red-700 text-white p-1 rounded shadow transition duration-200 ease-in-out">删除</UButton>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
const domainStore = useDomainStore();
|
||||||
|
const newDomainSuffix = ref('');
|
||||||
|
const newWhoisServer = ref('');
|
||||||
|
const suffixExists = computed(() => newDomainSuffix.value in domainStore.SupportedTLDs);
|
||||||
|
|
||||||
|
const toast = useToast()
|
||||||
|
|
||||||
|
const addSuffix = async () => {
|
||||||
|
if (newDomainSuffix.value && newWhoisServer.value && !suffixExists.value) {
|
||||||
|
await domainStore.addSuffix(newDomainSuffix.value, newWhoisServer.value);
|
||||||
|
newDomainSuffix.value = '';
|
||||||
|
newWhoisServer.value = '';
|
||||||
|
toast.add(
|
||||||
|
{ title: '添加成功' }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const removeSuffix = async (suffix: string) => {
|
||||||
|
await domainStore.removeSuffix(suffix);
|
||||||
|
toast.add(
|
||||||
|
{ title: '删除成功',
|
||||||
|
}
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const searchSuffix = () => {
|
||||||
|
// 这个方法被@input事件触发,用于即时反馈,但实际逻辑已由suffixExists处理
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
@ -1,5 +1,4 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import {SupportedTLDs} from "~/utils/domain";
|
|
||||||
import {useStyleStore} from "~/stores/style";
|
import {useStyleStore} from "~/stores/style";
|
||||||
|
|
||||||
const { t } = useI18n()
|
const { t } = useI18n()
|
||||||
@ -14,7 +13,9 @@ const router = useRouter();
|
|||||||
const runtimeConfig = useRuntimeConfig()
|
const runtimeConfig = useRuntimeConfig()
|
||||||
const localePath = useLocalePath()
|
const localePath = useLocalePath()
|
||||||
const settingsStore = useSettingsStore()
|
const settingsStore = useSettingsStore()
|
||||||
|
const domainStore = useDomainStore()
|
||||||
|
|
||||||
|
const SupportedTLDs = new Set(Object.keys(domainStore.SupportedTLDs));
|
||||||
const handleAction = async (url: any) => {
|
const handleAction = async (url: any) => {
|
||||||
if (!state.domain) return toast.add({ title: '请输入域名' })
|
if (!state.domain) return toast.add({ title: '请输入域名' })
|
||||||
let domain = trimDomain(state.domain);
|
let domain = trimDomain(state.domain);
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import {useStyleStore} from "~/stores/style";
|
import {useStyleStore} from "~/stores/style";
|
||||||
import {useSettingsStore} from "~/stores/settings";
|
import {useSettingsStore} from "~/stores/settings";
|
||||||
|
import {useDomainStore} from "~/stores/domain";
|
||||||
|
|
||||||
const styleStore = useStyleStore()
|
const styleStore = useStyleStore()
|
||||||
const settingsStore = useSettingsStore()
|
const settingsStore = useSettingsStore()
|
||||||
@ -11,6 +12,7 @@ styleStore.setIsPage(true)
|
|||||||
const {isHistory} = storeToRefs(settingsStore)
|
const {isHistory} = storeToRefs(settingsStore)
|
||||||
const isOpen = ref(false)
|
const isOpen = ref(false)
|
||||||
|
|
||||||
|
const isEditDomainOpen = ref(false)
|
||||||
|
|
||||||
const handleReset = async () => {
|
const handleReset = async () => {
|
||||||
settingsStore.setHistory(true)
|
settingsStore.setHistory(true)
|
||||||
@ -37,11 +39,61 @@ const handleReset = async () => {
|
|||||||
</UCard>
|
</UCard>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="setting">
|
||||||
|
<div class="text-2xl font-bold mt-[30px] mb-[20px]"> 后缀设置 </div>
|
||||||
|
<u-card class="set-item">
|
||||||
|
<div class="flex justify-between items-center">
|
||||||
|
<div class="text-base"> 自定义后缀 </div>
|
||||||
|
<div class="text-sm " >
|
||||||
|
自定义编辑管理添加后缀
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<u-button type="warning"
|
||||||
|
@click="isEditDomainOpen = true"
|
||||||
|
> 管理 </u-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<UModal
|
||||||
|
v-model="isEditDomainOpen"
|
||||||
|
>
|
||||||
|
<UCard
|
||||||
|
:ui="{
|
||||||
|
base: 'h-full flex flex-col',
|
||||||
|
rounded: '10',
|
||||||
|
divide: 'divide-y divide-gray-100 dark:divide-gray-800',
|
||||||
|
body: {
|
||||||
|
base: 'grow'
|
||||||
|
}
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<template #header>
|
||||||
|
<div class="flex items-center justify-between">
|
||||||
|
<h3 class="text-base font-semibold leading-6 text-gray-900 dark:text-white">
|
||||||
|
后缀管理
|
||||||
|
</h3>
|
||||||
|
<UButton
|
||||||
|
color="gray"
|
||||||
|
variant="ghost"
|
||||||
|
icon="i-heroicons-x-mark-20-solid"
|
||||||
|
class="-my-1"
|
||||||
|
type="button"
|
||||||
|
@click="isEditDomainOpen = false" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<div class="mx-auto">
|
||||||
|
<DomainEditor />
|
||||||
|
</div>
|
||||||
|
</UCard>
|
||||||
|
</UModal>
|
||||||
|
</u-card>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="setting">
|
<div class="setting">
|
||||||
<div class="text-2xl font-bold mt-[30px] mb-[20px]">{{ t('settings.linkOpenType') }}</div>
|
<div class="text-2xl font-bold mt-[30px] mb-[20px]">{{ t('settings.linkOpenType') }}</div>
|
||||||
<UCard>
|
<UCard>
|
||||||
<div class="flex justify-between items-center">
|
<div class="flex justify-between items-center">
|
||||||
<div class="text-base "> {{ t('settings.linkOpenTypeDesc') }} </div>
|
<div class="text-base "> {{ t('settings.linkOpenTypeDesc') }} </div>
|
||||||
<div>
|
<div>
|
||||||
<ClientOnly>
|
<ClientOnly>
|
||||||
<CommonLinkChange />
|
<CommonLinkChange />
|
||||||
@ -51,6 +103,7 @@ const handleReset = async () => {
|
|||||||
</UCard>
|
</UCard>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<div class="setting">
|
<div class="setting">
|
||||||
<div class="text-2xl font-bold mt-[30px] mb-[20px]"> {{ t('settings.miscellaneous') }} </div>
|
<div class="text-2xl font-bold mt-[30px] mb-[20px]"> {{ t('settings.miscellaneous') }} </div>
|
||||||
<u-card class="set-item">
|
<u-card class="set-item">
|
||||||
|
24
server/api/addSuffix.post.ts
Normal file
24
server/api/addSuffix.post.ts
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
import { defineEventHandler } from 'h3';
|
||||||
|
import fs from 'fs';
|
||||||
|
import path from 'path';
|
||||||
|
|
||||||
|
interface AddSuffixBody {
|
||||||
|
suffix: string;
|
||||||
|
server: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default defineEventHandler(async (event) => {
|
||||||
|
const body: AddSuffixBody = await readBody(event);
|
||||||
|
const filePath = path.join('server/whois/json', 'whois-servers.json');
|
||||||
|
|
||||||
|
const fileContent = fs.readFileSync(filePath, { encoding: 'utf8' });
|
||||||
|
const data: Record<string, string> = JSON.parse(fileContent);
|
||||||
|
|
||||||
|
// 添加或更新域名后缀
|
||||||
|
data[body.suffix] = body.server;
|
||||||
|
|
||||||
|
// 写入更新
|
||||||
|
fs.writeFileSync(filePath, JSON.stringify(data, null, 2), { encoding: 'utf8' });
|
||||||
|
|
||||||
|
return { message: 'ok' };
|
||||||
|
});
|
23
server/api/removeSuffix.post.ts
Normal file
23
server/api/removeSuffix.post.ts
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
import { defineEventHandler } from 'h3';
|
||||||
|
import fs from 'fs';
|
||||||
|
import path from 'path';
|
||||||
|
|
||||||
|
interface RemoveSuffixBody {
|
||||||
|
suffix: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default defineEventHandler(async (event) => {
|
||||||
|
const body: RemoveSuffixBody = await readBody(event);
|
||||||
|
const filePath = path.join('server/whois/json', 'whois-servers.json');
|
||||||
|
|
||||||
|
const fileContent = fs.readFileSync(filePath, { encoding: 'utf8' });
|
||||||
|
const data: Record<string, string> = JSON.parse(fileContent);
|
||||||
|
|
||||||
|
// 删除域名后缀
|
||||||
|
delete data[body.suffix];
|
||||||
|
|
||||||
|
// 写入更新
|
||||||
|
fs.writeFileSync(filePath, JSON.stringify(data, null, 2), { encoding: 'utf8' });
|
||||||
|
|
||||||
|
return { message: 'ok' };
|
||||||
|
});
|
@ -1533,7 +1533,6 @@
|
|||||||
"net.cn": "whois.cnnic.net.cn",
|
"net.cn": "whois.cnnic.net.cn",
|
||||||
"org.cn": "whois.cnnic.net.cn",
|
"org.cn": "whois.cnnic.net.cn",
|
||||||
"gov.cn": "whois.cnnic.net.cn",
|
"gov.cn": "whois.cnnic.net.cn",
|
||||||
"net.cn": "whois.cnnic.net.cn",
|
|
||||||
"ac.cn": "whois.cnnic.net.cn",
|
"ac.cn": "whois.cnnic.net.cn",
|
||||||
"bj.cn": "whois.cnnic.net.cn",
|
"bj.cn": "whois.cnnic.net.cn",
|
||||||
"sh.cn": "whois.cnnic.net.cn",
|
"sh.cn": "whois.cnnic.net.cn",
|
||||||
@ -1569,5 +1568,4 @@
|
|||||||
"gz.cn": "whois.cnnic.net.cn",
|
"gz.cn": "whois.cnnic.net.cn",
|
||||||
"sn.cn": "whois.cnnic.net.cn",
|
"sn.cn": "whois.cnnic.net.cn",
|
||||||
"xj.cn": "whois.cnnic.net.cn"
|
"xj.cn": "whois.cnnic.net.cn"
|
||||||
}
|
}
|
||||||
|
|
@ -6,7 +6,6 @@ import parametersData from '~/server/whois/json/parameters.json';
|
|||||||
|
|
||||||
const IANA_CHK_URL = 'https://www.iana.org/whois?q=';
|
const IANA_CHK_URL = 'https://www.iana.org/whois?q=';
|
||||||
|
|
||||||
|
|
||||||
interface IServers {
|
interface IServers {
|
||||||
[key: string]: string;
|
[key: string]: string;
|
||||||
}
|
}
|
||||||
|
49
stores/domain.ts
Normal file
49
stores/domain.ts
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
import { defineStore } from 'pinia';
|
||||||
|
import serversData from '~/server/whois/json/whois-servers.json';
|
||||||
|
|
||||||
|
// 定义接口来描述state的结构
|
||||||
|
interface DomainState {
|
||||||
|
SupportedTLDs: Record<string, string>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const useDomainStore = defineStore('domain', {
|
||||||
|
// 使用箭头函数和类型注解定义state
|
||||||
|
state: (): DomainState => ({
|
||||||
|
SupportedTLDs: { ...serversData },
|
||||||
|
}),
|
||||||
|
actions: {
|
||||||
|
async addSuffix(suffix: string, server: string) {
|
||||||
|
const response = await $fetch('/api/addSuffix', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
},
|
||||||
|
body: JSON.stringify({suffix, server}),
|
||||||
|
});
|
||||||
|
|
||||||
|
if (response.message === 'ok') {
|
||||||
|
// 更新本地状态
|
||||||
|
await nextTick();
|
||||||
|
this.SupportedTLDs[suffix] = server;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async removeSuffix(suffix: string) {
|
||||||
|
const response = await $fetch('/api/removeSuffix', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
},
|
||||||
|
body: JSON.stringify({suffix}),
|
||||||
|
});
|
||||||
|
|
||||||
|
if (response.message === 'ok') {
|
||||||
|
await nextTick();
|
||||||
|
// 更新本地状态
|
||||||
|
delete this.SupportedTLDs[suffix];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
persist:{
|
||||||
|
storage: persistedState.localStorage,
|
||||||
|
}
|
||||||
|
});
|
@ -1,2 +0,0 @@
|
|||||||
import serversData from '~/server/whois/json/whois-servers.json';
|
|
||||||
export const SupportedTLDs = new Set(Object.keys(serversData));
|
|
Loading…
x
Reference in New Issue
Block a user