feat: 展示 AI 资源创建人信息

- 为 Bot、工作流、知识库、插件列表补充创建人名称回填

- 在卡片中展示创建者与创建时间

- 补充后端与前端对应测试
This commit is contained in:
2026-04-13 14:58:14 +08:00
parent ae10383f17
commit 855e93ecbf
17 changed files with 642 additions and 3 deletions

View File

@@ -18,6 +18,8 @@ import {
ElText,
} from 'element-plus';
import { $t } from '#/locales';
export type ActionPlacement = 'inline' | 'menu';
export type ActionTone = 'danger' | 'default';
@@ -147,6 +149,23 @@ function hasVisibleActions(item: any) {
resolveInlineActions(item).length > 0 || resolveMenuActions(item).length > 0
);
}
function resolveMetaItems(item: any) {
const metaItems: Array<{ label: string; value: string }> = [];
if (item.createdByName) {
metaItems.push({
label: $t('aiResource.createdBy'),
value: String(item.createdByName),
});
}
if (item.created) {
metaItems.push({
label: $t('aiResource.created'),
value: String(item.created),
});
}
return metaItems;
}
</script>
<template>
@@ -203,6 +222,19 @@ function hasVisibleActions(item: any) {
</ElTag>
</slot>
</div>
<div
v-if="resolveMetaItems(item).length > 0"
class="card-meta-row"
>
<span
v-for="meta in resolveMetaItems(item)"
:key="meta.label"
class="card-meta-item"
>
<span class="card-meta-label">{{ meta.label }}</span>
<span class="card-meta-value">{{ meta.value }}</span>
</span>
</div>
</div>
</div>
@@ -355,13 +387,17 @@ function hasVisibleActions(item: any) {
}
.card-header {
display: flex;
gap: 14px;
display: grid;
grid-template-columns: 44px minmax(0, 1fr) auto;
column-gap: 14px;
row-gap: 10px;
align-items: flex-start;
width: 100%;
}
.card-avatar {
grid-column: 1;
grid-row: 1;
background: hsl(var(--surface-subtle));
border: 1px solid hsl(var(--line-subtle));
}
@@ -371,6 +407,8 @@ function hasVisibleActions(item: any) {
flex: 1;
flex-direction: column;
gap: 10px;
grid-column: 2;
grid-row: 1;
min-width: 0;
}
@@ -394,8 +432,41 @@ function hasVisibleActions(item: any) {
color: hsl(var(--text-muted));
}
.card-meta-row {
display: flex;
flex-direction: column;
gap: 4px;
align-items: flex-start;
grid-column: 1 / -1;
width: 100%;
font-size: 12px;
line-height: 18px;
color: hsl(var(--text-muted));
}
.card-meta-item {
display: flex;
gap: 4px;
align-items: flex-start;
justify-content: flex-start;
width: 100%;
min-width: 0;
}
.card-meta-label {
flex-shrink: 0;
}
.card-meta-value {
min-width: 0;
text-align: left;
word-break: break-all;
}
.card-corner-tag {
display: flex;
grid-column: 3;
grid-row: 1;
flex-shrink: 0;
align-items: flex-start;
justify-content: flex-end;

View File

@@ -14,6 +14,16 @@ vi.mock('@easyflow/access', () => ({
}),
}));
vi.mock('#/locales', () => ({
$t: (key: string) => {
const labelMap: Record<string, string> = {
'aiResource.created': '创建时间',
'aiResource.createdBy': '创建者',
};
return labelMap[key] || key;
},
}));
describe('cardList', () => {
function mountCardList(props: Record<string, unknown>) {
return mount(CardList, {
@@ -110,4 +120,55 @@ describe('cardList', () => {
expect(wrapper.get('.card-item').attributes('role')).toBeUndefined();
expect(legacyAction).toHaveBeenCalledTimes(1);
});
it('同时展示创建人与创建时间', () => {
const wrapper = mountCardList({
data: [
{
id: 'bot-1',
title: '演示卡片',
description: '用于验证元信息展示',
createdByName: '管理员',
created: '2026-04-12 10:00:00',
},
],
});
const metaText = wrapper.get('.card-meta-row').text();
expect(metaText).toContain('创建者:管理员');
expect(metaText).toContain('创建时间2026-04-12 10:00:00');
});
it('缺少创建人时仅展示创建时间', () => {
const wrapper = mountCardList({
data: [
{
id: 'bot-1',
title: '演示卡片',
description: '用于验证元信息展示',
created: '2026-04-12 10:00:00',
},
],
});
const metaText = wrapper.get('.card-meta-row').text();
expect(metaText).toContain('创建时间2026-04-12 10:00:00');
expect(metaText).not.toContain('创建者:');
});
it('缺少创建信息时不渲染元信息区', () => {
const wrapper = mountCardList({
data: [
{
id: 'bot-1',
title: '演示卡片',
description: '用于验证元信息展示',
},
],
});
expect(wrapper.find('.card-meta-row').exists()).toBe(false);
});
});