fix: the issue that post publishTime cannot be set and displayed back (halo-dev/console#718)

#### What type of PR is this?

/kind bug
/milestone 2.0

#### What this PR does / why we need it:

修复文章和自定义页面的发布时间无法设置和回显的问题。

#### Which issue(s) this PR fixes:

Fixes https://github.com/halo-dev/halo/issues/2770

#### Special notes for your reviewer:

测试方式:

1. 创建一篇文章和自定义页面。
2. 在高级设置中设置发布时间。
3. 检查发布后列表中显示的时间是否和设置的一致。
4. 再次打开文章设置,检查发布时间输入框的时间是否正确。

#### Does this PR introduce a user-facing change?


```release-note
修复 Console 端文章和自定义页面的发布时间无法设置和回显的问题。
```
pull/3445/head
Ryan Wang 2022-11-28 23:32:18 +08:00 committed by GitHub
parent 540a488d5b
commit 43d7765347
4 changed files with 91 additions and 7 deletions

View File

@ -7,6 +7,7 @@ import { apiClient } from "@/utils/api-client";
import { useThemeCustomTemplates } from "@/modules/interface/themes/composables/use-theme";
import { singlePageLabels } from "@/constants/labels";
import { randomUUID } from "@/utils/id";
import { toDatetimeLocal, toISOString } from "@/utils/date";
const initialFormState: SinglePage = {
spec: {
@ -69,6 +70,9 @@ const isUpdateMode = computed(() => {
const onVisibleChange = (visible: boolean) => {
emit("update:visible", visible);
if (!visible) {
setTimeout(() => {
activeTab.value = "general";
}, 200);
emit("close");
}
};
@ -162,6 +166,19 @@ watchEffect(() => {
// custom templates
const { templates } = useThemeCustomTemplates("page");
// publishTime
const publishTime = computed(() => {
const { publishTime } = formState.value.spec;
if (publishTime) {
return toDatetimeLocal(publishTime);
}
return "";
});
const onPublishTimeChange = (value: string) => {
formState.value.spec.publishTime = toISOString(value);
};
</script>
<template>
@ -261,10 +278,11 @@ const { templates } = useThemeCustomTemplates("page");
type="select"
></FormKit>
<FormKit
v-model="formState.spec.publishTime"
:value="publishTime"
label="发表时间"
type="datetime-local"
name="publishTime"
@input="onPublishTimeChange"
></FormKit>
<FormKit
v-model="formState.spec.template"

View File

@ -7,6 +7,7 @@ import { apiClient } from "@/utils/api-client";
import { useThemeCustomTemplates } from "@/modules/interface/themes/composables/use-theme";
import { postLabels } from "@/constants/labels";
import { randomUUID } from "@/utils/id";
import { toDatetimeLocal, toISOString } from "@/utils/date";
const initialFormState: Post = {
spec: {
@ -71,6 +72,9 @@ const isUpdateMode = computed(() => {
const handleVisibleChange = (visible: boolean) => {
emit("update:visible", visible);
if (!visible) {
setTimeout(() => {
activeTab.value = "general";
}, 200);
emit("close");
}
};
@ -153,6 +157,20 @@ watchEffect(() => {
// custom templates
const { templates } = useThemeCustomTemplates("post");
// publishTime convert
const publishTime = computed(() => {
const { publishTime } = formState.value.spec;
if (publishTime) {
console.log(toDatetimeLocal(publishTime));
return toDatetimeLocal(publishTime);
}
return "";
});
const onPublishTimeChange = (value: string) => {
formState.value.spec.publishTime = toISOString(value);
};
</script>
<template>
<VModal
@ -262,9 +280,10 @@ const { templates } = useThemeCustomTemplates("post");
type="select"
></FormKit>
<FormKit
v-model="formState.spec.publishTime"
:value="publishTime"
label="发表时间"
type="datetime-local"
@input="onPublishTimeChange"
></FormKit>
<FormKit
v-model="formState.spec.template"

View File

@ -1,10 +1,34 @@
import { describe, expect, it } from "vitest";
import { formatDatetime } from "../date";
import { formatDatetime, toDatetimeLocal, toISOString } from "../date";
describe.skip("date#formatDatetime", () => {
describe("date#formatDatetime", () => {
it("should return formatted datetime", () => {
const formattedDatetime = formatDatetime("2022-08-17T06:01:16.511575Z");
const formattedDatetime = formatDatetime(
"2022-08-17T06:01:16.511575Z",
"Asia/Shanghai"
);
expect(formattedDatetime).toEqual("2022-08-17 14:01");
});
});
describe("date#toISOString", () => {
it("should return ISO string", () => {
const currentDate = new Date();
const isoString = toISOString(currentDate);
expect(isoString).toEqual(currentDate.toISOString());
});
});
describe("date#toDatetimeLocal", () => {
it("should return datetime local", () => {
const datetimeLocal = toDatetimeLocal(
"2022-08-17T06:01:00.000Z",
"Asia/Shanghai"
);
expect(datetimeLocal).toEqual("2022-08-17T14:01");
});
});

View File

@ -1,14 +1,37 @@
import dayjs from "dayjs";
import "dayjs/locale/zh-cn";
import timezone from "dayjs/plugin/timezone";
import utc from "dayjs/plugin/utc";
dayjs.extend(timezone);
dayjs.extend(utc);
dayjs.locale("zh-cn");
export function formatDatetime(date: string | Date | undefined | null): string {
export function formatDatetime(
date: string | Date | undefined | null,
tz?: string
): string {
if (!date) {
return "";
}
return dayjs(date).format("YYYY-MM-DD HH:mm");
return dayjs(date).tz(tz).format("YYYY-MM-DD HH:mm");
}
export function toISOString(date: string | Date | undefined | null): string {
if (!date) {
return "";
}
return dayjs(date).utc(false).toISOString();
}
export function toDatetimeLocal(
date: string | Date | undefined | null,
tz?: string
): string {
if (!date) {
return "";
}
// see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/datetime-local#the_y10k_problem_often_client-side
return dayjs(date).tz(tz).format("YYYY-MM-DDTHH:mm");
}