Browse Source

食谱

main
kkerwin 2 years ago
parent
commit
70f49af415
  1. 16
      angular.json
  2. 2
      projects/admin/src/app/app-routing.module.ts
  3. 33
      projects/admin/src/app/components/dish-form/dish-form.component.html
  4. 63
      projects/admin/src/app/components/dish-form/dish-form.component.ts
  5. 74
      projects/admin/src/app/components/ingredient-form-basic/ingredient-form-basic.component.html
  6. 141
      projects/admin/src/app/components/ingredient-form-basic/ingredient-form-basic.component.ts
  7. 2
      projects/admin/src/app/pages/dish/dish.component.html
  8. 4
      projects/admin/src/app/pages/dish/dish.component.ts
  9. 2
      projects/admin/src/app/pages/food/food.component.html
  10. 4
      projects/admin/src/app/pages/food/food.component.ts
  11. 74
      projects/admin/src/app/pages/ingredients/ingredient-form/ingredient-form.component.ts
  12. 28
      projects/admin/src/app/pages/ingredients/ingredient-list/ingredient-list.component.html
  13. 38
      projects/admin/src/app/pages/ingredients/ingredient-list/ingredient-list.component.ts
  14. 2
      projects/admin/src/app/pages/standard/standard-form/standard-form.component.ts
  15. 10
      projects/admin/src/app/pages/standard/standard-setting/standard-setting.component.ts
  16. 5
      projects/cdk/src/dtos/enum.dto.ts
  17. 63
      projects/cdk/src/services/api.service.ts
  18. 1
      projects/cdk/src/shared/components/index.ts
  19. 15
      projects/cdk/src/shared/components/month-select/month-select.component.html
  20. 17
      projects/cdk/src/shared/components/month-select/month-select.component.less
  21. 93
      projects/cdk/src/shared/components/month-select/month-select.component.ts
  22. 5
      projects/cdk/src/shared/shared.module.ts
  23. 13
      projects/client/src/app/pages/system/org-info/org-info.component.ts

16
angular.json

@ -43,13 +43,13 @@
"budgets": [
{
"type": "initial",
"maximumWarning": "500kb",
"maximumError": "1mb"
"maximumWarning": "21mb",
"maximumError": "21mb"
},
{
"type": "anyComponentStyle",
"maximumWarning": "2kb",
"maximumError": "4kb"
"maximumWarning": "21mb",
"maximumError": "21mb"
}
],
"outputHashing": "all"
@ -164,13 +164,13 @@
"budgets": [
{
"type": "initial",
"maximumWarning": "500kb",
"maximumError": "1mb"
"maximumWarning": "21mb",
"maximumError": "21mb"
},
{
"type": "anyComponentStyle",
"maximumWarning": "2kb",
"maximumError": "4kb"
"maximumWarning": "21mb",
"maximumError": "21mb"
}
],
"outputHashing": "all"

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

