diff --git a/app/composables/directus/useProduct.ts b/app/composables/directus/useProduct.ts index 67c18ed..6ac5c1e 100644 --- a/app/composables/directus/useProduct.ts +++ b/app/composables/directus/useProduct.ts @@ -1,4 +1,5 @@ -import { readItem } from '@directus/sdk'; +import GetProduct from '@/graphql/product.graphql'; +import { print } from 'graphql'; export const useProduct = (id: string) => { const { $directus } = useNuxtApp(); @@ -7,104 +8,111 @@ export const useProduct = (id: string) => { const locale = getDirectusLocale(); return useAsyncData(`product-${id}-${locale}`, async () => { - return await $directus.request( - readItem('products', id, { - fields: [ - 'id', - { translations: ['id', 'name', 'summary', 'description'] }, - { - images: [ - 'id', - { - product_images_id: [ - 'id', - 'image', - { translations: ['id', 'caption'] }, - ], - }, - ], - }, - { - specs: [ - 'id', - { - translations: ['*'], - }, - { - specs: [ - 'id', - { - translations: ['id', 'key', 'value'], - }, - ], - }, - ], - }, - { - faqs: [ - 'id', - { - questions_id: [ - 'id', - { - translations: ['id', 'title', 'content'], - }, - ], - }, - ], - }, - { - documents: [ - 'id', - { - product_documents_id: [ - 'id', - { - file: ['id', 'filesize', 'filename_download'], - }, - { - translations: ['id', 'title'], - }, - ], - }, - ], - }, - ], - deep: { - translations: { - _filter: { - languages_code: { _eq: locale }, - }, - }, - images: { - product_images_id: { - translations: { - _filter: { - languages_code: { _eq: locale }, - }, - }, - }, - }, - faqs: { - questions_id: { - translations: { - _filter: { - languages_code: { _eq: locale }, - }, - }, - }, - }, - documents: { - documents_id: { - translations: { - _filter: { - languages_code: { _eq: locale }, - }, - }, - }, - }, - }, - }) + return await $directus.query<{ products_by_id: Product }>( + print(GetProduct), + { + id: id, + locale: locale, + } ); + // return await $directus.request( + // readItem('products', id, { + // fields: [ + // 'id', + // { translations: ['id', 'name', 'summary', 'description'] }, + // { + // images: [ + // 'id', + // { + // product_images_id: [ + // 'id', + // 'image', + // { translations: ['id', 'caption'] }, + // ], + // }, + // ], + // }, + // { + // specs: [ + // 'id', + // { + // translations: ['*'], + // }, + // { + // specs: [ + // 'id', + // { + // translations: ['id', 'key', 'value'], + // }, + // ], + // }, + // ], + // }, + // { + // faqs: [ + // 'id', + // { + // questions_id: [ + // 'id', + // { + // translations: ['id', 'title', 'content'], + // }, + // ], + // }, + // ], + // }, + // { + // documents: [ + // 'id', + // { + // product_documents_id: [ + // 'id', + // { + // file: ['id', 'filesize', 'filename_download'], + // }, + // { + // translations: ['id', 'title'], + // }, + // ], + // }, + // ], + // }, + // ], + // deep: { + // translations: { + // _filter: { + // languages_code: { _eq: locale }, + // }, + // }, + // images: { + // product_images_id: { + // translations: { + // _filter: { + // languages_code: { _eq: locale }, + // }, + // }, + // }, + // }, + // faqs: { + // questions_id: { + // translations: { + // _filter: { + // languages_code: { _eq: locale }, + // }, + // }, + // }, + // }, + // documents: { + // documents_id: { + // translations: { + // _filter: { + // languages_code: { _eq: locale }, + // }, + // }, + // }, + // }, + // }, + // }) + // ); }); }; diff --git a/app/composables/directus/useProductList.ts b/app/composables/directus/useProductList.ts index 989c88d..d13739c 100644 --- a/app/composables/directus/useProductList.ts +++ b/app/composables/directus/useProductList.ts @@ -1,4 +1,5 @@ -import { readItems } from '@directus/sdk'; +import GetProductList from '@/graphql/productList.graphql'; +import { print } from 'graphql'; export const useProductList = () => { const { $directus } = useNuxtApp(); @@ -7,37 +8,11 @@ export const useProductList = () => { const locale = getDirectusLocale(); return useAsyncData(`product-list-${locale}`, async () => { - return await $directus.request( - readItems('products', { - fields: [ - 'id', - { translations: ['id', 'name', 'summary'] }, - 'cover', - { - product_type: [ - 'id', - { - translations: ['id', 'name'], - }, - 'sort', - ], - }, - ], - deep: { - translations: { - _filter: { - languages_code: { _eq: locale }, - }, - }, - product_type: { - translations: { - _filter: { - languages_code: { _eq: locale }, - }, - }, - }, - }, - }) + return await $directus.query<{ products: Product[] }>( + print(GetProductList), + { + locale: locale, + } ); }); }; diff --git a/app/graphql/product.graphql b/app/graphql/product.graphql new file mode 100644 index 0000000..5965746 --- /dev/null +++ b/app/graphql/product.graphql @@ -0,0 +1,66 @@ +query GetProduct($id: ID!, $locale: String!) { + products_by_id(id: $id) { + id + status + translations(filter: { languages_code: { code: { _eq: $locale } } }) { + id + name + summary + description + } + images { + id + product_images_id { + id + image { + id + } + translations(filter: { languages_code: { code: { _eq: $locale } } }) { + id + caption + } + } + } + specs { + id + translations(filter: { languages_code: { code: { _eq: $locale } } }) { + id + name + } + specs { + translations(filter: { languages_code: { code: { _eq: $locale } } }) { + id + key + value + } + } + } + faqs { + id + questions_id { + id + translations(filter: { languages_code: { code: { _eq: $locale } } }) { + id + title + content + } + } + } + documents { + id + product_documents_id { + id + file { + id + filesize + filename_download + } + translations(filter: { languages_code: { code: { _eq: $locale } } }) { + id + title + } + } + } + } +} + diff --git a/app/graphql/productList.graphql b/app/graphql/productList.graphql new file mode 100644 index 0000000..788d12a --- /dev/null +++ b/app/graphql/productList.graphql @@ -0,0 +1,22 @@ +query GetProductList($locale: String!) { + products(filter: { status: { _eq: "in-production" } }) { + id + status + translations(filter: { languages_code: { code: { _eq: $locale } } }) { + id + name + summary + } + cover { + id + } + product_type { + id + translations(filter: { languages_code: { code: { _eq: $locale } } }) { + id + name + } + sort + } + } +} diff --git a/app/models/mappers/productMapper.test.ts b/app/models/mappers/productMapper.test.ts index 1e996f0..ad9a837 100644 --- a/app/models/mappers/productMapper.test.ts +++ b/app/models/mappers/productMapper.test.ts @@ -10,7 +10,9 @@ describe('toProductListView', () => { translations: [ { id: 10, name: 'Product Name', summary: 'Product Summary' }, ], - cover: 'cover-file-uuid-1234', + cover: { + id: 'cover-file-uuid-1234', + }, product_type: { id: 1, translations: [{ id: 20, name: 'Type Name' }], @@ -35,7 +37,9 @@ describe('toProductListView', () => { const rawData: Product = { id: 1, translations: [], - cover: 'cover-file-uuid-1234', + cover: { + id: 'cover-file-uuid-1234', + }, product_type: { id: 20, translations: [], diff --git a/app/models/mappers/productMapper.ts b/app/models/mappers/productMapper.ts index 724faff..9c61a5e 100644 --- a/app/models/mappers/productMapper.ts +++ b/app/models/mappers/productMapper.ts @@ -33,12 +33,14 @@ export function toProductListView(raw: Product): ProductListView { ? toProductTypeView(raw.product_type) : undefined; + const cover = isObject(raw.cover) ? raw.cover.id : ''; + return { id: raw.id, product_type: type, name: trans.name, summary: trans.summary, - cover: raw.cover.toString(), + cover: cover, }; } @@ -110,9 +112,10 @@ export function toProductView(raw: Product): ProductView { .map((item) => item.product_images_id) .filter(isObject) .map((item) => { + const image = isObject(item.image) ? item.image.id : ''; return { id: item.id, - image: item.image.toString(), + image: image, caption: item.translations?.[0]?.caption || '', }; }); diff --git a/app/pages/products/[...slug].vue b/app/pages/products/[slug].vue similarity index 86% rename from app/pages/products/[...slug].vue rename to app/pages/products/[slug].vue index cca08a3..6eee50a 100644 --- a/app/pages/products/[...slug].vue +++ b/app/pages/products/[slug].vue @@ -35,11 +35,12 @@ const localePath = useLocalePath(); // 获取路由参数 - const id = computed(() => route.params.slug as string); + const id = route.params.slug as string; - const { data, pending, error } = await useProduct(id.value); + const { data, pending, error } = await useProduct(id); + + const rawProduct = computed(() => data.value.products_by_id ?? null); - const rawProduct = computed(() => data.value ?? null); const product = computed(() => { if (rawProduct.value === null) { return null; @@ -60,10 +61,10 @@ }); // SEO - usePageSeo({ - title: product.value.name || $t('page-title.products'), - description: product.value.summary || '', - }); + // usePageSeo({ + // title: product.value.name || $t('page-title.products'), + // description: product.value.summary || '', + // });