feat: add cover for post list (#7519)

#### What type of PR is this?

/kind feature
/area ui
/milestone 2.21.x

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

<img width="508" alt="image" src="https://github.com/user-attachments/assets/3d7a9ac0-1e0a-4a4f-a658-03af7ff89904" />

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

Fixes #7437 

#### Special notes for your reviewer:

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

```release-note
文章管理列表支持显示封面图
```
pull/7521/head^2
Ryan Wang 2025-06-09 23:34:34 +08:00 committed by GitHub
parent aeea3a5488
commit 65d4751509
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 51 additions and 0 deletions

View File

@ -3,6 +3,7 @@ import PostContributorList from "@/components/user/PostContributorList.vue";
import { singlePageLabels } from "@/constants/labels";
import { formatDatetime, relativeTimeTo } from "@/utils/date";
import { usePermission } from "@/utils/permission";
import { generateThumbnailUrl } from "@/utils/thumbnail";
import type { ListedSinglePage, SinglePage } from "@halo-dev/api-client";
import { coreApiClient } from "@halo-dev/api-client";
import {
@ -131,6 +132,16 @@ const handleDelete = async () => {
/>
</template>
<template #start>
<VEntityField v-if="singlePage.page.spec.cover">
<template #description>
<div class="aspect-h-2 rounded-md overflow-hidden aspect-w-3 w-20">
<img
class="object-cover w-full h-full"
:src="generateThumbnailUrl(singlePage.page.spec.cover, 's')"
/>
</div>
</template>
</VEntityField>
<VEntityField
:title="singlePage.page.spec.title"
:route="{

View File

@ -22,6 +22,7 @@ import { computed, inject, markRaw, ref, toRefs } from "vue";
import { useI18n } from "vue-i18n";
import { useRouter } from "vue-router";
import ContributorsField from "./entity-fields/ContributorsField.vue";
import CoverField from "./entity-fields/CoverField.vue";
import PublishStatusField from "./entity-fields/PublishStatusField.vue";
import PublishTimeField from "./entity-fields/PublishTimeField.vue";
import TitleField from "./entity-fields/TitleField.vue";
@ -160,6 +161,15 @@ const { startFields, endFields } = useEntityFieldItemExtensionPoint<ListedPost>(
{
priority: 10,
position: "start",
component: markRaw(CoverField),
hidden: !props.post.post.spec.cover,
props: {
post: props.post,
},
},
{
priority: 20,
position: "start",
component: markRaw(TitleField),
props: {
post: props.post,

View File

@ -0,0 +1,25 @@
<script lang="ts" setup>
import { generateThumbnailUrl } from "@/utils/thumbnail";
import type { ListedPost } from "@halo-dev/api-client";
import { VEntityField } from "@halo-dev/components";
withDefaults(
defineProps<{
post: ListedPost;
}>(),
{}
);
</script>
<template>
<VEntityField v-if="post.post.spec.cover">
<template #description>
<div class="aspect-h-2 rounded-md overflow-hidden aspect-w-3 w-20">
<img
class="object-cover w-full h-full"
:src="generateThumbnailUrl(post.post.spec.cover, 's')"
/>
</div>
</template>
</VEntityField>
</template>

View File

@ -0,0 +1,5 @@
export function generateThumbnailUrl(url: string, size: string) {
return `/apis/api.storage.halo.run/v1alpha1/thumbnails/-/via-uri?uri=${encodeURI(
url
)}&size=${size}`;
}