@ -26,7 +26,7 @@ const routes: Routes = [
component: AppLayoutComponent,
canActivate: [authGuard],
children: [
{ path: "", pathMatch: "full", redirectTo: "home" },
{ path: "", pathMatch: "full", redirectTo: "food" },
{ path: "home", component: HomeComponent },
{ path: "food", component: FoodComponent, title: "食材管理" },
{ path: "dish", component: DishComponent, title: "菜品管理" },

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

@ -49,26 +49,7 @@
适用月份
</nz-form-label>
<nz-form-control [nzErrorTip]="formControlErrorTpl">
<div>
<label
nz-checkbox
[(ngModel)]="allMonthChecked"
[ngModelOptions]="{standalone: true}"
(ngModelChange)="updateAllMonthChecked()"
[nzIndeterminate]="indeterminate">
全年
</label>
</div>
<nz-divider nzDashed class="my-1"></nz-divider>
<div class="flex flex-wrap month-wrap">
<label *ngFor="let m of allMonth" nz-checkbox [(nzChecked)]="m.checked"
(nzCheckedChange)="monthChecked($event,m.value)">{{m.label}}</label>
</div>
<!-- <nz-checkbox-group [(ngModel)]="allMonth"
class="flex flex-wrap month-wrap"
[ngModelOptions]="{standalone: true}"
(ngModelChange)="monthChecked()">
</nz-checkbox-group> -->
<app-month-select formControlName="month"></app-month-select>
</nz-form-control>
</nz-form-item>
@ -146,11 +127,7 @@
{{f.value}}-{{f.text}}:
</button>
</div> -->
<!-- <div class="pr-2">
<nz-select class="!w-[200px]" nzPlaceHolder="食材标签"
formControlName="tag">
</nz-select>
</div> -->
<div class="flex-1 pr-2">
<nz-input-group nzAddOnBefore="{{f.value}}-{{f.text}}:" [nzAddOnAfter]="'g'" class="w-full">
<input
@ -161,6 +138,12 @@
placeholder="请输入{{f.value}}-{{f.text}}重量" />
</nz-input-group>
</div>
<div class="pl-2">
<nz-switch [ngModel]="f.isMain" (ngModelChange)="onMainChange($event,f.value)"
[ngModelOptions]="{standalone: true}">
</nz-switch>
是否主料
</div>
<!-- <div>
<button nz-button (click)="removeFood(i)">
<span nz-icon nzType="delete"></span>

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

@ -127,15 +127,13 @@ export class DishFormComponent {
this.allMonth = this.allMonth.map((i) =>
(this.data.month ?? []).includes(i.value) ? { ...i, checked: true } : i
);
this.monthCheckEffect();
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[f.key];
const num = this.data.ingredient.find((i: any) => i.key === f.key);
if (num) {
this.foodItemSelected.push({ num, ...item });
this.foodItemSelected.push({ num: num.value, ...item, isMain: num.isMain });
this.foodSelected.push(f.key);
}
});
@ -149,18 +147,22 @@ export class DishFormComponent {
public getValues() {
let values = null;
console.log("this.formGroup.getRawValue()", this.formGroup.getRawValue());
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 = Object.create(null);
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[f.value] = num;
ingredient.push({
isMain: f.isMain,
key: f.value,
value: num,
});
}
const month = this.allMonth
.reduce((a: any, c: any) => {
@ -181,6 +183,21 @@ export class DishFormComponent {
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 });
@ -223,38 +240,6 @@ export class DishFormComponent {
this.food.removeAt(idx);
}
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(checked: boolean, value: number) {
this.allMonth = this.allMonth.map((i) => (i.value === value ? { ...i, checked } : i));
this.monthCheckEffect();
}
monthCheckEffect() {
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;
}
}
onFileChange(e: Event) {
const target = e.target as HTMLInputElement;
const file = target.files![0];

74
projects/admin/src/app/components/ingredient-form-basic/ingredient-form-basic.component.html

@ -1,10 +1,49 @@
<form nz-form [formGroup]="formGroup" nzLayout="vertical">
<nz-form-item>
<nz-form-label nzRequired nzSpan="6">
食谱名称
</nz-form-label>
<nz-form-control [nzErrorTip]="formControlErrorTpl" nzSpan="12">
<input nz-input placeholder="请输入食谱名称" formControlName="name" />
</nz-form-control>
</nz-form-item>
<nz-form-item>
<nz-form-label nzRequired nzSpan="6">
标准
</nz-form-label>
<nz-form-control [nzErrorTip]="formControlErrorTpl" nzSpan="12">
<nz-select
nzShowSearch
nzServerSearch
nzPlaceHolder="请选择标准"
[nzShowArrow]="false"
formControlName="nutrient"
[nzFilterOption]="nzFilterOption"
(nzOnSearch)="searchStandard($event)"
(ngModelChange)="onStandardChange($event)">
<nz-option *ngFor="let o of standardOfOption"
[nzLabel]="o.label"
[nzValue]="o.value">
</nz-option>
</nz-select>
</nz-form-control>
</nz-form-item>
<nz-form-item>
<nz-form-label nzRequired nzSpan="6">
适用单位
</nz-form-label>
<nz-form-control [nzErrorTip]="formControlErrorTpl" nzSpan="12">
<nz-select [nzOptions]="[]" nzPlaceHolder="请选择单位"></nz-select>
<nz-select nzMode="multiple" formControlName="vendors" nzPlaceHolder="请选择单位"
[nzOptions]="currentOrgs">
</nz-select>
</nz-form-control>
</nz-form-item>
<nz-form-item class="block">
<nz-form-label nzRequired nzSpan="6">
适用月份
</nz-form-label>
<nz-form-control [nzErrorTip]="formControlErrorTpl" nzSpan="12">
<app-month-select formControlName="month"></app-month-select>
</nz-form-control>
</nz-form-item>
<nz-form-item>
@ -23,40 +62,33 @@
</nz-radio-group>
</nz-form-control>
</nz-form-item>
<nz-form-item>
<nz-form-item class="block">
<nz-form-label nzRequired nzSpan="6">
标题
餐次
</nz-form-label>
<nz-form-control [nzErrorTip]="formControlErrorTpl" nzSpan="12">
<nz-checkbox-wrapper class="flex flex-wrap checkbox-wrap">
<label nz-checkbox nzValue="1">早餐</label>
<label nz-checkbox nzValue="2">午餐</label>
<label nz-checkbox nzValue="3">晚餐</label>
</nz-checkbox-wrapper>
<nz-checkbox-group
class="flex flex-wrap checkbox-wrap"
[(ngModel)]="meals"
[ngModelOptions]="{standalone: true}">
</nz-checkbox-group>
</nz-form-control>
</nz-form-item>
<nz-form-item>
<nz-form-label nzRequired nzSpan="6">
标准
</nz-form-label>
<nz-form-control [nzErrorTip]="formControlErrorTpl" nzSpan="12">
<nz-select [nzOptions]="[]" nzPlaceHolder="请选择标准"></nz-select>
</nz-form-control>
</nz-form-item>
<nz-form-item>
<nz-form-item class="block" *ngIf="currentPeoples.length">
<nz-form-label nzRequired nzSpan="6">
人群显示
</nz-form-label>
<nz-form-control [nzErrorTip]="formControlErrorTpl">
<nz-checkbox-group [ngModel]="ages"
class="flex flex-wrap checkbox-wrap"
formControlName="month"
(ngModelChange)="ageChange()">
<nz-checkbox-group [(ngModel)]="currentPeoples"
[ngModelOptions]="{standalone: true}"
class="flex flex-wrap checkbox-wrap">
</nz-checkbox-group>
</nz-form-control>
</nz-form-item>
<nz-divider></nz-divider>
<nz-form-item>
<nz-form-label nzRequired nzSpan="6">
批量修改重量

141
projects/admin/src/app/components/ingredient-form-basic/ingredient-form-basic.component.ts

@ -1,6 +1,13 @@
import { Component, EventEmitter, OnInit, Output } 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";
import { Utils } from "@cdk/utils";
import { FormValidators } from "@cdk/validators";
import { NzMessageService } from "ng-zorro-antd/message";
import { Subject, debounceTime, distinctUntilChanged, filter, finalize, switchMap, takeUntil } from "rxjs";
@Component({
selector: "app-ingredient-form-basic",
@ -8,36 +15,138 @@ import { FormValidators } from "@cdk/validators";
styleUrls: ["./ingredient-form-basic.component.less"],
})
export class IngredientFormBasicComponent {
constructor(private fb: FormBuilder) {}
constructor(
private fb: FormBuilder,
private msg: NzMessageService,
private api: ApiService,
private router: Router
) {}
@Output() onSave = new EventEmitter();
private standardSearch$ = new Subject<string>();
private destroy$ = new Subject<void>();
formGroup!: FormGroup;
ages = [
{ value: "1", label: "6-8岁(男)", checked: false },
{ value: "2", label: "6-8岁(女)", checked: false },
{ value: "3", label: "9-11岁(男)", checked: false },
{ value: "4", label: "9-11岁(女)", checked: false },
{ value: "5", label: "12-14岁(男)", checked: false },
{ value: "6", label: "12-14岁(女)", checked: false },
];
meals = this.api.globalEnum.mealType;
standardOfOption: Array<OptionItemInterface> = [];
searchedStandard: Array<OptionItemInterface> = [];
currentOrgs: OptionItemInterface[] = [];
currentPeoples: OptionItemInterface[] = [];
submitLoading = false;
nzFilterOption = (): boolean => true;
ngOnInit(): void {
this.formGroup = this.fb.group({
id: this.fb.control("", [FormValidators.required()]),
unit: this.fb.control("", [FormValidators.required()]),
day: this.fb.control("1", [FormValidators.required()]),
id: this.fb.control("", []),
name: this.fb.control("", [FormValidators.required()]),
food: this.fb.array([], [FormValidators.required()]),
tag: this.fb.control([], []),
month: this.fb.control([], []),
nutrient: this.fb.control("", [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 }))
)
.subscribe((data) => {
let listOfOption: Array<OptionItemInterface> = [];
if (data.body) {
data.body.forEach((item) => {
listOfOption.push({
label: item.name,
value: item.id,
...item,
});
});
this.searchedStandard = this.searchedStandard.concat(listOfOption);
}
this.standardOfOption = listOfOption;
});
}
ngOnDestroy(): void {
this.destroy$.next();
this.destroy$.complete();
}
ageChange() {}
searchStandard(k: string) {
this.standardSearch$.next(k);
}
onStandardChange(v: any) {
const currentStandard = this.searchedStandard.find((f) => f.value === v);
if (currentStandard) {
this.api.getOrgList({ vendors: currentStandard["vendors"] }).subscribe((res) => {
this.currentOrgs = res.body.map((i) => ({
...i,
value: String(i.id),
label: i.name,
}));
});
this.currentPeoples = Object.entries(currentStandard["ingredient"] ?? {}).map(([k, v]) => {
return {
label: k,
value: k,
...(v as any),
};
});
}
}
onSubmit() {
this.onSave.emit();
if (Utils.validateFormGroup(this.formGroup)) {
if (!this.meals.some((s) => s["checked"])) {
this.msg.error("请选择餐次");
return;
}
if (!this.currentPeoples.some((s) => s["checked"])) {
this.msg.error("请选择人群显示");
return;
}
this.submitLoading = true;
this.api
.saveMenu({
...this.formGroup.value,
crows: this.currentPeoples
.reduce((a, c) => {
return c["checked"] ? a.concat(c.value) : a;
}, [] as string[])
.join(","),
month: this.formGroup.value.month.join(","),
vendors: this.formGroup.value.vendors.join(","),
meals: this.meals
.reduce((a, c) => {
return c["checked"] ? a.concat(c.value) : a;
}, [] as string[])
.join(","),
})
.pipe(
finalize(() => {
this.submitLoading = false;
})
)
.subscribe((res) => {
this.msg.success(res.desc);
this.onSave.emit();
this.router.navigate(["/ingredient/item/list"]);
});
}
}
}

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

@ -58,7 +58,7 @@
<ng-container *ngSwitchCase="'vender'">
{{ tableOrg[data] ? tableOrg[data].name : '-'}}
</ng-container>
<ng-container *ngSwitchCase="'foodArr'">
<ng-container *ngSwitchCase="'ingredient'">
<div class=" flex flex-wrap">
<ng-container *ngFor="let item of data">
<nz-tag *ngIf="tableFoods[item.key]" class="m-1">

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

@ -96,7 +96,7 @@ export class DishComponent {
{ key: "icon", title: "菜品图片", width: "66px" },
{ key: "name", title: "菜品名称" },
{ key: "marks", title: "菜品标签" },
{ key: "foodArr", title: "食材及含量", width: "30%" },
{ key: "ingredient", title: "食材及含量", width: "30%" },
{ key: "vender", title: "单位" },
]);
@ -132,7 +132,7 @@ export class DishComponent {
const vendors = res.body.content.map((i: any) => i.vender);
const foodKeys = new Set(
res.body.content.reduce((a: string[], c: any) => {
return a.concat(Object.keys(c.ingredient ?? {}));
return a.concat(c.ingredient.map((i: any) => i.key));
}, [] as string[])
);

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

@ -102,7 +102,7 @@
</ng-template>
<ng-template #foofFormFooterTpl>
<ng-template #foodFormFooterTpl>
<nz-space>
<button *nzSpaceItem nz-button (click)="cancelFoodForm()" type="button">
取消

4
projects/admin/src/app/pages/food/food.component.ts

@ -21,7 +21,7 @@ export class FoodComponent implements OnInit, OnDestroy {
private msg: NzMessageService
) {}
@ViewChild("foofFormFooterTpl") foofFormFooterTpl!: TemplateRef<{}>;
@ViewChild("foodFormFooterTpl") foodFormFooterTpl!: TemplateRef<{}>;
private drawerRef?: NzDrawerRef;
@ -104,7 +104,7 @@ export class FoodComponent implements OnInit, OnDestroy {
food,
},
nzContent: FoodFormComponent,
nzFooter: this.foofFormFooterTpl,
nzFooter: this.foodFormFooterTpl,
});
}

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

