mirror of https://github.com/halo-dev/halo
fix: post slug generation not following selected strategy (#6914)
#### What type of PR is this? /area ui /kind bug /milestone 2.20.x #### What this PR does / why we need it: 修复文章自动生成别名不按照别名生成策略生成的问题。 #### Which issue(s) this PR fixes: Fixes #6913 #### Special notes for your reviewer: 需要测试: 1. 分类、标签创建和更新时的别名生成 2. 文章新建时,别名是否按照生成策略生成。 #### Does this PR introduce a user-facing change? ```release-note 修复文章自动生成别名不按照别名生成策略生成的问题。 ```pull/6920/head
parent
329bcc5748
commit
9ecc8f1d95
|
@ -3,28 +3,20 @@ import { FormType } from "@/types/slug";
|
||||||
import { randomUUID } from "@/utils/id";
|
import { randomUUID } from "@/utils/id";
|
||||||
import ShortUniqueId from "short-unique-id";
|
import ShortUniqueId from "short-unique-id";
|
||||||
import { slugify } from "transliteration";
|
import { slugify } from "transliteration";
|
||||||
import { watch, type Ref } from "vue";
|
import { computed, watch, type Ref } from "vue";
|
||||||
|
|
||||||
const uid = new ShortUniqueId();
|
const uid = new ShortUniqueId();
|
||||||
const Strategy = {
|
|
||||||
generateByTitle: (value: string) => {
|
type SlugStrategy = (value?: string) => string;
|
||||||
if (!value) return "";
|
|
||||||
return slugify(value, { trim: true });
|
const strategies: Record<string, SlugStrategy> = {
|
||||||
},
|
generateByTitle: (value?: string) => slugify(value || "", { trim: true }),
|
||||||
shortUUID: (value: string) => {
|
shortUUID: () => uid.randomUUID(8),
|
||||||
if (!value) return "";
|
UUID: () => randomUUID(),
|
||||||
return uid.randomUUID(8);
|
timestamp: () => new Date().getTime().toString(),
|
||||||
},
|
|
||||||
UUID: (value: string) => {
|
|
||||||
if (!value) return "";
|
|
||||||
return randomUUID();
|
|
||||||
},
|
|
||||||
timestamp: (value: string) => {
|
|
||||||
if (!value) return "";
|
|
||||||
return new Date().getTime().toString();
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const onceList = ["shortUUID", "UUID", "timestamp"];
|
const onceStrategies = new Set(["shortUUID", "UUID", "timestamp"]);
|
||||||
|
|
||||||
export default function useSlugify(
|
export default function useSlugify(
|
||||||
source: Ref<string>,
|
source: Ref<string>,
|
||||||
|
@ -32,35 +24,43 @@ export default function useSlugify(
|
||||||
auto: Ref<boolean>,
|
auto: Ref<boolean>,
|
||||||
formType: FormType
|
formType: FormType
|
||||||
) {
|
) {
|
||||||
const handleGenerateSlug = (forceUpdate = false, formType: FormType) => {
|
|
||||||
const globalInfoStore = useGlobalInfoStore();
|
const globalInfoStore = useGlobalInfoStore();
|
||||||
const mode = globalInfoStore.globalInfo?.postSlugGenerationStrategy;
|
|
||||||
|
|
||||||
if (!mode) {
|
const currentStrategy = computed(
|
||||||
|
() =>
|
||||||
|
globalInfoStore.globalInfo?.postSlugGenerationStrategy ||
|
||||||
|
"generateByTitle"
|
||||||
|
);
|
||||||
|
|
||||||
|
const generateSlug = (value: string): string => {
|
||||||
|
const strategy =
|
||||||
|
formType === FormType.POST
|
||||||
|
? strategies[currentStrategy.value]
|
||||||
|
: strategies.generateByTitle;
|
||||||
|
|
||||||
|
return strategy(value);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleGenerateSlug = (forceUpdate = false) => {
|
||||||
|
if (
|
||||||
|
!forceUpdate &&
|
||||||
|
onceStrategies.has(currentStrategy.value) &&
|
||||||
|
target.value
|
||||||
|
) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (formType != FormType.POST) {
|
|
||||||
target.value = Strategy["generateByTitle"](source.value);
|
target.value = generateSlug(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);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => source.value,
|
source,
|
||||||
() => {
|
() => {
|
||||||
if (auto.value) {
|
if (auto.value) {
|
||||||
handleGenerateSlug(false, formType);
|
handleGenerateSlug(true);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{ immediate: true }
|
||||||
immediate: true,
|
|
||||||
}
|
|
||||||
);
|
);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -318,7 +318,7 @@ const { handleGenerateSlug } = useSlugify(
|
||||||
$t('core.page.settings.fields.slug.refresh_message')
|
$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"
|
class="group flex h-full cursor-pointer items-center border-l px-3 transition-all hover:bg-gray-100"
|
||||||
@click="handleGenerateSlug(true, FormType.SINGLE_PAGE)"
|
@click="handleGenerateSlug(true)"
|
||||||
>
|
>
|
||||||
<IconRefreshLine
|
<IconRefreshLine
|
||||||
class="h-4 w-4 text-gray-500 group-hover:text-gray-700"
|
class="h-4 w-4 text-gray-500 group-hover:text-gray-700"
|
||||||
|
|
|
@ -238,7 +238,7 @@ const { handleGenerateSlug } = useSlugify(
|
||||||
)
|
)
|
||||||
"
|
"
|
||||||
class="group flex h-full cursor-pointer items-center border-l px-3 transition-all hover:bg-gray-100"
|
class="group flex h-full cursor-pointer items-center border-l px-3 transition-all hover:bg-gray-100"
|
||||||
@click="handleGenerateSlug(true, FormType.CATEGORY)"
|
@click="handleGenerateSlug(true)"
|
||||||
>
|
>
|
||||||
<IconRefreshLine
|
<IconRefreshLine
|
||||||
class="h-4 w-4 text-gray-500 group-hover:text-gray-700"
|
class="h-4 w-4 text-gray-500 group-hover:text-gray-700"
|
||||||
|
|
|
@ -331,7 +331,7 @@ const showCancelPublishButton = computed(() => {
|
||||||
$t('core.post.settings.fields.slug.refresh_message')
|
$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"
|
class="group flex h-full cursor-pointer items-center border-l px-3 transition-all hover:bg-gray-100"
|
||||||
@click="handleGenerateSlug(true, FormType.POST)"
|
@click="handleGenerateSlug(true)"
|
||||||
>
|
>
|
||||||
<IconRefreshLine
|
<IconRefreshLine
|
||||||
class="h-4 w-4 text-gray-500 group-hover:text-gray-700"
|
class="h-4 w-4 text-gray-500 group-hover:text-gray-700"
|
||||||
|
|
|
@ -208,7 +208,7 @@ const { handleGenerateSlug } = useSlugify(
|
||||||
)
|
)
|
||||||
"
|
"
|
||||||
class="group flex h-full cursor-pointer items-center border-l px-3 transition-all hover:bg-gray-100"
|
class="group flex h-full cursor-pointer items-center border-l px-3 transition-all hover:bg-gray-100"
|
||||||
@click="handleGenerateSlug(true, FormType.TAG)"
|
@click="handleGenerateSlug(true)"
|
||||||
>
|
>
|
||||||
<IconRefreshLine
|
<IconRefreshLine
|
||||||
class="h-4 w-4 text-gray-500 group-hover:text-gray-700"
|
class="h-4 w-4 text-gray-500 group-hover:text-gray-700"
|
||||||
|
|
|
@ -114,7 +114,7 @@ const publishTimeHelp = computed(() => {
|
||||||
<div
|
<div
|
||||||
v-tooltip="$t('core.post.settings.fields.slug.refresh_message')"
|
v-tooltip="$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"
|
class="group flex h-full cursor-pointer items-center border-l px-3 transition-all hover:bg-gray-100"
|
||||||
@click="handleGenerateSlug(true, FormType.POST)"
|
@click="handleGenerateSlug(true)"
|
||||||
>
|
>
|
||||||
<IconRefreshLine
|
<IconRefreshLine
|
||||||
class="h-4 w-4 text-gray-500 group-hover:text-gray-700"
|
class="h-4 w-4 text-gray-500 group-hover:text-gray-700"
|
||||||
|
|
Loading…
Reference in New Issue