perf: 收敛前端按需加载与图标导入

- 延迟加载第三方登录组件并使用按需 SVG 图标入口

- 修复 CardList 图标依赖并整理组件格式
This commit is contained in:
2026-07-27 19:42:03 +08:00
parent 908eb5583d
commit 24b1142738
8 changed files with 38 additions and 35 deletions

View File

@@ -4,6 +4,7 @@ import type { TagProps } from 'element-plus';
import { computed } from 'vue'; import { computed } from 'vue';
import { useAccess } from '@easyflow/access'; import { useAccess } from '@easyflow/access';
import { IconifyIcon } from '@easyflow/icons';
import { Loading, MoreFilled } from '@element-plus/icons-vue'; import { Loading, MoreFilled } from '@element-plus/icons-vue';
import { import {
@@ -243,10 +244,7 @@ function resolveMetaItems(item: any) {
</ElTag> </ElTag>
</slot> </slot>
</div> </div>
<div <div v-if="resolveMetaItems(item).length > 0" class="card-meta-row">
v-if="resolveMetaItems(item).length > 0"
class="card-meta-row"
>
<span <span
v-for="meta in resolveMetaItems(item)" v-for="meta in resolveMetaItems(item)"
:key="meta.label" :key="meta.label"
@@ -274,11 +272,7 @@ function resolveMetaItems(item: any) {
</div> </div>
</div> </div>
<div <div v-if="hasVisibleActions(item)" class="card-actions" @click.stop>
v-if="hasVisibleActions(item)"
class="card-actions"
@click.stop
>
<ElButton <ElButton
v-for="(action, actionIndex) in resolveInlineActions(item)" v-for="(action, actionIndex) in resolveInlineActions(item)"
:key="`${item.id ?? index}-inline-${actionIndex}`" :key="`${item.id ?? index}-inline-${actionIndex}`"

View File

@@ -127,7 +127,8 @@ const strategyOptions = [
}, },
]; ];
const fileExt = computed(() => const fileExt = computed(
() =>
String(props.documentTitle || '') String(props.documentTitle || '')
.split('.') .split('.')
.pop() .pop()

View File

@@ -12,7 +12,7 @@ import {
SvgCakeIcon, SvgCakeIcon,
SvgCardIcon, SvgCardIcon,
SvgDownloadIcon, SvgDownloadIcon,
} from '@easyflow/icons'; } from '@easyflow/icons/svg';
import AnalyticsTrends from './analytics-trends.vue'; import AnalyticsTrends from './analytics-trends.vue';
import AnalyticsVisitsData from './analytics-visits-data.vue'; import AnalyticsVisitsData from './analytics-visits-data.vue';

View File

@@ -1,9 +1,10 @@
<script setup lang="ts"> <script setup lang="ts">
import type { ChatTimelineKnowledgeHit } from './types'; import type { ChatTimelineKnowledgeHit } from './types';
import {BookOpenText, X} from '@easyflow/icons';
import { computed, ref } from 'vue'; import { computed, ref } from 'vue';
import { BookOpenText, X } from '@easyflow/icons';
interface KnowledgeCitation { interface KnowledgeCitation {
id: string; id: string;
isFaq: boolean; isFaq: boolean;
@@ -50,13 +51,15 @@ function resolveGroupKey(item: ChatTimelineKnowledgeHit, index: number) {
return `faq:${label || asText(item.knowledgeId) || index}`; return `faq:${label || asText(item.knowledgeId) || index}`;
} }
const sourceName = asText(item.documentName) || sourceFileName(item); const sourceName = asText(item.documentName) || sourceFileName(item);
return [ return (
[
'doc', 'doc',
sourceName || asText(item.sourceUri) || label || asText(item.documentId), sourceName || asText(item.sourceUri) || label || asText(item.documentId),
asText(item.knowledgeId), asText(item.knowledgeId),
] ]
.filter(Boolean) .filter(Boolean)
.join(':') || `doc:${index}`; .join(':') || `doc:${index}`
);
} }
function formatScore(score: ChatTimelineKnowledgeHit['score']) { function formatScore(score: ChatTimelineKnowledgeHit['score']) {
@@ -65,7 +68,9 @@ function formatScore(score: ChatTimelineKnowledgeHit['score']) {
} }
const numberValue = Number(score); const numberValue = Number(score);
if (Number.isFinite(numberValue)) { if (Number.isFinite(numberValue)) {
return numberValue > 1 ? numberValue.toFixed(2) : `${Math.round(numberValue * 100)}%`; return numberValue > 1
? numberValue.toFixed(2)
: `${Math.round(numberValue * 100)}%`;
} }
return String(score); return String(score);
} }
@@ -97,8 +102,8 @@ const citations = computed<KnowledgeCitation[]>(() => {
return [...groups.values()]; return [...groups.values()];
}); });
const activeCitation = computed( const activeCitation = computed(() =>
() => citations.value.find((citation) => citation.id === activeId.value), citations.value.find((citation) => citation.id === activeId.value),
); );
function toggleCitation(id: string) { function toggleCitation(id: string) {
@@ -318,7 +323,7 @@ function toggleCitation(id: string) {
.chat-knowledge-card__popover-meta span + span::before { .chat-knowledge-card__popover-meta span + span::before {
margin-right: 6px; margin-right: 6px;
color: var(--el-border-color); color: var(--el-border-color);
content: "·"; content: '·';
} }
.chat-knowledge-card__close { .chat-knowledge-card__close {
@@ -369,7 +374,7 @@ function toggleCitation(id: string) {
.chat-knowledge-card__meta span + span::before { .chat-knowledge-card__meta span + span::before {
margin-right: 6px; margin-right: 6px;
color: var(--el-border-color); color: var(--el-border-color);
content: "/"; content: '/';
} }
.chat-knowledge-card__content { .chat-knowledge-card__content {

View File

@@ -1,7 +1,7 @@
<script setup lang="ts"> <script setup lang="ts">
import { useRoute } from 'vue-router'; import { useRoute } from 'vue-router';
import { SvgDingDingIcon } from '@easyflow/icons'; import { SvgDingDingIcon } from '@easyflow/icons/svg';
import { $t } from '@easyflow/locales'; import { $t } from '@easyflow/locales';
import { alert, useEasyFlowModal } from '@easyflow-core/popup-ui'; import { alert, useEasyFlowModal } from '@easyflow-core/popup-ui';

View File

@@ -5,7 +5,7 @@ import type { EasyFlowFormSchema } from '@easyflow-core/form-ui';
import type { AuthenticationProps } from './types'; import type { AuthenticationProps } from './types';
import { computed, onMounted, reactive, ref } from 'vue'; import { computed, defineAsyncComponent, onMounted, reactive, ref } from 'vue';
import { useRouter } from 'vue-router'; import { useRouter } from 'vue-router';
import { $t } from '@easyflow/locales'; import { $t } from '@easyflow/locales';
@@ -14,7 +14,6 @@ import { useEasyFlowForm } from '@easyflow-core/form-ui';
import { EasyFlowButton, EasyFlowCheckbox } from '@easyflow-core/shadcn-ui'; import { EasyFlowButton, EasyFlowCheckbox } from '@easyflow-core/shadcn-ui';
import Title from './auth-title.vue'; import Title from './auth-title.vue';
import ThirdPartyLogin from './third-party-login.vue';
interface Props extends AuthenticationProps { interface Props extends AuthenticationProps {
formSchema?: EasyFlowFormSchema[]; formSchema?: EasyFlowFormSchema[];
@@ -47,6 +46,10 @@ const emit = defineEmits<{
submit: [Recordable<any>]; submit: [Recordable<any>];
}>(); }>();
const ThirdPartyLogin = defineAsyncComponent(
() => import('./third-party-login.vue'),
);
const [Form, formApi] = useEasyFlowForm( const [Form, formApi] = useEasyFlowForm(
reactive({ reactive({
commonConfig: { commonConfig: {

View File

@@ -5,7 +5,7 @@ import {
SvgGoogleIcon, SvgGoogleIcon,
SvgQQChatIcon, SvgQQChatIcon,
SvgWeChatIcon, SvgWeChatIcon,
} from '@easyflow/icons'; } from '@easyflow/icons/svg';
import { $t } from '@easyflow/locales'; import { $t } from '@easyflow/locales';
import { EasyFlowIconButton } from '@easyflow-core/shadcn-ui'; import { EasyFlowIconButton } from '@easyflow-core/shadcn-ui';