浏览代码

feat(server): Create Facet & FacetValue entities, wire up relations

Relates to #2
Michael Bromley 7 年之前
父节点
当前提交
c5a1e647a5

+ 2 - 0
README.md

@@ -54,6 +54,8 @@ Custom fields can currently be added to the following entities:
 
 * Address
 * Customer
+* Facet
+* FacetValue
 * Product
 * ProductOption
 * ProductOptionGroup

文件差异内容过多而无法显示
+ 0 - 0
schema.json


+ 12 - 0
server/src/entity/custom-entity-fields.ts

@@ -10,6 +10,14 @@ import { coreEntitiesMap } from './entities';
 @Entity()
 export class CustomAddressFields {}
 @Entity()
+export class CustomFacetFields {}
+@Entity()
+export class CustomFacetFieldsTranslation {}
+@Entity()
+export class CustomFacetValueFields {}
+@Entity()
+export class CustomFacetValueFieldsTranslation {}
+@Entity()
 export class CustomCustomerFields {}
 @Entity()
 export class CustomProductFields {}
@@ -137,6 +145,10 @@ function assertNoLocaleStringFields(entity: Type<any>, customFields: CustomField
 export function registerCustomEntityFields(config: VendureConfig) {
     registerCustomFieldsForEntity(config, 'Address', CustomAddressFields);
     registerCustomFieldsForEntity(config, 'Customer', CustomCustomerFields);
+    registerCustomFieldsForEntity(config, 'Facet', CustomFacetFields);
+    registerCustomFieldsForEntity(config, 'Facet', CustomFacetFieldsTranslation, true);
+    registerCustomFieldsForEntity(config, 'FacetValue', CustomFacetValueFields);
+    registerCustomFieldsForEntity(config, 'FacetValue', CustomFacetValueFieldsTranslation, true);
     registerCustomFieldsForEntity(config, 'Product', CustomProductFields);
     registerCustomFieldsForEntity(config, 'Product', CustomProductFieldsTranslation, true);
     registerCustomFieldsForEntity(config, 'ProductOption', CustomProductOptionFields);

+ 8 - 0
server/src/entity/entities.ts

@@ -1,6 +1,10 @@
 import { Address } from './address/address.entity';
 import { Administrator } from './administrator/administrator.entity';
 import { Customer } from './customer/customer.entity';
+import { FacetValueTranslation } from './facet-value/facet-value-translation.entity';
+import { FacetValue } from './facet-value/facet-value.entity';
+import { FacetTranslation } from './facet/facet-translation.entity';
+import { Facet } from './facet/facet.entity';
 import { ProductOptionGroupTranslation } from './product-option-group/product-option-group-translation.entity';
 import { ProductOptionGroup } from './product-option-group/product-option-group.entity';
 import { ProductOptionTranslation } from './product-option/product-option-translation.entity';
@@ -18,6 +22,10 @@ export const coreEntitiesMap = {
     Address,
     Administrator,
     Customer,
+    Facet,
+    FacetTranslation,
+    FacetValue,
+    FacetValueTranslation,
     Product,
     ProductTranslation,
     ProductOption,

+ 26 - 0
server/src/entity/facet-value/facet-value-translation.entity.ts

@@ -0,0 +1,26 @@
+import { Column, Entity, ManyToOne } from 'typeorm';
+
+import { DeepPartial } from '../../../../shared/shared-types';
+import { LanguageCode } from '../../locale/language-code';
+import { Translation } from '../../locale/locale-types';
+import { VendureEntity } from '../base/base.entity';
+import { CustomFacetValueFieldsTranslation } from '../custom-entity-fields';
+
+import { FacetValue } from './facet-value.entity';
+
+@Entity()
+export class FacetValueTranslation extends VendureEntity implements Translation<FacetValue> {
+    constructor(input?: DeepPartial<Translation<FacetValue>>) {
+        super(input);
+    }
+
+    @Column() languageCode: LanguageCode;
+
+    @Column() name: string;
+
+    @ManyToOne(type => FacetValue, base => base.translations)
+    base: FacetValue;
+
+    @Column(type => CustomFacetValueFieldsTranslation)
+    customFields: CustomFacetValueFieldsTranslation;
+}

+ 29 - 0
server/src/entity/facet-value/facet-value.entity.ts

@@ -0,0 +1,29 @@
+import { Column, Entity, ManyToOne, OneToMany } from 'typeorm';
+
+import { DeepPartial, HasCustomFields } from '../../../../shared/shared-types';
+import { LocaleString, Translatable, Translation } from '../../locale/locale-types';
+import { VendureEntity } from '../base/base.entity';
+import { CustomFacetValueFields } from '../custom-entity-fields';
+import { Facet } from '../facet/facet.entity';
+
+import { FacetValueTranslation } from './facet-value-translation.entity';
+
+@Entity()
+export class FacetValue extends VendureEntity implements Translatable, HasCustomFields {
+    constructor(input?: DeepPartial<FacetValue>) {
+        super(input);
+    }
+    name: LocaleString;
+
+    @Column({ unique: true })
+    code: string;
+
+    @OneToMany(type => FacetValueTranslation, translation => translation.base, { eager: true })
+    translations: Array<Translation<FacetValue>>;
+
+    @ManyToOne(type => Facet, group => group.values)
+    facet: Facet;
+
+    @Column(type => CustomFacetValueFields)
+    customFields: CustomFacetValueFields;
+}

+ 26 - 0
server/src/entity/facet-value/facet-value.graphql

@@ -0,0 +1,26 @@
+type FacetValue implements Node {
+    id: ID!
+    createdAt: DateTime!
+    updatedAt: DateTime!
+    languageCode: LanguageCode
+    name: String
+    translations: [FacetValueTranslation!]!
+}
+
+type FacetValueTranslation {
+    id: ID!
+    createdAt: DateTime!
+    updatedAt: DateTime!
+    languageCode: LanguageCode!
+    name: String!
+}
+
+input FacetValueTranslationInput {
+    id: ID
+    languageCode: LanguageCode!
+    name: String!
+}
+
+input CreateFacetValueInput {
+    translations: [FacetValueTranslationInput!]!
+}

+ 26 - 0
server/src/entity/facet/facet-translation.entity.ts

@@ -0,0 +1,26 @@
+import { Column, Entity, ManyToOne } from 'typeorm';
+
+import { DeepPartial, HasCustomFields } from '../../../../shared/shared-types';
+import { LanguageCode } from '../../locale/language-code';
+import { Translation } from '../../locale/locale-types';
+import { VendureEntity } from '../base/base.entity';
+import { CustomFacetFieldsTranslation } from '../custom-entity-fields';
+
+import { Facet } from './facet.entity';
+
+@Entity()
+export class FacetTranslation extends VendureEntity implements Translation<Facet>, HasCustomFields {
+    constructor(input?: DeepPartial<Translation<Facet>>) {
+        super(input);
+    }
+
+    @Column() languageCode: LanguageCode;
+
+    @Column() name: string;
+
+    @ManyToOne(type => Facet, base => base.translations)
+    base: Facet;
+
+    @Column(type => CustomFacetFieldsTranslation)
+    customFields: CustomFacetFieldsTranslation;
+}

+ 30 - 0
server/src/entity/facet/facet.entity.ts

@@ -0,0 +1,30 @@
+import { Column, Entity, OneToMany } from 'typeorm';
+
+import { DeepPartial, HasCustomFields } from '../../../../shared/shared-types';
+import { LocaleString, Translatable, Translation } from '../../locale/locale-types';
+import { VendureEntity } from '../base/base.entity';
+import { CustomFacetFields } from '../custom-entity-fields';
+import { FacetValue } from '../facet-value/facet-value.entity';
+
+import { FacetTranslation } from './facet-translation.entity';
+
+@Entity()
+export class Facet extends VendureEntity implements Translatable, HasCustomFields {
+    constructor(input?: DeepPartial<Facet>) {
+        super(input);
+    }
+
+    name: LocaleString;
+
+    @Column({ unique: true })
+    code: string;
+
+    @OneToMany(type => FacetTranslation, translation => translation.base, { eager: true })
+    translations: Array<Translation<Facet>>;
+
+    @OneToMany(type => FacetValue, value => value.facet)
+    values: FacetValue[];
+
+    @Column(type => CustomFacetFields)
+    customFields: CustomFacetFields;
+}

+ 33 - 0
server/src/entity/facet/facet.graphql

@@ -0,0 +1,33 @@
+type Facet implements Node {
+    id: ID!
+    createdAt: DateTime!
+    updatedAt: DateTime!
+    languageCode: LanguageCode!
+    name: String!
+    values: [FacetValue!]!
+    translations: [FacetTranslation!]!
+}
+
+type FacetTranslation {
+    id: ID!
+    createdAt: DateTime!
+    updatedAt: DateTime!
+    languageCode: LanguageCode!
+    name: String!
+}
+
+input FacetTranslationInput {
+    id: ID
+    languageCode: LanguageCode!
+    name: String!
+}
+
+input CreateFacetInput {
+    translations: [FacetTranslationInput!]!
+    options: [CreateProductOptionInput!]!
+}
+
+input UpdateFacetInput {
+    id: ID!
+    translations: [FacetTranslationInput!]!
+}

+ 6 - 2
server/src/entity/product-variant/product-variant.entity.ts

@@ -1,10 +1,10 @@
 import { Column, Entity, JoinTable, ManyToMany, ManyToOne, OneToMany } from 'typeorm';
 
-import { DeepPartial } from '../../../../shared/shared-types';
-import { HasCustomFields } from '../../../../shared/shared-types';
+import { DeepPartial, HasCustomFields } from '../../../../shared/shared-types';
 import { LocaleString, Translatable, Translation } from '../../locale/locale-types';
 import { VendureEntity } from '../base/base.entity';
 import { CustomProductVariantFields } from '../custom-entity-fields';
+import { FacetValue } from '../facet-value/facet-value.entity';
 import { ProductOption } from '../product-option/product-option.entity';
 import { Product } from '../product/product.entity';
 
@@ -34,6 +34,10 @@ export class ProductVariant extends VendureEntity implements Translatable, HasCu
     @JoinTable()
     options: ProductOption[];
 
+    @ManyToMany(type => FacetValue)
+    @JoinTable()
+    facetValues: FacetValue[];
+
     @Column(type => CustomProductVariantFields)
     customFields: CustomProductVariantFields;
 }

+ 1 - 0
server/src/entity/product-variant/product-variant.graphql

@@ -8,6 +8,7 @@ type ProductVariant implements Node {
     image: String
     price: Int!
     options: [ProductOption!]!
+    facetValues: [FacetValue!]!
     translations: [ProductVariantTranslation!]!
 }
 

+ 7 - 2
server/src/service/product.service.ts

@@ -29,13 +29,18 @@ export class ProductService {
         lang: LanguageCode,
         options: ListQueryOptions<Product>,
     ): Promise<PaginatedList<Translated<Product>>> {
-        const relations = ['variants', 'optionGroups', 'variants.options'];
+        const relations = ['variants', 'optionGroups', 'variants.options', 'variants.facetValues'];
 
         return buildListQuery(this.connection, Product, options, relations)
             .getManyAndCount()
             .then(([products, totalItems]) => {
                 const items = products.map(product =>
-                    translateDeep(product, lang, ['optionGroups', 'variants', ['variants', 'options']]),
+                    translateDeep(product, lang, [
+                        'optionGroups',
+                        'variants',
+                        ['variants', 'options'],
+                        ['variants', 'facetValues'],
+                    ]),
                 );
                 return {
                     items,

+ 2 - 0
shared/shared-types.ts

@@ -43,6 +43,8 @@ export interface CustomFieldConfig {
 export interface CustomFields {
     Address?: CustomFieldConfig[];
     Customer?: CustomFieldConfig[];
+    Facet?: CustomFieldConfig[];
+    FacetValue?: CustomFieldConfig[];
     Product?: CustomFieldConfig[];
     ProductOption?: CustomFieldConfig[];
     ProductOptionGroup?: CustomFieldConfig[];

部分文件因为文件数量过多而无法显示