🔥 添加自定义后缀
This commit is contained in:
parent
168013cb27
commit
4c6250b1f9
@ -1,6 +1,6 @@
|
||||
<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 {t} = useI18n()
|
||||
</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">
|
||||
import {SupportedTLDs} from "~/utils/domain";
|
||||
import {useStyleStore} from "~/stores/style";
|
||||
|
||||
const { t } = useI18n()
|
||||
@ -14,7 +13,9 @@ const router = useRouter();
|
||||
const runtimeConfig = useRuntimeConfig()
|
||||
const localePath = useLocalePath()
|
||||
const settingsStore = useSettingsStore()
|
||||
const domainStore = useDomainStore()
|
||||
|
||||
const SupportedTLDs = new Set(Object.keys(domainStore.SupportedTLDs));
|
||||
const handleAction = async (url: any) => {
|
||||
if (!state.domain) return toast.add({ title: '请输入域名' })
|
||||
let domain = trimDomain(state.domain);
|
||||
|
@ -1,6 +1,7 @@
|
||||
<script setup lang="ts">
|
||||
import {useStyleStore} from "~/stores/style";
|
||||
import {useSettingsStore} from "~/stores/settings";
|
||||
import {useDomainStore} from "~/stores/domain";
|
||||
|
||||
const styleStore = useStyleStore()
|
||||
const settingsStore = useSettingsStore()
|
||||
@ -11,6 +12,7 @@ styleStore.setIsPage(true)
|
||||
const {isHistory} = storeToRefs(settingsStore)
|
||||
const isOpen = ref(false)
|
||||
|
||||
const isEditDomainOpen = ref(false)
|
||||
|
||||
const handleReset = async () => {
|
||||
settingsStore.setHistory(true)
|
||||
@ -37,11 +39,61 @@ const handleReset = async () => {
|
||||
</UCard>
|
||||
</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="text-2xl font-bold mt-[30px] mb-[20px]">{{ t('settings.linkOpenType') }}</div>
|
||||
<UCard>
|
||||
<div class="flex justify-between items-center">
|
||||
<div class="text-base "> {{ t('settings.linkOpenTypeDesc') }} </div>
|
||||
<div class="text-base "> {{ t('settings.linkOpenTypeDesc') }} </div>
|
||||
<div>
|
||||
<ClientOnly>
|
||||
<CommonLinkChange />
|
||||
@ -51,6 +103,7 @@ const handleReset = async () => {
|
||||
</UCard>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="setting">
|
||||
<div class="text-2xl font-bold mt-[30px] mb-[20px]"> {{ t('settings.miscellaneous') }} </div>
|
||||
<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",
|
||||
"org.cn": "whois.cnnic.net.cn",
|
||||
"gov.cn": "whois.cnnic.net.cn",
|
||||
"net.cn": "whois.cnnic.net.cn",
|
||||
"ac.cn": "whois.cnnic.net.cn",
|
||||
"bj.cn": "whois.cnnic.net.cn",
|
||||
"sh.cn": "whois.cnnic.net.cn",
|
||||
@ -1569,5 +1568,4 @@
|
||||
"gz.cn": "whois.cnnic.net.cn",
|
||||
"sn.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=';
|
||||
|
||||
|
||||
interface IServers {
|
||||
[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