Browse Source

权限页面

main
kkerwin 2 years ago
parent
commit
132a5ea209
  1. 66
      projects/admin/src/app/app-routing.module.ts
  2. 20
      projects/admin/src/app/app.module.ts
  3. 12
      projects/admin/src/app/components/app-layout/app-layout.component.html
  4. 8
      projects/admin/src/app/components/app-layout/app-layout.component.less
  5. 19
      projects/admin/src/app/components/app-layout/app-layout.component.ts
  6. 10
      projects/admin/src/app/components/app-page/app-page.component.html
  7. 3
      projects/admin/src/app/components/app-page/app-page.component.less
  8. 48
      projects/admin/src/app/components/app-page/app-page.component.ts
  9. 3
      projects/admin/src/app/components/index.ts
  10. 25
      projects/admin/src/app/components/role-permission/role-permission.component.html
  11. 0
      projects/admin/src/app/components/role-permission/role-permission.component.less
  12. 72
      projects/admin/src/app/components/role-permission/role-permission.component.ts
  13. 49
      projects/admin/src/app/components/user-list/user-list.component.html
  14. 0
      projects/admin/src/app/components/user-list/user-list.component.less
  15. 73
      projects/admin/src/app/components/user-list/user-list.component.ts
  16. 33
      projects/admin/src/app/pages/food/food.component.html
  17. 9
      projects/admin/src/app/pages/index.ts
  18. 104
      projects/admin/src/app/pages/organization/organization-form/organization-form.component.html
  19. 0
      projects/admin/src/app/pages/organization/organization-form/organization-form.component.less
  20. 54
      projects/admin/src/app/pages/organization/organization-form/organization-form.component.ts
  21. 59
      projects/admin/src/app/pages/organization/organization-list/organization-list.component.html
  22. 0
      projects/admin/src/app/pages/organization/organization-list/organization-list.component.less
  23. 82
      projects/admin/src/app/pages/organization/organization-list/organization-list.component.ts
  24. 59
      projects/admin/src/app/pages/standard/standard-form/standard-form.component.html
  25. 0
      projects/admin/src/app/pages/standard/standard-form/standard-form.component.less
  26. 57
      projects/admin/src/app/pages/standard/standard-form/standard-form.component.ts
  27. 52
      projects/admin/src/app/pages/standard/standard-list/standard-list.component.html
  28. 0
      projects/admin/src/app/pages/standard/standard-list/standard-list.component.less
  29. 76
      projects/admin/src/app/pages/standard/standard-list/standard-list.component.ts
  30. 42
      projects/admin/src/app/pages/standard/standard-setting/standard-setting.component.html
  31. 0
      projects/admin/src/app/pages/standard/standard-setting/standard-setting.component.less
  32. 57
      projects/admin/src/app/pages/standard/standard-setting/standard-setting.component.ts
  33. 88
      projects/admin/src/app/pages/system/user-manage/user-manage.component.html
  34. 17
      projects/admin/src/app/pages/system/user-manage/user-manage.component.less
  35. 68
      projects/admin/src/app/pages/system/user-manage/user-manage.component.ts
  36. 20
      projects/admin/src/styles.less

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

