Browse Source

食谱 添加 菜品

main
kely 2 years ago
parent
commit
4e80addeec
  1. 3
      angular.json
  2. 2
      projects/admin/src/app/app.module.ts
  3. 2
      projects/admin/src/app/components/dish-form/dish-form.component.html
  4. 34
      projects/admin/src/app/components/dish-form/dish-form.component.ts
  5. 2
      projects/admin/src/app/components/index.ts
  6. 2
      projects/admin/src/app/pages/dish/dish.component.html
  7. 25
      projects/admin/src/app/pages/dish/dish.component.ts
  8. 46
      projects/admin/src/app/pages/ingredients/ingredient-form/ingredient-form.component.html
  9. 90
      projects/admin/src/app/pages/ingredients/ingredient-form/ingredient-form.component.ts
  10. 2
      projects/admin/src/app/pages/ingredients/ingredient-list/ingredient-list.component.html
  11. 17
      projects/admin/src/app/pages/ingredients/ingredient-list/ingredient-list.component.ts
  12. 12
      projects/admin/src/app/pages/standard/standard-form/standard-form.component.ts
  13. 115
      projects/cdk/src/ingredient/add-dish-to-ingredient/add-dish-to-ingredient.component.html
  14. 61
      projects/cdk/src/ingredient/add-dish-to-ingredient/add-dish-to-ingredient.component.ts
  15. 34
      projects/cdk/src/ingredient/confirm-ingredient/confirm-ingredient.component.html
  16. 59
      projects/cdk/src/ingredient/confirm-ingredient/confirm-ingredient.component.ts
  17. 60
      projects/cdk/src/ingredient/ingredient-dish/ingredient-dish.component.html
  18. 25
      projects/cdk/src/ingredient/ingredient-dish/ingredient-dish.component.less
  19. 119
      projects/cdk/src/ingredient/ingredient-dish/ingredient-dish.component.ts
  20. 17
      projects/cdk/src/ingredient/ingredient-form-basic/ingredient-form-basic.component.html
  21. 0
      projects/cdk/src/ingredient/ingredient-form-basic/ingredient-form-basic.component.less
  22. 57
      projects/cdk/src/ingredient/ingredient-form-basic/ingredient-form-basic.component.ts
  23. 225
      projects/cdk/src/ingredient/ingredient-meals/ingredient-meals.component.html
  24. 6
      projects/cdk/src/ingredient/ingredient-meals/ingredient-meals.component.less
  25. 125
      projects/cdk/src/ingredient/ingredient-meals/ingredient-meals.component.ts
  26. 18
      projects/cdk/src/ingredient/ingredient.module.ts
  27. 10
      projects/cdk/src/services/api.service.ts
  28. 22
      projects/cdk/src/shared/components/dish-select/dish-select.component.html
  29. 0
      projects/cdk/src/shared/components/dish-select/dish-select.component.less
  30. 97
      projects/cdk/src/shared/components/dish-select/dish-select.component.ts
  31. 2
      projects/cdk/src/shared/components/index.ts
  32. 1
      projects/cdk/src/shared/components/month-select/month-select.component.ts
  33. 13
      projects/cdk/src/shared/components/org-select/org-select.component.html
  34. 0
      projects/cdk/src/shared/components/org-select/org-select.component.less
  35. 81
      projects/cdk/src/shared/components/org-select/org-select.component.ts
  36. 2
      projects/cdk/src/shared/ng-zorro.ts
  37. 13
      projects/cdk/src/shared/shared.module.ts

3
angular.json

