|
|
|
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<Record<string, string>>();
|
|
|
|
|
|
|
|
private foodSearch$ = new Subject<Record<string, string>>();
|
|
|
|
|
|
|
|
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.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,
|
|
|
|
});
|
|
|
|
if (this.data["icon"]) {
|
|
|
|
this.iconPreview = "/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 >= 5) {
|
|
|
|
this.msg.error("图片大小不能超过5M");
|
|
|
|
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);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|