2026-04-07 16:07:21 +08:00
|
|
|
<script setup lang="ts">
|
|
|
|
|
import {
|
|
|
|
|
AppstoreOutlined,
|
|
|
|
|
CalendarOutlined,
|
|
|
|
|
ClockCircleOutlined,
|
2026-04-25 21:36:44 +08:00
|
|
|
CopyOutlined,
|
2026-04-07 16:07:21 +08:00
|
|
|
EditOutlined,
|
2026-04-17 15:19:11 +08:00
|
|
|
TeamOutlined,
|
2026-04-07 16:07:21 +08:00
|
|
|
ThunderboltOutlined,
|
|
|
|
|
} from "@ant-design/icons-vue";
|
|
|
|
|
import { computed, type Component } from "vue";
|
|
|
|
|
|
|
|
|
|
import { formatDateTime, getSourceTypeLabel } from "@/lib/display";
|
|
|
|
|
|
|
|
|
|
const props = defineProps<{
|
|
|
|
|
sourceType?: string | null;
|
|
|
|
|
generationMode?: string | null;
|
|
|
|
|
createdAt?: string | null;
|
|
|
|
|
}>();
|
|
|
|
|
|
|
|
|
|
const sourceLabel = computed(() =>
|
|
|
|
|
getSourceTypeLabel(props.sourceType, props.generationMode),
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
const createdAtLabel = computed(() => formatDateTime(props.createdAt));
|
|
|
|
|
|
|
|
|
|
const sourceVariant = computed<
|
2026-04-25 21:36:44 +08:00
|
|
|
"template" | "custom" | "instant" | "schedule" | "free-create" | "imitation" | "kol" | "default"
|
2026-04-07 16:07:21 +08:00
|
|
|
>(() => {
|
|
|
|
|
if (props.sourceType === "template") {
|
|
|
|
|
return "template";
|
|
|
|
|
}
|
|
|
|
|
if (props.sourceType === "free_create") {
|
|
|
|
|
return "free-create";
|
|
|
|
|
}
|
2026-04-25 21:36:44 +08:00
|
|
|
if (props.sourceType === "imitation") {
|
|
|
|
|
return "imitation";
|
|
|
|
|
}
|
2026-04-17 15:19:11 +08:00
|
|
|
if (props.sourceType === "kol") {
|
|
|
|
|
return "kol";
|
|
|
|
|
}
|
2026-04-07 16:07:21 +08:00
|
|
|
if (props.sourceType === "custom_generation") {
|
|
|
|
|
if (props.generationMode === "schedule") {
|
|
|
|
|
return "schedule";
|
|
|
|
|
}
|
|
|
|
|
if (props.generationMode === "instant") {
|
|
|
|
|
return "instant";
|
|
|
|
|
}
|
|
|
|
|
return "custom";
|
|
|
|
|
}
|
|
|
|
|
return "default";
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const badgeIcon = computed<Component>(() => {
|
|
|
|
|
switch (sourceVariant.value) {
|
|
|
|
|
case "template":
|
|
|
|
|
return AppstoreOutlined;
|
|
|
|
|
case "instant":
|
|
|
|
|
return ThunderboltOutlined;
|
|
|
|
|
case "schedule":
|
|
|
|
|
return CalendarOutlined;
|
|
|
|
|
case "custom":
|
|
|
|
|
return ThunderboltOutlined;
|
|
|
|
|
case "free-create":
|
|
|
|
|
return EditOutlined;
|
2026-04-25 21:36:44 +08:00
|
|
|
case "imitation":
|
|
|
|
|
return CopyOutlined;
|
2026-04-17 15:19:11 +08:00
|
|
|
case "kol":
|
|
|
|
|
return TeamOutlined;
|
2026-04-07 16:07:21 +08:00
|
|
|
default:
|
|
|
|
|
return AppstoreOutlined;
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
<template>
|
|
|
|
|
<div class="article-source-meta">
|
|
|
|
|
<span
|
|
|
|
|
class="article-source-meta__badge"
|
|
|
|
|
:class="`article-source-meta__badge--${sourceVariant}`"
|
|
|
|
|
>
|
|
|
|
|
<component :is="badgeIcon" />
|
|
|
|
|
<span>{{ sourceLabel }}</span>
|
|
|
|
|
</span>
|
|
|
|
|
<span class="article-source-meta__time">
|
|
|
|
|
<ClockCircleOutlined />
|
|
|
|
|
<span>{{ createdAtLabel }}</span>
|
|
|
|
|
</span>
|
|
|
|
|
</div>
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
<style scoped>
|
|
|
|
|
.article-source-meta {
|
|
|
|
|
display: flex;
|
|
|
|
|
flex-wrap: wrap;
|
|
|
|
|
align-items: center;
|
|
|
|
|
gap: 10px 14px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.article-source-meta__badge {
|
|
|
|
|
display: inline-flex;
|
|
|
|
|
align-items: center;
|
|
|
|
|
gap: 6px;
|
|
|
|
|
padding: 4px 8px;
|
|
|
|
|
border-radius: 6px;
|
|
|
|
|
box-shadow: 0 1px 2px rgba(15, 23, 42, 0.04);
|
|
|
|
|
font-size: 12px;
|
|
|
|
|
font-weight: 600;
|
|
|
|
|
line-height: 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.article-source-meta__badge--template {
|
|
|
|
|
border: 1px solid #d9e5ff;
|
|
|
|
|
background: linear-gradient(180deg, #fbfcff 0%, #f3f7ff 100%);
|
|
|
|
|
color: #225fd1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.article-source-meta__badge--custom {
|
|
|
|
|
border: 1px solid #d9ccff;
|
|
|
|
|
background: linear-gradient(180deg, #f7f4ff 0%, #efe9ff 100%);
|
|
|
|
|
color: #6941c6;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.article-source-meta__badge--instant {
|
|
|
|
|
border: 1px solid #f3c796;
|
|
|
|
|
background: linear-gradient(180deg, #fff5e9 0%, #ffe9d2 100%);
|
|
|
|
|
color: #b54708;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.article-source-meta__badge--schedule {
|
|
|
|
|
border: 1px solid #a7ddd3;
|
|
|
|
|
background: linear-gradient(180deg, #eefaf7 0%, #def3ee 100%);
|
|
|
|
|
color: #0b6b61;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.article-source-meta__badge--free-create {
|
|
|
|
|
border: 1px solid #d4ead8;
|
|
|
|
|
background: linear-gradient(180deg, #f7fcf8 0%, #eef8f1 100%);
|
|
|
|
|
color: #18794e;
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-25 21:36:44 +08:00
|
|
|
.article-source-meta__badge--imitation {
|
|
|
|
|
border: 1px solid #bfdbfe;
|
|
|
|
|
background: linear-gradient(180deg, #f8fbff 0%, #e6f0ff 100%);
|
|
|
|
|
color: #1d4ed8;
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-17 15:19:11 +08:00
|
|
|
.article-source-meta__badge--kol {
|
|
|
|
|
border: 1px solid #d6e4ff;
|
|
|
|
|
background: linear-gradient(180deg, #f5f8ff 0%, #eaf1ff 100%);
|
|
|
|
|
color: #1d4ed8;
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-07 16:07:21 +08:00
|
|
|
.article-source-meta__badge--default {
|
|
|
|
|
border: 1px solid #dde3ea;
|
|
|
|
|
background: linear-gradient(180deg, #fbfcfd 0%, #f4f6f8 100%);
|
|
|
|
|
color: #44546a;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.article-source-meta__time {
|
|
|
|
|
display: inline-flex;
|
|
|
|
|
align-items: center;
|
|
|
|
|
gap: 6px;
|
|
|
|
|
color: #667085;
|
|
|
|
|
font-size: 12px;
|
|
|
|
|
line-height: 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.article-source-meta :deep(.anticon) {
|
|
|
|
|
font-size: 12px;
|
|
|
|
|
}
|
|
|
|
|
</style>
|