mirror of https://github.com/halo-dev/halo
feat: add strategy setting for post slug generation (#4551)
#### What type of PR is this? /kind improvement #### What this PR does / why we need it: 添加文章别名自动生成策略 #### Which issue(s) this PR fixes: Fixes https://github.com/halo-dev/halo/issues/1790 #### Special notes for your reviewer: 需要后端提供支持在globalInfo里面添加`gSlugMode`字段。它的类型为(后续可能会支持更多的模式) <img width="582" alt="image" src="https://github.com/halo-dev/halo/assets/110895612/586c4742-6172-4bbc-a601-ca04c2a9a281"> #### Does this PR introduce a user-facing change? ```release-note 文章支持多别名生成策略。 ```pull/4587/head
parent
31675dbbba
commit
e13563bad0
|
@ -79,6 +79,7 @@ public class SystemSetting {
|
|||
Integer categoryPageSize;
|
||||
Integer tagPageSize;
|
||||
Boolean review;
|
||||
String slugGenerationStrategy;
|
||||
}
|
||||
|
||||
@Data
|
||||
|
|
|
@ -53,6 +53,7 @@ public class GlobalInfoEndpoint {
|
|||
handleCommentSetting(info, configMap);
|
||||
handleUserSetting(info, configMap);
|
||||
handleBasicSetting(info, configMap);
|
||||
handlePostSlugGenerationStrategy(info, configMap);
|
||||
}));
|
||||
|
||||
return info;
|
||||
|
@ -81,6 +82,8 @@ public class GlobalInfoEndpoint {
|
|||
|
||||
private boolean dataInitialized;
|
||||
|
||||
private String postSlugGenerationStrategy;
|
||||
|
||||
private List<SocialAuthProvider> socialAuthProviders;
|
||||
}
|
||||
|
||||
|
@ -123,6 +126,13 @@ public class GlobalInfoEndpoint {
|
|||
}
|
||||
}
|
||||
|
||||
private void handlePostSlugGenerationStrategy(GlobalInfo info, ConfigMap configMap) {
|
||||
var post = SystemSetting.get(configMap, SystemSetting.Post.GROUP, SystemSetting.Post.class);
|
||||
if (post != null) {
|
||||
info.setPostSlugGenerationStrategy(post.getSlugGenerationStrategy());
|
||||
}
|
||||
}
|
||||
|
||||
private void handleBasicSetting(GlobalInfo info, ConfigMap configMap) {
|
||||
var basic = SystemSetting.get(configMap, Basic.GROUP, Basic.class);
|
||||
if (basic != null) {
|
||||
|
|
|
@ -31,7 +31,8 @@ data:
|
|||
"postPageSize": 10,
|
||||
"archivePageSize": 10,
|
||||
"categoryPageSize": 10,
|
||||
"tagPageSize": 10
|
||||
"tagPageSize": 10,
|
||||
"slugGenerationStrategy": "generateByTitle"
|
||||
}
|
||||
comment: |
|
||||
{
|
||||
|
@ -42,4 +43,4 @@ data:
|
|||
menu: |
|
||||
{
|
||||
"primary": "primary"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -55,6 +55,19 @@ spec:
|
|||
min: 1
|
||||
max: 100
|
||||
validation: required
|
||||
- $formkit: select
|
||||
label: "别名生成策略"
|
||||
name: slugGenerationStrategy
|
||||
value: 'generateByTitle'
|
||||
options:
|
||||
- label: '根据标题'
|
||||
value: 'generateByTitle'
|
||||
- label: '时间戳'
|
||||
value: 'timestamp'
|
||||
- label: 'Short UUID'
|
||||
value: 'shortUUID'
|
||||
- label: 'UUID'
|
||||
value: 'UUID'
|
||||
- group: seo
|
||||
label: SEO 设置
|
||||
formSchema:
|
||||
|
|
|
@ -92,6 +92,7 @@
|
|||
"pinia": "^2.1.6",
|
||||
"pretty-bytes": "^6.0.0",
|
||||
"qs": "^6.11.1",
|
||||
"short-unique-id": "^5.0.2",
|
||||
"transliteration": "^2.3.5",
|
||||
"vue": "^3.3.4",
|
||||
"vue-demi": "^0.14.5",
|
||||
|
|
|
@ -182,6 +182,9 @@ importers:
|
|||
qs:
|
||||
specifier: ^6.11.1
|
||||
version: 6.11.1
|
||||
short-unique-id:
|
||||
specifier: ^5.0.2
|
||||
version: 5.0.2
|
||||
transliteration:
|
||||
specifier: ^2.3.5
|
||||
version: 2.3.5
|
||||
|
@ -782,6 +785,7 @@ packages:
|
|||
/@babel/plugin-proposal-async-generator-functions@7.19.1(@babel/core@7.20.12):
|
||||
resolution: {integrity: sha512-0yu8vNATgLy4ivqMNBIwb1HebCelqN7YX8SL3FDXORv/RqT0zEEWUCH4GH44JsSrvCu6GqnAdR5EBFAPeNBB4Q==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
deprecated: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-async-generator-functions instead.
|
||||
peerDependencies:
|
||||
'@babel/core': ^7.0.0-0
|
||||
dependencies:
|
||||
|
@ -797,6 +801,7 @@ packages:
|
|||
/@babel/plugin-proposal-class-properties@7.18.6(@babel/core@7.20.12):
|
||||
resolution: {integrity: sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
deprecated: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-class-properties instead.
|
||||
peerDependencies:
|
||||
'@babel/core': ^7.0.0-0
|
||||
dependencies:
|
||||
|
@ -810,6 +815,7 @@ packages:
|
|||
/@babel/plugin-proposal-class-static-block@7.18.6(@babel/core@7.20.12):
|
||||
resolution: {integrity: sha512-+I3oIiNxrCpup3Gi8n5IGMwj0gOCAjcJUSQEcotNnCCPMEnixawOQ+KeJPlgfjzx+FKQ1QSyZOWe7wmoJp7vhw==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
deprecated: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-class-static-block instead.
|
||||
peerDependencies:
|
||||
'@babel/core': ^7.12.0
|
||||
dependencies:
|
||||
|
@ -824,6 +830,7 @@ packages:
|
|||
/@babel/plugin-proposal-dynamic-import@7.18.6(@babel/core@7.20.12):
|
||||
resolution: {integrity: sha512-1auuwmK+Rz13SJj36R+jqFPMJWyKEDd7lLSdOj4oJK0UTgGueSAtkrCvz9ewmgyU/P941Rv2fQwZJN8s6QruXw==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
deprecated: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-dynamic-import instead.
|
||||
peerDependencies:
|
||||
'@babel/core': ^7.0.0-0
|
||||
dependencies:
|
||||
|
@ -835,6 +842,7 @@ packages:
|
|||
/@babel/plugin-proposal-export-namespace-from@7.18.9(@babel/core@7.20.12):
|
||||
resolution: {integrity: sha512-k1NtHyOMvlDDFeb9G5PhUXuGj8m/wiwojgQVEhJ/fsVsMCpLyOP4h0uGEjYJKrRI+EVPlb5Jk+Gt9P97lOGwtA==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
deprecated: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-export-namespace-from instead.
|
||||
peerDependencies:
|
||||
'@babel/core': ^7.0.0-0
|
||||
dependencies:
|
||||
|
@ -846,6 +854,7 @@ packages:
|
|||
/@babel/plugin-proposal-json-strings@7.18.6(@babel/core@7.20.12):
|
||||
resolution: {integrity: sha512-lr1peyn9kOdbYc0xr0OdHTZ5FMqS6Di+H0Fz2I/JwMzGmzJETNeOFq2pBySw6X/KFL5EWDjlJuMsUGRFb8fQgQ==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
deprecated: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-json-strings instead.
|
||||
peerDependencies:
|
||||
'@babel/core': ^7.0.0-0
|
||||
dependencies:
|
||||
|
@ -857,6 +866,7 @@ packages:
|
|||
/@babel/plugin-proposal-logical-assignment-operators@7.18.9(@babel/core@7.20.12):
|
||||
resolution: {integrity: sha512-128YbMpjCrP35IOExw2Fq+x55LMP42DzhOhX2aNNIdI9avSWl2PI0yuBWarr3RYpZBSPtabfadkH2yeRiMD61Q==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
deprecated: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-logical-assignment-operators instead.
|
||||
peerDependencies:
|
||||
'@babel/core': ^7.0.0-0
|
||||
dependencies:
|
||||
|
@ -868,6 +878,7 @@ packages:
|
|||
/@babel/plugin-proposal-nullish-coalescing-operator@7.18.6(@babel/core@7.20.12):
|
||||
resolution: {integrity: sha512-wQxQzxYeJqHcfppzBDnm1yAY0jSRkUXR2z8RePZYrKwMKgMlE8+Z6LUno+bd6LvbGh8Gltvy74+9pIYkr+XkKA==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
deprecated: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-nullish-coalescing-operator instead.
|
||||
peerDependencies:
|
||||
'@babel/core': ^7.0.0-0
|
||||
dependencies:
|
||||
|
@ -879,6 +890,7 @@ packages:
|
|||
/@babel/plugin-proposal-numeric-separator@7.18.6(@babel/core@7.20.12):
|
||||
resolution: {integrity: sha512-ozlZFogPqoLm8WBr5Z8UckIoE4YQ5KESVcNudyXOR8uqIkliTEgJ3RoketfG6pmzLdeZF0H/wjE9/cCEitBl7Q==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
deprecated: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-numeric-separator instead.
|
||||
peerDependencies:
|
||||
'@babel/core': ^7.0.0-0
|
||||
dependencies:
|
||||
|
@ -890,6 +902,7 @@ packages:
|
|||
/@babel/plugin-proposal-object-rest-spread@7.18.9(@babel/core@7.20.12):
|
||||
resolution: {integrity: sha512-kDDHQ5rflIeY5xl69CEqGEZ0KY369ehsCIEbTGb4siHG5BE9sga/T0r0OUwyZNLMmZE79E1kbsqAjwFCW4ds6Q==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
deprecated: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-object-rest-spread instead.
|
||||
peerDependencies:
|
||||
'@babel/core': ^7.0.0-0
|
||||
dependencies:
|
||||
|
@ -904,6 +917,7 @@ packages:
|
|||
/@babel/plugin-proposal-optional-catch-binding@7.18.6(@babel/core@7.20.12):
|
||||
resolution: {integrity: sha512-Q40HEhs9DJQyaZfUjjn6vE8Cv4GmMHCYuMGIWUnlxH6400VGxOuwWsPt4FxXxJkC/5eOzgn0z21M9gMT4MOhbw==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
deprecated: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-optional-catch-binding instead.
|
||||
peerDependencies:
|
||||
'@babel/core': ^7.0.0-0
|
||||
dependencies:
|
||||
|
@ -915,6 +929,7 @@ packages:
|
|||
/@babel/plugin-proposal-optional-chaining@7.18.9(@babel/core@7.20.12):
|
||||
resolution: {integrity: sha512-v5nwt4IqBXihxGsW2QmCWMDS3B3bzGIk/EQVZz2ei7f3NJl8NzAJVvUmpDW5q1CRNY+Beb/k58UAH1Km1N411w==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
deprecated: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-optional-chaining instead.
|
||||
peerDependencies:
|
||||
'@babel/core': ^7.0.0-0
|
||||
dependencies:
|
||||
|
@ -927,6 +942,7 @@ packages:
|
|||
/@babel/plugin-proposal-private-methods@7.18.6(@babel/core@7.20.12):
|
||||
resolution: {integrity: sha512-nutsvktDItsNn4rpGItSNV2sz1XwS+nfU0Rg8aCx3W3NOKVzdMjJRu0O5OkgDp3ZGICSTbgRpxZoWsxoKRvbeA==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
deprecated: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-private-methods instead.
|
||||
peerDependencies:
|
||||
'@babel/core': ^7.0.0-0
|
||||
dependencies:
|
||||
|
@ -940,6 +956,7 @@ packages:
|
|||
/@babel/plugin-proposal-private-property-in-object@7.18.6(@babel/core@7.20.12):
|
||||
resolution: {integrity: sha512-9Rysx7FOctvT5ouj5JODjAFAkgGoudQuLPamZb0v1TGLpapdNaftzifU8NTWQm0IRjqoYypdrSmyWgkocDQ8Dw==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
deprecated: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-private-property-in-object instead.
|
||||
peerDependencies:
|
||||
'@babel/core': ^7.0.0-0
|
||||
dependencies:
|
||||
|
@ -955,6 +972,7 @@ packages:
|
|||
/@babel/plugin-proposal-unicode-property-regex@7.18.6(@babel/core@7.20.12):
|
||||
resolution: {integrity: sha512-2BShG/d5yoZyXZfVePH91urL5wTG6ASZU9M4o03lKK8u8UW1y08OMttBSOADTcJrnPMpvDXRG3G8fyLh4ovs8w==}
|
||||
engines: {node: '>=4'}
|
||||
deprecated: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-unicode-property-regex instead.
|
||||
peerDependencies:
|
||||
'@babel/core': ^7.0.0-0
|
||||
dependencies:
|
||||
|
@ -10168,6 +10186,11 @@ packages:
|
|||
vscode-textmate: 5.2.0
|
||||
dev: true
|
||||
|
||||
/short-unique-id@5.0.2:
|
||||
resolution: {integrity: sha512-4wZq1VLV4hsEx8guP5bN7XnY8UDsVXtdUDWFMP1gvEieAXolq5fWGKpuua21PRXaLn3OybTKFQNm7JGcHSWu/Q==}
|
||||
hasBin: true
|
||||
dev: false
|
||||
|
||||
/side-channel@1.0.4:
|
||||
resolution: {integrity: sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==}
|
||||
dependencies:
|
||||
|
|
|
@ -1,26 +1,63 @@
|
|||
import { slugify } from "transliteration";
|
||||
import { watch, type Ref } from "vue";
|
||||
import ShortUniqueId from "short-unique-id";
|
||||
import { FormType } from "@/types/slug";
|
||||
import { useGlobalInfoStore } from "@/stores/global-info";
|
||||
import { randomUUID } from "@/utils/id";
|
||||
const uid = new ShortUniqueId();
|
||||
const Strategy = {
|
||||
generateByTitle: (value: string) => {
|
||||
if (!value) return "";
|
||||
return slugify(value, { trim: true });
|
||||
},
|
||||
shortUUID: (value: string) => {
|
||||
if (!value) return "";
|
||||
return uid.randomUUID(8);
|
||||
},
|
||||
UUID: (value: string) => {
|
||||
if (!value) return "";
|
||||
return randomUUID();
|
||||
},
|
||||
timestamp: (value: string) => {
|
||||
if (!value) return "";
|
||||
return new Date().getTime().toString();
|
||||
},
|
||||
};
|
||||
|
||||
const onceList = ["shortUUID", "UUID", "timestamp"];
|
||||
|
||||
export default function useSlugify(
|
||||
source: Ref<string>,
|
||||
target: Ref<string>,
|
||||
auto: Ref<boolean>
|
||||
auto: Ref<boolean>,
|
||||
formType: FormType
|
||||
) {
|
||||
watch(
|
||||
() => source.value,
|
||||
() => {
|
||||
if (auto.value) {
|
||||
handleGenerateSlug();
|
||||
handleGenerateSlug(false, formType);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
const handleGenerateSlug = () => {
|
||||
if (!source.value) {
|
||||
const handleGenerateSlug = (forceUpdate = false, formType: FormType) => {
|
||||
const globalInfoStore = useGlobalInfoStore();
|
||||
const mode = globalInfoStore.globalInfo?.postSlugGenerationStrategy;
|
||||
|
||||
if (!mode) {
|
||||
return;
|
||||
}
|
||||
target.value = slugify(source.value, {
|
||||
trim: true,
|
||||
});
|
||||
if (formType != FormType.POST) {
|
||||
target.value = Strategy["generateByTitle"](source.value);
|
||||
return;
|
||||
}
|
||||
if (forceUpdate) {
|
||||
target.value = Strategy[mode](source.value);
|
||||
return;
|
||||
}
|
||||
if (onceList.includes(mode) && target.value) return;
|
||||
target.value = Strategy[mode](source.value);
|
||||
};
|
||||
|
||||
return {
|
||||
|
|
|
@ -19,6 +19,7 @@ import AnnotationsForm from "@/components/form/AnnotationsForm.vue";
|
|||
import useSlugify from "@/composables/use-slugify";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { usePageUpdateMutate } from "../composables/use-page-update-mutate";
|
||||
import { FormType } from "@/types/slug";
|
||||
|
||||
const initialFormState: SinglePage = {
|
||||
spec: {
|
||||
|
@ -277,7 +278,8 @@ const { handleGenerateSlug } = useSlugify(
|
|||
formState.value.spec.slug = value;
|
||||
},
|
||||
}),
|
||||
computed(() => !isUpdateMode.value)
|
||||
computed(() => !isUpdateMode.value),
|
||||
FormType.SINGLE_PAGE
|
||||
);
|
||||
</script>
|
||||
|
||||
|
@ -331,7 +333,7 @@ const { handleGenerateSlug } = useSlugify(
|
|||
$t('core.page.settings.fields.slug.refresh_message')
|
||||
"
|
||||
class="group flex h-full cursor-pointer items-center border-l px-3 transition-all hover:bg-gray-100"
|
||||
@click="handleGenerateSlug"
|
||||
@click="handleGenerateSlug(true, FormType.SINGLE_PAGE)"
|
||||
>
|
||||
<IconRefreshLine
|
||||
class="h-4 w-4 text-gray-500 group-hover:text-gray-700"
|
||||
|
|
|
@ -24,6 +24,7 @@ import { useThemeCustomTemplates } from "@/modules/interface/themes/composables/
|
|||
import AnnotationsForm from "@/components/form/AnnotationsForm.vue";
|
||||
import useSlugify from "@/composables/use-slugify";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { FormType } from "@/types/slug";
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
|
@ -199,7 +200,8 @@ const { handleGenerateSlug } = useSlugify(
|
|||
formState.value.spec.slug = value;
|
||||
},
|
||||
}),
|
||||
computed(() => !isUpdateMode.value)
|
||||
computed(() => !isUpdateMode.value),
|
||||
FormType.CATEGORY
|
||||
);
|
||||
</script>
|
||||
<template>
|
||||
|
@ -260,7 +262,7 @@ const { handleGenerateSlug } = useSlugify(
|
|||
)
|
||||
"
|
||||
class="group flex h-full cursor-pointer items-center border-l px-3 transition-all hover:bg-gray-100"
|
||||
@click="handleGenerateSlug"
|
||||
@click="handleGenerateSlug(true, FormType.CATEGORY)"
|
||||
>
|
||||
<IconRefreshLine
|
||||
class="h-4 w-4 text-gray-500 group-hover:text-gray-700"
|
||||
|
|
|
@ -19,6 +19,7 @@ import { submitForm } from "@formkit/core";
|
|||
import useSlugify from "@/composables/use-slugify";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { usePostUpdateMutate } from "../composables/use-post-update-mutate";
|
||||
import { FormType } from "@/types/slug";
|
||||
|
||||
const initialFormState: Post = {
|
||||
spec: {
|
||||
|
@ -240,7 +241,8 @@ const { handleGenerateSlug } = useSlugify(
|
|||
formState.value.spec.slug = value;
|
||||
},
|
||||
}),
|
||||
computed(() => !isUpdateMode.value)
|
||||
computed(() => !isUpdateMode.value),
|
||||
FormType.POST
|
||||
);
|
||||
</script>
|
||||
<template>
|
||||
|
@ -293,7 +295,7 @@ const { handleGenerateSlug } = useSlugify(
|
|||
$t('core.post.settings.fields.slug.refresh_message')
|
||||
"
|
||||
class="group flex h-full cursor-pointer items-center border-l px-3 transition-all hover:bg-gray-100"
|
||||
@click="handleGenerateSlug"
|
||||
@click="handleGenerateSlug(true, FormType.POST)"
|
||||
>
|
||||
<IconRefreshLine
|
||||
class="h-4 w-4 text-gray-500 group-hover:text-gray-700"
|
||||
|
|
|
@ -25,6 +25,7 @@ import { setFocus } from "@/formkit/utils/focus";
|
|||
import AnnotationsForm from "@/components/form/AnnotationsForm.vue";
|
||||
import useSlugify from "@/composables/use-slugify";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { FormType } from "@/types/slug";
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
|
@ -158,7 +159,8 @@ const { handleGenerateSlug } = useSlugify(
|
|||
formState.value.spec.slug = value;
|
||||
},
|
||||
}),
|
||||
computed(() => !isUpdateMode.value)
|
||||
computed(() => !isUpdateMode.value),
|
||||
FormType.TAG
|
||||
);
|
||||
</script>
|
||||
<template>
|
||||
|
@ -220,7 +222,7 @@ const { handleGenerateSlug } = useSlugify(
|
|||
)
|
||||
"
|
||||
class="group flex h-full cursor-pointer items-center border-l px-3 transition-all hover:bg-gray-100"
|
||||
@click="handleGenerateSlug"
|
||||
@click="handleGenerateSlug(true, FormType.TAG)"
|
||||
>
|
||||
<IconRefreshLine
|
||||
class="h-4 w-4 text-gray-500 group-hover:text-gray-700"
|
||||
|
|
|
@ -12,6 +12,7 @@ import type { ConfigMap, Setting } from "@halo-dev/api-client";
|
|||
import { useQuery, useQueryClient } from "@tanstack/vue-query";
|
||||
import { apiClient } from "@/utils/api-client";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { useGlobalInfoStore } from "@/stores/global-info";
|
||||
|
||||
const SYSTEM_CONFIGMAP_NAME = "system";
|
||||
|
||||
|
@ -58,7 +59,7 @@ const handleSaveConfigMap = async () => {
|
|||
Toast.success(t("core.common.toast.save_success"));
|
||||
|
||||
queryClient.invalidateQueries({ queryKey: ["system-configMap"] });
|
||||
|
||||
await useGlobalInfoStore().fetchGlobalInfo();
|
||||
systemConfigMapStore.configMap = data;
|
||||
|
||||
saving.value = false;
|
||||
|
|
|
@ -30,7 +30,6 @@ export async function setupPluginModules(app: App) {
|
|||
|
||||
enabledPluginNames.forEach((name) => {
|
||||
const module = window[name];
|
||||
|
||||
if (module) {
|
||||
registerModule(app, module, false);
|
||||
pluginModuleStore.registerPluginModule(name, module);
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
import type { ModeType } from "./slug";
|
||||
|
||||
export interface GlobalInfo {
|
||||
externalUrl: string;
|
||||
timeZone: string;
|
||||
|
@ -10,6 +12,7 @@ export interface GlobalInfo {
|
|||
userInitialized: boolean;
|
||||
dataInitialized: boolean;
|
||||
favicon?: string;
|
||||
postSlugGenerationStrategy: ModeType;
|
||||
}
|
||||
|
||||
export interface Info {
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
export type ModeType = "UUID" | "shortUUID" | "timestamp" | "generateByTitle";
|
||||
export enum FormType {
|
||||
TAG = "Tag",
|
||||
CATEGORY = "Category",
|
||||
POST = "Post",
|
||||
SINGLE_PAGE = "SinglePage",
|
||||
}
|
Loading…
Reference in New Issue