feat: 解决方案列表页标签排序
All checks were successful
deploy to server / build-and-deploy (push) Successful in 3m1s
All checks were successful
deploy to server / build-and-deploy (push) Successful in 3m1s
- 为SolutionType添加Sort字段用于排序 - 解决方案列表按照sort升序排序
This commit is contained in:
@ -12,7 +12,7 @@ export const useSolutionList = () => {
|
||||
'id',
|
||||
'cover',
|
||||
{
|
||||
type: ['id', { translations: ['id', 'name'] }],
|
||||
type: ['id', { translations: ['id', 'name'] }, 'sort'],
|
||||
},
|
||||
{
|
||||
translations: ['id', 'title', 'summary'],
|
||||
|
||||
@ -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,
|
||||
},
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@ -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<SolutionType>(raw.type)
|
||||
? raw.type.translations.length === 0
|
||||
? ''
|
||||
: raw.type.translations[0].name
|
||||
: '';
|
||||
? toSolutionTypeView(raw.type)
|
||||
: undefined;
|
||||
|
||||
return {
|
||||
id: raw.id,
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -19,14 +19,14 @@
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane
|
||||
v-for="(group, type) in groupedSolutions"
|
||||
:key="type"
|
||||
:label="type || '未分类'"
|
||||
:name="type || 'no-category'"
|
||||
v-for="[key, value] in Object.entries(groupedSolutions)"
|
||||
:key="key"
|
||||
:label="key || '未分类'"
|
||||
:name="key || 'no-category'"
|
||||
>
|
||||
<div class="solution-list">
|
||||
<solution-card
|
||||
v-for="solution in group"
|
||||
v-for="solution in value.data"
|
||||
:key="solution.id"
|
||||
:document-id="solution.id.toString()"
|
||||
:cover-url="getImageUrl(solution.cover || '')"
|
||||
@ -63,22 +63,19 @@
|
||||
|
||||
// 按类型分组
|
||||
const groupedSolutions = computed(() => {
|
||||
const gourps: Record<string, SolutionListView[]> = {};
|
||||
const groups: Record<string, { data: SolutionListView[]; sort: number }> =
|
||||
{};
|
||||
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) => {
|
||||
|
||||
Reference in New Issue
Block a user