feat: 相关问题查询添加问题类型查询

- 查询语句更改:添加type字段
- mapper增添:添加type字段的mapper
- 视图模型更改:QuestionListView添加type字段
This commit is contained in:
2025-12-03 15:53:20 +08:00
parent c82fea48b8
commit f4ec82a150
4 changed files with 110 additions and 1 deletions

View File

@ -1,6 +1,13 @@
query GetQuestionList($locale: String!) { query GetQuestionList($locale: String!) {
questions(filter: { status: { _eq: "published" } }) { questions(filter: { status: { _eq: "published" } }) {
id id
type {
id
translations(filter: { languages_code: { code: { _eq: $locale } } }) {
id
name
}
}
translations(filter: { languages_code: { code: { _eq: $locale } } }) { translations(filter: { languages_code: { code: { _eq: $locale } } }) {
id id
title title

View File

@ -1,5 +1,51 @@
import { describe, expect, test } from 'vitest'; import { describe, expect, test } from 'vitest';
import { toProductQuestionView, toQuestionListView } from './questionMapper'; import {
toProductQuestionView,
toQuestionListView,
toQuestionTypeView,
} from './questionMapper';
/**
* 单元测试: toQuestionTypeView
*/
describe('toQuestionTypeView', () => {
const baseData: QuestionType = {
id: 1,
translations: [{ id: 1, name: 'Type Name' }],
};
test('convert raw data to QuestionTypeView correctly', () => {
const rawData: QuestionType = {
...baseData,
};
expect(toQuestionTypeView(rawData)).toEqual({
id: '1',
type: 'Type Name',
});
});
test('convert raw data with missing translations', () => {
const rawData: QuestionType = {
...baseData,
translations: [],
};
expect(toQuestionTypeView(rawData)).toEqual({
id: '1',
type: '',
});
});
test('convert null input to default QuestionTypeView', () => {
const rawData: QuestionType | null = null;
expect(toQuestionTypeView(rawData)).toEqual({
id: '',
type: '',
});
});
});
/** /**
* 单元测试: toProductQuestionView * 单元测试: toProductQuestionView
@ -43,6 +89,10 @@ describe('toProductQuestionView', () => {
describe('toQuestionListView', () => { describe('toQuestionListView', () => {
const baseData: Question = { const baseData: Question = {
id: 1, id: 1,
type: {
id: 1,
translations: [{ id: 1, name: 'Type Name' }],
},
translations: [ translations: [
{ id: 1, title: 'Question Title', content: 'Question Answer' }, { id: 1, title: 'Question Title', content: 'Question Answer' },
], ],
@ -68,6 +118,10 @@ describe('toQuestionListView', () => {
expect(toQuestionListView(rawData)).toEqual({ expect(toQuestionListView(rawData)).toEqual({
id: '1', id: '1',
type: {
id: '1',
type: 'Type Name',
},
title: 'Question Title', title: 'Question Title',
content: 'Question Answer', content: 'Question Answer',
products: [ products: [
@ -104,6 +158,10 @@ describe('toQuestionListView', () => {
expect(toQuestionListView(rawData)).toEqual({ expect(toQuestionListView(rawData)).toEqual({
id: '1', id: '1',
type: {
id: '1',
type: 'Type Name',
},
title: '', title: '',
content: '', content: '',
products: [ products: [

View File

@ -1,5 +1,31 @@
import { isObject } from '../../server/utils/object'; import { isObject } from '../../server/utils/object';
/**
* 将 Directus 返回的 QuestionType 类型转换为 QuestionTypeView 视图模型
*
* @param raw: 原始的 QuestionType 数据
* @returns 转换后的 QuestionTypeView 对象
*
* @example
* const view = toQuestionTypeView(rawQuestionType);
*/
export function toQuestionTypeView(
raw: QuestionType | string | null
): QuestionTypeView {
if (typeof raw === 'string' || raw === null) {
return {
id: '',
type: '',
} satisfies QuestionTypeView;
}
const trans = raw.translations?.[0];
return {
id: raw.id.toString(),
type: trans?.name ?? '',
};
}
/** /**
* 将 Directus 返回的 Question 数据转换为 ProductQuestionView 视图模型 * 将 Directus 返回的 Question 数据转换为 ProductQuestionView 视图模型
* *
@ -31,6 +57,8 @@ export function toProductQuestionView(raw: Question): ProductQuestionView {
export function toQuestionListView(raw: Question): QuestionListView { export function toQuestionListView(raw: Question): QuestionListView {
const trans = raw.translations?.[0]; const trans = raw.translations?.[0];
const type = toQuestionTypeView(raw.type ?? null);
const related_products: QuestionListProduct[] = (raw.products ?? []) const related_products: QuestionListProduct[] = (raw.products ?? [])
.filter(isObject<ProductsQuestion>) .filter(isObject<ProductsQuestion>)
.map((item) => item.products_id) .map((item) => item.products_id)
@ -57,6 +85,7 @@ export function toQuestionListView(raw: Question): QuestionListView {
return { return {
id: raw.id.toString(), id: raw.id.toString(),
type: type,
title: trans?.title ?? '', title: trans?.title ?? '',
content: trans?.content ?? '', content: trans?.content ?? '',
products: related_products, products: related_products,

View File

@ -7,6 +7,18 @@ export interface QuestionListProductType {
name: string; name: string;
} }
/**
* 问题类型
* 用于在常见问题列表中提供产品筛选功能
*/
export interface QuestionTypeView {
/** 唯一标识符 **/
id: string;
/** 类型名 **/
type: string;
}
/** /**
* 问题关联产品模型 * 问题关联产品模型
* 用于在常见问题列表中提供产品筛选功能 * 用于在常见问题列表中提供产品筛选功能
@ -25,6 +37,9 @@ export interface QuestionListView {
/** 唯一标识符 **/ /** 唯一标识符 **/
id: string; id: string;
/** 问题类型 **/
type: QuestionTypeView;
/** 问题标题 **/ /** 问题标题 **/
title: string; title: string;