import { Component, Input, OnInit } from "@angular/core"; import { FormArray, FormBuilder, FormGroup } from "@angular/forms"; import { ApiService } from "@cdk/services"; import { Utils } from "@cdk/utils"; import { FormValidators } from "@cdk/validators"; import { NzMessageService } from "ng-zorro-antd/message"; import { Subject, debounceTime, distinctUntilChanged, filter, finalize, switchMap, throttleTime } from "rxjs"; @Component({ selector: "app-dish-form", templateUrl: "./dish-form.component.html", styleUrls: ["./dish-form.component.less"], }) export class DishFormComponent { constructor(private fb: FormBuilder, private msg: NzMessageService, private api: ApiService) {} @Input() data: any; @Input() orgs: any[] = []; @Input() foods: any[] = []; private orgSearch$ = new Subject>(); private foodSearch$ = new Subject>(); formGroup!: FormGroup; selectedValue = null; orgListOfOption: Array<{ value: string; text: string }> = []; foodListOfOption: Array<{ value: string; text: string }> = []; searchedFood: Array<{ value: string; text: string }> = []; foodSelected: string[] = []; foodItemSelected: any[] = []; nzFilterOption = (): boolean => true; globalEnum = this.api.globalEnum; uploadLoading = false; addFoodVisible = false; get food(): FormArray { return this.formGroup.get("ingredient") as FormArray; } get icon() { return this.formGroup.get("icon")?.value; } ngOnInit(): void { this.formGroup = this.fb.group({ id: this.fb.control("", []), name: this.fb.control("", [FormValidators.required()]), icon: this.fb.control("", []), mark: this.fb.control("", [FormValidators.required()]), month: this.fb.control([], []), }); this.orgSearch$ .pipe( debounceTime(500), distinctUntilChanged(), switchMap((q) => this.api.getOrgList(q)) ) .subscribe((data) => { const listOfOption: Array<{ value: string; text: string }> = []; data.body.forEach((item) => { listOfOption.push({ value: item.id.toString(), text: item.name, }); }); this.orgListOfOption = listOfOption; }); this.foodSearch$ .pipe( filter((f) => !!f), debounceTime(500), distinctUntilChanged(), switchMap((q) => this.api.getFoodList(q)) ) .subscribe((data) => { const listOfOption: Array<{ value: string; text: string }> = []; data.body.forEach((item) => { listOfOption.push({ value: item.key, text: item.name, }); }); this.searchedFood = this.searchedFood.concat(listOfOption); this.foodListOfOption = listOfOption; }); this.setValues(); } setValues() { this.orgListOfOption = this.orgs.map((i) => ({ text: i.name, value: i.id })); if (this.data) { // this.allMonth = this.allMonth.map((i) => // (this.data.month ?? []).includes(i.value) ? { ...i, checked: true } : i // ); this.foods.forEach((f) => { const item = { text: f.name, value: f.key }; this.foodListOfOption.push(item); this.searchedFood.push(item); const num = this.data.ingredient.find((i: any) => i.key === f.key); if (num) { this.foodItemSelected.push({ num: num.value, ...item, isMain: num.isMain }); this.foodSelected.push(f.key); } }); this.formGroup.patchValue({ ...this.data, mark: this.data.marks, }); } } public getValues() { let values = null; console.log("this.formGroup.getRawValue()", this.formGroup.getRawValue(), this.foodItemSelected); if (Utils.validateFormGroup(this.formGroup)) { const value = this.formGroup.getRawValue(); // const { _nutrition, key, name, type } = this.formGroup.getRawValue(); let ingredient: any[] = []; for (const f of this.foodItemSelected) { let num = Number(f.num); if (!num) { this.msg.error(`请输入${f.value}-${f.text}的重量`); return; } ingredient.push({ isMain: f.isMain, key: f.value, value: num, }); } const month = value.month.join(","); values = { ...value, month, ingredient, }; } return values; } onMainChange(e: boolean, key: string) { this.foodItemSelected.forEach((i) => { if (e) { i.isMain = false; if (i.value === key) { i.isMain = true; } } else { if (i.value === key) { i.isMain = false; } } }); } searchOrg(value: string): void { if (value) { this.orgSearch$.next({ keyword: value }); } } searchFood(value: string): void { if (value) { this.foodSearch$.next({ keyword: value }); } } onFoodSelected(v: string[]) { this.foodItemSelected = []; this.searchedFood.forEach((item) => { if (this.foodItemSelected.some((s) => s.value === item.value)) { return; } if (v.includes(item.value)) { this.foodItemSelected.push(item); } }); // this.foodItemSelected = this.searchedFood.filter((f) => { // return v.includes(f.value) // }); } addFood() { this.food.push( this.fb.group({ name: this.fb.control("", [FormValidators.required()]), tag: this.fb.control(0, [FormValidators.required()]), weight: this.fb.control(0, [FormValidators.required()]), }) ); } removeFood(idx: number) { this.food.removeAt(idx); } onFileChange(e: Event) { const target = e.target as HTMLInputElement; const file = target.files![0]; target.value = ""; if (file.size / 1024 / 1024 >= 5) { this.msg.error("图片大小不能超过5M"); return; } const fileReader = new FileReader(); fileReader.onload = () => { const base64 = fileReader.result as string; this.formGroup.get("icon")?.setValue(base64); }; fileReader.readAsDataURL(file); } }