@ -1,6 +1,9 @@
import { IngredientFormBasicComponent } from "@admin/app/components";
import { Component, OnInit } from "@angular/core";
import { ActivatedRoute, Router } from "@angular/router";
import { ConfirmIngredientComponent } from "@cdk/ingredient/confirm-ingredient/confirm-ingredient.component";
import { ApiService } from "@cdk/services";
import { NzMessageService } from "ng-zorro-antd/message";
import { NzModalService } from "ng-zorro-antd/modal";
@Component({
@ -9,15 +12,30 @@ import { NzModalService } from "ng-zorro-antd/modal";
styleUrls: ["./ingredient-form.component.less"],
})
export class IngredientFormComponent implements OnInit {
constructor(private modal: NzModalService) {}
constructor(
private modal: NzModalService,
private msg: NzMessageService,
private router: Router,
private route: ActivatedRoute,
private api: ApiService
) {
this.id = this.route.snapshot.paramMap.get("id");
console.log("this.id", this.id);
}
step = 0;
step = 1;
id: string | null = "";
expanded = new Set<number>();
ingredients = Array.from({ length: 7 }, (_, i) => 1 + i);
ngOnInit(): void {}
ngOnInit(): void {
this.api.getMenuItem().subscribe((res) => {
console.log("res", res);
});
}
onStepChange() {
this.step = 1;
@ -44,3 +62,53 @@ export class IngredientFormComponent implements OnInit {
});
}
}
const data = {
menuId: [1, 2, 3],
dishs: [
{
name: "番茄炒鸡蛋",
dishId: 1,
foods: [
{
key: "001001",
isMain: false,
ingredient: [
{ name: "轻体力", value: 500 },
{ name: "重体力", value: 200 },
],
},
{
key: "001002",
isMain: false,
ingredient: [
{ name: "轻体力", value: 100 },
{ name: "重体力", value: 200 },
],
},
],
},
{
name: "另一个菜品",
dishId: 1,
foods: [
{
key: "001001",
isMain: false,
ingredient: [
{ name: "轻体力", value: 500 },
{ name: "重体力", value: 200 },
],
},
{
key: "001002",
isMain: false,
ingredient: [
{ name: "轻体力", value: 100 },
{ name: "重体力", value: 200 },
],
},
],
},
],
};

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

