refactor: 重构项目的数据获取方法 #72
5
.graphqlrc.yaml
Normal file
5
.graphqlrc.yaml
Normal file
@ -0,0 +1,5 @@
|
||||
schema:
|
||||
- 'http://192.168.86.5:8055/graphql':
|
||||
headers:
|
||||
Authorization: 'Bearer ixSWeViHIqwj6_r7NM-uZVR3NNOyBa_W'
|
||||
documents: 'app/graphql/**/*.{graphql,js,ts,jsx,tsx}'
|
||||
@ -1,4 +1,4 @@
|
||||
import { readSingleton } from '@directus/sdk';
|
||||
import GetCompanyProfile from '@/graphql/companyProfile.graphql?raw';
|
||||
|
||||
export const useCompanyProfile = () => {
|
||||
const { $directus } = useNuxtApp();
|
||||
@ -6,24 +6,11 @@ export const useCompanyProfile = () => {
|
||||
const locale = getDirectusLocale();
|
||||
|
||||
return useAsyncData(`company-profile-${locale}`, async () => {
|
||||
return await $directus.request(
|
||||
readSingleton('company_profile', {
|
||||
fields: [
|
||||
'id',
|
||||
{
|
||||
translations: ['id', 'content'],
|
||||
},
|
||||
],
|
||||
deep: {
|
||||
translations: {
|
||||
_filter: {
|
||||
languages_code: {
|
||||
_eq: locale,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
return await $directus.query<{ company_profile: CompanyProfile }>(
|
||||
GetCompanyProfile,
|
||||
{
|
||||
locale: locale,
|
||||
}
|
||||
);
|
||||
});
|
||||
};
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { readSingleton } from '@directus/sdk';
|
||||
import GetContactInfo from '@/graphql/contactInfo.graphql?raw';
|
||||
|
||||
export const useContactInfo = () => {
|
||||
const { $directus } = useNuxtApp();
|
||||
@ -6,24 +6,11 @@ export const useContactInfo = () => {
|
||||
const locale = getDirectusLocale();
|
||||
|
||||
return useAsyncData(`contact-info-${locale}`, async () => {
|
||||
return await $directus.request(
|
||||
readSingleton('contact_info', {
|
||||
fields: [
|
||||
'id',
|
||||
{
|
||||
translations: ['id', 'content'],
|
||||
},
|
||||
],
|
||||
deep: {
|
||||
translations: {
|
||||
_filter: {
|
||||
languages_code: {
|
||||
_eq: locale,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
return await $directus.query<{ contact_info: ContactInfo }>(
|
||||
GetContactInfo,
|
||||
{
|
||||
locale: locale,
|
||||
}
|
||||
);
|
||||
});
|
||||
};
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { readItems } from '@directus/sdk';
|
||||
import GetDocumentList from '@/graphql/documentList.graphql?raw';
|
||||
|
||||
export const useDocumentList = () => {
|
||||
const { $directus } = useNuxtApp();
|
||||
@ -6,62 +6,11 @@ export const useDocumentList = () => {
|
||||
const locale = getDirectusLocale();
|
||||
|
||||
return useAsyncData(`document-list-${locale}`, async () => {
|
||||
return await $directus.request(
|
||||
readItems('product_documents', {
|
||||
fields: [
|
||||
'id',
|
||||
{
|
||||
file: ['id', 'filesize', 'filename_download'],
|
||||
},
|
||||
{
|
||||
translations: ['id', 'title'],
|
||||
},
|
||||
{
|
||||
products: [
|
||||
'id',
|
||||
{
|
||||
products_id: [
|
||||
'id',
|
||||
{
|
||||
translations: ['id', 'name'],
|
||||
},
|
||||
{
|
||||
product_type: [
|
||||
'id',
|
||||
{
|
||||
translations: ['id', 'name'],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
deep: {
|
||||
translations: {
|
||||
_filter: {
|
||||
languages_code: { _eq: locale },
|
||||
},
|
||||
},
|
||||
products: {
|
||||
products_id: {
|
||||
translations: {
|
||||
_filter: {
|
||||
languages_code: { _eq: locale },
|
||||
},
|
||||
},
|
||||
product_type: {
|
||||
translations: {
|
||||
_filter: {
|
||||
languages_code: { _eq: locale },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
return await $directus.query<{ product_documents: ProductDocument[] }>(
|
||||
GetDocumentList,
|
||||
{
|
||||
locale: locale,
|
||||
}
|
||||
);
|
||||
});
|
||||
};
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { readSingleton } from '@directus/sdk';
|
||||
import GetHomepage from '@/graphql/homepage.graphql?raw';
|
||||
|
||||
export const useHomepage = () => {
|
||||
const { $directus } = useNuxtApp();
|
||||
@ -6,49 +6,8 @@ export const useHomepage = () => {
|
||||
const locale = getDirectusLocale();
|
||||
|
||||
return useAsyncData(`homepage-${locale}`, async () => {
|
||||
return await $directus.request(
|
||||
readSingleton('homepage', {
|
||||
fields: [
|
||||
'id',
|
||||
{
|
||||
carousel: ['id', 'directus_files_id'],
|
||||
},
|
||||
{
|
||||
recommend_products: [
|
||||
'id',
|
||||
{
|
||||
translations: ['id', 'name', 'summary'],
|
||||
},
|
||||
'cover',
|
||||
],
|
||||
},
|
||||
{
|
||||
recommend_solutions: [
|
||||
'id',
|
||||
{
|
||||
translations: ['id', 'title', 'summary'],
|
||||
},
|
||||
'cover',
|
||||
],
|
||||
},
|
||||
],
|
||||
deep: {
|
||||
recommend_products: {
|
||||
translations: {
|
||||
_filter: {
|
||||
languages_code: { _eq: locale },
|
||||
},
|
||||
},
|
||||
},
|
||||
recommend_solutions: {
|
||||
translations: {
|
||||
_filter: {
|
||||
languages_code: { _eq: locale },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
);
|
||||
return await $directus.query<{ homepage: Homepage }>(GetHomepage, {
|
||||
locale: locale,
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { readItem } from '@directus/sdk';
|
||||
import GetProduct from '@/graphql/product.graphql?raw';
|
||||
|
||||
export const useProduct = (id: string) => {
|
||||
const { $directus } = useNuxtApp();
|
||||
@ -7,104 +7,9 @@ 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 }>(GetProduct, {
|
||||
id: id,
|
||||
locale: locale,
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { readItems } from '@directus/sdk';
|
||||
import GetProductList from '@/graphql/productList.graphql?raw';
|
||||
|
||||
export const useProductList = () => {
|
||||
const { $directus } = useNuxtApp();
|
||||
@ -7,37 +7,8 @@ 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[] }>(GetProductList, {
|
||||
locale: locale,
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { readItems } from '@directus/sdk';
|
||||
import GetQuestionList from '@/graphql/questionList.graphql?raw';
|
||||
|
||||
export const useQuestionList = () => {
|
||||
const { $directus } = useNuxtApp();
|
||||
@ -7,57 +7,8 @@ export const useQuestionList = () => {
|
||||
const locale = getDirectusLocale();
|
||||
|
||||
return useAsyncData(`question-list-${locale}`, async () => {
|
||||
return await $directus.request(
|
||||
readItems('questions', {
|
||||
fields: [
|
||||
'id',
|
||||
{
|
||||
translations: ['*'],
|
||||
},
|
||||
{
|
||||
products: [
|
||||
'id',
|
||||
{
|
||||
products_id: [
|
||||
'id',
|
||||
{
|
||||
product_type: [
|
||||
'id',
|
||||
{
|
||||
translations: ['id', 'name'],
|
||||
},
|
||||
],
|
||||
},
|
||||
{ translations: ['id', 'name'] },
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
deep: {
|
||||
translations: {
|
||||
_filter: {
|
||||
languages_code: { _eq: locale },
|
||||
},
|
||||
},
|
||||
products: {
|
||||
products_id: {
|
||||
product_type: {
|
||||
translations: {
|
||||
_filter: {
|
||||
languages_code: { _eq: locale },
|
||||
},
|
||||
},
|
||||
},
|
||||
translations: {
|
||||
_filter: {
|
||||
languages_code: { _eq: locale },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
);
|
||||
return await $directus.query<{ questions: Question[] }>(GetQuestionList, {
|
||||
locale: locale,
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { readItem } from '@directus/sdk';
|
||||
import GetSolution from '@/graphql/solution.graphql?raw';
|
||||
|
||||
export const useSolution = (id: string) => {
|
||||
const { $directus } = useNuxtApp();
|
||||
@ -6,23 +6,9 @@ export const useSolution = (id: string) => {
|
||||
const locale = getDirectusLocale();
|
||||
|
||||
return useAsyncData(`solution-${id}-${locale}`, async () => {
|
||||
return await $directus.request(
|
||||
readItem('solutions', id, {
|
||||
fields: [
|
||||
'id',
|
||||
{
|
||||
translations: ['*'],
|
||||
},
|
||||
'create_at',
|
||||
],
|
||||
deep: {
|
||||
translations: {
|
||||
_filter: {
|
||||
languages_code: { _eq: locale },
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
);
|
||||
return await $directus.query<{ solutions_by_id: Solution }>(GetSolution, {
|
||||
id: id,
|
||||
locale: locale,
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { readItems } from '@directus/sdk';
|
||||
import GetSolutionList from '@/graphql/solutionList.graphql?raw';
|
||||
|
||||
export const useSolutionList = () => {
|
||||
const { $directus } = useNuxtApp();
|
||||
@ -6,33 +6,8 @@ export const useSolutionList = () => {
|
||||
const locale = getDirectusLocale();
|
||||
|
||||
return useAsyncData(`solution-list-${locale}`, async () => {
|
||||
return await $directus.request(
|
||||
readItems('solutions', {
|
||||
fields: [
|
||||
'id',
|
||||
'cover',
|
||||
{
|
||||
type: ['id', { translations: ['id', 'name'] }, 'sort'],
|
||||
},
|
||||
{
|
||||
translations: ['id', 'title', 'summary'],
|
||||
},
|
||||
],
|
||||
deep: {
|
||||
type: {
|
||||
translations: {
|
||||
_filter: {
|
||||
languages_code: { _eq: locale },
|
||||
},
|
||||
},
|
||||
},
|
||||
translations: {
|
||||
_filter: {
|
||||
languages_code: { _eq: locale },
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
);
|
||||
return await $directus.query<{ solutions: Solution[] }>(GetSolutionList, {
|
||||
locale: locale,
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
9
app/graphql/companyProfile.graphql
Normal file
9
app/graphql/companyProfile.graphql
Normal file
@ -0,0 +1,9 @@
|
||||
query GetCompanyProfile($locale: String!) {
|
||||
company_profile {
|
||||
id
|
||||
translations(filter: { languages_code: { code: { _eq: $locale } } }) {
|
||||
id
|
||||
content
|
||||
}
|
||||
}
|
||||
}
|
||||
9
app/graphql/contactInfo.graphql
Normal file
9
app/graphql/contactInfo.graphql
Normal file
@ -0,0 +1,9 @@
|
||||
query GetContactInfo($locale: String!) {
|
||||
contact_info {
|
||||
id
|
||||
translations(filter: { languages_code: { code: { _eq: $locale } } }) {
|
||||
id
|
||||
content
|
||||
}
|
||||
}
|
||||
}
|
||||
31
app/graphql/documentList.graphql
Normal file
31
app/graphql/documentList.graphql
Normal file
@ -0,0 +1,31 @@
|
||||
query GetDocumentList($locale: String!) {
|
||||
product_documents {
|
||||
id
|
||||
file {
|
||||
id
|
||||
filesize
|
||||
filename_download
|
||||
}
|
||||
translations(filter: { languages_code: { code: { _eq: $locale } } }) {
|
||||
id
|
||||
title
|
||||
}
|
||||
products {
|
||||
id
|
||||
products_id {
|
||||
id
|
||||
translations(filter: { languages_code: { code: { _eq: $locale } } }) {
|
||||
id
|
||||
name
|
||||
}
|
||||
product_type {
|
||||
id
|
||||
translations(filter: { languages_code: { code: { _eq: $locale } } }) {
|
||||
id
|
||||
name
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
33
app/graphql/homepage.graphql
Normal file
33
app/graphql/homepage.graphql
Normal file
@ -0,0 +1,33 @@
|
||||
query GetHomepage($locale: String!) {
|
||||
homepage {
|
||||
id
|
||||
carousel {
|
||||
id
|
||||
directus_files_id {
|
||||
id
|
||||
}
|
||||
}
|
||||
recommend_products {
|
||||
id
|
||||
translations(filter: { languages_code: { code: { _eq: $locale } } }) {
|
||||
id
|
||||
name
|
||||
summary
|
||||
}
|
||||
cover {
|
||||
id
|
||||
}
|
||||
}
|
||||
recommend_solutions {
|
||||
id
|
||||
translations(filter: { languages_code: { code: { _eq: $locale } } }) {
|
||||
id
|
||||
title
|
||||
summary
|
||||
}
|
||||
cover {
|
||||
id
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
65
app/graphql/product.graphql
Normal file
65
app/graphql/product.graphql
Normal file
@ -0,0 +1,65 @@
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
22
app/graphql/productList.graphql
Normal file
22
app/graphql/productList.graphql
Normal file
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
27
app/graphql/questionList.graphql
Normal file
27
app/graphql/questionList.graphql
Normal file
@ -0,0 +1,27 @@
|
||||
query GetQuestionList($locale: String!) {
|
||||
questions {
|
||||
id
|
||||
translations(filter: { languages_code: { code: { _eq: $locale } } }) {
|
||||
id
|
||||
title
|
||||
content
|
||||
}
|
||||
products {
|
||||
id
|
||||
products_id {
|
||||
id
|
||||
product_type {
|
||||
id
|
||||
translations(filter: { languages_code: { code: { _eq: $locale } } }) {
|
||||
id
|
||||
name
|
||||
}
|
||||
}
|
||||
translations(filter: { languages_code: { code: { _eq: $locale } } }) {
|
||||
id
|
||||
name
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
12
app/graphql/solution.graphql
Normal file
12
app/graphql/solution.graphql
Normal file
@ -0,0 +1,12 @@
|
||||
query GetSolution($id: ID!, $locale: String!) {
|
||||
solutions_by_id(id: $id) {
|
||||
id
|
||||
translations(filter: { languages_code: { code: { _eq: $locale } } }) {
|
||||
id
|
||||
title
|
||||
summary
|
||||
content
|
||||
}
|
||||
create_at
|
||||
}
|
||||
}
|
||||
21
app/graphql/solutionList.graphql
Normal file
21
app/graphql/solutionList.graphql
Normal file
@ -0,0 +1,21 @@
|
||||
query GetSolutionList($locale: String!) {
|
||||
solutions {
|
||||
id
|
||||
cover {
|
||||
id
|
||||
}
|
||||
type {
|
||||
id
|
||||
translations(filter: { languages_code: { code: { _eq: $locale } } }) {
|
||||
id
|
||||
name
|
||||
}
|
||||
sort
|
||||
}
|
||||
translations(filter: { languages_code: { code: { _eq: $locale } } }) {
|
||||
id
|
||||
title
|
||||
summary
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -8,8 +8,18 @@ describe('toHomepageView', () => {
|
||||
const rawData: Homepage = {
|
||||
id: 1,
|
||||
carousel: [
|
||||
{ id: 1, directus_files_id: 'file-uuid-1' },
|
||||
{ id: 2, directus_files_id: 'file-uuid-2' },
|
||||
{
|
||||
id: 1,
|
||||
directus_files_id: {
|
||||
id: 'file-uuid-1',
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
directus_files_id: {
|
||||
id: 'file-uuid-2',
|
||||
},
|
||||
},
|
||||
],
|
||||
recommend_products: [
|
||||
{
|
||||
|
||||
@ -11,7 +11,8 @@ export function toHomepageView(raw: Homepage): HomepageView {
|
||||
const carousel = (raw.carousel ?? [])
|
||||
.filter(isObject<HomepageFile>)
|
||||
.map((item) => item.directus_files_id)
|
||||
.filter((item) => typeof item === 'string');
|
||||
.filter(isObject<DirectusFile>)
|
||||
.map((file) => file.id);
|
||||
|
||||
const products = (raw.recommend_products ?? [])
|
||||
.filter(isObject<Product>)
|
||||
|
||||
@ -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: [],
|
||||
|
||||
@ -33,12 +33,14 @@ export function toProductListView(raw: Product): ProductListView {
|
||||
? toProductTypeView(raw.product_type)
|
||||
: undefined;
|
||||
|
||||
const cover = isObject<DirectusFile>(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<ProductImage>)
|
||||
.map((item) => {
|
||||
const image = isObject<DirectusFile>(item.image) ? item.image.id : '';
|
||||
return {
|
||||
id: item.id,
|
||||
image: item.image.toString(),
|
||||
image: image,
|
||||
caption: item.translations?.[0]?.caption || '',
|
||||
};
|
||||
});
|
||||
|
||||
@ -34,7 +34,9 @@
|
||||
];
|
||||
const { data, pending, error } = await useCompanyProfile();
|
||||
|
||||
const content = computed(() => toCompanyProfileView(data.value));
|
||||
const content = computed(() =>
|
||||
toCompanyProfileView(data.value.company_profile)
|
||||
);
|
||||
|
||||
watch(error, (value) => {
|
||||
if (value) {
|
||||
|
||||
@ -16,7 +16,7 @@
|
||||
const { data, pending, error } = await useHomepage();
|
||||
|
||||
const homepageData = computed(() => {
|
||||
return toHomepageView(data.value);
|
||||
return toHomepageView(data.value.homepage);
|
||||
});
|
||||
|
||||
const pageTilte = $t('page-title.homepage');
|
||||
|
||||
@ -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 || '',
|
||||
// });
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
@ -37,7 +37,7 @@
|
||||
const localePath = useLocalePath();
|
||||
const { getImageUrl } = useDirectusImage();
|
||||
|
||||
const { data, pending, error } = useProductList();
|
||||
const { data, pending, error } = await useProductList();
|
||||
|
||||
const activeNames = ref<string[]>([]);
|
||||
|
||||
@ -46,12 +46,13 @@
|
||||
{ label: $t('navigation.products') },
|
||||
];
|
||||
|
||||
const productsRaw = computed(() => data.value ?? []);
|
||||
const productsRaw = computed(() => data.value.products ?? []);
|
||||
|
||||
const products = computed(() =>
|
||||
productsRaw.value.map((item) => toProductListView(item))
|
||||
);
|
||||
|
||||
logger.debug('products: ', products.value);
|
||||
logger.debug('产品列表数据: ', products.value);
|
||||
|
||||
// 按类型分组
|
||||
const groupedProducts = computed(() => {
|
||||
|
||||
@ -26,16 +26,16 @@
|
||||
const route = useRoute();
|
||||
const localePath = useLocalePath();
|
||||
|
||||
// 获取路由参数(documentId)
|
||||
const id = computed(() => route.params.slug as string);
|
||||
// 获取路由参数
|
||||
const id = route.params.slug as string;
|
||||
|
||||
const { data, pending, error } = await useSolution(id.value);
|
||||
const { data, pending, error } = await useSolution(id);
|
||||
|
||||
const solution = computed(() => {
|
||||
if (!data.value) {
|
||||
return null;
|
||||
}
|
||||
return toSolutionView(data.value);
|
||||
return toSolutionView(data.value.solutions_by_id);
|
||||
});
|
||||
|
||||
const breadcrumbItems = computed(() => [
|
||||
@ -54,7 +54,7 @@
|
||||
|
||||
const { data, pending, error } = await useSolutionList();
|
||||
|
||||
const solutionsRaw = computed(() => data.value ?? []);
|
||||
const solutionsRaw = computed(() => data.value.solutions ?? []);
|
||||
const solutions = computed(() =>
|
||||
solutionsRaw.value.map((item) => toSolutionListView(item))
|
||||
);
|
||||
|
||||
@ -24,7 +24,7 @@
|
||||
];
|
||||
const { data, pending, error } = await useContactInfo();
|
||||
|
||||
const content = computed(() => toContactInfoView(data.value));
|
||||
const content = computed(() => toContactInfoView(data.value.contact_info));
|
||||
|
||||
watch(error, (value) => {
|
||||
if (value) {
|
||||
|
||||
@ -38,7 +38,9 @@
|
||||
const { data, pending, error } = await useDocumentList();
|
||||
|
||||
const documents = computed(
|
||||
() => data?.value.map((item) => toDocumentListView(item)) ?? []
|
||||
() =>
|
||||
data?.value.product_documents.map((item) => toDocumentListView(item)) ??
|
||||
[]
|
||||
);
|
||||
|
||||
const productTypeOptions = computed(() => {
|
||||
|
||||
@ -41,7 +41,7 @@
|
||||
const { data, pending, error } = await useQuestionList();
|
||||
|
||||
const questions = computed(
|
||||
() => data.value.map((item) => toQuestionListView(item)) ?? null
|
||||
() => data.value.questions.map((item) => toQuestionListView(item)) ?? null
|
||||
);
|
||||
|
||||
const productTypeOptions = computed(() => {
|
||||
|
||||
@ -1,10 +1,11 @@
|
||||
import { createDirectus, rest, staticToken } from '@directus/sdk';
|
||||
import { createDirectus, rest, staticToken, graphql } from '@directus/sdk';
|
||||
|
||||
export default defineNuxtPlugin(() => {
|
||||
const config = useRuntimeConfig();
|
||||
|
||||
const directus = createDirectus<Schema>(config.public.directus.url)
|
||||
.with(rest())
|
||||
.with(graphql())
|
||||
.with(staticToken(config.public.directus.token || ''));
|
||||
return {
|
||||
provide: { directus },
|
||||
|
||||
@ -1,4 +1,6 @@
|
||||
// https://nuxt.com/docs/api/configuration/nuxt-config
|
||||
import GraphQLLoader from 'vite-plugin-graphql-loader';
|
||||
|
||||
export default defineNuxtConfig({
|
||||
compatibilityDate: '2025-07-15',
|
||||
devtools: { enabled: true },
|
||||
@ -90,6 +92,7 @@ export default defineNuxtConfig({
|
||||
},
|
||||
},
|
||||
},
|
||||
plugins: [GraphQLLoader()],
|
||||
},
|
||||
|
||||
devServer: {
|
||||
|
||||
@ -25,12 +25,14 @@
|
||||
"dompurify": "^3.2.6",
|
||||
"element-plus": "^2.10.7",
|
||||
"fuse.js": "^7.1.0",
|
||||
"graphql": "^16.12.0",
|
||||
"markdown-it": "^14.1.0",
|
||||
"meilisearch": "^0.53.0",
|
||||
"nuxt": "^4.0.3",
|
||||
"nuxt-directus": "5.7.0",
|
||||
"sass": "^1.90.0",
|
||||
"sharp": "^0.34.3",
|
||||
"vite-plugin-graphql-loader": "^4.0.4",
|
||||
"vue": "^3.5.18",
|
||||
"vue-router": "^4.5.1"
|
||||
},
|
||||
|
||||
32
pnpm-lock.yaml
generated
32
pnpm-lock.yaml
generated
@ -50,6 +50,9 @@ importers:
|
||||
fuse.js:
|
||||
specifier: ^7.1.0
|
||||
version: 7.1.0
|
||||
graphql:
|
||||
specifier: ^16.12.0
|
||||
version: 16.12.0
|
||||
markdown-it:
|
||||
specifier: ^14.1.0
|
||||
version: 14.1.0
|
||||
@ -68,6 +71,9 @@ importers:
|
||||
sharp:
|
||||
specifier: ^0.34.3
|
||||
version: 0.34.3
|
||||
vite-plugin-graphql-loader:
|
||||
specifier: ^4.0.4
|
||||
version: 4.0.4
|
||||
vue:
|
||||
specifier: ^3.5.18
|
||||
version: 3.5.21(typescript@5.9.2)
|
||||
@ -3498,6 +3504,16 @@ packages:
|
||||
graphemer@1.4.0:
|
||||
resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==}
|
||||
|
||||
graphql-tag@2.12.6:
|
||||
resolution: {integrity: sha512-FdSNcu2QQcWnM2VNvSCCDCVS5PpPqpzgFT8+GXzqJuoDd0CBncxCY278u4mhRO7tMgo2JjgJA5aZ+nWSQ/Z+xg==}
|
||||
engines: {node: '>=10'}
|
||||
peerDependencies:
|
||||
graphql: ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0
|
||||
|
||||
graphql@16.12.0:
|
||||
resolution: {integrity: sha512-DKKrynuQRne0PNpEbzuEdHlYOMksHSUI8Zc9Unei5gTsMNA2/vMpoMz/yKba50pejK56qj98qM0SjYxAKi13gQ==}
|
||||
engines: {node: ^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0}
|
||||
|
||||
gzip-size@6.0.0:
|
||||
resolution: {integrity: sha512-ax7ZYomf6jqPTQ4+XCpUGyXKHk5WweS+e05MBO4/y3WJ5RkmPXNKvX+bx1behVILVwr6JSQvZAku021CHPXG3Q==}
|
||||
engines: {node: '>=10'}
|
||||
@ -5388,6 +5404,9 @@ packages:
|
||||
vue-tsc:
|
||||
optional: true
|
||||
|
||||
vite-plugin-graphql-loader@4.0.4:
|
||||
resolution: {integrity: sha512-lYnpQ2luV2fcuXmOJADljuktfMbDW00Y+6QS+Ek8Jz1Vdzlj/51LSGJwZqyjJ24a5YQ+o29Hr6el/5+nlZetvg==}
|
||||
|
||||
vite-plugin-inspect@11.3.3:
|
||||
resolution: {integrity: sha512-u2eV5La99oHoYPHE6UvbwgEqKKOQGz86wMg40CCosP6q8BkB6e5xPneZfYagK4ojPJSj5anHCrnvC20DpwVdRA==}
|
||||
engines: {node: '>=14'}
|
||||
@ -9479,6 +9498,13 @@ snapshots:
|
||||
|
||||
graphemer@1.4.0: {}
|
||||
|
||||
graphql-tag@2.12.6(graphql@16.12.0):
|
||||
dependencies:
|
||||
graphql: 16.12.0
|
||||
tslib: 2.8.1
|
||||
|
||||
graphql@16.12.0: {}
|
||||
|
||||
gzip-size@6.0.0:
|
||||
dependencies:
|
||||
duplexer: 0.1.2
|
||||
@ -11725,6 +11751,12 @@ snapshots:
|
||||
optionator: 0.9.4
|
||||
typescript: 5.9.2
|
||||
|
||||
vite-plugin-graphql-loader@4.0.4:
|
||||
dependencies:
|
||||
graphql: 16.12.0
|
||||
graphql-tag: 2.12.6(graphql@16.12.0)
|
||||
magic-string: 0.30.19
|
||||
|
||||
vite-plugin-inspect@11.3.3(@nuxt/kit@3.19.2(magicast@0.3.5))(vite@7.1.5(@types/node@24.4.0)(jiti@2.5.1)(sass@1.92.1)(terser@5.44.0)(yaml@2.8.1)):
|
||||
dependencies:
|
||||
ansis: 4.1.0
|
||||
|
||||
9
shared/types/graphql.d.ts
vendored
Normal file
9
shared/types/graphql.d.ts
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
declare module '*.graphql' {
|
||||
const Query: import('graphql').DocumentNode;
|
||||
export default Query;
|
||||
export const _queries: Record<string, import('graphql').DocumentNode>;
|
||||
export const _fragments: Record<
|
||||
string,
|
||||
import('graphql').FragmentDefinitionNode
|
||||
>;
|
||||
}
|
||||
Reference in New Issue
Block a user