From 0363a887853086be759b99e0159c1a2941ed361b Mon Sep 17 00:00:00 2001 From: R2m1liA <15258427350@163.com> Date: Sat, 8 Nov 2025 15:46:37 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E8=A7=A3=E5=86=B3=E6=96=B9=E6=A1=88?= =?UTF-8?q?=E5=88=97=E8=A1=A8=E9=A1=B5=E6=A0=87=E7=AD=BE=E6=8E=92=E5=BA=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 为SolutionType添加Sort字段用于排序 - 解决方案列表按照sort升序排序 --- app/composables/directus/useSolutionList.ts | 2 +- app/models/mappers/solutionMapper.test.ts | 14 +++++++-- app/models/mappers/solutionMapper.ts | 27 ++++++++++++++--- app/models/views/SolutionListView.ts | 17 ++++++++++- app/pages/solutions/index.vue | 33 ++++++++++----------- 5 files changed, 67 insertions(+), 26 deletions(-) diff --git a/app/composables/directus/useSolutionList.ts b/app/composables/directus/useSolutionList.ts index 030e272..8fe659f 100644 --- a/app/composables/directus/useSolutionList.ts +++ b/app/composables/directus/useSolutionList.ts @@ -12,7 +12,7 @@ export const useSolutionList = () => { 'id', 'cover', { - type: ['id', { translations: ['id', 'name'] }], + type: ['id', { translations: ['id', 'name'] }, 'sort'], }, { translations: ['id', 'title', 'summary'], diff --git a/app/models/mappers/solutionMapper.test.ts b/app/models/mappers/solutionMapper.test.ts index 1850d47..743414f 100644 --- a/app/models/mappers/solutionMapper.test.ts +++ b/app/models/mappers/solutionMapper.test.ts @@ -13,6 +13,7 @@ describe('toSolutionListView', () => { type: { id: 1, translations: [{ id: 1, name: 'Type Name' }], + sort: 1, }, }; @@ -20,7 +21,11 @@ describe('toSolutionListView', () => { id: 1, title: 'Solution Title', summary: 'Solution Summary', - solution_type: 'Type Name', + solution_type: { + id: 1, + name: 'Type Name', + sort: 1, + }, }); }); @@ -31,6 +36,7 @@ describe('toSolutionListView', () => { type: { id: 1, translations: [], + sort: null, }, }; @@ -38,7 +44,11 @@ describe('toSolutionListView', () => { id: 1, title: '', summary: '', - solution_type: '', + solution_type: { + id: 1, + name: '', + sort: 999, + }, }); }); }); diff --git a/app/models/mappers/solutionMapper.ts b/app/models/mappers/solutionMapper.ts index baf1694..d869024 100644 --- a/app/models/mappers/solutionMapper.ts +++ b/app/models/mappers/solutionMapper.ts @@ -1,3 +1,24 @@ +/** + * 将 Directus 返回的 SolutionType 数据转换为 SolutionTypeView 视图模型 + * + * @param raw: 原始的 SolutionType 数据 + * @returns 转换后的 SolutionTypeView 对象 + * + * --- + * + * @example + * const view = toSolutionTypeView(rawSolutionType); + */ +export function toSolutionTypeView(raw: SolutionType): SolutionTypeView { + const trans = raw.translations?.[0] ?? { name: '' }; + + return { + id: raw.id, + name: trans.name, + sort: raw?.sort ?? 999, + }; +} + /** * 将 Directus 返回的 Solution 数据转换为 SolutionListView 视图模型 * @@ -16,10 +37,8 @@ export function toSolutionListView(raw: Solution): SolutionListView { }; const type = isObject(raw.type) - ? raw.type.translations.length === 0 - ? '' - : raw.type.translations[0].name - : ''; + ? toSolutionTypeView(raw.type) + : undefined; return { id: raw.id, diff --git a/app/models/views/SolutionListView.ts b/app/models/views/SolutionListView.ts index fa41cfe..b688271 100644 --- a/app/models/views/SolutionListView.ts +++ b/app/models/views/SolutionListView.ts @@ -1,3 +1,18 @@ +/** + * 解决方案类型视图模型 + * 用于解决方案列表页标签栏的渲染与排序 + */ +export interface SolutionTypeView { + /** 唯一标识符 **/ + id: number; + + /** 类型名 **/ + name: string; + + /** 排序字段 **/ + sort: number; +} + /** * 解决方案列表模型 * 用于解决方案列表(/solutions)渲染的数据结构 @@ -13,7 +28,7 @@ export interface SolutionListView { summary: string; /** 解决方案类型 **/ - solution_type: string; + solution_type: SolutionTypeView; /** 解决方案封面(图片id) **/ cover: string; diff --git a/app/pages/solutions/index.vue b/app/pages/solutions/index.vue index 24f293d..33bf637 100644 --- a/app/pages/solutions/index.vue +++ b/app/pages/solutions/index.vue @@ -19,14 +19,14 @@
{ - const gourps: Record = {}; + const groups: Record = + {}; for (const sol of solutions.value) { - let typeKey = ''; - if (typeof sol.solution_type === 'string') { - typeKey = sol.solution_type; - } else if ( - sol.solution_type && - typeof sol.solution_type === 'object' && - 'type' in sol.solution_type - ) { - typeKey = sol.solution_type || ''; + const typeKey = sol.solution_type?.name ?? ''; + if (!groups[typeKey]) { + groups[typeKey] = { data: [], sort: sol.solution_type?.sort ?? 999 }; } - if (!gourps[typeKey]) gourps[typeKey] = []; - gourps[typeKey]?.push(sol); + groups[typeKey]?.data.push(sol); } - return gourps; + const sortedGroups = Object.fromEntries( + Object.entries(groups).sort(([, a], [, b]) => a.sort - b.sort) + ); + return sortedGroups; }); watch(error, (value) => {