15 changed files with 961 additions and 777 deletions
@ -1,210 +1,210 @@ |
|||
import { FoodFormComponent } from "@admin/app/components"; |
|||
import { ApiService } from "@cdk/services"; |
|||
import { Component, OnDestroy, OnInit, TemplateRef, ViewChild } from "@angular/core"; |
|||
import { FormControl, FormGroup } from "@angular/forms"; |
|||
import { AnyObject, TableListOption } from "@cdk/public-api"; |
|||
import { NzDrawerRef, NzDrawerService } from "ng-zorro-antd/drawer"; |
|||
import { NzModalRef, NzModalService } from "ng-zorro-antd/modal"; |
|||
import { Subject, finalize, lastValueFrom, map, takeUntil } from "rxjs"; |
|||
import { NzMessageService } from "ng-zorro-antd/message"; |
|||
import { FoodFormComponent } from '@admin/app/components' |
|||
import { ApiService } from '@cdk/services' |
|||
import { Component, OnDestroy, OnInit, TemplateRef, ViewChild } from '@angular/core' |
|||
import { FormControl, FormGroup } from '@angular/forms' |
|||
import { AnyObject, TableListOption } from '@cdk/public-api' |
|||
import { NzDrawerRef, NzDrawerService } from 'ng-zorro-antd/drawer' |
|||
import { NzModalRef, NzModalService } from 'ng-zorro-antd/modal' |
|||
import { Subject, finalize, lastValueFrom, map, takeUntil } from 'rxjs' |
|||
import { NzMessageService } from 'ng-zorro-antd/message' |
|||
|
|||
@Component({ |
|||
selector: "app-food", |
|||
templateUrl: "./food.component.html", |
|||
styleUrls: ["./food.component.less"], |
|||
selector: 'app-food', |
|||
templateUrl: './food.component.html', |
|||
styleUrls: ['./food.component.less'], |
|||
}) |
|||
export class FoodComponent implements OnInit, OnDestroy { |
|||
constructor( |
|||
private drawer: NzDrawerService, |
|||
private api: ApiService, |
|||
private modal: NzModalService, |
|||
private msg: NzMessageService |
|||
private msg: NzMessageService, |
|||
) {} |
|||
|
|||
@ViewChild("foodFormFooterTpl") foodFormFooterTpl!: TemplateRef<{}>; |
|||
@ViewChild('foodFormFooterTpl') foodFormFooterTpl!: TemplateRef<{}> |
|||
|
|||
private drawerRef?: NzDrawerRef; |
|||
private drawerRef?: NzDrawerRef |
|||
|
|||
private importModalRef?: NzModalRef; |
|||
private importModalRef?: NzModalRef |
|||
|
|||
public tableList = new TableListOption(this.fetchData.bind(this), { |
|||
selectable: true, |
|||
frontPagination: false, |
|||
rowKey: "key", |
|||
}); |
|||
rowKey: 'key', |
|||
}) |
|||
|
|||
public globalEnum = this.api.globalEnum; |
|||
public globalEnum = this.api.globalEnum |
|||
|
|||
public queryForm = new FormGroup({ |
|||
keyword: new FormControl(""), |
|||
type: new FormControl(""), |
|||
}); |
|||
keyword: new FormControl(''), |
|||
type: new FormControl(''), |
|||
}) |
|||
|
|||
private destroy$ = new Subject<void>(); |
|||
private destroy$ = new Subject<void>() |
|||
|
|||
public selectedIds: string[] = []; |
|||
public selectedIds: string[] = [] |
|||
|
|||
submitLoading = false; |
|||
submitLoading = false |
|||
|
|||
uploadLoading = false; |
|||
uploadLoading = false |
|||
|
|||
editItem = null; |
|||
editItem = null |
|||
|
|||
ngOnInit(): void { |
|||
this.initTableList(); |
|||
this.initTableList() |
|||
this.tableList.getState$.pipe(takeUntil(this.destroy$)).subscribe((res) => { |
|||
this.selectedIds = res.selectedKeys as Array<string>; |
|||
}); |
|||
this.selectedIds = res.selectedKeys as Array<string> |
|||
}) |
|||
} |
|||
|
|||
ngOnDestroy(): void { |
|||
this.destroy$.next(); |
|||
this.destroy$.complete(); |
|||
this.destroy$.next() |
|||
this.destroy$.complete() |
|||
} |
|||
|
|||
initTableList() { |
|||
this.tableList.scroll = { x: null }; |
|||
this.tableList.scroll = { x: null } |
|||
this.tableList = this.tableList.setColumns([ |
|||
{ key: "key", title: "食材编号" }, |
|||
{ key: "name", title: "食材名称" }, |
|||
{ key: "type", title: "食材类型" }, |
|||
{ key: "nutrientArr", title: "营养素(每100g可食部)", width: "40%" }, |
|||
{ key: "modify", title: "更新日期" }, |
|||
]); |
|||
{ key: 'key', title: '食材编号' }, |
|||
{ key: 'name', title: '食材名称' }, |
|||
{ key: 'type', title: '食材类型' }, |
|||
{ key: 'nutrientArr', title: '营养素(每100g可食部)', width: '40%' }, |
|||
{ key: 'modify', title: '更新日期' }, |
|||
]) |
|||
|
|||
this.tableList = this.tableList.setOptions([ |
|||
{ |
|||
title: "编辑", |
|||
title: '编辑', |
|||
premissions: [], |
|||
onClick: this.showFoodForm.bind(this), |
|||
}, |
|||
{ |
|||
title: "删除", |
|||
title: '删除', |
|||
premissions: [], |
|||
onClick: this.deleteFood.bind(this), |
|||
}, |
|||
]); |
|||
]) |
|||
} |
|||
|
|||
fetchData(query: AnyObject, pager: AnyObject) { |
|||
return this.api.getFoodPage(pager, query).pipe(); |
|||
return this.api.getFoodPage(pager, query).pipe() |
|||
} |
|||
|
|||
onTypeChange(type: string) { |
|||
this.queryForm.patchValue({ type }); |
|||
this.tableList.reset(); |
|||
this.queryForm.patchValue({ type }) |
|||
this.tableList.reset() |
|||
} |
|||
|
|||
showFoodForm(food?: any) { |
|||
this.editItem = food; |
|||
this.editItem = food |
|||
this.drawerRef = this.drawer.create({ |
|||
nzTitle: food ? "编辑食材" : "新增食材", |
|||
nzTitle: food ? '编辑食材' : '新增食材', |
|||
nzWidth: 520, |
|||
nzContentParams: { |
|||
food, |
|||
}, |
|||
nzContent: FoodFormComponent, |
|||
nzFooter: this.foodFormFooterTpl, |
|||
}); |
|||
}) |
|||
} |
|||
|
|||
onFoodSubmit() { |
|||
if (this.drawerRef) { |
|||
const com = this.drawerRef.getContentComponent() as FoodFormComponent; |
|||
const val = com.getValues(); |
|||
const com = this.drawerRef.getContentComponent() as FoodFormComponent |
|||
const val = com.getValues() |
|||
if (val) { |
|||
this.submitLoading = true; |
|||
this.submitLoading = true |
|||
this.api |
|||
.saveFood(val, !!this.editItem) |
|||
.pipe( |
|||
finalize(() => { |
|||
this.submitLoading = false; |
|||
}) |
|||
this.submitLoading = false |
|||
}), |
|||
) |
|||
.subscribe((res) => { |
|||
this.msg.success(res.desc); |
|||
this.cancelFoodForm(); |
|||
this.tableList.run(); |
|||
}); |
|||
this.msg.success(res.desc) |
|||
this.cancelFoodForm() |
|||
this.tableList.run() |
|||
}) |
|||
} |
|||
} |
|||
} |
|||
cancelFoodForm() { |
|||
this.drawerRef?.close(); |
|||
this.drawerRef?.close() |
|||
} |
|||
|
|||
deleteFood(v?: any) { |
|||
const ids = v ? [v.key] : this.selectedIds; |
|||
const ids = v ? [v.key] : this.selectedIds |
|||
this.modal.confirm({ |
|||
nzTitle: "警告", |
|||
nzTitle: '警告', |
|||
nzContent: `是否要删除${ids.length}个食材?`, |
|||
nzOkDanger: true, |
|||
nzOnOk: async () => { |
|||
const res = await lastValueFrom(this.api.deleteFoods(ids)); |
|||
this.msg.success(res.desc); |
|||
this.tableList.run(); |
|||
const res = await lastValueFrom(this.api.deleteFoods(ids)) |
|||
this.msg.success(res.desc) |
|||
this.tableList.run() |
|||
}, |
|||
}); |
|||
}) |
|||
} |
|||
|
|||
downloadTemplate() { |
|||
this.api.getFoodExcelTemplate().subscribe((res) => { |
|||
console.log("res", res); |
|||
}); |
|||
console.log('res', res) |
|||
}) |
|||
} |
|||
|
|||
showImportForm(nzContent: TemplateRef<{}>) { |
|||
this.importModalRef = this.modal.create({ |
|||
nzTitle: "导入食材清单", |
|||
nzTitle: '导入食材清单', |
|||
nzWidth: 520, |
|||
nzContent, |
|||
nzFooter: null, |
|||
}); |
|||
}) |
|||
} |
|||
|
|||
suppress(e: Event) { |
|||
e.stopPropagation(); |
|||
e.preventDefault(); |
|||
e.stopPropagation() |
|||
e.preventDefault() |
|||
} |
|||
|
|||
handleDrop = (e: Event) => { |
|||
e.stopPropagation(); |
|||
e.preventDefault(); |
|||
const event = e as DragEvent; |
|||
const files = event.dataTransfer?.files; |
|||
e.stopPropagation() |
|||
e.preventDefault() |
|||
const event = e as DragEvent |
|||
const files = event.dataTransfer?.files |
|||
if (files) { |
|||
this.onFileChange(files); |
|||
this.onFileChange(files) |
|||
} |
|||
} |
|||
}; |
|||
|
|||
onFileChange(e: FileList | Event) { |
|||
let files: FileList; |
|||
let files: FileList |
|||
if (e instanceof FileList) { |
|||
files = e; |
|||
files = e |
|||
} else { |
|||
const target = e.target as HTMLInputElement; |
|||
files = target.files!; |
|||
const target = e.target as HTMLInputElement |
|||
files = target.files! |
|||
} |
|||
if (files?.length > 0) { |
|||
const formData = new FormData(); |
|||
formData.append("file", files[0]); |
|||
this.uploadLoading = true; |
|||
const formData = new FormData() |
|||
formData.append('file', files[0]) |
|||
this.uploadLoading = true |
|||
this.api |
|||
.importFood(formData) |
|||
.pipe( |
|||
finalize(() => { |
|||
this.uploadLoading = false; |
|||
}) |
|||
this.uploadLoading = false |
|||
}), |
|||
) |
|||
.subscribe(() => { |
|||
this.msg.success("导入成功"); |
|||
this.tableList.run(); |
|||
this.importModalRef?.close(); |
|||
}); |
|||
this.msg.success('导入成功') |
|||
this.tableList.run() |
|||
this.importModalRef?.close() |
|||
}) |
|||
} |
|||
if (e instanceof Event) { |
|||
const target = e.target as HTMLInputElement; |
|||
target.value = ""; |
|||
const target = e.target as HTMLInputElement |
|||
target.value = '' |
|||
} |
|||
} |
|||
} |
|||
|
@ -0,0 +1,33 @@ |
|||
<table-list |
|||
#tableRef |
|||
[props]="tableList" |
|||
[search]="searchTpl" |
|||
[formGroup]="queryForm" |
|||
[renderColumns]="renderColumnsTpl" |
|||
> |
|||
<ng-template #searchTpl> |
|||
<nz-form-item> |
|||
<nz-form-control> |
|||
<input nz-input placeholder="请输入食材名称/编号" formControlName="keyword" /> |
|||
</nz-form-control> |
|||
</nz-form-item> |
|||
</ng-template> |
|||
|
|||
<ng-template #renderColumnsTpl let-data let-key="key" let-row="row"> |
|||
<ng-container [ngSwitch]="key"> |
|||
<ng-container *ngSwitchCase="'nutrientArr'"> |
|||
<div class="flex flex-wrap"> |
|||
<nz-tag *ngFor="let item of data" class="m-1"> |
|||
{{ item.label }}:{{ item.value }}{{ item.measurement }} |
|||
</nz-tag> |
|||
</div> |
|||
</ng-container> |
|||
<ng-container *ngSwitchCase="'modify'"> |
|||
{{ data | date : 'yyyy-MM-dd HH:mm:ss' }} |
|||
</ng-container> |
|||
<ng-container *ngSwitchDefault> |
|||
{{ data }} |
|||
</ng-container> |
|||
</ng-container> |
|||
</ng-template> |
|||
</table-list> |
@ -0,0 +1,66 @@ |
|||
import { Component, OnInit, ViewChild } from '@angular/core' |
|||
import { FormControl, FormGroup } from '@angular/forms' |
|||
import { AnyObject, TableListComponent, TableListOption } from '@cdk/public-api' |
|||
import { ApiService } from '@cdk/services' |
|||
import { Subject, takeUntil, tap } from 'rxjs' |
|||
|
|||
@Component({ |
|||
selector: 'lib-select-food', |
|||
templateUrl: './select-food.component.html', |
|||
styleUrls: ['./select-food.component.less'], |
|||
}) |
|||
export class SelectFoodComponent implements OnInit { |
|||
constructor(private api: ApiService) {} |
|||
|
|||
@ViewChild('tableRef') tableRef!: TableListComponent |
|||
|
|||
selectedIds: string[] = [] |
|||
|
|||
allFood: any[] = [] |
|||
|
|||
private destroy$ = new Subject<void>() |
|||
|
|||
public tableList = new TableListOption(this.fetchData.bind(this), { |
|||
selectable: true, |
|||
frontPagination: false, |
|||
rowKey: 'key', |
|||
}) |
|||
|
|||
public queryForm = new FormGroup({ |
|||
keyword: new FormControl(''), |
|||
type: new FormControl(''), |
|||
}) |
|||
|
|||
ngOnInit(): void { |
|||
this.tableList.getState$.pipe(takeUntil(this.destroy$)).subscribe((res) => { |
|||
this.selectedIds = res.selectedKeys as Array<string> |
|||
}) |
|||
this.initTableList() |
|||
} |
|||
|
|||
ngOnDestroy(): void { |
|||
this.destroy$.next() |
|||
this.destroy$.complete() |
|||
} |
|||
|
|||
fetchData(query: AnyObject, pager: AnyObject) { |
|||
return this.api.getFoodPage(pager, query).pipe( |
|||
tap((res) => { |
|||
this.allFood = this.allFood.concat(res.body.content) |
|||
}), |
|||
) |
|||
} |
|||
|
|||
getSelectedFoods() { |
|||
return this.allFood.filter((f) => this.selectedIds.includes(f['key'])) |
|||
} |
|||
|
|||
initTableList() { |
|||
this.tableList.scroll = { x: null } |
|||
this.tableList = this.tableList.setColumns([ |
|||
{ key: 'key', title: '食材编号' }, |
|||
{ key: 'name', title: '食材名称' }, |
|||
{ key: 'type', title: '食材类型' }, |
|||
]) |
|||
} |
|||
} |
Loading…
Reference in new issue