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 iconPreview = '' 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()]), poly: 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.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, }) if (this.data['icon']) { this.iconPreview = '/api/icon/' + this.data['icon'] } } } 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 >= 2) { this.msg.error('图片大小不能超过2M') return } const fileReader = new FileReader() fileReader.onload = () => { const base64 = fileReader.result as string this.iconPreview = base64 // this.formGroup.get("icon")?.setValue(base64); } fileReader.readAsDataURL(file) const formdata = new FormData() formdata.append('file', file) this.api.upload(formdata).subscribe((res) => { this.formGroup.get('icon')?.setValue(res.body) }) } }