mirror of https://github.com/halo-dev/halo-admin
perf: add supports for force updating of post and single page settings (#907)
> **Warning** > > 此 PR 的改动来自:<https://github.com/halo-dev/halo/pull/3498> > 因为目前 Console 仓库已经合并到 Halo 主仓库,但主仓库的 release-2.3 分支不包含 Console,所以如果需要发布 2.3.x 的 patch 版本,依旧需要在此仓库修改。 #### What type of PR is this? /kind improvement /milestone 2.3.2 #### What this PR does / why we need it: 支持强制保存文章和单页面的设置,绕开后端 version 锁的机制,因为目前发现在后端 Reconcile 处理文章较慢时会影响文章的保存。 需要注意的是,这是一个不太合理的处理方式,但目前别无选择。 #### Which issue(s) this PR fixes: Fixes https://github.com/halo-dev/halo/issues/3339 #### Special notes for your reviewer: 测试方式: 1. 同时打开多个同文章的编辑页面的窗口。 2. 编辑任意一个窗口的文章设置。 3. 然后再去其他窗口保存,观察是否有异常。 #### Does this PR introduce a user-facing change? ```release-note 支持强制保存文章和页面的设置,避免因为 Version 锁的机制导致保存失败。 ```dependabot/npm_and_yarn/word-wrap-1.2.4
parent
09417bad26
commit
db9fcb8e2c
|
@ -17,6 +17,7 @@ import { toDatetimeLocal, toISOString } from "@/utils/date";
|
|||
import { submitForm } from "@formkit/core";
|
||||
import AnnotationsForm from "@/components/form/AnnotationsForm.vue";
|
||||
import useSlugify from "@/composables/use-slugify";
|
||||
import { useMutation } from "@tanstack/vue-query";
|
||||
|
||||
const initialFormState: SinglePage = {
|
||||
spec: {
|
||||
|
@ -110,6 +111,40 @@ const handlePublishClick = () => {
|
|||
});
|
||||
};
|
||||
|
||||
// Fix me:
|
||||
// Force update post settings,
|
||||
// because currently there may be errors caused by changes in version due to asynchronous processing.
|
||||
const { mutateAsync: singlePageUpdateMutate } = useMutation({
|
||||
mutationKey: ["singlePage-update"],
|
||||
mutationFn: async (page: SinglePage) => {
|
||||
const { data: latestSinglePage } =
|
||||
await apiClient.extension.singlePage.getcontentHaloRunV1alpha1SinglePage({
|
||||
name: page.metadata.name,
|
||||
});
|
||||
return apiClient.extension.singlePage.updatecontentHaloRunV1alpha1SinglePage(
|
||||
{
|
||||
name: page.metadata.name,
|
||||
singlePage: {
|
||||
...latestSinglePage,
|
||||
spec: page.spec,
|
||||
metadata: {
|
||||
...latestSinglePage.metadata,
|
||||
annotations: page.metadata.annotations,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
mute: true,
|
||||
}
|
||||
);
|
||||
},
|
||||
retry: 3,
|
||||
onError: (error) => {
|
||||
console.error("Failed to update post", error);
|
||||
Toast.error(`服务器内部错误`);
|
||||
},
|
||||
});
|
||||
|
||||
const handleSave = async () => {
|
||||
annotationsFormRef.value?.handleSubmit();
|
||||
await nextTick();
|
||||
|
@ -133,15 +168,8 @@ const handleSave = async () => {
|
|||
try {
|
||||
saving.value = true;
|
||||
|
||||
saving.value = true;
|
||||
|
||||
const { data } = isUpdateMode.value
|
||||
? await apiClient.extension.singlePage.updatecontentHaloRunV1alpha1SinglePage(
|
||||
{
|
||||
name: formState.value.metadata.name,
|
||||
singlePage: formState.value,
|
||||
}
|
||||
)
|
||||
? await singlePageUpdateMutate(formState.value)
|
||||
: await apiClient.extension.singlePage.createcontentHaloRunV1alpha1SinglePage(
|
||||
{
|
||||
singlePage: formState.value,
|
||||
|
|
|
@ -17,6 +17,7 @@ import { toDatetimeLocal, toISOString } from "@/utils/date";
|
|||
import AnnotationsForm from "@/components/form/AnnotationsForm.vue";
|
||||
import { submitForm } from "@formkit/core";
|
||||
import useSlugify from "@/composables/use-slugify";
|
||||
import { useMutation } from "@tanstack/vue-query";
|
||||
|
||||
const initialFormState: Post = {
|
||||
spec: {
|
||||
|
@ -114,6 +115,40 @@ const handlePublishClick = () => {
|
|||
});
|
||||
};
|
||||
|
||||
// Fix me:
|
||||
// Force update post settings,
|
||||
// because currently there may be errors caused by changes in version due to asynchronous processing.
|
||||
const { mutateAsync: postUpdateMutate } = useMutation({
|
||||
mutationKey: ["post-update"],
|
||||
mutationFn: async (post: Post) => {
|
||||
const { data: latestPost } =
|
||||
await apiClient.extension.post.getcontentHaloRunV1alpha1Post({
|
||||
name: post.metadata.name,
|
||||
});
|
||||
return apiClient.extension.post.updatecontentHaloRunV1alpha1Post(
|
||||
{
|
||||
name: post.metadata.name,
|
||||
post: {
|
||||
...latestPost,
|
||||
spec: post.spec,
|
||||
metadata: {
|
||||
...latestPost.metadata,
|
||||
annotations: post.metadata.annotations,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
mute: true,
|
||||
}
|
||||
);
|
||||
},
|
||||
retry: 3,
|
||||
onError: (error) => {
|
||||
console.error("Failed to update post", error);
|
||||
Toast.error(`服务器内部错误`);
|
||||
},
|
||||
});
|
||||
|
||||
const handleSave = async () => {
|
||||
annotationsFormRef.value?.handleSubmit();
|
||||
await nextTick();
|
||||
|
@ -139,10 +174,7 @@ const handleSave = async () => {
|
|||
saving.value = true;
|
||||
|
||||
const { data } = isUpdateMode.value
|
||||
? await apiClient.extension.post.updatecontentHaloRunV1alpha1Post({
|
||||
name: formState.value.metadata.name,
|
||||
post: formState.value,
|
||||
})
|
||||
? await postUpdateMutate(formState.value)
|
||||
: await apiClient.extension.post.createcontentHaloRunV1alpha1Post({
|
||||
post: formState.value,
|
||||
});
|
||||
|
|
|
@ -2,6 +2,7 @@ import { beforeEach, describe, expect, it } from "vitest";
|
|||
import { mount } from "@vue/test-utils";
|
||||
import PostSettingModal from "../PostSettingModal.vue";
|
||||
import { createPinia, setActivePinia } from "pinia";
|
||||
import { VueQueryPlugin } from "@tanstack/vue-query";
|
||||
|
||||
describe("PostSettingModal", () => {
|
||||
beforeEach(() => {
|
||||
|
@ -9,12 +10,19 @@ describe("PostSettingModal", () => {
|
|||
});
|
||||
|
||||
it("should render", () => {
|
||||
const wrapper = mount({
|
||||
const wrapper = mount(
|
||||
{
|
||||
components: {
|
||||
PostSettingModal,
|
||||
},
|
||||
template: `<PostSettingModal></PostSettingModal>`,
|
||||
});
|
||||
},
|
||||
{
|
||||
global: {
|
||||
plugins: [VueQueryPlugin],
|
||||
},
|
||||
}
|
||||
);
|
||||
expect(wrapper).toBeDefined();
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue