Bläddra i källkod

feat: 完善喂养计划编辑

IlhamTahir 11 månader sedan
förälder
incheckning
73ac0f8049

+ 16 - 1
src/pet-feeder/controller/feeding-plan.controller.ts

@@ -1,4 +1,4 @@
-import { Body, Controller, Post } from '@nestjs/common';
+import { Body, Controller, Get, Param, Post, Put } from '@nestjs/common';
 import { CreateFeedingPlanRequest } from '@/pet-feeder/dto/create-feeding-plan.request';
 import { FeedingPlanService } from '@/pet-feeder/service/feeding-plan.service';
 import { FeedingPlanVo } from '@/pet-feeder/vo/feeding-plan.vo';
@@ -19,4 +19,19 @@ export class FeedingPlanController {
       await this.feedingPlanService.create(createFeedingPlanRequest),
     );
   }
+
+  @Put(':id')
+  async update(
+    @Param('id') id: string,
+    @Body() updateFeedingRequest: CreateFeedingPlanRequest,
+  ) {
+    return this.feedingPlanMapper.toVo(
+      await this.feedingPlanService.update(id, updateFeedingRequest),
+    );
+  }
+
+  @Get(':id')
+  async get(@Param('id') id: string): Promise<FeedingPlanVo> {
+    return this.feedingPlanMapper.toVo(await this.feedingPlanService.get(id));
+  }
 }

+ 1 - 1
src/pet-feeder/dto/create-feeding-plan.request.ts

@@ -25,5 +25,5 @@ export class CreateFeedingPlanRequest {
     message: '产品 ID 不能为空',
   })
   @ApiProperty()
-  products: { id: string; dailyUsageWeight: number }[];
+  products: { id: string; dailyUsageWeight: number; percentage: number }[];
 }

+ 3 - 0
src/pet-feeder/entity/feeding-plan-product.entity.ts

@@ -8,6 +8,9 @@ export class FeedingPlanProduct extends BaseEntity {
   @Column()
   dailyUsageWeight: number;
 
+  @Column()
+  percentage: number;
+
   @ManyToOne(
     () => FeedingPlan,
     (feedingPlan) => feedingPlan.feedingPlanProducts,

+ 2 - 1
src/pet-feeder/entity/feeding-plan.entity.ts

@@ -18,7 +18,8 @@ export class FeedingPlan extends BaseEntity {
 
   @OneToMany(
     () => FeedingPlanProduct,
-    (feedingPlanProduct) => feedingPlanProduct.product,
+    (feedingPlanProduct) => feedingPlanProduct.feedingPlan,
+    { eager: true },
   )
   feedingPlanProducts: FeedingPlanProduct[];
 }

+ 2 - 1
src/pet-feeder/mapper/feeding-plan-product.mapper.ts

@@ -16,7 +16,8 @@ export class FeedingPlanProductMapper extends BaseMapper<
     return {
       ...super.toVo(entity),
       dailyUsageWeight: entity.dailyUsageWeight,
-      product: this.productMapper.toVo(entity.product),
+      percentage: entity.percentage,
+      product: entity.product ? this.productMapper.toVo(entity.product) : null,
     };
   }
 }

+ 5 - 6
src/pet-feeder/mapper/feeding-plan.mapper.ts

@@ -2,15 +2,12 @@ import { BaseMapper } from '@/core/mapper/base.mapper';
 import { FeedingPlan } from '@/pet-feeder/entity/feeding-plan.entity';
 import { FeedingPlanVo } from '@/pet-feeder/vo/feeding-plan.vo';
 import { Injectable } from '@nestjs/common';
-import { PetMapper } from '@/pet-feeder/mapper/pet.mapper';
 import { ProductMapper } from '@/pet-feeder/mapper/product.mapper';
+import { FeedingPlanProductMapper } from '@/pet-feeder/mapper/feeding-plan-product.mapper';
 
 @Injectable()
 export class FeedingPlanMapper extends BaseMapper<FeedingPlan, FeedingPlanVo> {
-  constructor(
-    private petMapper: PetMapper,
-    private productMapper: ProductMapper,
-  ) {
+  constructor(private feedingPlanProductMapper: FeedingPlanProductMapper) {
     super();
   }
   toVo(entity: FeedingPlan): FeedingPlanVo {
@@ -18,7 +15,9 @@ export class FeedingPlanMapper extends BaseMapper<FeedingPlan, FeedingPlanVo> {
       ...super.toVo(entity),
       targetWeight: entity.targetWeight,
       feedingGoal: entity.feedingGoal,
-      pet: this.petMapper.toVo(entity.pet),
+      feedingPlanProducts: this.feedingPlanProductMapper.toVos(
+        entity.feedingPlanProducts,
+      ),
     };
   }
 }

+ 8 - 0
src/pet-feeder/mapper/pet.mapper.ts

@@ -3,9 +3,14 @@ import { Pet } from '@/pet-feeder/entity/pet.entity';
 import { PetVo } from '@/pet-feeder/vo/pet.vo';
 import { Injectable } from '@nestjs/common';
 import { DateUtil } from '@/core/util/date.util';
+import { FeedingPlanMapper } from '@/pet-feeder/mapper/feeding-plan.mapper';
 
 @Injectable()
 export class PetMapper extends BaseMapper<Pet, PetVo> {
+  constructor(private readonly feedingPlanMapper: FeedingPlanMapper) {
+    super();
+  }
+
   toVo(entity: Pet): PetVo {
     return {
       ...super.toVo(entity),
@@ -20,6 +25,9 @@ export class PetMapper extends BaseMapper<Pet, PetVo> {
       isSterilization: entity.isSterilization,
       isLactation: entity.isLactation,
       bodyType: entity.bodyType,
+      feedingPlan: entity.feedingPlan
+        ? this.feedingPlanMapper.toVo(entity.feedingPlan)
+        : null,
     };
   }
 }

+ 51 - 1
src/pet-feeder/service/feeding-plan.service.ts

@@ -38,11 +38,61 @@ export class FeedingPlanService {
         const feedingPlanProduct = this.feedingPlanProductRepository.create({
           product: existProduct,
           dailyUsageWeight: product.dailyUsageWeight,
+          percentage: product.percentage,
         });
-        feedingPlanProducts.push(feedingPlanProduct);
+        feedingPlanProducts.push(
+          await this.feedingPlanProductRepository.save(feedingPlanProduct),
+        );
       }),
     );
     feedingPlan.feedingPlanProducts = feedingPlanProducts;
     return this.feedingPlanRepository.save(feedingPlan);
   }
+
+  async update(
+    id: string,
+    updateFeedingPlanRequest: CreateFeedingPlanRequest,
+  ): Promise<FeedingPlan> {
+    const feedingPlan = await this.get(id);
+    feedingPlan.feedingGoal = updateFeedingPlanRequest.feedingGoal;
+    feedingPlan.targetWeight = updateFeedingPlanRequest.targetWeight;
+    const feedingPlanProducts: FeedingPlanProduct[] = [];
+
+    await Promise.all(
+      updateFeedingPlanRequest.products.map(async (product) => {
+        const existProduct = await this.productService.get(product.id);
+        const exitFeedingPlanProduct =
+          await this.feedingPlanProductRepository.findOneBy({
+            product: existProduct,
+          });
+        if (exitFeedingPlanProduct) {
+          exitFeedingPlanProduct.dailyUsageWeight = product.dailyUsageWeight;
+          exitFeedingPlanProduct.percentage = product.percentage;
+          feedingPlanProducts.push(
+            await this.feedingPlanProductRepository.save(
+              exitFeedingPlanProduct,
+            ),
+          );
+        } else {
+          const feedingPlanProduct = this.feedingPlanProductRepository.create({
+            product: existProduct,
+            dailyUsageWeight: product.dailyUsageWeight,
+            percentage: product.percentage,
+          });
+          feedingPlanProducts.push(
+            await this.feedingPlanProductRepository.save(feedingPlanProduct),
+          );
+        }
+      }),
+    );
+    return this.feedingPlanRepository.save(feedingPlan);
+  }
+
+  async get(id: string): Promise<FeedingPlan> {
+    const feedingPlan = await this.feedingPlanRepository.findOneBy({ id });
+    if (!feedingPlan) {
+      throw new Error('Feeding plan not found');
+    }
+    return feedingPlan;
+  }
 }

+ 3 - 2
src/pet-feeder/service/pet.service.ts

@@ -41,8 +41,9 @@ export class PetService {
 
   async ownPetList(): Promise<Pet[]> {
     const id = RequestContext.currentContext.req.user.id;
-    return this.petRepository.findBy({
-      createBy: { id },
+    return this.petRepository.find({
+      where: { createBy: { id } },
+      relations: ['feedingPlan'],
     });
   }
 }

+ 3 - 0
src/pet-feeder/vo/feeding-plan-product.vo.ts

@@ -9,6 +9,9 @@ export class FeedingPlanProductVo extends BaseVo {
   @ApiProperty()
   dailyUsageWeight: number;
 
+  @ApiProperty()
+  percentage: number;
+
   @ApiProperty()
   product: ProductVo;
 }

+ 0 - 5
src/pet-feeder/vo/feeding-plan.vo.ts

@@ -1,8 +1,6 @@
 import { BaseVo } from '@/core/vo/base.vo';
 import { ApiProperty, ApiSchema } from '@nestjs/swagger';
 import { FeedingGoal } from '@/pet-feeder/enum/feeding-goal';
-import { PetVo } from '@/pet-feeder/vo/pet.vo';
-import { FeedingPlanProduct } from '@/pet-feeder/entity/feeding-plan-product.entity';
 import { FeedingPlanProductVo } from '@/pet-feeder/vo/feeding-plan-product.vo';
 
 @ApiSchema({
@@ -15,9 +13,6 @@ export class FeedingPlanVo extends BaseVo {
   @ApiProperty()
   feedingGoal: FeedingGoal;
 
-  @ApiProperty()
-  pet: PetVo;
-
   @ApiProperty()
   feedingPlanProducts: FeedingPlanProductVo[];
 }

+ 5 - 0
src/pet-feeder/vo/pet.vo.ts

@@ -3,6 +3,8 @@ import { ApiProperty, ApiSchema } from '@nestjs/swagger';
 import { PetType } from '@/pet-feeder/enum/pet-type';
 import { Gender } from '@/core/enum/Gender';
 import { PetBodyType } from '@/pet-feeder/enum/pet-body-type';
+import { FeedingPlan } from '@/pet-feeder/entity/feeding-plan.entity';
+import { FeedingPlanVo } from '@/pet-feeder/vo/feeding-plan.vo';
 
 @ApiSchema({
   name: 'Pet',
@@ -32,4 +34,7 @@ export class PetVo extends TraceableVo {
   isLactation: boolean;
   @ApiProperty()
   bodyType: PetBodyType;
+
+  @ApiProperty()
+  feedingPlan: FeedingPlanVo | null;
 }