15 changed files with 961 additions and 777 deletions
@ -1,114 +1,111 @@ |
|||
<app-page [scroll]="false"> |
|||
<ng-template #pageExtraTpl> |
|||
<nz-space> |
|||
<button *nzSpaceItem nz-button [disabled]="!selectedIds.length" (click)="deleteFood()">批量删除</button> |
|||
<button *nzSpaceItem nz-button (click)="showImportForm(importFormTpl)">导入食材清单</button> |
|||
<button *nzSpaceItem nz-button nzType="primary" (click)="showFoodForm()"> |
|||
<i nz-icon nzType="plus"></i> |
|||
新增食材 |
|||
</button> |
|||
</nz-space> |
|||
</ng-template> |
|||
<div nz-row class="h-full overflow-hidden bg-white rounded-lg"> |
|||
<div nz-col nzFlex="220px" class="food-type h-full"> |
|||
<nz-card class="h-full" [nzBordered]="false" nzTitle="食材类型" |
|||
[nzBodyStyle]="{padding:'1px 0 0 0', height:'100%',overflow:'auto'}"> |
|||
<ul nz-menu nzMode="inline"> |
|||
<li nz-menu-item (click)="onTypeChange('')" [nzSelected]="!queryForm.get('type')?.value"> |
|||
<a> |
|||
全部 |
|||
</a> |
|||
</li> |
|||
<li nz-menu-item [nzSelected]="cate.key === queryForm.get('type')?.value" |
|||
*ngFor="let cate of globalEnum.category" (click)="onTypeChange(cate.key)"> |
|||
<a> |
|||
{{cate.key}} |
|||
</a> |
|||
</li> |
|||
</ul> |
|||
</nz-card> |
|||
</div> |
|||
<div nz-col nzFlex="1" class="flex-1 overflow-hidden bg-white h-full"> |
|||
<ng-template #pageExtraTpl> |
|||
<nz-space> |
|||
<button *nzSpaceItem nz-button [disabled]="!selectedIds.length" (click)="deleteFood()">批量删除</button> |
|||
<button *nzSpaceItem nz-button (click)="showImportForm(importFormTpl)">导入食材清单</button> |
|||
<button *nzSpaceItem nz-button nzType="primary" (click)="showFoodForm()"> |
|||
<i nz-icon nzType="plus"></i> |
|||
新增食材 |
|||
</button> |
|||
</nz-space> |
|||
</ng-template> |
|||
<div nz-row class="h-full overflow-hidden bg-white rounded-lg"> |
|||
<div nz-col nzFlex="220px" class="food-type h-full"> |
|||
<nz-card |
|||
class="h-full" |
|||
[nzBordered]="false" |
|||
nzTitle="食材类型" |
|||
[nzBodyStyle]="{ padding: '1px 0 0 0', height: '100%', overflow: 'auto' }" |
|||
> |
|||
<ul nz-menu nzMode="inline"> |
|||
<li nz-menu-item (click)="onTypeChange('')" [nzSelected]="!queryForm.get('type')?.value"> |
|||
<a> 全部 </a> |
|||
</li> |
|||
<li |
|||
nz-menu-item |
|||
[nzSelected]="cate.key === queryForm.get('type')?.value" |
|||
*ngFor="let cate of globalEnum.category" |
|||
(click)="onTypeChange(cate.key)" |
|||
> |
|||
<a> |
|||
{{ cate.key }} |
|||
</a> |
|||
</li> |
|||
</ul> |
|||
</nz-card> |
|||
</div> |
|||
<div nz-col nzFlex="1" class="flex-1 overflow-hidden bg-white h-full"> |
|||
<nz-card [nzBordered]="false" nzTitle="食材管理" class="scroll-card-body"> |
|||
<div class="m-4"> |
|||
<table-list |
|||
[props]="tableList" |
|||
[search]="searchTpl" |
|||
[action]="pageExtraTpl" |
|||
[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> |
|||
|
|||
<nz-card [nzBordered]="false" nzTitle="食材管理" class="scroll-card-body"> |
|||
<div class="m-4"> |
|||
<table-list |
|||
[props]="tableList" |
|||
[search]="searchTpl" |
|||
[action]="pageExtraTpl" |
|||
[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> |
|||
</div> |
|||
</nz-card> |
|||
|
|||
</div> |
|||
</div> |
|||
<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> |
|||
</div> |
|||
</nz-card> |
|||
</div> |
|||
</div> |
|||
</app-page> |
|||
|
|||
<ng-template #importFormTpl> |
|||
<p class=" text-slate-400"> |
|||
提示:<a (click)="downloadTemplate()">下载示例模版</a>,进行编辑,导入Excel文件,批量导入食材 |
|||
</p> |
|||
<div> |
|||
<nz-spin [nzSpinning]="uploadLoading"> |
|||
<div class="upload-area flex-col" |
|||
(drop)="handleDrop($event)" |
|||
(dragenter)="suppress($event)" |
|||
(dragover)="suppress($event)"> |
|||
<input type="file" id="file" (change)="onFileChange($event)" accept=".xlsx,.xls" /> |
|||
<div class="text-center"> |
|||
<p class="text-4xl mb-1"> |
|||
<a nz-icon nzType="upload" nzTheme="outline"></a> |
|||
</p> |
|||
<p class="mb-1"> |
|||
点击或将文件拖拽到这里上传 |
|||
</p> |
|||
<p class="text-slate-400"> |
|||
支持扩展名:.xls .xlsx |
|||
</p> |
|||
</div> |
|||
</div> |
|||
</nz-spin> |
|||
</div> |
|||
<p class="text-slate-400"> |
|||
提示:<a (click)="downloadTemplate()">下载示例模版</a>,进行编辑,导入Excel文件,批量导入食材 |
|||
</p> |
|||
<div> |
|||
<nz-spin [nzSpinning]="uploadLoading"> |
|||
<div |
|||
class="upload-area flex-col" |
|||
(drop)="handleDrop($event)" |
|||
(dragenter)="suppress($event)" |
|||
(dragover)="suppress($event)" |
|||
> |
|||
<input type="file" id="file" (change)="onFileChange($event)" accept=".xlsx,.xls" /> |
|||
<div class="text-center"> |
|||
<p class="text-4xl mb-1"> |
|||
<a nz-icon nzType="upload" nzTheme="outline"></a> |
|||
</p> |
|||
<p class="mb-1">点击或将文件拖拽到这里上传</p> |
|||
<p class="text-slate-400">支持扩展名:.xls .xlsx</p> |
|||
</div> |
|||
</div> |
|||
</nz-spin> |
|||
</div> |
|||
</ng-template> |
|||
|
|||
|
|||
<ng-template #foodFormFooterTpl> |
|||
<nz-space> |
|||
<button *nzSpaceItem nz-button (click)="cancelFoodForm()" type="button"> |
|||
取消 |
|||
</button> |
|||
<button *nzSpaceItem nz-button nzType="primary" [nzLoading]="submitLoading" (click)="onFoodSubmit()"> |
|||
保存 |
|||
</button> |
|||
</nz-space> |
|||
<nz-space> |
|||
<button *nzSpaceItem nz-button (click)="cancelFoodForm()" type="button">取消</button> |
|||
<button *nzSpaceItem nz-button nzType="primary" [nzLoading]="submitLoading" (click)="onFoodSubmit()"> |
|||
保存 |
|||
</button> |
|||
</nz-space> |
|||
</ng-template> |
@ -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: '食材类型' }, |
|||
]) |
|||
} |
|||
} |
@ -1,225 +1,221 @@ |
|||
<form nz-form class="query-form mb-2" [formGroup]="formGroup" [nzLayout]="searchLayout"> |
|||
<div> |
|||
<div nz-row> |
|||
<div nz-col nzFlex="auto" nz-row [nzGutter]="[12,12]" class="search-row"> |
|||
<ng-container> |
|||
<ng-container [ngTemplateOutlet]="search!"></ng-container> |
|||
|
|||
<div nz-col nzFlex="120px"> |
|||
<nz-form-item> |
|||
<nz-form-label nzNoColon></nz-form-label> |
|||
<nz-form-control> |
|||
<nz-space> |
|||
<button nz-button nzGhost nzType="primary" *nzSpaceItem (click)="doQuery()"> |
|||
查询 |
|||
</button> |
|||
<button nz-button *nzSpaceItem (click)="reset()"> |
|||
重置 |
|||
</button> |
|||
</nz-space> |
|||
</nz-form-control> |
|||
</nz-form-item> |
|||
</div> |
|||
</ng-container> |
|||
</div> |
|||
<div nz-col class="flex items-center justify-end"> |
|||
<ng-container *ngIf="action"> |
|||
<ng-container [ngTemplateOutlet]="action"></ng-container> |
|||
</ng-container> |
|||
</div> |
|||
</div> |
|||
|
|||
</div> |
|||
<div> |
|||
<div nz-row> |
|||
<div nz-col nzFlex="auto" nz-row [nzGutter]="[12, 12]" class="search-row"> |
|||
<ng-container> |
|||
<ng-container [ngTemplateOutlet]="search!"></ng-container> |
|||
|
|||
<div nz-col nzFlex="120px"> |
|||
<nz-form-item> |
|||
<nz-form-label nzNoColon></nz-form-label> |
|||
<nz-form-control> |
|||
<nz-space> |
|||
<button nz-button nzGhost nzType="primary" *nzSpaceItem (click)="doQuery()"> |
|||
查询 |
|||
</button> |
|||
<button nz-button *nzSpaceItem (click)="reset()">重置</button> |
|||
</nz-space> |
|||
</nz-form-control> |
|||
</nz-form-item> |
|||
</div> |
|||
</ng-container> |
|||
</div> |
|||
<div nz-col class="flex items-center justify-end"> |
|||
<ng-container *ngIf="action"> |
|||
<ng-container [ngTemplateOutlet]="action"></ng-container> |
|||
</ng-container> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</form> |
|||
|
|||
|
|||
<ng-template #renderTableTpl> |
|||
<div class="table-card table-list shadow-sm "> |
|||
<div #tableEl class="overflow-auto"> |
|||
<nz-table |
|||
#basicTable |
|||
|
|||
[nzData]="dataSource" |
|||
[nzPageSizeOptions]="[5,10,20,]" |
|||
[nzLoading]="props.pager.loading" |
|||
[(nzPageSize)]="props.pager.size" |
|||
[(nzPageIndex)]="props.pager.page" |
|||
[nzTotal]="props.pager.total" |
|||
[nzShowTotal]="totalTpl" |
|||
[nzFrontPagination]="props.frontPagination" |
|||
[nzShowPagination]="true" |
|||
[nzShowSizeChanger]="true" |
|||
[nzShowQuickJumper]="true" |
|||
(nzPageIndexChange)="onPageChange()" |
|||
(nzPageSizeChange)="onPageChange()" |
|||
[nzTableLayout]="props.scroll.x ? 'fixed' : 'auto' " |
|||
[nzScroll]="props.scroll"> |
|||
<thead> |
|||
<tr> |
|||
<th |
|||
*ngIf="props.selectable" |
|||
[nzChecked]="dataSource && selection.selected.length === dataSource.length && dataSource.length !== 0" |
|||
(nzCheckedChange)="onChecked($event)" |
|||
nzWidth="40px"> |
|||
</th> |
|||
<ng-container *ngFor="let col of columns"> |
|||
<th *ngIf="col.visible" |
|||
[nzWidth]="col.width || null " |
|||
[nzShowSort]="col.sort" |
|||
[nzSortDirections]="['ascend', 'descend']" |
|||
[nzSortOrder]="props.pager.sort[col.key] || null" |
|||
(nzSortOrderChange)="onSort($event,col.key)"> |
|||
{{col.title}} |
|||
</th> |
|||
</ng-container> |
|||
<th *ngIf="operation.length" [nzWidth]="optionWidth!" [nzRight]="!!props.scroll.x"> |
|||
操作 |
|||
</th> |
|||
<th nzRight nzWidth="40px" *ngIf="props.theadSettable"> |
|||
<span (click)="toggleColumnVisible(columnVisibleSettingTpl)" |
|||
class="cursor-pointer" |
|||
nz-icon |
|||
nzType="setting" |
|||
nzTheme="outline"> |
|||
</span> |
|||
</th> |
|||
</tr> |
|||
</thead> |
|||
<tbody> |
|||
<tr *ngFor="let dataItem of basicTable.data" (click)="onTrClick(dataItem)" |
|||
[ngClass]="rowClass"> |
|||
<td *ngIf="props.selectable" [nzChecked]="selection.isSelected(dataItem[props.rowKey])" |
|||
(nzCheckedChange)="onChecked($event,dataItem[props.rowKey])"> |
|||
</td> |
|||
<ng-container *ngFor="let col of columns"> |
|||
<td *ngIf="col.visible" nzEllipsis> |
|||
|
|||
<ng-container [ngSwitch]="col.key"> |
|||
<ng-container *ngSwitchCase="'createTime'"> |
|||
<ng-container |
|||
[ngTemplateOutlet]="dateTimeTpl" |
|||
[ngTemplateOutletContext]="{$implicit:dataItem[col.key]}"> |
|||
</ng-container> |
|||
</ng-container> |
|||
<ng-container *ngSwitchCase="'updateTime'"> |
|||
<ng-container |
|||
[ngTemplateOutlet]="dateTimeTpl" |
|||
[ngTemplateOutletContext]="{$implicit:dataItem[col.key]}"> |
|||
</ng-container> |
|||
</ng-container> |
|||
|
|||
<ng-container *ngSwitchDefault> |
|||
<ng-container *ngIf="renderColumns else defaultTdTpl" |
|||
[ngTemplateOutlet]="renderColumns" |
|||
[ngTemplateOutletContext]="{ |
|||
$implicit:dataItem[col.key], |
|||
key:col.key, |
|||
row:dataItem, |
|||
column:col |
|||
}"> |
|||
</ng-container> |
|||
<ng-template #defaultTdTpl> |
|||
{{dataItem[col.key]}} |
|||
</ng-template> |
|||
</ng-container> |
|||
</ng-container> |
|||
</td> |
|||
</ng-container> |
|||
|
|||
<td *ngIf="operation.length" [nzRight]="!!props.scroll.x" class="operation"> |
|||
<dec-table-operation [rowData]="dataItem" [options]="operation"> |
|||
</dec-table-operation> |
|||
</td> |
|||
<td nzRight *ngIf="props.theadSettable"></td> |
|||
</tr> |
|||
</tbody> |
|||
</nz-table> |
|||
</div> |
|||
|
|||
</div> |
|||
<div class="table-card table-list shadow-sm"> |
|||
<div #tableEl class="overflow-auto"> |
|||
<nz-table |
|||
#basicTable |
|||
[nzData]="dataSource" |
|||
[nzPageSizeOptions]="[5, 10, 20]" |
|||
[nzLoading]="props.pager.loading" |
|||
[(nzPageSize)]="props.pager.size" |
|||
[(nzPageIndex)]="props.pager.page" |
|||
[nzTotal]="props.pager.total" |
|||
[nzShowTotal]="totalTpl" |
|||
[nzFrontPagination]="props.frontPagination" |
|||
[nzShowPagination]="true" |
|||
[nzShowSizeChanger]="true" |
|||
[nzShowQuickJumper]="true" |
|||
(nzPageIndexChange)="onPageChange()" |
|||
(nzPageSizeChange)="onPageChange()" |
|||
[nzTableLayout]="props.scroll.x ? 'fixed' : 'auto'" |
|||
[nzScroll]="props.scroll" |
|||
> |
|||
<thead> |
|||
<tr> |
|||
<!-- [nzChecked]="dataSource && selection.selected.length === dataSource.length && dataSource.length !== 0" --> |
|||
<th |
|||
*ngIf="props.selectable" |
|||
[nzChecked]="checkedAll(dataSource)" |
|||
(nzCheckedChange)="onChecked($event)" |
|||
nzWidth="40px" |
|||
></th> |
|||
<ng-container *ngFor="let col of columns"> |
|||
<th |
|||
*ngIf="col.visible" |
|||
[nzWidth]="col.width || null" |
|||
[nzShowSort]="col.sort" |
|||
[nzSortDirections]="['ascend', 'descend']" |
|||
[nzSortOrder]="props.pager.sort[col.key] || null" |
|||
(nzSortOrderChange)="onSort($event, col.key)" |
|||
> |
|||
{{ col.title }} |
|||
</th> |
|||
</ng-container> |
|||
<th *ngIf="operation.length" [nzWidth]="optionWidth!" [nzRight]="!!props.scroll.x">操作</th> |
|||
<th nzRight nzWidth="40px" *ngIf="props.theadSettable"> |
|||
<span |
|||
(click)="toggleColumnVisible(columnVisibleSettingTpl)" |
|||
class="cursor-pointer" |
|||
nz-icon |
|||
nzType="setting" |
|||
nzTheme="outline" |
|||
> |
|||
</span> |
|||
</th> |
|||
</tr> |
|||
</thead> |
|||
<tbody> |
|||
<tr *ngFor="let dataItem of basicTable.data" (click)="onTrClick(dataItem)" [ngClass]="rowClass"> |
|||
<td |
|||
*ngIf="props.selectable" |
|||
[nzChecked]="selection.isSelected(dataItem[props.rowKey])" |
|||
(nzCheckedChange)="onChecked($event, dataItem[props.rowKey])" |
|||
></td> |
|||
<ng-container *ngFor="let col of columns"> |
|||
<td *ngIf="col.visible" nzEllipsis> |
|||
<ng-container [ngSwitch]="col.key"> |
|||
<ng-container *ngSwitchCase="'createTime'"> |
|||
<ng-container |
|||
[ngTemplateOutlet]="dateTimeTpl" |
|||
[ngTemplateOutletContext]="{ $implicit: dataItem[col.key] }" |
|||
> |
|||
</ng-container> |
|||
</ng-container> |
|||
<ng-container *ngSwitchCase="'updateTime'"> |
|||
<ng-container |
|||
[ngTemplateOutlet]="dateTimeTpl" |
|||
[ngTemplateOutletContext]="{ $implicit: dataItem[col.key] }" |
|||
> |
|||
</ng-container> |
|||
</ng-container> |
|||
|
|||
<ng-container *ngSwitchDefault> |
|||
<ng-container |
|||
*ngIf="renderColumns; else defaultTdTpl" |
|||
[ngTemplateOutlet]="renderColumns" |
|||
[ngTemplateOutletContext]="{ |
|||
$implicit: dataItem[col.key], |
|||
key: col.key, |
|||
row: dataItem, |
|||
column: col |
|||
}" |
|||
> |
|||
</ng-container> |
|||
<ng-template #defaultTdTpl> |
|||
{{ dataItem[col.key] }} |
|||
</ng-template> |
|||
</ng-container> |
|||
</ng-container> |
|||
</td> |
|||
</ng-container> |
|||
|
|||
<td *ngIf="operation.length" [nzRight]="!!props.scroll.x" class="operation"> |
|||
<dec-table-operation [rowData]="dataItem" [options]="operation"> </dec-table-operation> |
|||
</td> |
|||
<td nzRight *ngIf="props.theadSettable"></td> |
|||
</tr> |
|||
</tbody> |
|||
</nz-table> |
|||
</div> |
|||
</div> |
|||
</ng-template> |
|||
|
|||
|
|||
|
|||
<ng-container *ngIf="renderItem else renderTableTpl"> |
|||
<ng-container *ngIf="props.pager.loading"> |
|||
<nz-card [nzBordered]="false"> |
|||
<nz-skeleton [nzActive]="true"></nz-skeleton> |
|||
</nz-card> |
|||
</ng-container> |
|||
<div class="custom-render" *ngIf="!props.pager.loading"> |
|||
<ng-container *ngIf="dataSource.length > 0 else emptyTpl"> |
|||
<div> |
|||
<ng-container |
|||
[ngTemplateOutlet]="renderItem" |
|||
[ngTemplateOutletContext]="{$implicit:dataSource}"> |
|||
</ng-container> |
|||
</div> |
|||
<div class="mt-4 flex justify-end"> |
|||
<nz-pagination [nzPageSizeOptions]="[10,20,50,100]" |
|||
[(nzPageSize)]="props.pager.size" |
|||
[(nzPageIndex)]="props.pager.page" |
|||
[nzTotal]="props.pager.total" |
|||
[nzShowTotal]="totalTpl" |
|||
[nzShowSizeChanger]="true" |
|||
[nzShowQuickJumper]="true" |
|||
(nzPageIndexChange)="onPageChange()" |
|||
(nzPageSizeChange)="onPageChange()"> |
|||
</nz-pagination> |
|||
</div> |
|||
</ng-container> |
|||
<ng-template #emptyTpl> |
|||
<nz-card [nzBordered]="false"> |
|||
<nz-empty></nz-empty> |
|||
</nz-card> |
|||
</ng-template> |
|||
</div> |
|||
<ng-container *ngIf="renderItem; else renderTableTpl"> |
|||
<ng-container *ngIf="props.pager.loading"> |
|||
<nz-card [nzBordered]="false"> |
|||
<nz-skeleton [nzActive]="true"></nz-skeleton> |
|||
</nz-card> |
|||
</ng-container> |
|||
<div class="custom-render" *ngIf="!props.pager.loading"> |
|||
<ng-container *ngIf="dataSource.length > 0; else emptyTpl"> |
|||
<div> |
|||
<ng-container [ngTemplateOutlet]="renderItem" [ngTemplateOutletContext]="{ $implicit: dataSource }"> |
|||
</ng-container> |
|||
</div> |
|||
<div class="mt-4 flex justify-end"> |
|||
<nz-pagination |
|||
[nzPageSizeOptions]="[10, 20, 50, 100]" |
|||
[(nzPageSize)]="props.pager.size" |
|||
[(nzPageIndex)]="props.pager.page" |
|||
[nzTotal]="props.pager.total" |
|||
[nzShowTotal]="totalTpl" |
|||
[nzShowSizeChanger]="true" |
|||
[nzShowQuickJumper]="true" |
|||
(nzPageIndexChange)="onPageChange()" |
|||
(nzPageSizeChange)="onPageChange()" |
|||
> |
|||
</nz-pagination> |
|||
</div> |
|||
</ng-container> |
|||
<ng-template #emptyTpl> |
|||
<nz-card [nzBordered]="false"> |
|||
<nz-empty></nz-empty> |
|||
</nz-card> |
|||
</ng-template> |
|||
</div> |
|||
</ng-container> |
|||
|
|||
|
|||
|
|||
<ng-template #columnVisibleSettingTpl> |
|||
<nz-checkbox-wrapper class="w-full"> |
|||
<ul cdkDropList (cdkDropListDropped)="colunmsSort($event)" class="columns-list"> |
|||
<li *ngFor="let item of columns" |
|||
class="table-setting-item cursor-pointer" cdkDrag> |
|||
<div class="columns-item-placeholder" *cdkDragPlaceholder></div> |
|||
<div class="flex items-center justify-between p-2"> |
|||
<div class="flex-shrink-0"> |
|||
<span nz-icon nzType="holder" nzTheme="outline"></span> |
|||
</div> |
|||
<div class="flex-1 pl-1"> |
|||
{{item.title}} |
|||
</div> |
|||
<div class="flex-shrink-0"> |
|||
<nz-switch |
|||
nzSize="small" |
|||
[disabled]="!!item.disabled" |
|||
[(ngModel)]="item.visible" |
|||
(ngModelChange)="onColumnsChange()"> |
|||
</nz-switch> |
|||
</div> |
|||
</div> |
|||
</li> |
|||
</ul> |
|||
</nz-checkbox-wrapper> |
|||
<nz-checkbox-wrapper class="w-full"> |
|||
<ul cdkDropList (cdkDropListDropped)="colunmsSort($event)" class="columns-list"> |
|||
<li *ngFor="let item of columns" class="table-setting-item cursor-pointer" cdkDrag> |
|||
<div class="columns-item-placeholder" *cdkDragPlaceholder></div> |
|||
<div class="flex items-center justify-between p-2"> |
|||
<div class="flex-shrink-0"> |
|||
<span nz-icon nzType="holder" nzTheme="outline"></span> |
|||
</div> |
|||
<div class="flex-1 pl-1"> |
|||
{{ item.title }} |
|||
</div> |
|||
<div class="flex-shrink-0"> |
|||
<nz-switch |
|||
nzSize="small" |
|||
[disabled]="!!item.disabled" |
|||
[(ngModel)]="item.visible" |
|||
(ngModelChange)="onColumnsChange()" |
|||
> |
|||
</nz-switch> |
|||
</div> |
|||
</div> |
|||
</li> |
|||
</ul> |
|||
</nz-checkbox-wrapper> |
|||
</ng-template> |
|||
|
|||
<ng-template #totalTpl let-total> |
|||
<ng-container *ngIf="showTotal"> |
|||
<ng-template [ngTemplateOutlet]="showTotal" [ngTemplateOutletContext]="{$implicit:props.pager}"></ng-template> |
|||
</ng-container> |
|||
<ng-container *ngIf="!showTotal"> |
|||
共{{total}}条 |
|||
</ng-container> |
|||
<ng-container *ngIf="showTotal"> |
|||
<ng-template |
|||
[ngTemplateOutlet]="showTotal" |
|||
[ngTemplateOutletContext]="{ $implicit: props.pager }" |
|||
></ng-template> |
|||
</ng-container> |
|||
<ng-container *ngIf="!showTotal"> 共{{ total }}条 </ng-container> |
|||
</ng-template> |
|||
|
|||
<ng-template #dateTimeTpl let-date> |
|||
{{date| date:'yyyy-MM-dd HH:mm:ss'}} |
|||
{{ date | date : 'yyyy-MM-dd HH:mm:ss' }} |
|||
</ng-template> |
|||
|
|||
|
|||
<!-- 为了计算操作栏的宽度 ---- start --> |
|||
<dec-table-operation #operationEl [rowData]="{}" [options]="operation" class="hidden-option"> |
|||
</dec-table-operation> |
|||
<dec-table-operation #operationEl [rowData]="{}" [options]="operation" class="hidden-option"> </dec-table-operation> |
|||
<!-- 为了计算操作栏的宽度 ---- end --> |
Loading…
Reference in new issue