@ -35,15 +35,31 @@
</ng-template>
<ng-template #renderColumnsTpl let-data let-key="key" let-row="row">
<ng-container [ngSwitch]="key">
<!-- <ng-container *ngSwitchCase="'img'">
<div class="dish-img overflow-auto"
[ngStyle]="{'background-image':'url(' + tempImg + ')'}">
<ng-container *ngSwitchCase="'modify'">
{{data | date:'yyyy-MM-dd HH:mm:ss'}}
</ng-container>
<ng-container *ngSwitchCase="'meals'">
<nz-tag *ngFor="let item of data">{{item}}</nz-tag>
</ng-container>
<ng-container *ngSwitchCase="'day'">
{{data}} 天
</ng-container>
<ng-container *ngSwitchCase="'month'">
<div class="flex flex-wrap">
<ng-container *ngIf="data.length === 12">
<nz-tag>
全年
</nz-tag>
</ng-container>
<ng-container *ngIf="data.length !== 12">
<nz-tag *ngFor="let item of data" class="mb-1">
{{monthText[item]}}
</nz-tag>
</ng-container>
</div>
</ng-container> -->
</ng-container>
<ng-container *ngSwitchDefault>
{{data}}
</ng-container>
</ng-container>
</ng-template>

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

@ -17,14 +17,29 @@ export class IngredientListComponent {
private drawerRef?: NzDrawerRef;
tempImg = "https://cdn.pixabay.com/photo/2023/08/08/18/01/butterfly-8177925_1280.jpg";
public tableList = new TableListOption(this.fetchData.bind(this));
public tableList = new TableListOption(this.fetchData.bind(this), {
frontPagination: false,
});
public queryForm = new FormGroup({
name: new FormControl(""),
});
monthText = {
1: "一月",
2: "二月",
3: "三月",
4: "四月",
5: "五月",
6: "六月",
7: "七月",
8: "八月",
9: "九月",
10: "十月",
11: "十一月",
12: "十二月",
} as any;
ngOnInit(): void {
this.initTableList();
}
@ -33,14 +48,13 @@ export class IngredientListComponent {
this.tableList.scroll = { x: null };
this.tableList = this.tableList.setColumns([
{ key: "name", title: "食谱名称" },
{ key: "name", title: "单位" },
{ key: "name", title: "包含餐次" },
{ key: "name", title: "单位" },
{ key: "name", title: "适用月份" },
{ key: "name", title: "周期" },
{ key: "name", title: "状态" },
{ key: "name", title: "更新时间" },
{ key: "name", title: "创建人" },
{ key: "vender", title: "单位" },
{ key: "meals", title: "包含餐次" },
{ key: "month", title: "适用月份", width: "300px" },
{ key: "day", title: "周期" },
{ key: "status", title: "状态" },
{ key: "modify", title: "更新时间" },
{ key: "operate", title: "创建人" },
]);
this.tableList = this.tableList.setOptions([
@ -78,7 +92,7 @@ export class IngredientListComponent {
}
fetchData(query: AnyObject, pager: AnyObject) {
return this.api.page(pager, query);
return this.api.getMenuPage(pager, query);
}
showFoodForm(food?: any) {

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

@ -125,7 +125,7 @@ export class StandardFormComponent {
)
.subscribe((res) => {
this.msg.success(res.desc);
const redirectTo = gotoSetting ? ["/", "standard", "setting", res.body] : ["/standard/list"];
const redirectTo = gotoSetting ? ["/", "standard", "setting", res.body.id] : ["/standard/list"];
this.router.navigate(redirectTo);
});
}

10
projects/admin/src/app/pages/standard/standard-setting/standard-setting.component.ts

@ -139,12 +139,10 @@ export class StandardSettingComponent {
};
}, {} as AnyObject);
this.api
.saveStandard({ id: this.state.id, foodCategoryDay, foodCategoryWeek, ingredient }, true)
.subscribe((res) => {
this.msg.success(res.desc);
this.router.navigate(["/standard/list"]);
});
this.api.saveStandard({ ...this.state, foodCategoryDay, foodCategoryWeek, ingredient }, true).subscribe((res) => {
this.msg.success(res.desc);
this.router.navigate(["/standard/list"]);
});
}
addFoodType(type: string) {

5
projects/cdk/src/dtos/enum.dto.ts

@ -1,14 +1,19 @@
import { OptionItemInterface } from "@cdk/types";
export type GlobalEnum = {
category: CategoryDTO[];
mark: MarkDTO[];
nutrient: NutrientDTO[];
venderType: CategoryDTO[];
mealType: OptionItemInterface[];
menuStatus: OptionItemInterface[];
};
export type CategoryDTO = {
key: string;
value: string;
};
export type MarkDTO = {
key: string;
value: string;

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

@ -1,6 +1,6 @@
import { HttpClient, HttpParams, HttpResponse } from "@angular/common/http";
import { Inject, Injectable, InjectionToken } from "@angular/core";
import { AnyObject, PageResult, ResponseType } from "@cdk/types";
import { AnyObject, OptionItemInterface, PageResult, ResponseType } from "@cdk/types";
import { Utils } from "@cdk/utils";
import { Observable, map, of, tap } from "rxjs";
import {
@ -12,6 +12,7 @@ import {
ClientAccountDTO,
AdminAccountDTO,
OrgConfigDTO,
CategoryDTO,
} from "@cdk/public-api";
export const PROJECT_NAME = new InjectionToken<string>("projectName");
@ -58,13 +59,20 @@ export class ApiService {
}
}
private _formatEnum(v: CategoryDTO[]): OptionItemInterface[] {
return v.map((i) => ({ label: i.key, value: i.value }));
}
getAllEnum(force?: boolean): Observable<GlobalEnum> {
if (this.globalEnum && !force) {
return of(this.globalEnum);
}
return this.http.get<ResponseType<GlobalEnum>>("/api/basic/enum").pipe(
return this.http.get<ResponseType<any>>("/api/enum").pipe(
map((res) => {
return res.body;
return {
...res.body,
mealType: this._formatEnum(res.body.mealType),
};
}),
tap((r) => {
this.globalEnum = r;
@ -103,7 +111,7 @@ export class ApiService {
updatePassword(v: {}) {
const body = Utils.objectToFormData(v);
return this.http.post<ResponseType>("/api/basic/user", body);
return this.http.post<ResponseType>("/api/password", body);
}
getRoleList() {
@ -151,7 +159,7 @@ export class ApiService {
});
}
getOrgList(query: {}) {
getOrgList(query: { vendors?: number[]; keyword?: string }) {
const q = Utils.objectStringify(query);
return this.http.get<ResponseType<OrgDTO[]>>(`/api/vender/select?${q}`);
}
@ -302,6 +310,11 @@ export class ApiService {
);
}
getStandard(q: { id?: string; name?: string }) {
const query = Utils.objectStringify(q);
return this.http.get<ResponseType<any[]>>(`/api/nutrition/select?${query}`);
}
saveStandard(v: AnyObject, isEdit?: boolean) {
const body = Utils.objectToFormData({ ...v, vendors: v["vendors"]?.join(",") });
const method = v["id"] ? "post" : "put";
@ -318,18 +331,18 @@ export class ApiService {
return this.http.get<ResponseType<PageResult>>(`/api/dish?${params}`).pipe(
map((r) => {
if (Array.isArray(r.body.content)) {
r.body.content = r.body.content.map((o) => {
return {
...o,
foodArr: Object.entries(o.ingredient).map(([k, v]) => {
return {
key: k,
value: v,
label: k,
};
}),
};
});
// r.body.content = r.body.content.map((o) => {
// return {
// ...o,
// foodArr: Object.entries(o.ingredient).map(([k, v]) => {
// return {
// key: k,
// value: v,
// label: k,
// };
// }),
// };
// });
}
return r;
})
@ -346,4 +359,20 @@ export class ApiService {
const params = Utils.objectToFormData({ ids: ids.join(",") });
return this.http.delete<ResponseType>(`/api/dish`, { body: params });
}
getMenuPage(p: {}, q: {}) {
const params = Utils.objectStringify({ ...p, ...q });
return this.http.get<ResponseType<PageResult>>(`/api/menu?${params}`);
}
getMenuItem() {
const params = Utils.objectStringify({ menuId: 1 });
return this.http.get(`/api/menu/dish?${params}`);
}
saveMenu(v: AnyObject) {
const body = Utils.objectToFormData(v);
const method = v["id"] ? "post" : "put";
return this.http[method]<ResponseType>("/api/menu", body);
}
}

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

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

15
projects/cdk/src/shared/components/month-select/month-select.component.html

@ -0,0 +1,15 @@
<div>
<label
nz-checkbox
[(ngModel)]="allMonthChecked"
[ngModelOptions]="{standalone: true}"
(ngModelChange)="updateAllMonthChecked()"
[nzIndeterminate]="indeterminate">
全年
</label>
</div>
<nz-divider nzDashed class="my-1"></nz-divider>
<div class="flex flex-wrap month-wrap">
<label *ngFor="let m of allMonth" nz-checkbox [(nzChecked)]="m.checked"
(nzCheckedChange)="monthChecked($event,m.value)">{{m.label}}</label>
</div>

17
projects/cdk/src/shared/components/month-select/month-select.component.less

@ -0,0 +1,17 @@
.month-wrap {
::ng-deep {
.ant-checkbox-wrapper {
margin: 6px 0;
flex-basis: calc(100% / 6);
}
}
}
.block-label {
::ng-deep {
label {
display: inline-flex;
width: 100%;
}
}
}

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

@ -0,0 +1,93 @@
import { Component } from "@angular/core";
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from "@angular/forms";
@Component({
selector: "app-month-select",
templateUrl: "./month-select.component.html",
styleUrls: ["./month-select.component.less"],
providers: [
{
provide: NG_VALUE_ACCESSOR,
multi: true,
useExisting: MonthSelectComponent,
},
],
})
export class MonthSelectComponent implements ControlValueAccessor {
allMonthChecked = false;
indeterminate = false;
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 },
];
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,
}));
}
this.formatVal();
}
monthChecked(checked: boolean, value: number) {
this.allMonth = this.allMonth.map((i) => (i.value === value ? { ...i, checked } : i));
this.monthCheckEffect();
this.formatVal();
}
monthCheckEffect() {
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;
}
}
formatVal() {
const vals = this.allMonth.reduce((a, c) => {
return c.checked ? a.concat(c.value) : a;
}, [] as number[]);
this.onChange(vals);
}
onChange(v: number[]) {}
ontouch(v: any) {}
writeValue(v: number[]): void {
this.allMonth = this.allMonth.map((i) => (v.includes(i.value) ? { ...i, checked: true } : i));
this.monthCheckEffect();
}
registerOnChange(fn: any): void {
this.onChange = fn;
}
registerOnTouched(fn: any): void {
this.ontouch = fn;
}
}

5
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 } from "./components";
import { SearchAndSelectComponent, MonthSelectComponent } from "./components";
const ngModules = [CommonModule, HttpClientModule, FormsModule, RouterModule, ReactiveFormsModule];
const components: any = [];
@ -36,7 +36,7 @@ const cdks = [
] as any;
@NgModule({
declarations: [...components, ...directives, SearchAndSelectComponent],
declarations: [...components, ...directives, SearchAndSelectComponent, MonthSelectComponent],
imports: [...ngZorroModules, ...ngModules, ...cdks, AppPageComponent],
exports: [
...ngZorroModules,
@ -46,6 +46,7 @@ const cdks = [
...cdks,
AppPageComponent,
SearchAndSelectComponent,
MonthSelectComponent,
],
})
export class SharedModule {}

13
projects/client/src/app/pages/system/org-info/org-info.component.ts

@ -9,6 +9,7 @@ import { NzMessageService } from "ng-zorro-antd/message";
import { OrgFormComponent } from "../../../components";
import { lastValueFrom } from "rxjs";
import { MD5 } from "crypto-js";
import { Router } from "@angular/router";
@Component({
selector: "app-org-info",
@ -16,7 +17,12 @@ import { MD5 } from "crypto-js";
styleUrls: ["./org-info.component.less"],
})
export class OrgInfoComponent implements OnInit {
constructor(private api: ApiService, private modal: NzModalService, private msg: NzMessageService) {}
constructor(
private api: ApiService,
private modal: NzModalService,
private msg: NzMessageService,
private router: Router
) {}
account: any = this.api.account;
@ -73,11 +79,16 @@ export class OrgInfoComponent implements OnInit {
}
const res = await lastValueFrom(
this.api.updatePassword({
oldPassword: MD5(value.oldPwd!).toString().slice(-16),
password: MD5(value.newPwd!).toString().slice(-16),
// name:
})
);
this.msg.success(res.desc);
this.api.logout().subscribe(() => {
this.msg.success("请重新登录");
this.router.navigate(["/login"]);
});
return true;
}
return false;

Loading…
Cancel
Save