mirror of https://github.com/halo-dev/halo
refactor: add chunked execution mechanism for post batch operations (#7378)
#### What type of PR is this? /area ui /kind improvement /milestone 2.20.x #### What this PR does / why we need it: Use `Promise.all` to execute part of the batch operation logic of the post in chunks to optimize the execution performance. #### Which issue(s) this PR fixes: Fixes # #### Does this PR introduce a user-facing change? ```release-note 优化文章部分批量操作的执行性能 ```pull/7386/head
parent
c2819f1f5a
commit
7a315302a8
|
@ -23,6 +23,7 @@ import {
|
|||
VStatusDot,
|
||||
} from "@halo-dev/components";
|
||||
import { useQuery } from "@tanstack/vue-query";
|
||||
import { chunk } from "lodash-es";
|
||||
import { ref, watch } from "vue";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import PostTag from "./tags/components/PostTag.vue";
|
||||
|
@ -109,13 +110,18 @@ const handleDeletePermanentlyInBatch = async () => {
|
|||
confirmText: t("core.common.buttons.confirm"),
|
||||
cancelText: t("core.common.buttons.cancel"),
|
||||
onConfirm: async () => {
|
||||
const chunks = chunk(selectedPostNames.value, 5);
|
||||
|
||||
for (const chunk of chunks) {
|
||||
await Promise.all(
|
||||
selectedPostNames.value.map((name) => {
|
||||
chunk.map((name) => {
|
||||
return coreApiClient.content.post.deletePost({
|
||||
name,
|
||||
});
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
await refetch();
|
||||
selectedPostNames.value = [];
|
||||
|
||||
|
@ -158,8 +164,11 @@ const handleRecoveryInBatch = async () => {
|
|||
confirmText: t("core.common.buttons.confirm"),
|
||||
cancelText: t("core.common.buttons.cancel"),
|
||||
onConfirm: async () => {
|
||||
const chunks = chunk(selectedPostNames.value, 5);
|
||||
|
||||
for (const chunk of chunks) {
|
||||
await Promise.all(
|
||||
selectedPostNames.value.map((name) => {
|
||||
chunk.map((name) => {
|
||||
const isPostExist = posts.value?.some(
|
||||
(item) => item.post.metadata.name === name
|
||||
);
|
||||
|
@ -180,6 +189,8 @@ const handleRecoveryInBatch = async () => {
|
|||
});
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
await refetch();
|
||||
selectedPostNames.value = [];
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@ import {
|
|||
} from "@halo-dev/components";
|
||||
import { useQuery } from "@tanstack/vue-query";
|
||||
import { useRouteQuery } from "@vueuse/router";
|
||||
import { chunk } from "lodash-es";
|
||||
import type { Ref } from "vue";
|
||||
import { computed, provide, ref, watch } from "vue";
|
||||
import { useI18n } from "vue-i18n";
|
||||
|
@ -266,13 +267,18 @@ const handleDeleteInBatch = async () => {
|
|||
confirmText: t("core.common.buttons.confirm"),
|
||||
cancelText: t("core.common.buttons.cancel"),
|
||||
onConfirm: async () => {
|
||||
const chunks = chunk(selectedPostNames.value, 5);
|
||||
|
||||
for (const chunk of chunks) {
|
||||
await Promise.all(
|
||||
selectedPostNames.value.map((name) => {
|
||||
chunk.map((name) => {
|
||||
return consoleApiClient.content.post.recyclePost({
|
||||
name,
|
||||
});
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
await refetch();
|
||||
selectedPostNames.value = [];
|
||||
|
||||
|
@ -288,9 +294,14 @@ const handlePublishInBatch = async () => {
|
|||
confirmText: t("core.common.buttons.confirm"),
|
||||
cancelText: t("core.common.buttons.cancel"),
|
||||
onConfirm: async () => {
|
||||
for (const i in selectedPostNames.value) {
|
||||
const name = selectedPostNames.value[i];
|
||||
await consoleApiClient.content.post.publishPost({ name });
|
||||
const chunks = chunk(selectedPostNames.value, 5);
|
||||
|
||||
for (const chunk of chunks) {
|
||||
await Promise.all(
|
||||
chunk.map((name) => {
|
||||
return consoleApiClient.content.post.publishPost({ name });
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
await refetch();
|
||||
|
@ -308,9 +319,14 @@ const handleCancelPublishInBatch = async () => {
|
|||
confirmText: t("core.common.buttons.confirm"),
|
||||
cancelText: t("core.common.buttons.cancel"),
|
||||
onConfirm: async () => {
|
||||
for (const i in selectedPostNames.value) {
|
||||
const name = selectedPostNames.value[i];
|
||||
await consoleApiClient.content.post.unpublishPost({ name });
|
||||
const chunks = chunk(selectedPostNames.value, 5);
|
||||
|
||||
for (const chunk of chunks) {
|
||||
await Promise.all(
|
||||
chunk.map((name) => {
|
||||
return consoleApiClient.content.post.unpublishPost({ name });
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
await refetch();
|
||||
|
|
|
@ -6,6 +6,7 @@ import {
|
|||
} from "@halo-dev/api-client";
|
||||
import { Toast, VButton, VModal, VSpace } from "@halo-dev/components";
|
||||
import { useMutation, useQueryClient } from "@tanstack/vue-query";
|
||||
import { chunk } from "lodash-es";
|
||||
import { ref } from "vue";
|
||||
import { useI18n } from "vue-i18n";
|
||||
|
||||
|
@ -50,8 +51,11 @@ const modal = ref<InstanceType<typeof VModal> | null>(null);
|
|||
const { mutate, isLoading } = useMutation({
|
||||
mutationKey: ["batch-update-posts"],
|
||||
mutationFn: async ({ data }: { data: FormData }) => {
|
||||
for (const key in props.posts) {
|
||||
const post = props.posts[key];
|
||||
const postChunks = chunk(props.posts, 5);
|
||||
|
||||
for (const postChunk of postChunks) {
|
||||
await Promise.all(
|
||||
postChunk.map((post) => {
|
||||
const jsonPatchInner: JsonPatchInner[] = [];
|
||||
if (data.category.enabled) {
|
||||
jsonPatchInner.push({
|
||||
|
@ -101,10 +105,12 @@ const { mutate, isLoading } = useMutation({
|
|||
});
|
||||
}
|
||||
|
||||
await coreApiClient.content.post.patchPost({
|
||||
return coreApiClient.content.post.patchPost({
|
||||
name: post.post.metadata.name,
|
||||
jsonPatchInner,
|
||||
});
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
Toast.success(t("core.common.toast.save_success"));
|
||||
|
|
Loading…
Reference in New Issue