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) => {