@ -9,6 +9,12 @@ import {
IngredientReleaseComponent,
IngredientReviewComponent,
LoginComponent,
OrganizationListComponent,
OrganizationFormComponent,
UserManageComponent,
StandardListComponent,
StandardFormComponent,
StandardSettingComponent,
} from "./pages";
import { AppLayoutComponent } from "./components";
@ -20,10 +26,33 @@ const routes: Routes = [
children: [
{ path: "", pathMatch: "full", redirectTo: "home" },
{ path: "home", component: HomeComponent },
{ path: "food", component: FoodComponent },
{ path: "dish", component: DishComponent },
{ path: "food", component: FoodComponent, title: "食材管理" },
{ path: "dish", component: DishComponent, title: "菜品管理" },
{
path: "standard",
children: [
{
path: "",
pathMatch: "full",
redirectTo: "list",
},
{
path: "list",
component: StandardListComponent,
},
{
path: "form/:id",
component: StandardFormComponent,
},
{
path: "setting/:id",
component: StandardSettingComponent,
},
],
},
{
path: "ingredient",
title: "食谱管理",
children: [
{
path: "",
@ -32,6 +61,7 @@ const routes: Routes = [
},
{
path: "item",
title: "食谱库",
children: [
{
path: "",
@ -51,14 +81,46 @@ const routes: Routes = [
{
path: "review",
title: "食谱审核",
component: IngredientReviewComponent,
},
{
path: "release",
title: "食谱发布计划",
component: IngredientReleaseComponent,
},
],
},
{
path: "organization",
title: "单位管理",
children: [
{
path: "",
pathMatch: "full",
redirectTo: "list",
},
{
path: "list",
component: OrganizationListComponent,
},
{
path: "form/:id",
component: OrganizationFormComponent,
},
],
},
{
path: "system",
title: "系统设置",
children: [
{
path: "user",
title: "用户管理",
component: UserManageComponent,
},
],
},
],
},
];

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

@ -19,6 +19,8 @@ import {
FoodFormComponent,
DishFormComponent,
IngredientFormBasicComponent,
UserListComponent,
RolePermissionComponent,
} from "./components";
import {
HomeComponent,
@ -29,6 +31,12 @@ import {
IngredientReleaseComponent,
IngredientReviewComponent,
IngredientFormComponent,
OrganizationListComponent,
OrganizationFormComponent,
UserManageComponent,
StandardListComponent,
StandardFormComponent,
StandardSettingComponent,
} from "./pages";
import { HTTPInterceptor } from "./services/http.interceptor";
@ -51,6 +59,18 @@ registerLocaleData(zh);
IngredientReleaseComponent,
IngredientReviewComponent,
IngredientFormComponent,
OrganizationListComponent,
OrganizationFormComponent,
UserManageComponent,
UserListComponent,
RolePermissionComponent,
StandardListComponent,
StandardFormComponent,
StandardSettingComponent,
],
imports: [
BrowserModule,

12
projects/admin/src/app/components/app-layout/app-layout.component.html

@ -23,29 +23,29 @@
</li>
<li nz-submenu nzTitle="食谱管理" nzIcon="book">
<li nz-submenu nzTitle="食谱管理" nzIcon="book" [nzOpen]="currentUrl.includes('/ingredient/')">
<ul>
<li nz-menu-item nzMatchRouter [routerLink]="['/','ingredient','item']">食谱库</li>
<li nz-menu-item nzMatchRouter [routerLink]="['/','ingredient','review']">食谱审核</li>
<li nz-menu-item nzMatchRouter [routerLink]="['/','ingredient','release']">食谱发布计划</li>
</ul>
</li>
<li nz-menu-item nz-icon="profile">
<li nz-menu-item nz-icon="profile" nzMatchRouter [routerLink]="['/','standard']">
<span nz-icon nzType="profile" nzTheme="outline"></span>
<span>人群营养标准管理</span>
</li>
<li nz-menu-item>
<li nz-menu-item nzMatchRouter [routerLink]="['/','organization']">
<span nz-icon nzType="usergroup-add" nzTheme="outline"></span>
<span>单位管理</span>
</li>
<li nz-submenu nzTitle="系统设置" nzIcon="setting">
<li nz-submenu nzTitle="系统设置" nzIcon="setting" [nzOpen]="currentUrl.includes('/system/')">
<ul>
<li nz-menu-item>用户管理</li>
<li nz-menu-item nzMatchRouter [routerLink]="['/','system','user']">用户管理</li>
</ul>
</li>
</ul>
</nz-sider>
<nz-layout class="inner-layout">
<nz-layout class="inner-layout overflow-hidden">
<router-outlet></router-outlet>
</nz-layout>
</nz-layout>

8
projects/admin/src/app/components/app-layout/app-layout.component.less

@ -1,7 +1,7 @@
:host {
display: flex;
flex-direction: column;
min-height: 100%;
height: 100%;
}
@header-height: 48px;
@ -10,7 +10,7 @@
display: flex;
flex-direction: column;
flex: 1;
min-height: 100%;
height: 100%;
}
.app-header {
@ -42,7 +42,7 @@
}
.app-layout-main {
min-height: 100%;
height: 100%;
}
.inner-layout {
@ -53,7 +53,7 @@
router-outlet+* {
display: flex;
flex-direction: column;
min-height: 100%;
height: 100%;
}
}
}

19
projects/admin/src/app/components/app-layout/app-layout.component.ts

@ -1,8 +1,25 @@
import { Component } from "@angular/core";
import { NavigationEnd, Router } from "@angular/router";
import { Subject, filter, takeUntil } from "rxjs";
@Component({
selector: "app-layout",
templateUrl: "./app-layout.component.html",
styleUrls: ["./app-layout.component.less"],
})
export class AppLayoutComponent {}
export class AppLayoutComponent {
constructor(private router: Router) {
this.router.events
.pipe(
takeUntil(this.unSubscribe$),
filter((e): e is NavigationEnd => e instanceof NavigationEnd)
)
.subscribe((e) => {
this.currentUrl = e.url;
});
}
unSubscribe$ = new Subject<void>();
currentUrl: string = "";
}

10
projects/admin/src/app/components/app-page/app-page.component.html

@ -1,4 +1,4 @@
<div class="app-page flex flex-col h-full " [ngClass]="{'m-4' : !full}">
<div class="app-page flex flex-col h-full" [ngClass]="{'p-4' : !full}">
<div class="app-header flex justify-between mb-2" *ngIf="pageTitle || pageExtra">
<div class="app-page-title" *ngIf="pageTitle">
<h2 *nzStringTemplateOutlet="pageTitle" class="mb-1">
@ -11,7 +11,13 @@
</ng-container>
</div>
</div>
<main class="app-page-body flex-1 ">
<main class="app-page-body flex-1 " [ngClass]="{'overflow-auto':!scroll}">
<!-- <nz-breadcrumb *ngIf="!full" class="mb-2">
<nz-breadcrumb-item *ngFor="let item of breadcrumb">
<a [routerLink]="['']">{{item.label}}</a>
</nz-breadcrumb-item>
</nz-breadcrumb> -->
<ng-content></ng-content>
</main>
</div>

3
projects/admin/src/app/components/app-page/app-page.component.less

@ -1,7 +1,8 @@
:host {
display: flex;
flex-direction: column;
min-height: 100%;
height: 100%;
overflow: auto;
}
.app-page {

48
projects/admin/src/app/components/app-page/app-page.component.ts

@ -1,16 +1,58 @@
import { Component, Input, TemplateRef } from "@angular/core";
import { Component, Input, OnDestroy, TemplateRef } from "@angular/core";
import { ActivatedRoute, NavigationEnd, Router, Scroll } from "@angular/router";
import { Subject, filter, startWith, take, takeUntil } from "rxjs";
interface BreadcrumbInterface {
label: string;
href?: string;
}
@Component({
selector: "app-page",
templateUrl: "./app-page.component.html",
styleUrls: ["./app-page.component.less"],
})
export class AppPageComponent {
constructor() {}
export class AppPageComponent implements OnDestroy {
constructor(private route: ActivatedRoute, private router: Router) {
// this.router.events
// .pipe(
// takeUntil(this.unSubscribe$),
// filter((e) => e instanceof NavigationEnd || e instanceof Scroll)
// )
// .subscribe(() => {
// this.genBreadcrumb();
// });
}
@Input() pageTitle?: TemplateRef<{}> | string;
@Input() full: boolean = false;
@Input() scroll: boolean = true;
@Input() pageExtra?: TemplateRef<{}> | string;
unSubscribe$ = new Subject<void>();
breadcrumb: BreadcrumbInterface[] = [];
ngOnDestroy(): void {
this.unSubscribe$.next();
this.unSubscribe$.complete();
}
genBreadcrumb() {
let route: ActivatedRoute | null = this.route;
this.breadcrumb = [];
while (route) {
if (route.routeConfig?.title) {
this.breadcrumb.unshift({
label: route.routeConfig!.title as string,
href: route.routeConfig.path,
});
}
route = route?.parent ?? null;
}
console.log("this.route", this.breadcrumb);
}
}

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

@ -5,3 +5,6 @@ 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";

25
projects/admin/src/app/components/role-permission/role-permission.component.html

@ -0,0 +1,25 @@
<div class="pb-10">
<nz-card *ngFor="let group of permissions | keyvalue : returenZero;" nzType="inner" [nzTitle]="group.key"
class="mb-4">
<div nz-row [nzGutter]="[12,12]">
<div nz-col nzSpan="8" *ngFor="let perm of group.value">
<label nz-checkbox
[nzChecked]="hasPermissions.has(perm.value)"
(nzCheckedChange)="onPermissionChange($event,perm.value)">
{{perm.label}}
</label>
</div>
</div>
</nz-card>
<div class="fixed-footter bg-white py-2 absolute left-0 bottom-0 right-0">
<div class="flex pl-16">
<nz-space>
<button *nzSpaceItem nz-button nzType="primary" (click)="onSubmit()">
保存
</button>
</nz-space>
</div>
</div>
</div>

0
projects/admin/src/app/components/role-permission/role-permission.component.less

72
projects/admin/src/app/components/role-permission/role-permission.component.ts

@ -0,0 +1,72 @@
import { ApiService } from "@admin/app/services";
import { Component } from "@angular/core";
import { ActivatedRoute } from "@angular/router";
@Component({
selector: "app-role-permission",
templateUrl: "./role-permission.component.html",
styleUrls: ["./role-permission.component.less"],
})
export class RolePermissionComponent {
constructor(private api: ApiService, private route: ActivatedRoute) {}
roleId: string | null = null;
permissions = {
: [
{ label: "食材列表-查看", value: "1-1" },
{ label: "食材-新增/编辑/删除", value: "1-2" },
],
: [
{ label: "菜品列表-查看", value: "2-1" },
{ label: "菜品-新增/编辑/删除", value: "2-2" },
],
: [
{ label: "食谱列表-查看", value: "3-1" },
{ label: "食谱-新增/编辑/删除", value: "3-2" },
{ label: "食谱审核列表-查看", value: "3-3" },
{ label: "食谱审核列表-通过/驳回", value: "3-4" },
{ label: "食谱发布计划-查看", value: "3-5" },
{ label: "食谱发布计划-发布/取消发布", value: "3-6" },
],
: [
{ label: "模型列表-查看", value: "4-1" },
{ label: "营养标准模型-新增/编辑/删除", value: "4-2" },
],
: [
{ label: "单位列表-查看", value: "5-1" },
{ label: "单位-新增/编辑/启用/禁用/删除", value: "5-2" },
],
: [
{ label: "用户列表-查看", value: "6-1" },
{ label: "角色权限-新增/编辑/删除", value: "6-2" },
{ label: "用户-新增/编辑/删除", value: "6-3" },
],
};
hasPermissions = new Set<string>();
ngOnInit(): void {
this.route.queryParamMap.subscribe((r) => {
this.roleId = r.get("roleId");
if (this.roleId) {
}
});
}
returenZero() {
return 0;
}
onPermissionChange(checked: boolean, key: string) {
if (!checked && this.hasPermissions.has(key)) {
this.hasPermissions.delete(key);
} else {
this.hasPermissions.add(key);
}
}
onSubmit() {
console.log("this.hasPermissions", this.hasPermissions);
}
}

49
projects/admin/src/app/components/user-list/user-list.component.html

@ -0,0 +1,49 @@
<table-list [props]="tableList" [search]="searchTpl" [action]="pageExtraTpl" [formGroup]="queryForm">
<ng-template #searchTpl>
<nz-form-item>
<nz-form-control>
<input nz-input placeholder="请输入用户" formControlName="name" />
</nz-form-control>
</nz-form-item>
</ng-template>
</table-list>
<ng-template #pageExtraTpl>
<nz-space>
<button *nzSpaceItem nz-button nzType="primary" (click)="openForm()">
<i nz-icon nzType="plus"></i>
新增用户
</button>
</nz-space>
</ng-template>
<ng-template #userFormTpl>
<form nz-form>
<nz-form-item>
<nz-form-label nzSpan="6" nzRequired>
姓名
</nz-form-label>
<nz-form-control nzSpan="12">
<input nz-input placeholder="请输入用户姓名" />
</nz-form-control>
</nz-form-item>
<nz-form-item>
<nz-form-label nzSpan="6" nzRequired>
账号
</nz-form-label>
<nz-form-control nzSpan="12">
<input nz-input placeholder="请输入用户账号" />
</nz-form-control>
</nz-form-item>
<nz-form-item>
<nz-form-label nzSpan="6" nzRequired>
密码
</nz-form-label>
<nz-form-control nzSpan="12">
<input nz-input placeholder="请输入用户密码" type="password" />
</nz-form-control>
</nz-form-item>
</form>
</ng-template>

0
projects/admin/src/app/components/user-list/user-list.component.less

73
projects/admin/src/app/components/user-list/user-list.component.ts

@ -0,0 +1,73 @@
import { ApiService } from "@admin/app/services";
import { Component, OnInit, TemplateRef, ViewChild } from "@angular/core";
import { FormControl, FormGroup } from "@angular/forms";
import { ActivatedRoute } from "@angular/router";
import { AnyObject, TableListOption } from "@cdk/public-api";
import { NzModalService } from "ng-zorro-antd/modal";
@Component({
selector: "app-user-list",
templateUrl: "./user-list.component.html",
styleUrls: ["./user-list.component.less"],
})
export class UserListComponent {
constructor(private api: ApiService, private route: ActivatedRoute, private modal: NzModalService) {}
@ViewChild("userFormTpl") public userFormTpl!: TemplateRef<void>;
public tableList = new TableListOption(this.fetchData.bind(this), {
manual: true,
});
public queryForm = new FormGroup({
name: new FormControl(""),
});
roleId: string | null = null;
ngOnInit(): void {
this.route.queryParamMap.subscribe((r) => {
this.roleId = r.get("roleId");
if (this.roleId) {
this.tableList.reset();
}
});
this.initTableList();
}
initTableList() {
this.tableList.scroll = { x: null };
this.tableList = this.tableList.setColumns([
{ key: "name", title: "账号" },
{ key: "name", title: "姓名" },
{ key: "name", title: "角色" },
{ key: "name", title: "添加时间" },
]);
this.tableList = this.tableList.setOptions([
{
title: "编辑",
premissions: [],
onClick: this.openForm.bind(this),
},
{
title: "删除",
premissions: [],
onClick: this.deleteItem.bind(this),
},
]);
}
fetchData(query: AnyObject, pager: AnyObject) {
return this.api.page(pager, query);
}
deleteItem() {}
openForm(item?: any) {
this.modal.create({
nzTitle: item ? "编辑用户" : "新增用户",
nzContent: this.userFormTpl,
});
}
}

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

@ -1,4 +1,4 @@
<app-page>
<app-page [scroll]="false">
<ng-template #pageExtraTpl>
<nz-space>
<button *nzSpaceItem nz-button>批量删除</button>
@ -36,22 +36,25 @@
</ul>
</nz-card>
</div>
<div nz-col nzFlex="1" class="flex-1 overflow-hidden bg-white ">
<div nz-col nzFlex="1" class="flex-1 overflow-hidden bg-white h-full">
<nz-card [nzBordered]="false" nzTitle="食材管理">
<table-list [props]="tableList" [search]="searchTpl" [action]="pageExtraTpl" [formGroup]="queryForm">
<nz-card [nzBordered]="false" nzTitle="食材管理" class="scroll-card-body">
<div class="m-4">
<table-list [props]="tableList" [search]="searchTpl" [action]="pageExtraTpl"
[formGroup]="queryForm">
<ng-template #actionTpl>
<button nz-button>批量删除</button>
</ng-template>
<ng-template #searchTpl>
<nz-form-item>
<nz-form-control>
<input nz-input placeholder="请输入食材名称/编号" formControlName="name" />
</nz-form-control>
</nz-form-item>
</ng-template>
</table-list>
<ng-template #actionTpl>
<button nz-button>批量删除</button>
</ng-template>
<ng-template #searchTpl>
<nz-form-item>
<nz-form-control>
<input nz-input placeholder="请输入食材名称/编号" formControlName="name" />
</nz-form-control>
</nz-form-item>
</ng-template>
</table-list>
</div>
</nz-card>
</div>

9
projects/admin/src/app/pages/index.ts

@ -9,3 +9,12 @@ export * from "./ingredients/ingredient-list/ingredient-list.component";
export * from "./ingredients/ingredient-review/ingredient-review.component";
export * from "./ingredients/ingredient-release/ingredient-release.component";
export * from "./ingredients/ingredient-form/ingredient-form.component";
export * from "./organization/organization-list/organization-list.component";
export * from "./organization/organization-form/organization-form.component";
export * from "./system/user-manage/user-manage.component";
export * from "./standard/standard-list/standard-list.component";
export * from "./standard/standard-form/standard-form.component";
export * from "./standard/standard-setting/standard-setting.component";

104
projects/admin/src/app/pages/organization/organization-form/organization-form.component.html

@ -0,0 +1,104 @@
<app-page>
<form nz-form [formGroup]="formGroup" nzLayout="vertical">
<nz-card nzTitle="单位基础信息">
<nz-form-item>
<nz-form-label nzRequired>
单位名称
</nz-form-label>
<nz-form-control [nzErrorTip]="formControlErrorTpl" nzSpan="12">
<input nz-input placeholder="请输入单位名称" />
</nz-form-control>
</nz-form-item>
<nz-form-item>
<nz-form-label>
单位Logo
</nz-form-label>
<nz-form-control [nzErrorTip]="formControlErrorTpl" nzSpan="12">
<button class="upload-btn " nz-button [nzLoading]="uploadLoading">
<i nz-icon nzType="upload"></i>
上传图片
<input type="file" formControlName="logo" (change)="onFileChange($event)" />
</button>
</nz-form-control>
</nz-form-item>
<nz-form-item>
<nz-form-label>
地址
</nz-form-label>
<nz-form-control [nzErrorTip]="formControlErrorTpl" nzSpan="12">
<input nz-input placeholder="请输入单位地址" />
</nz-form-control>
</nz-form-item>
<nz-form-item>
<nz-form-label>
联系人
</nz-form-label>
<nz-form-control [nzErrorTip]="formControlErrorTpl" nzSpan="12">
<input nz-input placeholder="请输入联系人" />
</nz-form-control>
</nz-form-item>
<nz-form-item>
<nz-form-label>
联系电话
</nz-form-label>
<nz-form-control [nzErrorTip]="formControlErrorTpl" nzSpan="12">
<input nz-input placeholder="请输入联系电话" />
</nz-form-control>
</nz-form-item>
<nz-form-item>
<nz-form-label>
邮箱
</nz-form-label>
<nz-form-control [nzErrorTip]="formControlErrorTpl" nzSpan="12">
<input nz-input placeholder="请输入邮箱" />
</nz-form-control>
</nz-form-item>
</nz-card>
<nz-card nzTitle="账号信息" class="my-4">
<nz-form-item>
<nz-form-label nzRequired>
账号
</nz-form-label>
<nz-form-control [nzErrorTip]="formControlErrorTpl" nzSpan="12">
<input nz-input placeholder="请输入账号" />
</nz-form-control>
</nz-form-item>
<nz-form-item>
<nz-form-label nzRequired>
初始密码
</nz-form-label>
<nz-form-control [nzErrorTip]="formControlErrorTpl" nzSpan="12">
<input nz-input type="password" placeholder="请输入初始密码" />
</nz-form-control>
</nz-form-item>
<nz-form-item>
<nz-form-label nzRequired>
账号到期时间
</nz-form-label>
<nz-form-control [nzErrorTip]="formControlErrorTpl" nzSpan="12">
<nz-date-picker nzPlaceHolder="请选择账号到期时间" class="w-full"></nz-date-picker>
</nz-form-control>
</nz-form-item>
</nz-card>
<div class="fixed-footter left-[218px] fixed bottom-0 right-0 bg-white z-10 pl-8 py-2">
<nz-space>
<button *nzSpaceItem nz-button nzType="primary" (click)="onSubmit()">
确定
</button>
<button *nzSpaceItem nz-button>
取消
</button>
</nz-space>
</div>
</form>
<ng-template #formControlErrorTpl let-control>
<form-error-tips [control]="control"></form-error-tips>
</ng-template>
</app-page>

0
projects/admin/src/app/pages/organization/organization-form/organization-form.component.less

54
projects/admin/src/app/pages/organization/organization-form/organization-form.component.ts

@ -0,0 +1,54 @@
import { Component } from "@angular/core";
import { FormBuilder, FormGroup } from "@angular/forms";
import { FormValidators } from "@cdk/validators";
@Component({
selector: "app-organization-form",
templateUrl: "./organization-form.component.html",
styleUrls: ["./organization-form.component.less"],
})
export class OrganizationFormComponent {
constructor(private fb: FormBuilder) {}
formGroup!: FormGroup;
uploadLoading = false;
ngOnInit(): void {
this.formGroup = this.fb.group({
id: this.fb.control("", [FormValidators.required()]),
name: this.fb.control("", [FormValidators.required()]),
unit: this.fb.control("", [FormValidators.required()]),
day: this.fb.control("1", [FormValidators.required()]),
logo: this.fb.control("", []),
month: this.fb.control([], []),
});
}
onSubmit() {}
onFileChange(e: Event) {
const target = e.target as HTMLInputElement;
const file = target.files![0];
target.value = "";
const formData = new FormData();
const fileReader = new FileReader();
fileReader.onload = () => {
const base64 = fileReader.result as string;
const v = base64.split("base64,")[1];
};
formData.append("file", file);
this.uploadLoading = true;
// this.api
// .uploadLogo(formData)
// .pipe(
// finalize(() => {
// this.uploadLoading = false;
// })
// )
// .subscribe((r) => {
// this.msg.success(r.desc);
// fileReader.readAsDataURL(file);
// });
}
}

59
projects/admin/src/app/pages/organization/organization-list/organization-list.component.html

@ -0,0 +1,59 @@
<app-page>
<ng-template #pageExtraTpl>
<nz-space>
<button *nzSpaceItem nz-button nzType="primary" [routerLink]="['/','organization','form','create']">
<i nz-icon nzType="plus"></i>
新增单位
</button>
</nz-space>
</ng-template>
<div class="h-full overflow-hidden bg-white rounded-lg">
<nz-card [nzBordered]="false" nzTitle="单位列表">
<table-list [props]="tableList" [search]="searchTpl" [action]="pageExtraTpl" [formGroup]="queryForm"
[renderColumns]="renderColumnsTpl">
<ng-template #actionTpl>
<button nz-button>批量删除</button>
</ng-template>
<ng-template #searchTpl>
<nz-form-item class="w-40">
<nz-form-control>
<nz-select nzPlaceHolder="单位类型" [nzOptions]="[]"></nz-select>
</nz-form-control>
</nz-form-item>
<nz-form-item class="w-60">
<nz-form-control>
<input nz-input placeholder="请输入单位名称" />
</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="'img'">
</ng-container>
<ng-container *ngSwitchDefault>
{{data}}
</ng-container>
</ng-container>
</ng-template>
</table-list>
</nz-card>
</div>
</app-page>
<ng-template #formFooterTpl>
<nz-space>
<button *nzSpaceItem nz-button (click)="cancelFoodForm()">
取消
</button>
<button *nzSpaceItem nz-button nzType="primary">
保存
</button>
</nz-space>
</ng-template>

0
projects/admin/src/app/pages/organization/organization-list/organization-list.component.less

82
projects/admin/src/app/pages/organization/organization-list/organization-list.component.ts

@ -0,0 +1,82 @@
import { Component, OnInit, TemplateRef, ViewChild } from "@angular/core";
import { FormControl, FormGroup } from "@angular/forms";
import { NzDrawerRef, NzDrawerService } from "ng-zorro-antd/drawer";
import { AnyObject, TableListOption } from "@cdk/public-api";
import { DishFormComponent } from "@admin/app/components";
import { ApiService } from "@admin/app/services";
@Component({
selector: "app-organization-list",
templateUrl: "./organization-list.component.html",
styleUrls: ["./organization-list.component.less"],
})
export class OrganizationListComponent {
constructor(private drawer: NzDrawerService, private api: ApiService) {}
@ViewChild("formFooterTpl") formFooterTpl!: TemplateRef<{}>;
private drawerRef?: NzDrawerRef;
public tableList = new TableListOption(this.fetchData.bind(this), {
selectable: true,
});
public queryForm = new FormGroup({
name: new FormControl(""),
});
ngOnInit(): void {
this.initTableList();
}
initTableList() {
this.tableList.scroll = { x: null };
this.tableList = this.tableList.setColumns([
{ key: "name", title: "账号" },
{ key: "name", title: "单位名称" },
{ key: "name", title: "单位类型" },
{ key: "name", title: "地址", width: "30%" },
{ key: "name", title: "联系人" },
{ key: "name", title: "联系电话" },
{ key: "name", title: "使用状态" },
{ key: "name", title: "到期时间" },
]);
this.tableList = this.tableList.setOptions([
{
title: "续费",
premissions: [],
onClick: this.showFoodForm.bind(this),
},
{
title: "编辑",
premissions: [],
onClick: this.showFoodForm.bind(this),
},
{
title: "删除",
premissions: [],
onClick: this.deleteItem.bind(this),
},
]);
}
fetchData(query: AnyObject, pager: AnyObject) {
return this.api.page(pager, query);
}
showFoodForm(food?: any) {
this.drawerRef = this.drawer.create({
nzTitle: food ? "编辑菜品" : "新增菜品",
nzWidth: 700,
nzContent: DishFormComponent,
nzFooter: this.formFooterTpl,
});
}
cancelFoodForm() {
this.drawerRef?.close();
}
deleteItem() {}
}

59
projects/admin/src/app/pages/standard/standard-form/standard-form.component.html

@ -0,0 +1,59 @@
<app-page>
<form nz-form [formGroup]="formGroup" nzLayout="vertical">
<nz-card nzTitle="新增营养标准">
<nz-form-item>
<nz-form-label nzRequired>
营养标准名称
</nz-form-label>
<nz-form-control [nzErrorTip]="formControlErrorTpl" nzSpan="12">
<input nz-input placeholder="请输入营养标准名称" />
</nz-form-control>
</nz-form-item>
<nz-form-item>
<nz-form-label nzRequired>
溢出范围
</nz-form-label>
<nz-form-control [nzErrorTip]="formControlErrorTpl" nzSpan="12">
<nz-input-group nzAddOnBefore="±" nzAddOnAfter="%">
<input nz-input />
</nz-input-group>
</nz-form-control>
</nz-form-item>
<nz-form-item>
<nz-form-label nzRequired>
适用单位
</nz-form-label>
<nz-form-control [nzErrorTip]="formControlErrorTpl" nzSpan="12">
<nz-select [nzOptions]="[]" nzMode="multiple" nzPlaceHolder="请选择适用单位"></nz-select>
</nz-form-control>
</nz-form-item>
<nz-form-item>
<nz-form-control [nzErrorTip]="formControlErrorTpl" nzSpan="12">
<nz-space>
<button *nzSpaceItem nz-button nzType="primary" (click)="onSubmit()">
保存并设置营养标准
</button>
<button *nzSpaceItem nz-button nzType="primary" (click)="onSubmit()">
确定
</button>
<button *nzSpaceItem nz-button>
取消
</button>
</nz-space>
</nz-form-control>
</nz-form-item>
</nz-card>
</form>
<ng-template #formControlErrorTpl let-control>
<form-error-tips [control]="control"></form-error-tips>
</ng-template>
</app-page>

0
projects/admin/src/app/pages/standard/standard-form/standard-form.component.less

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

@ -0,0 +1,57 @@
import { Component } from "@angular/core";
import { FormBuilder, FormGroup } from "@angular/forms";
import { Router } from "@angular/router";
import { FormValidators } from "@cdk/validators";
@Component({
selector: "app-standard-form",
templateUrl: "./standard-form.component.html",
styleUrls: ["./standard-form.component.less"],
})
export class StandardFormComponent {
constructor(private fb: FormBuilder, private router: Router) {}
formGroup!: FormGroup;
uploadLoading = false;
ngOnInit(): void {
this.formGroup = this.fb.group({
id: this.fb.control("", [FormValidators.required()]),
name: this.fb.control("", [FormValidators.required()]),
unit: this.fb.control("", [FormValidators.required()]),
day: this.fb.control("1", [FormValidators.required()]),
logo: this.fb.control("", []),
month: this.fb.control([], []),
});
}
onSubmit() {
this.router.navigate(["/", "standard", "setting", "45"]);
}
onFileChange(e: Event) {
const target = e.target as HTMLInputElement;
const file = target.files![0];
target.value = "";
const formData = new FormData();
const fileReader = new FileReader();
fileReader.onload = () => {
const base64 = fileReader.result as string;
const v = base64.split("base64,")[1];
};
formData.append("file", file);
this.uploadLoading = true;
// this.api
// .uploadLogo(formData)
// .pipe(
// finalize(() => {
// this.uploadLoading = false;
// })
// )
// .subscribe((r) => {
// this.msg.success(r.desc);
// fileReader.readAsDataURL(file);
// });
}
}

52
projects/admin/src/app/pages/standard/standard-list/standard-list.component.html

@ -0,0 +1,52 @@
<app-page>
<ng-template #pageExtraTpl>
<nz-space>
<button *nzSpaceItem nz-button nzType="primary" [routerLink]="['/','standard','form','create']">
<i nz-icon nzType="plus"></i>
新增营养标准
</button>
</nz-space>
</ng-template>
<div class="h-full overflow-hidden bg-white rounded-lg">
<nz-card [nzBordered]="false" nzTitle="营养标准列表">
<table-list [props]="tableList" [search]="searchTpl" [action]="pageExtraTpl" [formGroup]="queryForm"
[renderColumns]="renderColumnsTpl">
<ng-template #searchTpl>
<nz-form-item class="w-60">
<nz-form-control>
<input nz-input placeholder="请输入营养标准名称" />
</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="'img'">
</ng-container>
<ng-container *ngSwitchDefault>
{{data}}
</ng-container>
</ng-container>
</ng-template>
</table-list>
</nz-card>
</div>
</app-page>
<ng-template #formFooterTpl>
<nz-space>
<button *nzSpaceItem nz-button (click)="cancelFoodForm()">
取消
</button>
<button *nzSpaceItem nz-button nzType="primary">
保存
</button>
</nz-space>
</ng-template>

0
projects/admin/src/app/pages/standard/standard-list/standard-list.component.less

76
projects/admin/src/app/pages/standard/standard-list/standard-list.component.ts

@ -0,0 +1,76 @@
import { Component, OnInit, TemplateRef, ViewChild } from "@angular/core";
import { FormControl, FormGroup } from "@angular/forms";
import { NzDrawerRef, NzDrawerService } from "ng-zorro-antd/drawer";
import { AnyObject, TableListOption } from "@cdk/public-api";
import { DishFormComponent } from "@admin/app/components";
import { ApiService } from "@admin/app/services";
@Component({
selector: "app-standard-list",
templateUrl: "./standard-list.component.html",
styleUrls: ["./standard-list.component.less"],
})
export class StandardListComponent {
constructor(private drawer: NzDrawerService, private api: ApiService) {}
@ViewChild("formFooterTpl") formFooterTpl!: TemplateRef<{}>;
private drawerRef?: NzDrawerRef;
public tableList = new TableListOption(this.fetchData.bind(this));
public queryForm = new FormGroup({
name: new FormControl(""),
});
ngOnInit(): void {
this.initTableList();
}
initTableList() {
this.tableList.scroll = { x: null };
this.tableList = this.tableList.setColumns([
{ key: "name", title: "营养标准名称" },
{ key: "name", title: "人群细分" },
{ key: "name", title: "适用单位" },
{ key: "name", title: "更新时间" },
]);
this.tableList = this.tableList.setOptions([
{
title: "标准设置",
premissions: [],
onClick: this.showFoodForm.bind(this),
},
{
title: "编辑",
premissions: [],
onClick: this.showFoodForm.bind(this),
},
{
title: "删除",
premissions: [],
onClick: this.deleteItem.bind(this),
},
]);
}
fetchData(query: AnyObject, pager: AnyObject) {
return this.api.page(pager, query);
}
showFoodForm(food?: any) {
this.drawerRef = this.drawer.create({
nzTitle: food ? "编辑菜品" : "新增菜品",
nzWidth: 700,
nzContent: DishFormComponent,
nzFooter: this.formFooterTpl,
});
}
cancelFoodForm() {
this.drawerRef?.close();
}
deleteItem() {}
}

42
projects/admin/src/app/pages/standard/standard-setting/standard-setting.component.html

@ -0,0 +1,42 @@
<app-page>
<form nz-form [formGroup]="formGroup" nzLayout="vertical">
<nz-card nzTitle="食物种类及数量标准设置">
<div nz-row [nzGutter]="12">
<div nz-col nzSpan="12">
<ng-template #dayBtnTpl>
<button nz-button nzType="link">
添加食物种类
</button>
</ng-template>
<nz-card nzType="inner" nzTitle="食物种类及数量标准(日)" [nzExtra]="dayBtnTpl">
<div class=" overflow-y-auto h-80">
add
</div>
</nz-card>
</div>
<div nz-col nzSpan="12">
<ng-template #weekBtnTpl>
<button nz-button nzType="link">
添加食物种类
</button>
</ng-template>
<nz-card nzType="inner" nzTitle="食物种类及数量标准(周)" [nzExtra]="weekBtnTpl">
<div class=" overflow-y-auto h-80">
</div>
</nz-card>
</div>
</div>
</nz-card>
<nz-card nzTitle="人群名称1" class="mt-4"></nz-card>
</form>
<ng-template #formControlErrorTpl let-control>
<form-error-tips [control]="control"></form-error-tips>
</ng-template>
</app-page>

0
projects/admin/src/app/pages/standard/standard-setting/standard-setting.component.less

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

@ -0,0 +1,57 @@
import { Component } from "@angular/core";
import { FormBuilder, FormGroup } from "@angular/forms";
import { Router } from "@angular/router";
import { FormValidators } from "@cdk/validators";
@Component({
selector: "app-standard-setting",
templateUrl: "./standard-setting.component.html",
styleUrls: ["./standard-setting.component.less"],
})
export class StandardSettingComponent {
constructor(private fb: FormBuilder, private router: Router) {}
formGroup!: FormGroup;
uploadLoading = false;
ngOnInit(): void {
this.formGroup = this.fb.group({
id: this.fb.control("", [FormValidators.required()]),
name: this.fb.control("", [FormValidators.required()]),
unit: this.fb.control("", [FormValidators.required()]),
day: this.fb.control("1", [FormValidators.required()]),
logo: this.fb.control("", []),
month: this.fb.control([], []),
});
}
onSubmit() {
this.router.navigate(["/", "standard", "setting", "45"]);
}
onFileChange(e: Event) {
const target = e.target as HTMLInputElement;
const file = target.files![0];
target.value = "";
const formData = new FormData();
const fileReader = new FileReader();
fileReader.onload = () => {
const base64 = fileReader.result as string;
const v = base64.split("base64,")[1];
};
formData.append("file", file);
this.uploadLoading = true;
// this.api
// .uploadLogo(formData)
// .pipe(
// finalize(() => {
// this.uploadLoading = false;
// })
// )
// .subscribe((r) => {
// this.msg.success(r.desc);
// fileReader.readAsDataURL(file);
// });
}
}

88
projects/admin/src/app/pages/system/user-manage/user-manage.component.html

@ -0,0 +1,88 @@
<app-page [scroll]="false">
<div nz-row class="h-full overflow-hidden bg-white rounded-lg">
<div nz-col nzFlex="220px" class="user-type">
<nz-card
class="h-full "
[nzBordered]="false"
nzTitle="用户角色"
[nzBodyStyle]="{padding:'1px 0 0 0'}">
<ul nz-menu nzMode="inline">
<li
nz-menu-item
(click)="onRoleChange('super')"
[nzSelected]="roleId === 'super'"
class="flex items-center justify-between">
<span>
超级管理员12
</span>
<a nz-button nzType="text" nz-dropdown [nzDropdownMenu]="menu">
<span nz-icon nzType="more"></span>
</a>
<nz-dropdown-menu #menu="nzDropdownMenu">
<ul nz-menu nzSelectable>
<li nz-menu-item (click)="openForm(roleFormTpl,$event,'super')">编辑</li>
<li nz-menu-item nzDanger (click)="deleteItem($event,'super')">删除</li>
</ul>
</nz-dropdown-menu>
</li>
<li nz-menu-item (click)="onRoleChange('1')" [nzSelected]="roleId === '1'">
<a>
自定义管理员1
</a>
</li>
<li nz-menu-item (click)="onRoleChange('2')" [nzSelected]="roleId === '2'">
<a>
自定义管理员2
</a>
</li>
<li nz-menu-item (click)="onRoleChange('3')" [nzSelected]="roleId === '3'">
<a>
自定义管理员3
</a>
</li>
</ul>
<div class="px-4 py-2">
<button nz-button nzType="dashed" nzBlock (click)="openForm(roleFormTpl,$event)">
<i nz-icon nzType="plus"></i>
<span>
新增角色
</span>
</button>
</div>
</nz-card>
</div>
<div nz-col nzFlex="1" class="flex-1 h-full overflow-hidden bg-white ">
<nz-card [nzBordered]="false"
class="h-full scroll-card-body ">
<nz-card-tab>
<nz-tabset nzSize="large" [nzSelectedIndex]="tab" (nzSelectedIndexChange)="onTabChange($event)">
<nz-tab nzTitle="用户列表"></nz-tab>
<nz-tab nzTitle="权限管理"></nz-tab>
</nz-tabset>
</nz-card-tab>
<div class="p-4">
<app-user-list *ngIf="tab.toString() === '0'"></app-user-list>
<app-role-permission *ngIf="tab.toString() === '1'"></app-role-permission>
</div>
</nz-card>
</div>
</div>
</app-page>
<ng-template #roleFormTpl>
<form nz-form>
<nz-form-item>
<nz-form-label nzSpan="6" nzRequired>
角色名称
</nz-form-label>
<nz-form-control nzSpan="12">
<input nz-input placeholder="请输入角色名称" />
</nz-form-control>
</nz-form-item>
</form>
</ng-template>

17
projects/admin/src/app/pages/system/user-manage/user-manage.component.less

@ -0,0 +1,17 @@
.user-type {
border-right: 1px solid #e8e8e8;
::ng-deep {
.ant-menu-inline {
border-right: none;
}
}
}
.role-head {
::ng-deep {
.ant-card-extra {
padding: 10px 0;
}
}
}

68
projects/admin/src/app/pages/system/user-manage/user-manage.component.ts

@ -0,0 +1,68 @@
import { FoodFormComponent } from "@admin/app/components";
import { ApiService } from "@admin/app/services";
import { Component, OnInit, TemplateRef, ViewChild } from "@angular/core";
import { FormControl, FormGroup } from "@angular/forms";
import { ActivatedRoute, Router } from "@angular/router";
import { AnyObject, TableListOption } from "@cdk/public-api";
import { NzDrawerRef, NzDrawerService } from "ng-zorro-antd/drawer";
import { NzModalService } from "ng-zorro-antd/modal";
@Component({
selector: "app-user-manage",
templateUrl: "./user-manage.component.html",
styleUrls: ["./user-manage.component.less"],
})
export class UserManageComponent {
constructor(
private route: ActivatedRoute,
private api: ApiService,
private router: Router,
private modal: NzModalService
) {}
public tab = 0;
public roleId: string | null = null;
ngOnInit(): void {
this.roleId = this.route.snapshot.queryParamMap.get("roleId");
this.tab = Number(this.route.snapshot.queryParamMap.get("tab")) || 0;
}
onRoleChange(roleId: string) {
this.roleId = roleId;
this.router.navigate(["/system/user"], {
queryParams: {
roleId,
},
queryParamsHandling: "merge",
});
}
onTabChange(index: number) {
this.tab = index;
this.router.navigate(["/system/user"], {
queryParams: {
tab: index,
},
queryParamsHandling: "merge",
});
}
openForm(nzContent: TemplateRef<{}>, event: MouseEvent, roleId?: string) {
event.preventDefault();
this.modal.create({
nzTitle: roleId ? "编辑角色" : "新增角色",
nzContent,
});
}
deleteItem(event: MouseEvent, id: string) {
event.preventDefault();
this.modal.confirm({
nzTitle: "警告",
nzContent: "是否要删除该角色?",
nzOkDanger: true,
});
}
}

20
projects/admin/src/styles.less

@ -36,4 +36,24 @@ li {
font-size: 0;
cursor: pointer;
}
}
.fixed-footter {
box-shadow: 0 0 10px -2px rgba(0, 0, 0, .25)
}
.scroll-card-body {
height: 100%;
&>.ant-card-body {
overflow: auto;
height: calc(100% - 60px);
padding: 0
}
&>.ant-card-head {
position: relative;
z-index: 10;
}
}
Loading…
Cancel
Save