@ -2,7 +2,8 @@
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
"version": 1,
"cli": {
"packageManager": "pnpm"
"packageManager": "pnpm",
"analytics": false
},
"newProjectRoot": "projects",
"projects": {

2
projects/admin/src/app/app.module.ts

@ -15,7 +15,6 @@ import {
AppLayoutComponent,
FoodFormComponent,
DishFormComponent,
IngredientFormBasicComponent,
UserListComponent,
RolePermissionComponent,
IngredientStatusListComponent,
@ -49,7 +48,6 @@ registerLocaleData(zh);
AppLayoutComponent,
FoodFormComponent,
DishFormComponent,
IngredientFormBasicComponent,
UserListComponent,
RolePermissionComponent,

2
projects/admin/src/app/components/dish-form/dish-form.component.html

@ -45,7 +45,7 @@
</nz-form-control>
</nz-form-item>
<nz-form-item>
<nz-form-label>
<nz-form-label nzRequired>
适用月份
</nz-form-label>
<nz-form-control [nzErrorTip]="formControlErrorTpl">

34
projects/admin/src/app/components/dish-form/dish-form.component.ts

@ -42,25 +42,6 @@ export class DishFormComponent {
globalEnum = this.api.globalEnum;
allMonth = [
{ value: 1, label: "一月", checked: false },
{ value: 2, label: "二月", checked: false },
{ value: 3, label: "三月", checked: false },
{ value: 4, label: "四月", checked: false },
{ value: 5, label: "五月", checked: false },
{ value: 6, label: "六月", checked: false },
{ value: 7, label: "七月", checked: false },
{ value: 8, label: "八月", checked: false },
{ value: 9, label: "九月", checked: false },
{ value: 10, label: "十月", checked: false },
{ value: 11, label: "十一月", checked: false },
{ value: 12, label: "十二月", checked: false },
];
allMonthChecked = false;
indeterminate = false;
uploadLoading = false;
addFoodVisible = false;
@ -124,9 +105,9 @@ export class DishFormComponent {
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.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);
@ -164,14 +145,7 @@ export class DishFormComponent {
value: num,
});
}
const month = this.allMonth
.reduce((a: any, c: any) => {
if (c.checked) {
return a.concat(Number(c.value));
}
return a;
}, [] as number[])
.join(",");
const month = value.month.join(",");
const vendors = value.vendors?.join(",") ?? "";
values = {
...value,

2
projects/admin/src/app/components/index.ts

@ -3,8 +3,6 @@ export * from "./app-layout/app-layout.component";
export * from "./food-form/food-form.component";
export * from "./dish-form/dish-form.component";
export * from "./ingredient-form-basic/ingredient-form-basic.component";
export * from "./user-list/user-list.component";
export * from "./role-permission/role-permission.component";
export * from "./ingredient-status-list/ingredient-status-list.component";

2
projects/admin/src/app/pages/dish/dish.component.html

@ -83,7 +83,7 @@
<button *nzSpaceItem nz-button (click)="cancelForm()" type="button">
取消
</button>
<button *nzSpaceItem nz-button nzType="primary" (click)="onSubmit()">
<button *nzSpaceItem nz-button nzType="primary" [nzLoading]="submitLoading" (click)="onSubmit()">
保存
</button>
</nz-space>

25
projects/admin/src/app/pages/dish/dish.component.ts

@ -4,7 +4,17 @@ import { NzDrawerRef, NzDrawerService } from "ng-zorro-antd/drawer";
import { AnyObject, OrgDTO, TableListOption } from "@cdk/public-api";
import { DishFormComponent } from "@admin/app/components";
import { ApiService } from "@cdk/services";
import { Subject, debounceTime, distinctUntilChanged, filter, lastValueFrom, switchMap, takeUntil, tap } from "rxjs";
import {
Subject,
debounceTime,
distinctUntilChanged,
filter,
finalize,
lastValueFrom,
switchMap,
takeUntil,
tap,
} from "rxjs";
import { NzModalService } from "ng-zorro-antd/modal";
import { NzMessageService } from "ng-zorro-antd/message";
import { ResponseType } from "@cdk/types";
@ -28,6 +38,8 @@ export class DishComponent {
private destroy$ = new Subject<void>();
private orgSearch$ = new Subject<string>();
public globalEnum = this.api.globalEnum;
public tableList = new TableListOption(this.fetchData.bind(this), {
@ -41,8 +53,6 @@ export class DishComponent {
vendors: new FormControl(""),
});
private orgSearch$ = new Subject<string>();
public selectedIds: string[] = [];
tableOrg: { [k: number]: OrgDTO } = {};
@ -188,7 +198,14 @@ export class DishComponent {
const val = com.getValues();
if (val) {
this.submitLoading = true;
this.api.saveDish(val).subscribe((res) => {
this.api
.saveDish(val)
.pipe(
finalize(() => {
this.submitLoading = false;
})
)
.subscribe((res) => {
this.msg.success(res.desc);
this.tableList.run();
this.cancelForm();

46
projects/admin/src/app/pages/ingredients/ingredient-form/ingredient-form.component.html

@ -2,11 +2,12 @@
<div class="p-4" *ngIf="step === 0">
<nz-card nzTitle="录入食谱基础信息">
<app-ingredient-form-basic (onSave)="onStepChange($event)"></app-ingredient-form-basic>
<app-ingredient-form-basic [menu]="menuItem" (onSave)="onStepChange($event)"></app-ingredient-form-basic>
</nz-card>
</div>
<ng-container *ngIf="step === 1">
<nz-card nzSize="small">
<div class="flex justify-between">
<div class="flex-1 ">
@ -31,52 +32,15 @@
<button *nzSpaceItem nz-button nzType="primary" (click)="confirmSave()">
保存
</button>
<button *nzSpaceItem nz-button>
<!-- <button *nzSpaceItem nz-button>
另存为
</button>
</button> -->
</nz-space>
</div>
</nz-card>
<div class="p-4">
<nz-card
*ngFor="let i of ingredients"
[nzTitle]="dayTitleTpl"
class="day-item mb-4"
[nzExtra]="dayExtraTpl"
[nzBodyStyle]="{padding:0}">
<ng-template #dayTitleTpl>
<div class=" relative -left-4 z-10">
<button nz-button nzType="text" (click)="expandChange(i)">
<span nz-icon nzType="caret-right" nzTheme="outline"></span>
</button>
<span>
第{{i}}天
</span>
</div>
</ng-template>
<ng-template #dayExtraTpl>
<nz-space>
<button *nzSpaceItem nz-button nzType="link">
本天菜品应用到其他天
</button>
<button *nzSpaceItem nz-button nzType="link">
本日营养分析
</button>
</nz-space>
</ng-template>
<nz-card-tab>
<nz-tabset nzSize="large">
<nz-tab nzTitle="早餐"></nz-tab>
<nz-tab nzTitle="午餐"></nz-tab>
<nz-tab nzTitle="晚餐"></nz-tab>
</nz-tabset>
</nz-card-tab>
<div class="p-4" *ngIf="expanded.has(i)">
<lib-ingredient-meals></lib-ingredient-meals>
</div>
</nz-card>
<app-ingredient-dish #menuDish [menu]="menuItem"></app-ingredient-dish>
</div>
</ng-container>
</app-page>

90
projects/admin/src/app/pages/ingredients/ingredient-form/ingredient-form.component.ts

@ -1,8 +1,10 @@
import { IngredientFormBasicComponent } from "@admin/app/components";
import { Component, OnInit } from "@angular/core";
import { Component, OnInit, ViewChild } from "@angular/core";
import { ActivatedRoute, Router } from "@angular/router";
import { ConfirmIngredientComponent } from "@cdk/ingredient/confirm-ingredient/confirm-ingredient.component";
import { IngredientDishComponent } from "@cdk/ingredient/ingredient-dish/ingredient-dish.component";
import { MealDishInterface } from "@cdk/ingredient/ingredient-meals/ingredient-meals.component";
import { ApiService } from "@cdk/services";
import { OptionItemInterface } from "@cdk/types";
import { NzMessageService } from "ng-zorro-antd/message";
import { NzModalService } from "ng-zorro-antd/modal";
@ -20,45 +22,99 @@ export class IngredientFormComponent implements OnInit {
private api: ApiService
) {
this.id = this.route.snapshot.paramMap.get("id");
console.log("this.id", this.id);
}
@ViewChild("menuDish") menuDish!: IngredientDishComponent;
step = 0;
id: string | null = "";
expanded = new Set<number>();
ingredients = Array.from({ length: 7 }, (_, i) => 1 + i);
menuItem: any = null;
ngOnInit(): void {
this.api.getMenuItem().subscribe((res) => {
console.log("res", res);
this.step = this.id && this.id !== "create" ? 1 : 0;
this.getDetail();
}
getDetail() {
if (this.id && this.id !== "create") {
this.api.getMenuItem(this.id).subscribe((res) => {
if (res.body) {
this.menuItem = res.body;
}
});
}
}
onStepChange(basicInfo: any) {
this.step = 1;
console.log(basicInfo);
this.menuItem = {
...basicInfo,
menuIds: basicInfo.menuId,
meals: basicInfo.meals.reduce(
(a: string[], c: OptionItemInterface) => (c["checked"] ? a.concat(c.value) : a),
[] as string[]
),
crows: basicInfo.peoples.reduce(
(a: string[], c: OptionItemInterface) => (c["checked"] ? a.concat(c.value) : a),
[] as string[]
),
};
}
shopDishForm() {}
cancelForm() {}
expandChange(i: number) {
if (this.expanded.has(i)) {
this.expanded.delete(i);
} else {
this.expanded.add(i);
}
}
confirmSave() {
// console.log("this.menuItem", this.menuItem);
this.modal.create({
nzTitle: "确认食谱信息",
nzContent: ConfirmIngredientComponent,
nzData: this.menuItem,
nzWidth: 650,
nzOnOk: () => {
// const { menuObject } = this.menuDish;
// const serverNeed = this.formatData(menuObject);
// this.api.saveMenuDist(serverNeed).subscribe((res) => {
// this.msg.success(res.desc);
// this.router.navigate(["/ingredient/item/list"]);
// });
},
});
}
formatData(menuObject: any) {
let dishes: any[] = [];
Object.entries(menuObject).forEach(([day, v]) => {
Object.entries(v as Record<string, MealDishInterface[]>).forEach(([mealIndex, dishList]) => {
dishList.forEach((dish) => {
dishes.push({
...dish,
day: Number(day),
meal: this.menuItem.meals[mealIndex],
items: dish.foods.map((food) => {
return {
...food,
value: food.groupValues.reduce((a, c) => {
return {
...a,
[c.peopleName]: c.value,
};
}, {} as Record<string, number>),
};
}),
});
});
});
});
const toServer = {
menuIds: this.menuItem.menuIds ?? [this.menuItem.id],
dishes,
};
return toServer;
}
}

2
projects/admin/src/app/pages/ingredients/ingredient-list/ingredient-list.component.html

@ -19,7 +19,7 @@
<ng-template #searchTpl>
<nz-form-item class="w-60">
<nz-form-control>
<nz-select nzPlaceHolder="单位" [nzOptions]="[]"></nz-select>
<app-org-select formControlName="vender"></app-org-select>
</nz-form-control>
</nz-form-item>
<nz-form-item class="w-40">

17
projects/admin/src/app/pages/ingredients/ingredient-list/ingredient-list.component.ts

@ -8,6 +8,7 @@ import { NzModalService } from "ng-zorro-antd/modal";
import { lastValueFrom, tap } from "rxjs";
import { NzMessageService } from "ng-zorro-antd/message";
import { MyResponse } from "@cdk/types";
import { Router } from "@angular/router";
@Component({
selector: "app-ingredient-list",
@ -19,7 +20,8 @@ export class IngredientListComponent {
private drawer: NzDrawerService,
private api: ApiService,
private modal: NzModalService,
private msg: NzMessageService
private msg: NzMessageService,
private router: Router
) {}
globalEnum = this.api.globalEnum;
@ -36,6 +38,8 @@ export class IngredientListComponent {
public queryForm = new FormGroup({
name: new FormControl(""),
vender: new FormControl(""),
status: new FormControl(""),
});
startTime: Date | null = null;
@ -89,6 +93,7 @@ export class IngredientListComponent {
{
title: "导出",
premissions: [],
onClick: this.showFoodForm.bind(this),
},
{
@ -101,7 +106,7 @@ export class IngredientListComponent {
// 2 发布 编辑 删除
// 3 提交审核 编辑 删除
// 4 提交审核 编辑 删除
return ["0", "3", "4"].includes(v.status);
return [0, 3, 4].includes(v.status);
},
},
{
@ -109,15 +114,17 @@ export class IngredientListComponent {
premissions: [],
onClick: this.release.bind(this),
visible(v) {
return ["2"].includes(v.status);
return [2].includes(v.status);
},
},
{
title: "编辑",
premissions: [],
onClick: this.deleteItem.bind(this),
onClick: (v) => {
this.router.navigate([`/ingredient/item/form/${v["id"]}`]);
},
visible(v) {
return v.status !== "1";
return v.status !== 1;
},
},
{

12
projects/admin/src/app/pages/standard/standard-form/standard-form.component.ts

@ -115,9 +115,13 @@ export class StandardFormComponent {
onSubmit(gotoSetting?: boolean) {
if (Utils.validateFormGroup(this.formGroup)) {
this.submitLoading = true;
const { foodCategoryDay, foodCategoryWeek, ingredient } = this.state;
this.api
.saveStandard({ foodCategoryDay, foodCategoryWeek, ingredient, ...this.formGroup.value })
.saveStandard({
foodCategoryDay: this.state?.foodCategoryDay,
foodCategoryWeek: this.state?.foodCategoryWeek,
ingredient: this.state?.ingredient,
...this.formGroup.value,
})
.pipe(
finalize(() => {
this.submitLoading = false;
@ -126,7 +130,9 @@ export class StandardFormComponent {
.subscribe((res) => {
this.msg.success(res.desc);
const redirectTo = gotoSetting ? ["/", "standard", "setting", res.body.id] : ["/standard/list"];
this.router.navigate(redirectTo);
this.router.navigate(redirectTo, {
state: res.body,
});
});
}
}

115
projects/cdk/src/ingredient/add-dish-to-ingredient/add-dish-to-ingredient.component.html

@ -1,24 +1,28 @@
<form nz-form>
<div nz-form>
<div nz-row [nzGutter]="12">
<div nz-col nzSpan="12">
<div nz-col nzSpan="14">
<nz-form-item>
<nz-form-label nzRequired="">菜品名称</nz-form-label>
<nz-form-control>
<nz-select nzShowSearch nzPlaceHolder="请输入菜品名称搜索"></nz-select>
<!-- 请输入菜品名称搜索 -->
<app-dish-select [(ngModel)]="dish" (ngModelChange)="onDishChange($event)"></app-dish-select>
</nz-form-control>
</nz-form-item>
</div>
<div nz-col nzSpan="12">
<div nz-col nzSpan="10">
<nz-form-item>
<nz-form-label nzRequired="">菜品标签</nz-form-label>
<nz-form-control>
<nz-select nzPlaceHolder="请选择菜品标签"></nz-select>
<nz-select nzPlaceHolder="请选择菜品标签" [(ngModel)]="mark">
<nz-option *ngFor="let item of globalEnum.mark" [nzValue]="item.value"
[nzLabel]="item.key"></nz-option>
</nz-select>
</nz-form-control>
</nz-form-item>
</div>
</div>
<nz-form-item>
<!-- <nz-form-item>
<nz-form-label nzRequired="">食材搜索方式</nz-form-label>
<nz-form-control>
<nz-radio-group nzButtonStyle="solid">
@ -26,44 +30,47 @@
<label nz-radio nzValue="2" nz-radio-button>营养素</label>
</nz-radio-group>
</nz-form-control>
</nz-form-item>
</nz-form-item> -->
<div>
<nz-table nzTemplateMode [nzBordered]="true" nzSize="small">
<nz-table nzTemplateMode [nzBordered]="true" nzSize="small" [nzScroll]="{ x: '1000px' }">
<thead>
<tr>
<th>
<th nzWidth="200px">
食材
</th>
<th>
<th nzWidth="80px">
是否主料
</th>
<th>
轻体力1
<th *ngFor="let p of peopleGroups" nzWidth="120px">
{{p}}
</th>
<th>
轻体力2
</th>
<th>
<!-- <th nzRight nzWidth="150px">
操作
</th>
</th> -->
</tr>
</thead>
<tbody>
<tr>
<tr *ngFor="let item of foods">
<td>
味精
{{item.foodName}}
</td>
<td>
<nz-switch nzCheckedChildren="是" nzUnCheckedChildren="否"></nz-switch>
<nz-switch
[(ngModel)]="item.isMain"
[nzDisabled]="true"
nzCheckedChildren="是"
nzUnCheckedChildren="否">
</nz-switch>
</td>
<td>
<input nz-input placeholder="重量" />
</td>
<td>
<input nz-input placeholder="重量" />
<td *ngFor="let p of item.groupValues">
<nz-input-group nzAddOnAfter="g">
<input nz-input type="number" min="0" placeholder="重量" [(ngModel)]="p.value" />
</nz-input-group>
</td>
<td>
<nz-space>
<!-- <td nzRight>
<nz-space nzSize="small">
<button *nzSpaceItem nz-button nzType="link">
修改
</button>
@ -71,57 +78,11 @@
删除
</button>
</nz-space>
</td>
</tr>
<tr>
<td>
味精
</td>
<td>
<nz-switch nzCheckedChildren="是" nzUnCheckedChildren="否"></nz-switch>
</td>
<td>
<input nz-input placeholder="重量" />
</td>
<td>
<input nz-input placeholder="重量" />
</td>
<td>
<nz-space>
<button *nzSpaceItem nz-button nzType="link">
修改
</button>
<button *nzSpaceItem nz-button nzType="link" nzDanger>
删除
</button>
</nz-space>
</td>
</tr>
<tr>
<td>
味精
</td>
<td>
<nz-switch nzCheckedChildren="是" nzUnCheckedChildren="否"></nz-switch>
</td>
<td>
<input nz-input placeholder="重量" />
</td>
<td>
<input nz-input placeholder="重量" />
</td>
<td>
<nz-space>
<button *nzSpaceItem nz-button nzType="link">
修改
</button>
<button *nzSpaceItem nz-button nzType="link" nzDanger>
删除
</button>
</nz-space>
</td>
</td> -->
</tr>
</tbody>
</nz-table>
<nz-empty class="mt-4" *ngIf="foods.length === 0"></nz-empty>
</div>
</form>
</div>

61
projects/cdk/src/ingredient/add-dish-to-ingredient/add-dish-to-ingredient.component.ts

@ -1,8 +1,63 @@
import { Component } from "@angular/core";
import { Component, Input, OnInit } from "@angular/core";
import { ApiService } from "@cdk/services";
export interface FoodInDishInterface {
foodName: string;
key: string;
isMain: boolean;
groupValues: Array<{
peopleName: string;
value: number;
}>;
value: Record<string, number>;
}
@Component({
selector: "lib-add-dish-to-ingredient",
selector: "app-add-dish-to-ingredient",
templateUrl: "./add-dish-to-ingredient.component.html",
styleUrls: ["./add-dish-to-ingredient.component.less"],
})
export class AddDishToIngredientComponent {}
export class AddDishToIngredientComponent implements OnInit {
constructor(private api: ApiService) {}
@Input() peopleGroups: string[] = [];
globalEnum = this.api.globalEnum;
dish: any = null;
mark: string = "";
foods: FoodInDishInterface[] = [];
ngOnInit(): void {
console.log("this.peopleGroups", this.peopleGroups);
}
onDishChange(dish: any) {
if (dish) {
this.mark = dish.marks;
this.getFoodNameByKeys(dish.ingredient);
}
}
getFoodNameByKeys(foods: any[]) {
const keys = foods.map((i) => i.key);
this.api.getFoodList({ keys }).subscribe((res) => {
this.foods = res.body.map((i) => {
return {
foodName: i.name,
key: i.key,
isMain: foods.find((f) => f.key === i.key)?.isMain ?? false,
groupValues: this.peopleGroups.map((p) => {
return {
peopleName: p,
value: 0,
};
}),
value: {},
};
});
});
}
}

34
projects/cdk/src/ingredient/confirm-ingredient/confirm-ingredient.component.html

@ -1,10 +1,10 @@
<form nz-form [formGroup]="formGroup">
<div nz-form>
<nz-form-item>
<nz-form-label nzSpan="4">
天数
</nz-form-label>
<nz-form-control nzSpan="12">
<nz-tag nzColor="cyan">7</nz-tag>
<nz-tag nzColor="cyan">{{data.day}}</nz-tag>
</nz-form-control>
</nz-form-item>
<nz-form-item>
@ -13,9 +13,7 @@
</nz-form-label>
<nz-form-control nzSpan="12">
<nz-space>
<nz-tag *nzSpaceItem nzColor="blue">早餐</nz-tag>
<nz-tag *nzSpaceItem nzColor="blue">午餐</nz-tag>
<nz-tag *nzSpaceItem nzColor="blue">晚餐</nz-tag>
<ng-container *ngFor="let m of data.meals">{{m}}</ng-container>
</nz-space>
</nz-form-control>
</nz-form-item>
@ -24,30 +22,16 @@
食谱名称
</nz-form-label>
<nz-form-control nzSpan="16">
<input nz-input placeholder="请输入食谱名称" />
{{data.name}}
<!-- <input nz-input placeholder="请输入食谱名称" [ngModel]="data.name" /> -->
</nz-form-control>
</nz-form-item>
<nz-form-item>
<!-- <nz-form-item>
<nz-form-label nzSpan="4" nzRequired>
适用月份
</nz-form-label>
<nz-form-control nzSpan="16">
<div>
<label
nz-checkbox
[(ngModel)]="allMonthChecked"
[ngModelOptions]="{standalone: true}"
(ngModelChange)="updateAllMonthChecked()"
[nzIndeterminate]="indeterminate">
全年
</label>
</div>
<nz-divider nzDashed class="my-2"></nz-divider>
<nz-checkbox-group [ngModel]="allMonth"
class="flex flex-wrap month-wrap"
formControlName="month"
(ngModelChange)="monthChecked()">
</nz-checkbox-group>
<app-month-select [ngModel]="[1,2,3]"></app-month-select>
</nz-form-control>
</nz-form-item>
</form>
</nz-form-item> -->
</div>

59
projects/cdk/src/ingredient/confirm-ingredient/confirm-ingredient.component.ts

@ -1,7 +1,8 @@
import { Component } from "@angular/core";
import { Component, inject } from "@angular/core";
import { FormBuilder, FormGroup } from "@angular/forms";
import { FormValidators } from "@cdk/public-api";
import { NzMessageService } from "ng-zorro-antd/message";
import { NZ_MODAL_DATA } from "ng-zorro-antd/modal";
@Component({
selector: "lib-confirm-ingredient",
@ -11,61 +12,11 @@ import { NzMessageService } from "ng-zorro-antd/message";
export class ConfirmIngredientComponent {
constructor(private fb: FormBuilder, private msg: NzMessageService) {}
formGroup!: FormGroup;
allMonth = [
{ value: "1", label: "一月", checked: false },
{ value: "2", label: "二月", checked: false },
{ value: "3", label: "三月", checked: false },
{ value: "4", label: "四月", checked: false },
{ value: "5", label: "五月", checked: false },
{ value: "6", label: "六月", checked: false },
{ value: "7", label: "七月", checked: false },
{ value: "8", label: "八月", checked: false },
{ value: "9", label: "九月", checked: false },
{ value: "10", label: "十月", checked: false },
{ value: "11", label: "十一月", checked: false },
{ value: "12", label: "十二月", checked: false },
];
allMonthChecked = false;
data = inject(NZ_MODAL_DATA);
indeterminate = false;
formGroup!: FormGroup;
ngOnInit(): void {
this.formGroup = this.fb.group({
id: this.fb.control("", [FormValidators.required()]),
name: this.fb.control("", [FormValidators.required()]),
month: this.fb.control([], [FormValidators.required()]),
});
}
updateAllMonthChecked() {
this.indeterminate = false;
if (this.allMonthChecked) {
this.allMonth = this.allMonth.map((item) => ({
...item,
checked: true,
}));
} else {
this.allMonth = this.allMonth.map((item) => ({
...item,
checked: false,
}));
}
}
monthChecked() {
if (this.allMonth.every((item) => !item.checked)) {
this.allMonthChecked = false;
this.indeterminate = false;
} else if (this.allMonth.every((item) => item.checked)) {
this.allMonthChecked = true;
this.indeterminate = false;
} else {
this.indeterminate = true;
}
console.log("data", this.data);
}
}

60
projects/cdk/src/ingredient/ingredient-dish/ingredient-dish.component.html

@ -0,0 +1,60 @@
<nz-spin [nzSpinning]="!menu">
<ng-container>
<!-- {{ menuObject | json }} -->
<nz-card
*ngFor="let day of days"
[nzTitle]="dayTitleTpl"
class="day-item mb-4"
[ngClass]="{'expanded':expanded.has(day)}"
[nzExtra]="dayExtraTpl"
[nzBodyStyle]="{padding:0}">
<ng-template #dayTitleTpl>
<div class=" relative -left-4 z-10">
<button nz-button nzType="text" (click)="expandChange(day)">
<span class="expanded-icon" nz-icon nzType="caret-right" nzTheme="outline"></span>
</button>
<span>
第 {{day + 1}} 天
</span>
</div>
</ng-template>
<ng-template #dayExtraTpl>
<nz-space>
<button *nzSpaceItem nz-button nzType="link" (click)="reuse(day + 1, selectDayTpl)">
本天菜品应用到其他天
</button>
<button *nzSpaceItem nz-button nzType="link">
本日营养分析
</button>
</nz-space>
</ng-template>
<ng-container *ngIf="expanded.has(day)">
<nz-card-tab>
<nz-tabset nzSize="large" [(nzSelectedIndex)]="mealCurrentIndex[day]">
<nz-tab [nzTitle]="meal" *ngFor="let meal of menu.meals; let idx = index">
</nz-tab>
</nz-tabset>
</nz-card-tab>
<div class="p-4">
<ng-container *ngFor="let meal of menu.meals; let mealIndex = index ">
<app-ingredient-meals *ngIf="mealCurrentIndex[day] === mealIndex"
[day]="day + 1"
[mealIndex]="mealIndex"
[peopleGroups]="menu.crows"
[mealDishs]="mealDishList"
(onSaveDish)="onSaveDish($event,day+1,mealIndex)">
<!-- (onSaveDish)="onSaveDish($event,day+1,mealIndex)" -->
</app-ingredient-meals>
</ng-container>
</div>
</ng-container>
</nz-card>
</ng-container>
</nz-spin>
<ng-template #selectDayTpl>
<nz-alert nzType="warning" nzMessage="请注意,如果其它天已经存在菜品,新应用的菜品将会追加在其中,不影响已经存在的菜品" nzShowIcon>
</nz-alert>
<nz-checkbox-group [(ngModel)]="selectDay" class="select-day mt-4"></nz-checkbox-group>
</ng-template>

25
projects/cdk/src/ingredient/ingredient-dish/ingredient-dish.component.less

@ -0,0 +1,25 @@
.day-item {
::ng-deep {
.ant-card-head-title {
overflow: visible;
}
}
&.expanded {
.expanded-icon {
transform: rotate(90deg);
}
}
}
.select-day {
display: flex;
flex-wrap: wrap;
::ng-deep {
>label {
margin: 0 0 12px 0;
flex-basis: 25%;
}
}
}

119
projects/cdk/src/ingredient/ingredient-dish/ingredient-dish.component.ts

@ -0,0 +1,119 @@
import { Component, Input, OnChanges, SimpleChanges, TemplateRef } from "@angular/core";
// import { MealDishInterface } from "../ingredient-meals/ingredient-meals.component";
import { NzModalService } from "ng-zorro-antd/modal";
import { Augmented, OptionItemInterface } from "@cdk/types";
import { NzMessageService } from "ng-zorro-antd/message";
// export interface MenuObjectInterface {
// [Day: number]: {
// [MealIndex: number]: MealDishInterface[];
// };
// }
export type DishInterface = Augmented<{
dishId: number;
day: number;
meal: string;
mark: string;
items: Array<
Augmented<{
key: string;
isMain: boolean;
value: Record<string, number>;
}>
>;
}>;
@Component({
selector: "app-ingredient-dish",
templateUrl: "./ingredient-dish.component.html",
styleUrls: ["./ingredient-dish.component.less"],
})
export class IngredientDishComponent implements OnChanges {
constructor(private modal: NzModalService, private msg: NzMessageService) {}
@Input() menu: any | null;
expanded = new Set<number>();
days: number[] = [];
selectDay: OptionItemInterface[] = [];
mealCurrentIndex: Record<number, number> = {};
// d = {
// 1:{
// zaocan:[
// {dishId:1...}
// ]
// }
// }
// menuObject!: MenuObjectInterface;
mealDishList: DishInterface[] = [];
ngOnChanges(changes: SimpleChanges): void {
if (changes["menu"]?.currentValue) {
this.initMenu();
}
}
initMenu() {
if (this.menu) {
const meals = this.menu.meals as string[];
const day = this.menu.day as number;
this.days = Array.from({ length: day }, (_, i) => {
this.selectDay.push({
label: `${i + 1}`,
value: String(i + 1),
});
this.mealCurrentIndex[i] = 0;
// if (!this.menuObject) {
// this.menuObject = {};
// }
// this.menuObject[i + 1] = meals.reduce((a, c, idx) => {
// return {
// ...a,
// [idx]: [],
// };
// }, {} as Record<number, MealDishInterface[]>);
return i;
});
}
}
expandChange(i: number) {
if (this.expanded.has(i)) {
this.expanded.delete(i);
} else {
this.expanded.add(i);
}
}
onSaveDish(v: DishInterface[], day: number, mealIndex: number) {
this.mealDishList = JSON.parse(JSON.stringify(v));
// this.menuObject[day][mealIndex] = JSON.parse(JSON.stringify(v));
}
reuse(day: number, nzContent: TemplateRef<{}>) {
const thisDayDishs = this.mealDishList.filter((f) => f.day === day);
console.log("dayDishs", day, this.mealDishList, thisDayDishs);
this.modal.create({
nzTitle: "请选择应用到的日期",
nzContent,
nzOnOk: () => {
this.selectDay.forEach((i) => {
if (i["checked"]) {
thisDayDishs.forEach((reused) => {
this.mealDishList.push(JSON.parse(JSON.stringify({ ...reused, day: Number(i.value) })));
});
}
i["checked"] = false;
});
this.mealDishList = JSON.parse(JSON.stringify(this.mealDishList));
this.msg.success("操作成功");
},
});
}
}

17
projects/admin/src/app/components/ingredient-form-basic/ingredient-form-basic.component.html → projects/cdk/src/ingredient/ingredient-form-basic/ingredient-form-basic.component.html

@ -13,6 +13,7 @@
</nz-form-label>
<nz-form-control [nzErrorTip]="formControlErrorTpl" nzSpan="12">
<nz-select
[nzDisabled]="menu"
nzShowSearch
nzServerSearch
nzPlaceHolder="请选择标准"
@ -33,7 +34,7 @@
适用单位
</nz-form-label>
<nz-form-control [nzErrorTip]="formControlErrorTpl" nzSpan="12">
<nz-select nzMode="multiple" formControlName="vendors" nzPlaceHolder="请选择单位"
<nz-select nzMode="multiple" [nzDisabled]="menu" formControlName="vendors" nzPlaceHolder="请选择单位"
[nzOptions]="currentOrgs">
</nz-select>
</nz-form-control>
@ -52,13 +53,13 @@
</nz-form-label>
<nz-form-control [nzErrorTip]="formControlErrorTpl">
<nz-radio-group formControlName="day">
<label nz-radio nzValue="1">1天</label>
<label nz-radio nzValue="2">2天</label>
<label nz-radio nzValue="3">3天</label>
<label nz-radio nzValue="4">4天</label>
<label nz-radio nzValue="5">5天</label>
<label nz-radio nzValue="6">6天</label>
<label nz-radio nzValue="7">7天</label>
<label nz-radio [nzValue]="1">1天</label>
<label nz-radio [nzValue]="2">2天</label>
<label nz-radio [nzValue]="3">3天</label>
<label nz-radio [nzValue]="4">4天</label>
<label nz-radio [nzValue]="5">5天</label>
<label nz-radio [nzValue]="6">6天</label>
<label nz-radio [nzValue]="7">7天</label>
</nz-radio-group>
</nz-form-control>
</nz-form-item>

0
projects/admin/src/app/components/ingredient-form-basic/ingredient-form-basic.component.less → projects/cdk/src/ingredient/ingredient-form-basic/ingredient-form-basic.component.less

57
projects/admin/src/app/components/ingredient-form-basic/ingredient-form-basic.component.ts → projects/cdk/src/ingredient/ingredient-form-basic/ingredient-form-basic.component.ts

@ -1,6 +1,5 @@
import { Component, EventEmitter, OnInit, Output } from "@angular/core";
import { Component, EventEmitter, Input, OnChanges, OnInit, Output, SimpleChanges } from "@angular/core";
import { FormArray, FormBuilder, FormGroup } from "@angular/forms";
import { Router } from "@angular/router";
import { OrgDTO } from "@cdk/dtos";
import { ApiService } from "@cdk/services";
import { OptionItemInterface } from "@cdk/types";
@ -14,17 +13,14 @@ import { Subject, debounceTime, distinctUntilChanged, filter, finalize, switchMa
templateUrl: "./ingredient-form-basic.component.html",
styleUrls: ["./ingredient-form-basic.component.less"],
})
export class IngredientFormBasicComponent {
constructor(
private fb: FormBuilder,
private msg: NzMessageService,
private api: ApiService,
private router: Router
) {}
export class IngredientFormBasicComponent implements OnChanges {
constructor(private fb: FormBuilder, private msg: NzMessageService, private api: ApiService) {}
@Input() menu: any | null;
@Output() onSave = new EventEmitter();
private standardSearch$ = new Subject<string>();
private standardSearch$ = new Subject<{ id?: string; name?: string }>();
private destroy$ = new Subject<void>();
@ -49,22 +45,25 @@ export class IngredientFormBasicComponent {
id: this.fb.control("", []),
name: this.fb.control("", [FormValidators.required()]),
nutrient: this.fb.control("", [FormValidators.required()]),
day: this.fb.control("1", [FormValidators.required()]),
day: this.fb.control(1, [FormValidators.required()]),
vendors: this.fb.control([], [FormValidators.required()]),
month: this.fb.control([], [FormValidators.required()]),
});
this.standardSearch$
.pipe(
filter((f) => !!f),
debounceTime(500),
distinctUntilChanged(),
takeUntil(this.destroy$),
switchMap((term: string) => this.api.getStandard({ name: term }))
switchMap((q) => this.api.getStandard(q))
)
.subscribe((data) => {
let listOfOption: Array<OptionItemInterface> = [];
if (data.body) {
const getById = data.body && !Array.isArray(data.body);
if (getById) {
data.body = [data.body];
}
data.body.forEach((item) => {
listOfOption.push({
label: item.name,
@ -73,10 +72,29 @@ export class IngredientFormBasicComponent {
});
});
this.searchedStandard = this.searchedStandard.concat(listOfOption);
if (getById && this.menu.nutrient) {
this.onStandardChange(this.menu.nutrient);
}
}
this.standardOfOption = listOfOption;
});
this.setValues();
}
ngOnChanges(changes: SimpleChanges): void {}
setValues() {
if (this.menu) {
console.log("this.formGroup", this.formGroup, this.menu);
this.standardSearch$.next({ id: this.menu.nutrient });
this.meals = this.meals.map((i) => (this.menu.meals.includes(i.value) ? { ...i, checked: true } : i));
this.formGroup.patchValue({
...this.menu,
vendors: [String(this.menu.vender)],
});
}
}
ngOnDestroy(): void {
@ -87,7 +105,9 @@ export class IngredientFormBasicComponent {
ageChange() {}
searchStandard(k: string) {
this.standardSearch$.next(k);
if (k) {
this.standardSearch$.next({ name: k });
}
}
onStandardChange(v: any) {
@ -104,6 +124,7 @@ export class IngredientFormBasicComponent {
return {
label: k,
value: k,
checked: this.menu?.crows?.includes(k),
...(v as any),
};
});
@ -144,8 +165,12 @@ export class IngredientFormBasicComponent {
)
.subscribe((res) => {
this.msg.success(res.desc);
this.onSave.emit({ meals: this.meals, menuId: res.body, peoples: this.currentPeoples });
// this.router.navigate(["/ingredient/item/list"]);
this.onSave.emit({
...this.formGroup.value,
meals: this.meals,
menuId: res.body,
peoples: this.currentPeoples,
});
});
}
}

225
projects/cdk/src/ingredient/ingredient-meals/ingredient-meals.component.html

@ -4,7 +4,7 @@
<button *nzSpaceItem nz-button nzType="primary" (click)="shopDishForm()">
添加菜品
</button>
<button *nzSpaceItem nz-button>
<button *nzSpaceItem nz-button (click)="clearThisMeal()">
清空本餐
</button>
</nz-space>
@ -14,62 +14,53 @@
<tr>
<th colSpan="2"></th>
<th [colSpan]="5">
<th [colSpan]="peopleGroups.length">
重量/克
</th>
</tr>
<tr>
<th [rowSpan]="2">
<th nzWidth="200px">
菜品
</th>
<th [rowSpan]="2">
<th nzWidth="200px">
食材
</th>
<th>
轻体力(体重过低)
</th>
<th>
轻体力(正常体重)
</th>
<th>
休息(超重/肥胖)
</th>
<th>
轻体力(体重过低)
</th>
<th>
轻体力(正常体重)
<th *ngFor="let p of peopleGroups">
{{p}}
</th>
</tr>
</thead>
<tbody>
<ng-container *ngFor="let dish of currentDishs">
<ng-container *ngFor="let food of dish['items'];let first = first;">
<tr>
<td [rowSpan]="2">
<td *ngIf="first" [rowSpan]="dish['items'].length ">
<div class="flex justify-between">
<span>
番茄煎蛋面
{{dish['dishName']}}
</span>
<button nz-button nzType="text" nz-dropdown [nzDropdownMenu]="dishOptions">
<i nz-icon nzType="more"></i>
<button nz-button nzType="text" (click)="onRemoveDish(dish)">
<i nz-icon nzType="delete"></i>
</button>
<nz-dropdown-menu #dishOptions="nzDropdownMenu">
<!-- nz-dropdown [nzDropdownMenu]="dishOptions" -->
<!-- <nz-dropdown-menu #dishOptions="nzDropdownMenu">
<ul nz-menu nzSelectable class=" w-20">
<li nz-menu-item>编辑</li>
<li nz-menu-item nzDanger>删除</li>
</ul>
</nz-dropdown-menu>
</nz-dropdown-menu> -->
</div>
</td>
<td>
<div class="flex justify-between">
<span>
番茄
{{food['foodName']}}
</span>
<button nz-button nzType="text" nz-dropdown [nzDropdownMenu]="foodOptions">
<!-- <button nz-button nzType="text" nz-dropdown [nzDropdownMenu]="foodOptions">
<i nz-icon nzType="more"></i>
</button>
<nz-dropdown-menu #foodOptions="nzDropdownMenu">
@ -77,176 +68,28 @@
<li nz-menu-item>设置价格</li>
<li nz-menu-item nzDanger>删除</li>
</ul>
</nz-dropdown-menu>
</div>
</td>
<td>
1
</td>
<td>
1
</td>
<td>
1
</td>
<td>
1
</td>
<td>
1
</td>
</tr>
<tr>
<td>
<div class="flex justify-between">
<span>
面条
</span>
<button nz-button nzType="text">
<i nz-icon nzType="more"></i>
</button>
</div>
</td>
<td>
1
</td>
<td>
1
</td>
<td>
1
</td>
<td>
1
</td>
<td>
1
</td>
</tr>
<tr>
<td [rowSpan]="4">
<div class="flex justify-between">
<span>
鸡蛋青菜面
</span>
<button nz-button nzType="text">
<i nz-icon nzType="more"></i>
</button>
</nz-dropdown-menu> -->
</div>
</td>
<td>
<div class="flex justify-between">
<span>
食用油
</span>
<button nz-button nzType="text">
<i nz-icon nzType="more"></i>
</button>
</div>
</td>
<td>
1
</td>
<td>
1
</td>
<td>
1
</td>
<td>
1
</td>
<td>
1
<td *ngFor="let g of food.value | keyvalue">
{{g.value}}
</td>
</tr>
<tr>
<td>
</ng-container>
</ng-container>
<div class="flex justify-between">
<span>
小白菜[青菜]
</span>
<button nz-button nzType="text">
<i nz-icon nzType="more"></i>
</button>
</div>
</td>
<td>
1
</td>
<td>
1
</td>
<td>
1
</td>
<td>
1
</td>
<td>
1
</td>
</tr>
<tr>
<td>
<div class="flex justify-between">
<span>
鸡蛋(均值)
</span>
<button nz-button nzType="text">
<i nz-icon nzType="more"></i>
</button>
</div>
</td>
<td>
1
</td>
<td>
1
</td>
<td>
1
</td>
<td>
1
</td>
<td>
1
</td>
</tr>
<tr>
<td>
<div class="flex justify-between">
<span>
面条(均值)
</span>
<button nz-button nzType="text">
<i nz-icon nzType="more"></i>
</button>
</div>
</td>
<td>
1
</td>
<td>
1
</td>
<td>
1
</td>
<td>
1
</td>
<td>
1
</td>
</tr>
</tbody>
</nz-table>
<nz-empty *ngIf="currentDishs.length === 0" class="empty"></nz-empty>
</div>
<ng-template #addDishFooter>
<nz-space>
<button *nzSpaceItem nz-button (click)="cancelForm()" type="button">
取消
</button>
<button *nzSpaceItem nz-button nzType="primary" [nzLoading]="submitLoading" (click)="onSubmit()">
保存
</button>
</nz-space>
</ng-template>

6
projects/cdk/src/ingredient/ingredient-meals/ingredient-meals.component.less

@ -0,0 +1,6 @@
.empty {
margin: 0;
padding: 24px;
border: 1px solid #f0f0f0;
border-top: none;
}

125
projects/cdk/src/ingredient/ingredient-meals/ingredient-meals.component.ts

@ -1,21 +1,130 @@
import { Component } from "@angular/core";
import {
Component,
EventEmitter,
Input,
OnChanges,
OnInit,
Output,
SimpleChanges,
TemplateRef,
ViewChild,
} from "@angular/core";
import { NzModalService } from "ng-zorro-antd/modal";
import { AddDishToIngredientComponent } from "../add-dish-to-ingredient/add-dish-to-ingredient.component";
import { NzDrawerService } from "ng-zorro-antd/drawer";
import {
AddDishToIngredientComponent,
FoodInDishInterface,
} from "../add-dish-to-ingredient/add-dish-to-ingredient.component";
import { NzDrawerRef, NzDrawerService } from "ng-zorro-antd/drawer";
import { NzMessageService } from "ng-zorro-antd/message";
import { Augmented } from "@cdk/types";
import { DishInterface } from "../ingredient-dish/ingredient-dish.component";
export type MealDishInterface = Augmented<{
dishId: number;
dishName: string;
mark: string;
foods: FoodInDishInterface[];
}>;
@Component({
selector: "lib-ingredient-meals",
selector: "app-ingredient-meals",
templateUrl: "./ingredient-meals.component.html",
styleUrls: ["./ingredient-meals.component.less"],
})
export class IngredientMealsComponent {
constructor(private modal: NzModalService, private drawer: NzDrawerService) {}
export class IngredientMealsComponent implements OnChanges, OnInit {
constructor(private modal: NzModalService, private msg: NzMessageService, private drawer: NzDrawerService) {}
@Input() day!: number;
@Input() mealIndex!: number;
@Input() peopleGroups: string[] = [];
@Input() mealDishs: DishInterface[] = [];
@Output() onSaveDish = new EventEmitter<DishInterface[]>();
@ViewChild("addDishFooter") addDishFooter!: TemplateRef<{}>;
drawerRef?: NzDrawerRef;
submitLoading = false;
currentDishs: DishInterface[] = [];
ngOnInit(): void {
this.init();
}
ngOnChanges(changes: SimpleChanges): void {
if (changes["mealDishs"]?.currentValue) {
this.init();
}
}
init() {
console.log(" ", this.mealDishs, this.day, this.mealIndex);
this.currentDishs = this.mealDishs.filter((f) => f.day === this.day && this.mealIndex === f["mealIndex"]);
}
shopDishForm() {
this.drawer.create({
this.drawerRef = this.drawer.create({
nzTitle: "添加菜品",
nzWidth: 1000,
nzWidth: 1200,
nzContent: AddDishToIngredientComponent,
nzFooter: this.addDishFooter,
nzContentParams: {
peopleGroups: this.peopleGroups,
},
});
}
clearThisMeal() {
this.modal.confirm({
nzTitle: "警告",
nzContent: "是否要清空本餐?",
nzOkDanger: true,
nzOnOk: () => {
this.mealDishs = this.mealDishs.filter((f) => !(f.day === this.day && f["mealIndex"] === this.mealIndex));
this.onSaveDish.emit(this.mealDishs);
},
});
}
cancelForm() {
this.drawerRef?.close();
}
onSubmit() {
if (this.drawerRef) {
const { dish, foods } = this.drawerRef.getContentComponent() as AddDishToIngredientComponent;
this.mealDishs.push({
day: this.day,
mealIndex: this.mealIndex,
meal: "",
dishId: dish.id,
dishName: dish.name,
mark: dish.marks,
items: foods.map((f) => ({
...f,
value: f.groupValues.reduce((a, c) => {
return {
...a,
[c.peopleName]: c.value,
};
}, {} as Record<string, number>),
})),
});
this.onSaveDish.emit(this.mealDishs);
}
this.cancelForm();
}
onRemoveDish(d: DishInterface) {
this.mealDishs = this.mealDishs.filter(
(f) => !(f.dishId === d.dishId && f.day === this.day && f["mealIndex"] === this.mealIndex)
);
this.onSaveDish.emit(this.mealDishs);
}
}

18
projects/cdk/src/ingredient/ingredient.module.ts

@ -3,10 +3,24 @@ import { SharedModule } from "@cdk/shared/shared.module";
import { AddDishToIngredientComponent } from "./add-dish-to-ingredient/add-dish-to-ingredient.component";
import { IngredientMealsComponent } from "./ingredient-meals/ingredient-meals.component";
import { ConfirmIngredientComponent } from "./confirm-ingredient/confirm-ingredient.component";
import { IngredientDishComponent } from "./ingredient-dish/ingredient-dish.component";
import { IngredientFormBasicComponent } from "./ingredient-form-basic/ingredient-form-basic.component";
@NgModule({
declarations: [AddDishToIngredientComponent, IngredientMealsComponent, ConfirmIngredientComponent],
declarations: [
AddDishToIngredientComponent,
IngredientMealsComponent,
ConfirmIngredientComponent,
IngredientFormBasicComponent,
IngredientDishComponent,
],
imports: [SharedModule],
exports: [AddDishToIngredientComponent, IngredientMealsComponent, ConfirmIngredientComponent],
exports: [
AddDishToIngredientComponent,
IngredientMealsComponent,
ConfirmIngredientComponent,
IngredientFormBasicComponent,
IngredientDishComponent,
],
})
export class IngredientModule {}

10
projects/cdk/src/services/api.service.ts

@ -372,9 +372,9 @@ export class ApiService {
return this.http.get<ResponseType<PageResult>>(`/api/menu?${params}`);
}
getMenuItem() {
const params = Utils.objectStringify({ menuId: 1 });
return this.http.get(`/api/menu/dish?${params}`);
getMenuItem(id: string | number) {
const params = Utils.objectStringify({ id });
return this.http.get<ResponseType>(`/api/menu?${params}`);
}
saveMenu(v: AnyObject) {
@ -408,4 +408,8 @@ export class ApiService {
const params = Utils.objectToFormData({ id });
return this.http.delete<ResponseType>(`/api/menu`, { body: params });
}
saveMenuDist(d: {}) {
return this.http.put<ResponseType>(`/api/menu/dish/batch`, d);
}
}

22
projects/cdk/src/shared/components/dish-select/dish-select.component.html

@ -0,0 +1,22 @@
<nz-select
nzShowSearch
nzServerSearch
nzPlaceHolder="请输入菜品名称搜索"
[nzShowArrow]="false"
[nzFilterOption]="nzFilterOption"
[(ngModel)]="value"
(ngModelChange)="onSelectChange($event)"
(nzOnSearch)="search($event)">
<ng-container *ngIf="!loading">
<nz-option *ngFor="let o of listOfOption" [nzLabel]="o.label"
[nzValue]="o.value">
</nz-option>
</ng-container>
<nz-option *ngIf="loading" nzDisabled nzCustomContent>
<span nz-icon nzType="loading" class="loading-icon"></span>
数据加载中...
</nz-option>
</nz-select>

0
projects/cdk/src/shared/components/dish-select/dish-select.component.less

97
projects/cdk/src/shared/components/dish-select/dish-select.component.ts

@ -0,0 +1,97 @@
import { Component, OnInit } from "@angular/core";
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from "@angular/forms";
import { ApiService } from "@cdk/services";
import { OptionItemInterface } from "@cdk/types";
import { Subject, debounceTime, distinctUntilChanged, filter, finalize, switchMap, takeUntil, tap } from "rxjs";
@Component({
selector: "app-dish-select",
templateUrl: "./dish-select.component.html",
styleUrls: ["./dish-select.component.less"],
providers: [
{
provide: NG_VALUE_ACCESSOR,
multi: true,
useExisting: DishSelectComponent,
},
],
})
export class DishSelectComponent implements OnInit, ControlValueAccessor {
constructor(private api: ApiService) {}
private destroy$ = new Subject<void>();
private dishSearch$ = new Subject<string>();
nzFilterOption = (): boolean => true;
value?: string | string[];
listOfOption: OptionItemInterface[] = [];
loading = false;
ngOnInit(): void {
this.dishSearch$
.pipe(
filter((f) => !!f),
debounceTime(500),
distinctUntilChanged(),
takeUntil(this.destroy$),
tap(() => {
this.loading = true;
}),
switchMap((term: string) =>
this.api.getDishPage({ pageNo: 0, pageSize: 5 }, { keyword: term }).pipe(
finalize(() => {
this.loading = false;
})
)
)
)
.subscribe((data) => {
const listOfOption: Array<OptionItemInterface> = [];
data.body.content.forEach((item) => {
listOfOption.push({
...item,
value: String(item.id),
label: item.name,
});
});
this.listOfOption = listOfOption;
});
}
ngOnDestroy(): void {
this.destroy$.next();
this.destroy$.complete();
}
onSelectChange(v: any) {
const item = this.listOfOption.find((f) => f.value === v);
// console.log("v", item);
if (item) {
this.onChange(item);
}
}
search = (k: string) => {
this.dishSearch$.next(k);
};
onChange(v: OptionItemInterface) {}
ontouch(v: any) {}
writeValue(v?: string[] | string): void {
this.value = v;
}
registerOnChange(fn: any): void {
this.onChange = fn;
}
registerOnTouched(fn: any): void {
this.ontouch = fn;
}
}

2
projects/cdk/src/shared/components/index.ts

@ -1,2 +1,4 @@
export * from "./search-and-select/search-and-select.component";
export * from "./month-select/month-select.component";
export * from "./org-select/org-select.component";
export * from "./dish-select/dish-select.component";

1
projects/cdk/src/shared/components/month-select/month-select.component.ts

@ -79,6 +79,7 @@ export class MonthSelectComponent implements ControlValueAccessor {
ontouch(v: any) {}
writeValue(v: number[]): void {
console.log("v", v);
this.allMonth = this.allMonth.map((i) => (v.includes(i.value) ? { ...i, checked: true } : i));
this.monthCheckEffect();
}

13
projects/cdk/src/shared/components/org-select/org-select.component.html

@ -0,0 +1,13 @@
<nz-select
nzShowSearch
nzServerSearch
nzPlaceHolder="请选择单位"
[nzShowArrow]="false"
[nzFilterOption]="nzFilterOption"
[(ngModel)]="value"
(ngModelChange)="onSelectChange($event)"
(nzOnSearch)="searchOrg($event)">
<nz-option *ngFor="let o of listOfOption" [nzLabel]="o.label"
[nzValue]="o.value">
</nz-option>
</nz-select>

0
projects/cdk/src/shared/components/org-select/org-select.component.less

81
projects/cdk/src/shared/components/org-select/org-select.component.ts

@ -0,0 +1,81 @@
import { Component, OnInit } from "@angular/core";
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from "@angular/forms";
import { ApiService } from "@cdk/services";
import { OptionItemInterface } from "@cdk/types";
import { Subject, debounceTime, distinctUntilChanged, filter, switchMap, takeUntil } from "rxjs";
@Component({
selector: "app-org-select",
templateUrl: "./org-select.component.html",
styleUrls: ["./org-select.component.less"],
providers: [
{
provide: NG_VALUE_ACCESSOR,
multi: true,
useExisting: OrgSelectComponent,
},
],
})
export class OrgSelectComponent implements OnInit, ControlValueAccessor {
constructor(private api: ApiService) {}
private destroy$ = new Subject<void>();
private orgSearch$ = new Subject<string>();
nzFilterOption = (): boolean => true;
value?: string | string[];
listOfOption: OptionItemInterface[] = [];
ngOnInit(): void {
this.orgSearch$
.pipe(
filter((f) => !!f),
debounceTime(500),
distinctUntilChanged(),
takeUntil(this.destroy$),
switchMap((term: string) => this.api.getOrgList({ keyword: term }))
)
.subscribe((data) => {
const listOfOption: Array<OptionItemInterface> = [];
data.body.forEach((item) => {
listOfOption.push({
value: String(item.id),
label: item.name,
});
});
this.listOfOption = listOfOption;
});
}
ngOnDestroy(): void {
this.destroy$.next();
this.destroy$.complete();
}
onSelectChange(v: any) {
this.onChange(v);
}
searchOrg = (k: string) => {
this.orgSearch$.next(k);
};
onChange(v: number[]) {}
ontouch(v: any) {}
writeValue(v?: string[] | string): void {
this.value = v;
}
registerOnChange(fn: any): void {
this.onChange = fn;
}
registerOnTouched(fn: any): void {
this.ontouch = fn;
}
}

2
projects/cdk/src/shared/ng-zorro.ts

@ -47,8 +47,10 @@ import { NzInputNumberModule } from "ng-zorro-antd/input-number";
import { NzLayoutModule } from "ng-zorro-antd/layout";
import { NzBreadCrumbModule } from "ng-zorro-antd/breadcrumb";
import { NzOutletModule } from "ng-zorro-antd/core/outlet";
import { NzAlertModule } from "ng-zorro-antd/alert";
export const ngZorroModules = [
NzAlertModule,
NzOutletModule,
NzBreadCrumbModule,
NzLayoutModule,

13
projects/cdk/src/shared/shared.module.ts

@ -20,7 +20,7 @@ import {
// import { environment } from "@manage/environments/environment";
import { NgxPermissionsModule } from "ngx-permissions";
import { AppPageComponent } from "@cdk/app-page/app-page.component";
import { SearchAndSelectComponent, MonthSelectComponent } from "./components";
import { SearchAndSelectComponent, MonthSelectComponent, OrgSelectComponent, DishSelectComponent } from "./components";
const ngModules = [CommonModule, HttpClientModule, FormsModule, RouterModule, ReactiveFormsModule];
const components: any = [];
@ -36,7 +36,14 @@ const cdks = [
] as any;
@NgModule({
declarations: [...components, ...directives, SearchAndSelectComponent, MonthSelectComponent],
declarations: [
...components,
...directives,
SearchAndSelectComponent,
MonthSelectComponent,
DishSelectComponent,
OrgSelectComponent,
],
imports: [...ngZorroModules, ...ngModules, ...cdks, AppPageComponent],
exports: [
...ngZorroModules,
@ -47,6 +54,8 @@ const cdks = [
AppPageComponent,
SearchAndSelectComponent,
MonthSelectComponent,
OrgSelectComponent,
DishSelectComponent,
],
})
export class SharedModule {}

Loading…
Cancel
Save