mirror of
https://github.com/iflytek/skillhub.git
synced 2026-08-27 11:14:59 +00:00
feat(skill-card): show author and update time in skill card
Add ownerId and ownerDisplayName fields to SkillSummaryResponse, and render author and last update time at the bottom of each skill card. 在技能卡片底部新增作者和最近更新时间显示,搜索结果接口新增 ownerId 和 ownerDisplayName 字段。 Log: 技能卡片新增作者和更新时间 Influence: 搜索结果页技能卡片底部显示作者和更新时间信息,接口新增 ownerId/ownerDisplayName 字段。 Signed-off-by: wurongjie <wurongjie@uniontech.com>
This commit is contained in:
parent
26f49e6819
commit
f43c047a6b
9 changed files with 52 additions and 3 deletions
|
|
@ -18,6 +18,8 @@ public record SkillSummaryResponse(
|
|||
Integer ratingCount,
|
||||
String namespace,
|
||||
Instant updatedAt,
|
||||
String ownerId,
|
||||
String ownerDisplayName,
|
||||
boolean canSubmitPromotion,
|
||||
SkillLifecycleVersionResponse headlineVersion,
|
||||
SkillLifecycleVersionResponse publishedVersion,
|
||||
|
|
|
|||
|
|
@ -75,6 +75,8 @@ public class JpaMySkillQueryRepository implements MySkillQueryRepository {
|
|||
skill.getRatingCount(),
|
||||
namespace != null ? namespace.getSlug() : null,
|
||||
skill.getUpdatedAt(),
|
||||
skill.getOwnerId(),
|
||||
null,
|
||||
canSubmitPromotion(skill, publishedVersion, namespace),
|
||||
toLifecycleVersion(headlineVersion),
|
||||
toLifecycleVersion(publishedVersion),
|
||||
|
|
|
|||
|
|
@ -249,6 +249,8 @@ public class SkillSearchAppService {
|
|||
skill.getRatingCount(),
|
||||
namespaceSlug,
|
||||
skill.getUpdatedAt(),
|
||||
skill.getOwnerId(),
|
||||
null,
|
||||
false,
|
||||
toLifecycleVersion(projection.headlineVersion()),
|
||||
toLifecycleVersion(projection.publishedVersion()),
|
||||
|
|
|
|||
|
|
@ -116,6 +116,8 @@ class ClawHubCompatControllerTest {
|
|||
2,
|
||||
"global",
|
||||
Instant.parse("2026-03-13T09:00:00Z"),
|
||||
null,
|
||||
null,
|
||||
false,
|
||||
new SkillLifecycleVersionResponse(11L, "1.2.0", "PUBLISHED"),
|
||||
new SkillLifecycleVersionResponse(11L, "1.2.0", "PUBLISHED"),
|
||||
|
|
|
|||
|
|
@ -51,6 +51,8 @@ class ClawHubRegistryFacadeTest {
|
|||
2,
|
||||
"global",
|
||||
updatedAt,
|
||||
null,
|
||||
null,
|
||||
false,
|
||||
new SkillLifecycleVersionResponse(11L, "1.0.0", "PUBLISHED"),
|
||||
new SkillLifecycleVersionResponse(11L, "1.0.0", "PUBLISHED"),
|
||||
|
|
|
|||
|
|
@ -71,6 +71,8 @@ class MeControllerTest {
|
|||
0,
|
||||
"team-ai",
|
||||
Instant.parse("2026-03-17T12:00:00Z"),
|
||||
null,
|
||||
null,
|
||||
false,
|
||||
new SkillLifecycleVersionResponse(11L, "1.0.0", "PUBLISHED"),
|
||||
new SkillLifecycleVersionResponse(11L, "1.0.0", "PUBLISHED"),
|
||||
|
|
|
|||
|
|
@ -72,7 +72,7 @@ class CliSkillAppServiceTest {
|
|||
List.of(new SkillSummaryResponse(
|
||||
1L, "pdf-parser", "PDF Parser", "Parse PDFs",
|
||||
"PUBLIC", "ACTIVE", 100L, 5, BigDecimal.valueOf(4.5), 10,
|
||||
"global", Instant.now(), false,
|
||||
"global", Instant.now(), null, null, false,
|
||||
new SkillLifecycleVersionResponse(1L, "1.2.0", "PUBLISHED"),
|
||||
new SkillLifecycleVersionResponse(1L, "1.2.0", "PUBLISHED"),
|
||||
null, "PUBLISHED", null
|
||||
|
|
@ -100,7 +100,7 @@ class CliSkillAppServiceTest {
|
|||
new SkillSummaryResponse(
|
||||
2L, "ready", "Ready", "Installable",
|
||||
"PUBLIC", "ACTIVE", 0L, 0, BigDecimal.ZERO, 0,
|
||||
"global", Instant.now(), false,
|
||||
"global", Instant.now(), null, null, false,
|
||||
new SkillLifecycleVersionResponse(2L, "1.0.0", "PUBLISHED"),
|
||||
new SkillLifecycleVersionResponse(2L, "1.0.0", "PUBLISHED"),
|
||||
null, "PUBLISHED", null
|
||||
|
|
|
|||
|
|
@ -208,6 +208,8 @@ export interface SkillSummary {
|
|||
ratingCount: number
|
||||
namespace: string
|
||||
updatedAt: string
|
||||
ownerId?: string
|
||||
ownerDisplayName?: string
|
||||
canSubmitPromotion: boolean
|
||||
headlineVersion?: SkillLifecycleVersion
|
||||
publishedVersion?: SkillLifecycleVersion
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import { Card } from '@/shared/ui/card'
|
|||
import { NamespaceBadge } from '@/shared/components/namespace-badge'
|
||||
import { getHeadlineVersion } from '@/shared/lib/skill-lifecycle'
|
||||
import { formatCompactCount } from '@/shared/lib/number-format'
|
||||
import { Bookmark, ShieldCheck } from 'lucide-react'
|
||||
import { Bookmark, ShieldCheck, User, Clock } from 'lucide-react'
|
||||
|
||||
interface SkillCardProps {
|
||||
skill: SkillSummary
|
||||
|
|
@ -13,6 +13,25 @@ interface SkillCardProps {
|
|||
highlightStarred?: boolean
|
||||
}
|
||||
|
||||
function formatRelativeTime(dateString: string): string {
|
||||
const date = new Date(dateString)
|
||||
const now = new Date()
|
||||
const diffMs = now.getTime() - date.getTime()
|
||||
const diffSeconds = Math.floor(diffMs / 1000)
|
||||
const diffMinutes = Math.floor(diffSeconds / 60)
|
||||
const diffHours = Math.floor(diffMinutes / 60)
|
||||
const diffDays = Math.floor(diffHours / 24)
|
||||
const diffMonths = Math.floor(diffDays / 30)
|
||||
const diffYears = Math.floor(diffDays / 365)
|
||||
|
||||
if (diffSeconds < 60) return '刚刚'
|
||||
if (diffMinutes < 60) return `${diffMinutes}分钟前`
|
||||
if (diffHours < 24) return `${diffHours}小时前`
|
||||
if (diffDays < 30) return `${diffDays}天前`
|
||||
if (diffMonths < 12) return `${diffMonths}个月前`
|
||||
return `${diffYears}年前`
|
||||
}
|
||||
|
||||
/**
|
||||
* Reusable card for displaying one skill in lists such as landing, namespace, search, and stars.
|
||||
*/
|
||||
|
|
@ -108,6 +127,22 @@ export function SkillCard({ skill, onClick, highlightStarred = true }: SkillCard
|
|||
</span>
|
||||
)}
|
||||
</div>
|
||||
{(skill.ownerDisplayName || skill.updatedAt) && (
|
||||
<div className="mt-2 pt-2 border-t border-border/50 flex items-center gap-3 text-xs text-muted-foreground">
|
||||
{skill.ownerDisplayName && (
|
||||
<span className="flex items-center gap-1">
|
||||
<User className="w-3 h-3" />
|
||||
{skill.ownerDisplayName}
|
||||
</span>
|
||||
)}
|
||||
{skill.updatedAt && (
|
||||
<span className="flex items-center gap-1">
|
||||
<Clock className="w-3 h-3" />
|
||||
{formatRelativeTime(skill.updatedAt)}
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</Card>
|
||||
)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue