diff --git a/package.json b/package.json index 416b8da..76040ca 100644 --- a/package.json +++ b/package.json @@ -26,7 +26,7 @@ "date-fns": "^2.30.0", "immer": "^10.0.2", "ng-zorro-antd": "16.1.0", - "ngx-permissions": "^15.0.1", + "ngx-permissions": "^16.0.1", "query-string": "^8.1.0", "rxjs": "~7.8.0", "tslib": "^2.3.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 853c60a..f8a257e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -48,8 +48,8 @@ dependencies: specifier: 16.1.0 version: 16.1.0(@angular/animations@16.1.0)(@angular/common@16.1.0)(@angular/core@16.1.0)(@angular/forms@16.1.0)(@angular/platform-browser@16.1.0)(@angular/router@16.1.0)(rxjs@7.8.0) ngx-permissions: - specifier: ^15.0.1 - version: 15.0.1(@angular/core@16.1.0)(@angular/router@16.1.0)(rxjs@7.8.0) + specifier: ^16.0.1 + version: 16.0.1(@angular/core@16.1.0)(@angular/router@16.1.0)(rxjs@7.8.0) query-string: specifier: ^8.1.0 version: 8.1.0 @@ -5345,8 +5345,8 @@ packages: - rxjs dev: false - /ngx-permissions@15.0.1(@angular/core@16.1.0)(@angular/router@16.1.0)(rxjs@7.8.0): - resolution: {integrity: sha512-GjPF54B0DYtzqVb95YUh1XZivU4ilpCnx04gtADnIz4grihb/AtVwGwjgeeC1N/zrwUaZWLxTkIm5emN11JlDw==} + /ngx-permissions@16.0.1(@angular/core@16.1.0)(@angular/router@16.1.0)(rxjs@7.8.0): + resolution: {integrity: sha512-4nGBuZCMgVySgUbwLpTNRFAS73bTt8uFCwBC5XQW/RxvkIH7UmtdtBD9VKBa7fgG8nEW5GPOCXy7L7ixP1gTvg==} peerDependencies: '@angular/core': '>=13 || >18' '@angular/router': '>=13 || >18' diff --git a/projects/admin/src/app/app-routing.module.ts b/projects/admin/src/app/app-routing.module.ts index c286e4d..dff4780 100644 --- a/projects/admin/src/app/app-routing.module.ts +++ b/projects/admin/src/app/app-routing.module.ts @@ -19,20 +19,55 @@ import { } from "./pages"; import { AppLayoutComponent } from "./components"; import { authGuard } from "./services/auth.guard"; +// import { PermissionLoadGuard } from "@client/app/services/permisson.guard"; +import { ngxPermissionsGuard } from "ngx-permissions"; +import { ForbiddenComponent, NotfoundComponent } from "@cdk/shared/components"; +import { PermissionLoadGuard } from "./services/permisson.guard"; const routes: Routes = [ { path: "login", component: LoginComponent }, + { path: "forbidden", component: ForbiddenComponent }, { path: "", component: AppLayoutComponent, - canActivate: [authGuard], + canActivate: [authGuard, PermissionLoadGuard], + children: [ { path: "", pathMatch: "full", redirectTo: "food" }, { path: "home", component: HomeComponent }, - { path: "food", component: FoodComponent, title: "食材管理" }, - { path: "dish", component: DishComponent, title: "菜品管理" }, + { + path: "food", + component: FoodComponent, + title: "食材管理", + canActivate: [ngxPermissionsGuard], + data: { + permissions: { + only: ["1", "2"], + redirectTo: "/forbidden", + }, + }, + }, + { + path: "dish", + component: DishComponent, + title: "菜品管理", + canActivate: [ngxPermissionsGuard], + data: { + permissions: { + only: ["3", "4"], + redirectTo: "/forbidden", + }, + }, + }, { path: "standard", + canActivate: [ngxPermissionsGuard], + data: { + permissions: { + only: ["11", "12"], + redirectTo: "/forbidden", + }, + }, children: [ { path: "", @@ -56,6 +91,13 @@ const routes: Routes = [ { path: "ingredient", title: "食谱管理", + canActivate: [ngxPermissionsGuard], + data: { + permissions: { + only: ["5", "6", "7", "8", "9", "10"], + redirectTo: "/forbidden", + }, + }, children: [ { path: "", @@ -65,6 +107,13 @@ const routes: Routes = [ { path: "item", title: "食谱库", + canActivate: [ngxPermissionsGuard], + data: { + permissions: { + only: ["5", "6"], + redirectTo: "/forbidden", + }, + }, children: [ { path: "", @@ -86,22 +135,50 @@ const routes: Routes = [ path: "review", title: "食谱审核", component: IngredientReviewComponent, + canActivate: [ngxPermissionsGuard], + data: { + permissions: { + only: ["7", "8"], + redirectTo: "/forbidden", + }, + }, }, { path: "preview", title: "食谱预览", component: IngredientPreviewPageComponent, + // canActivate: [ngxPermissionsGuard], + // data: { + // permissions: { + // only: ["23", "24"], + // redirectTo: "/forbidden", + // }, + // }, }, { path: "release", title: "食谱发布计划", component: IngredientReleaseComponent, + canActivate: [ngxPermissionsGuard], + data: { + permissions: { + only: ["9", "10"], + redirectTo: "/forbidden", + }, + }, }, ], }, { path: "organization", title: "单位管理", + canActivate: [ngxPermissionsGuard], + data: { + permissions: { + only: ["13", "14"], + redirectTo: "/forbidden", + }, + }, children: [ { path: "", @@ -121,6 +198,13 @@ const routes: Routes = [ { path: "system", title: "系统设置", + canActivate: [ngxPermissionsGuard], + data: { + permissions: { + only: ["15", "16", "17"], + redirectTo: "/forbidden", + }, + }, children: [ { path: "user", @@ -131,6 +215,10 @@ const routes: Routes = [ }, ], }, + { + path: "**", + component: NotfoundComponent, + }, ]; @NgModule({ diff --git a/projects/admin/src/app/app.module.ts b/projects/admin/src/app/app.module.ts index 6559eae..f105f87 100644 --- a/projects/admin/src/app/app.module.ts +++ b/projects/admin/src/app/app.module.ts @@ -40,6 +40,7 @@ import { HTTPInterceptor } from "./services/http.interceptor"; import { IconsProviderModule, PROJECT_NAME } from "@cdk/public-api"; import { SharedModule } from "@cdk/shared/shared.module"; import { IngredientModule } from "@cdk/ingredient/ingredient.module"; +import { NgxPermissionsModule } from "ngx-permissions"; registerLocaleData(zh); @@ -81,6 +82,7 @@ registerLocaleData(zh); IconsProviderModule, SharedModule, IngredientModule, + NgxPermissionsModule.forRoot(), ], providers: [ { provide: NZ_I18N, useValue: zh_CN }, diff --git a/projects/admin/src/app/pages/dish/dish.component.ts b/projects/admin/src/app/pages/dish/dish.component.ts index 3b2c460..8f9b837 100644 --- a/projects/admin/src/app/pages/dish/dish.component.ts +++ b/projects/admin/src/app/pages/dish/dish.component.ts @@ -138,11 +138,19 @@ export class DishComponent { this.msg.loading("数据请求中,请不要刷新页面", { nzDuration: 0, }); - this.api.getDishLabel(v.id).subscribe((res) => { - this.printData = res.body[0]; - this.printRef.print(); - this.msg.remove(); - }); + this.api + .getDishLabel(v.id) + .pipe( + finalize(() => { + setTimeout(() => { + this.msg.remove(); + }, 1000); + }) + ) + .subscribe((res) => { + this.printData = res.body[0]; + this.printRef.print(); + }); } fetchData(query: AnyObject, pager: AnyObject) { diff --git a/projects/admin/src/app/pages/ingredients/ingredient-form/ingredient-form.component.html b/projects/admin/src/app/pages/ingredients/ingredient-form/ingredient-form.component.html index 0db1e17..549a710 100644 --- a/projects/admin/src/app/pages/ingredients/ingredient-form/ingredient-form.component.html +++ b/projects/admin/src/app/pages/ingredients/ingredient-form/ingredient-form.component.html @@ -17,7 +17,7 @@ - + [nzBodyStyle]="{padding:'1px 0 0 0',flex:'1', 'overflow':'hidden'}"> +
+ +
+ +
+
diff --git a/projects/admin/src/app/services/permisson.guard.ts b/projects/admin/src/app/services/permisson.guard.ts new file mode 100644 index 0000000..dc75c00 --- /dev/null +++ b/projects/admin/src/app/services/permisson.guard.ts @@ -0,0 +1,36 @@ +import { inject } from "@angular/core"; +import { + ActivatedRoute, + ActivatedRouteSnapshot, + CanActivateChildFn, + CanActivateFn, + Route, + Router, + RouterStateSnapshot, +} from "@angular/router"; +import { ClientAccountDTO } from "@cdk/dtos"; +import { ApiService } from "@cdk/services"; +import { NgxPermissionsService } from "ngx-permissions"; + +export const PermissionLoadGuard: CanActivateFn = async (route: ActivatedRouteSnapshot, state: RouterStateSnapshot) => { + const permissionsService = inject(NgxPermissionsService); + const api = inject(ApiService); + const auth = localStorage.getItem(api.accountKey); + + if (auth) { + try { + const authData = JSON.parse(auth) as ClientAccountDTO; + if (Array.isArray(authData.roleItems)) { + const permissionList = authData.roleItems; + const permissions = permissionList.reduce((a, c) => { + if (c.itemType === "管理端") { + return a.concat(String(c.id)); + } + return a; + }, [] as string[]); + permissionsService.loadPermissions(permissions); + } + } catch (error) {} + } + return true; +}; diff --git a/projects/admin/src/favicon.ico b/projects/admin/src/favicon.ico index 997406a..016b266 100644 Binary files a/projects/admin/src/favicon.ico and b/projects/admin/src/favicon.ico differ diff --git a/projects/admin/src/index.html b/projects/admin/src/index.html index afa2e93..23e99b0 100644 --- a/projects/admin/src/index.html +++ b/projects/admin/src/index.html @@ -7,9 +7,7 @@ - + diff --git a/projects/admin/src/styles.less b/projects/admin/src/styles.less index 19d2aab..1b40e71 100644 --- a/projects/admin/src/styles.less +++ b/projects/admin/src/styles.less @@ -150,4 +150,18 @@ li { border: 1px solid #000; font-weight: normal; } +} + +.analysis-drawer { + + .ant-drawer-header-title { + position: absolute; + right: 0; + top: 24px; + } + + .ant-drawer-body { + padding-top: 0; + } + } \ No newline at end of file diff --git a/projects/cdk/src/ingredient/ingredient-analysis/ingredient-analysis.component.html b/projects/cdk/src/ingredient/ingredient-analysis/ingredient-analysis.component.html index bdd69ef..8d2b0cb 100644 --- a/projects/cdk/src/ingredient/ingredient-analysis/ingredient-analysis.component.html +++ b/projects/cdk/src/ingredient/ingredient-analysis/ingredient-analysis.component.html @@ -1,9 +1,9 @@
-
+
- + @@ -26,10 +26,158 @@
- - - + + + + + + + + + + + + 能量占比 + + + 要求(%) + + + 实际摄入(%) + + + 评价 + + + + + + + {{e.name}} + + + {{e.standard}} + + + {{e.value}} + + + + + +
+ + {{e.conclusion}} +
+
+ +
+ + {{e.conclusion}} +
+
+ +
+ + {{e.conclusion}} +
+
+ {{e.conclusion}} +
+ + + +
+
+
+
- + + +

+ 周规则 +

+
+ + + + + 种类名称 + + + 至少需要 + + + 当前含有 + + + 还需 + + + + + + + {{w.name}} + + + {{w.standard}} + + + {{w.supplied}} + + + {{w.lack}} + + + + +
+

+ 日规则 +

+
+
+ + + + + 种类名称 + + + 至少需要 + + + 当前含有 + + + 还需 + + + + + + + 第{{d.day}}天 + + + {{d.name}} + + + {{d.standard}} + + + {{d.supplied}} + + + {{d.lack}} + + + + +
+
+
+
\ No newline at end of file diff --git a/projects/cdk/src/ingredient/ingredient-analysis/ingredient-analysis.component.ts b/projects/cdk/src/ingredient/ingredient-analysis/ingredient-analysis.component.ts index 096a1ac..cb9554a 100644 --- a/projects/cdk/src/ingredient/ingredient-analysis/ingredient-analysis.component.ts +++ b/projects/cdk/src/ingredient/ingredient-analysis/ingredient-analysis.component.ts @@ -23,29 +23,44 @@ export class IngredientAnalysisComponent implements OnInit { analysis: any; + rules: any; + + energy: any; + analysisLoading = false; ngOnInit(): void { this.currentDay = this.current.day; this.currentPeople = this.menu.crows[0]; this.getAnalysis(); + this.getRule(); } getAnalysis() { - if (this.currentDay && this.currentPeople) { - this.analysisLoading = true; - this.api - .getAnalysis(this.menu.id, this.currentDay, this.currentPeople) - .pipe( - finalize(() => { - this.analysisLoading = false; - }) - ) - .subscribe((res) => { - this.analysis = res.body; - }); - } else { - console.error(this.currentDay, this.currentPeople, "this.currentDay && this.currentPeople 不存在"); - } + this.analysisLoading = true; + this.api + .getAnalysis(this.menu.id, this.currentDay, this.currentPeople) + .pipe( + finalize(() => { + this.analysisLoading = false; + }) + ) + .subscribe((res) => { + this.analysis = res.body; + }); + + this.getEnergy(); + } + + getEnergy() { + this.api.getAnalysisEnergy(this.menu.id, this.currentDay, this.currentPeople).subscribe((res) => { + this.energy = res.body; + }); + } + + getRule() { + this.api.getAnalysisRule(this.menu.id, this.currentDay, this.currentPeople).subscribe((res) => { + this.rules = res.body; + }); } } diff --git a/projects/cdk/src/ingredient/ingredient-dish/ingredient-dish.component.html b/projects/cdk/src/ingredient/ingredient-dish/ingredient-dish.component.html index eaef699..86869c8 100644 --- a/projects/cdk/src/ingredient/ingredient-dish/ingredient-dish.component.html +++ b/projects/cdk/src/ingredient/ingredient-dish/ingredient-dish.component.html @@ -15,16 +15,16 @@ - 第 {{day + 1}} 天 + 第 {{day}} 天
- - @@ -39,12 +39,12 @@
+ (onSaveDish)="onSaveDish($event,day,mealIndex)"> diff --git a/projects/cdk/src/ingredient/ingredient-dish/ingredient-dish.component.less b/projects/cdk/src/ingredient/ingredient-dish/ingredient-dish.component.less index f4abfea..a184201 100644 --- a/projects/cdk/src/ingredient/ingredient-dish/ingredient-dish.component.less +++ b/projects/cdk/src/ingredient/ingredient-dish/ingredient-dish.component.less @@ -22,20 +22,4 @@ flex-basis: 25%; } } -} - -::ng-deep { - .analysis-drawer { - - .ant-drawer-header-title { - position: absolute; - right: 0; - top: 24px; - } - - .ant-drawer-body { - padding-top: 0; - } - - } } \ No newline at end of file diff --git a/projects/cdk/src/ingredient/ingredient-dish/ingredient-dish.component.ts b/projects/cdk/src/ingredient/ingredient-dish/ingredient-dish.component.ts index 94f590c..3d47d06 100644 --- a/projects/cdk/src/ingredient/ingredient-dish/ingredient-dish.component.ts +++ b/projects/cdk/src/ingredient/ingredient-dish/ingredient-dish.component.ts @@ -118,7 +118,7 @@ export class IngredientDishComponent implements OnChanges { // [idx]: [], // }; // }, {} as Record); - return i; + return i + 1; }); } } @@ -158,6 +158,7 @@ export class IngredientDishComponent implements OnChanges { } analysis(day: number) { + console.log("this.days", this.days); this.drawer.create({ nzWidth: 620, nzWrapClassName: "analysis-drawer", diff --git a/projects/cdk/src/ingredient/ingredient-form-basic/ingredient-form-basic.component.html b/projects/cdk/src/ingredient/ingredient-form-basic/ingredient-form-basic.component.html index 0b49c99..57d5b06 100644 --- a/projects/cdk/src/ingredient/ingredient-form-basic/ingredient-form-basic.component.html +++ b/projects/cdk/src/ingredient/ingredient-form-basic/ingredient-form-basic.component.html @@ -90,14 +90,14 @@ - + diff --git a/projects/cdk/src/ingredient/ingredient-meals/ingredient-meals.component.html b/projects/cdk/src/ingredient/ingredient-meals/ingredient-meals.component.html index 00996e4..c1fc4c2 100644 --- a/projects/cdk/src/ingredient/ingredient-meals/ingredient-meals.component.html +++ b/projects/cdk/src/ingredient/ingredient-meals/ingredient-meals.component.html @@ -103,7 +103,7 @@ 本餐生重总量 - {{totalObj[p]?.toFixed(2)}} + {{$any(totalObj[p])?.toFixed(2)}} diff --git a/projects/cdk/src/ingredient/ingredient-preview/ingredient-preview.component.html b/projects/cdk/src/ingredient/ingredient-preview/ingredient-preview.component.html index 460a1c5..f85784b 100644 --- a/projects/cdk/src/ingredient/ingredient-preview/ingredient-preview.component.html +++ b/projects/cdk/src/ingredient/ingredient-preview/ingredient-preview.component.html @@ -1,5 +1,6 @@
+
diff --git a/projects/cdk/src/ingredient/ingredient-preview/ingredient-preview.component.ts b/projects/cdk/src/ingredient/ingredient-preview/ingredient-preview.component.ts index 38b61aa..50246bf 100644 --- a/projects/cdk/src/ingredient/ingredient-preview/ingredient-preview.component.ts +++ b/projects/cdk/src/ingredient/ingredient-preview/ingredient-preview.component.ts @@ -4,6 +4,8 @@ import { ApiService } from "@cdk/services"; import { NzMessageService } from "ng-zorro-antd/message"; import { DishInterface } from "../ingredient-dish/ingredient-dish.component"; import { forkJoin, map } from "rxjs"; +import { IngredientAnalysisComponent } from "../ingredient-analysis/ingredient-analysis.component"; +import { NzDrawerService } from "ng-zorro-antd/drawer"; @Component({ selector: "app-ingredient-preview", @@ -15,7 +17,8 @@ export class IngredientPreviewComponent { private route: ActivatedRoute, private router: Router, private api: ApiService, - private msg: NzMessageService + private msg: NzMessageService, + private drawer: NzDrawerService ) {} basic: any | null; @@ -128,4 +131,21 @@ export class IngredientPreviewComponent { }); return total.toFixed(2); } + + analysis(day: number) { + this.drawer.create({ + nzWidth: 620, + nzWrapClassName: "analysis-drawer", + nzContent: IngredientAnalysisComponent, + nzContentParams: { + menu: { + ...this.basic, + days: this.days, + }, + current: { + day, + }, + }, + }); + } } diff --git a/projects/cdk/src/ingredient/nutrition-table/nutrition-table.component.html b/projects/cdk/src/ingredient/nutrition-table/nutrition-table.component.html index 1a190b0..8a6d8e5 100644 --- a/projects/cdk/src/ingredient/nutrition-table/nutrition-table.component.html +++ b/projects/cdk/src/ingredient/nutrition-table/nutrition-table.component.html @@ -52,4 +52,40 @@ - \ No newline at end of file + +
+ +
+
+ +
+

+ 不足 +

+
+
+
+ +
+

+ 适量 +

+
+
+
+ +
+

+ 过量 +

+
+
+
+ +
+

+ 严重超标 +

+
+
+
\ No newline at end of file diff --git a/projects/cdk/src/ingredient/nutrition-table/nutrition-table.component.less b/projects/cdk/src/ingredient/nutrition-table/nutrition-table.component.less index d4a1a6f..ec24bbd 100644 --- a/projects/cdk/src/ingredient/nutrition-table/nutrition-table.component.less +++ b/projects/cdk/src/ingredient/nutrition-table/nutrition-table.component.less @@ -24,21 +24,32 @@ } - .row { - &.less .inner { - background-color: #a7a7a7; - } - &.success .inner { - background-color: #1bbc9b; - } +} - &.warning .inner { - background-color: #f3c200; - } +.tag { + display: inline-block; + width: 48px; + height: 20px; + border-radius: 4px; +} - &.danger .inner { - background-color: #f5222d; - } - } +.less { + background-color: #a7a7a7; + color: #fff; +} + +.success { + background-color: #1bbc9b; + color: #fff; +} + +.warning { + background-color: #f3c200; + color: #fff; +} + +.danger { + background-color: #f5222d; + color: #fff; } \ No newline at end of file diff --git a/projects/cdk/src/services/api.service.ts b/projects/cdk/src/services/api.service.ts index bb4710c..e44fd2d 100644 --- a/projects/cdk/src/services/api.service.ts +++ b/projects/cdk/src/services/api.service.ts @@ -458,6 +458,15 @@ export class ApiService { return this.http.get(`/api/menu/dish/analysis?${params}`); } + getAnalysisEnergy(id: number, day?: number, crow?: string) { + const params = Utils.objectStringify({ id, day, crow }); + return this.http.get(`/api/menu/dish/analysis/energy?${params}`); + } + getAnalysisRule(id: number, day?: number, crow?: string) { + const params = Utils.objectStringify({ id, day, crow }); + return this.http.get(`/api/menu/dish/analysis/types?${params}`); + } + getMenuDataVis() { return this.http.get(`/api/menu/dish`); } diff --git a/projects/cdk/src/shared/components/forbidden/forbidden.component.html b/projects/cdk/src/shared/components/forbidden/forbidden.component.html new file mode 100644 index 0000000..a753299 --- /dev/null +++ b/projects/cdk/src/shared/components/forbidden/forbidden.component.html @@ -0,0 +1,4 @@ +
+ +

你没有此页面的访问权限。

+
\ No newline at end of file diff --git a/projects/cdk/src/shared/components/forbidden/forbidden.component.less b/projects/cdk/src/shared/components/forbidden/forbidden.component.less new file mode 100644 index 0000000..e69de29 diff --git a/projects/cdk/src/shared/components/forbidden/forbidden.component.ts b/projects/cdk/src/shared/components/forbidden/forbidden.component.ts new file mode 100644 index 0000000..3bdfe40 --- /dev/null +++ b/projects/cdk/src/shared/components/forbidden/forbidden.component.ts @@ -0,0 +1,14 @@ +import { ActivatedRoute, Router } from "@angular/router"; +import { Component, OnInit } from "@angular/core"; +import { NgxPermissionsService } from "ngx-permissions"; + +@Component({ + selector: "app-forbidden", + templateUrl: "./forbidden.component.html", + styleUrls: ["./forbidden.component.less"], +}) +export class ForbiddenComponent implements OnInit { + constructor(private perm: NgxPermissionsService, private router: Router, private route: ActivatedRoute) {} + + async ngOnInit() {} +} diff --git a/projects/cdk/src/shared/components/index.ts b/projects/cdk/src/shared/components/index.ts index eabde4b..e927e43 100644 --- a/projects/cdk/src/shared/components/index.ts +++ b/projects/cdk/src/shared/components/index.ts @@ -3,3 +3,5 @@ export * from "./month-select/month-select.component"; export * from "./org-select/org-select.component"; export * from "./dish-select/dish-select.component"; export * from "./print/print.component"; +export * from "./forbidden/forbidden.component"; +export * from "./notfound/notfound.component"; diff --git a/projects/cdk/src/shared/components/notfound/notfound.component.html b/projects/cdk/src/shared/components/notfound/notfound.component.html new file mode 100644 index 0000000..df4b62f --- /dev/null +++ b/projects/cdk/src/shared/components/notfound/notfound.component.html @@ -0,0 +1,6 @@ +
+ +

+ 此页面未找到。 +

+
\ No newline at end of file diff --git a/projects/cdk/src/shared/components/notfound/notfound.component.less b/projects/cdk/src/shared/components/notfound/notfound.component.less new file mode 100644 index 0000000..e69de29 diff --git a/projects/cdk/src/shared/components/notfound/notfound.component.ts b/projects/cdk/src/shared/components/notfound/notfound.component.ts new file mode 100644 index 0000000..0368db3 --- /dev/null +++ b/projects/cdk/src/shared/components/notfound/notfound.component.ts @@ -0,0 +1,10 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'app-notfound', + templateUrl: './notfound.component.html', + styleUrls: ['./notfound.component.less'] +}) +export class NotfoundComponent { + +} diff --git a/projects/cdk/src/shared/shared.module.ts b/projects/cdk/src/shared/shared.module.ts index 6bce007..38fcff3 100644 --- a/projects/cdk/src/shared/shared.module.ts +++ b/projects/cdk/src/shared/shared.module.ts @@ -26,6 +26,8 @@ import { OrgSelectComponent, DishSelectComponent, PrintComponent, + ForbiddenComponent, + NotfoundComponent, } from "./components"; const ngModules = [CommonModule, HttpClientModule, FormsModule, RouterModule, ReactiveFormsModule]; @@ -39,6 +41,7 @@ const cdks = [ TableListModule, StorageModule, // QuickDateRangeComponent, + NgxPermissionsModule, ] as any; @NgModule({ @@ -50,6 +53,8 @@ const cdks = [ DishSelectComponent, OrgSelectComponent, PrintComponent, + ForbiddenComponent, + NotfoundComponent, ], imports: [...ngZorroModules, ...ngModules, ...cdks, AppPageComponent], exports: [ @@ -64,6 +69,8 @@ const cdks = [ OrgSelectComponent, DishSelectComponent, PrintComponent, + ForbiddenComponent, + NotfoundComponent, ], }) export class SharedModule {} diff --git a/projects/cdk/src/types/index.ts b/projects/cdk/src/types/index.ts index 3cb9626..c221cd0 100644 --- a/projects/cdk/src/types/index.ts +++ b/projects/cdk/src/types/index.ts @@ -48,18 +48,3 @@ export interface PageResult { totalElements: number; totalPages: number; } - -export interface AuthInterface { - role: string; - userId: string; - userName: string; - permissionList: AuthPermissionInterface[]; -} - -export interface AuthPermissionInterface { - name: string; - roleId: string; - scope: 1 | 0; - type: number; - value: "true" | "false"; -} diff --git a/projects/cdk/src/utils/index.ts b/projects/cdk/src/utils/index.ts index bfbc3dd..5207c18 100644 --- a/projects/cdk/src/utils/index.ts +++ b/projects/cdk/src/utils/index.ts @@ -68,7 +68,7 @@ export class Utils { if (obj.hasOwnProperty(key)) { let value = obj[key]; if (![void 0, null, ""].includes(value)) { - if (typeof value === "object") { + if (typeof value === "object" && !Array.isArray(value)) { params.append(key, JSON.stringify(value)); } else { params.append(key, value); diff --git a/projects/client/src/app/app-routing.module.ts b/projects/client/src/app/app-routing.module.ts index f91da31..dc543c1 100644 --- a/projects/client/src/app/app-routing.module.ts +++ b/projects/client/src/app/app-routing.module.ts @@ -16,13 +16,18 @@ import { } from "./pages"; import { AppLayoutComponent } from "./components"; import { authGuard } from "./services/auth.guard"; +import { PermissionLoadGuard } from "./services/permisson.guard"; +import { ForbiddenComponent, NotfoundComponent } from "@cdk/shared/components"; +import { ngxPermissionsGuard } from "ngx-permissions"; const routes: Routes = [ { path: "login", component: LoginComponent }, + { path: "forbidden", component: ForbiddenComponent }, { path: "", component: AppLayoutComponent, - canActivate: [authGuard], + canActivate: [authGuard, PermissionLoadGuard], + children: [ { path: "", @@ -32,26 +37,68 @@ const routes: Routes = [ { path: "dashboard", component: DashboardComponent, + canActivate: [ngxPermissionsGuard], + data: { + permissions: { + only: ["18"], + redirectTo: "/forbidden", + }, + }, }, { path: "meal-setting", component: MealSettingComponent, + canActivate: [ngxPermissionsGuard], + data: { + permissions: { + only: ["21", "22"], + redirectTo: "/forbidden", + }, + }, }, { path: "data-vis", component: DataVisComponent, + canActivate: [ngxPermissionsGuard], + data: { + permissions: { + only: ["19", "20"], + redirectTo: "/forbidden", + }, + }, }, { path: "food", component: FoodComponent, + canActivate: [ngxPermissionsGuard], + data: { + permissions: { + only: ["23", "24"], + redirectTo: "/forbidden", + }, + }, }, { path: "dish", component: DishComponent, + canActivate: [ngxPermissionsGuard], + data: { + permissions: { + only: ["25", "26"], + redirectTo: "/forbidden", + }, + }, }, { path: "ingredient", title: "食谱管理", + canActivate: [ngxPermissionsGuard], + data: { + permissions: { + only: ["27", "28", "29", "30", "31"], + redirectTo: "/forbidden", + }, + }, children: [ { path: "", @@ -61,6 +108,13 @@ const routes: Routes = [ { path: "item", title: "食谱库", + canActivate: [ngxPermissionsGuard], + data: { + permissions: { + only: ["27", "28"], + redirectTo: "/forbidden", + }, + }, children: [ { path: "", @@ -86,25 +140,58 @@ const routes: Routes = [ { path: "release", title: "食谱发布计划", + canActivate: [ngxPermissionsGuard], component: IngredientReleaseComponent, + data: { + permissions: { + only: ["30", "31"], + redirectTo: "/forbidden", + }, + }, }, ], }, { path: "system", + canActivate: [ngxPermissionsGuard], + data: { + permissions: { + only: ["33", "34", "35", "36", "37"], + redirectTo: "/forbidden", + }, + }, children: [ { path: "org", component: OrgInfoComponent, + canActivate: [ngxPermissionsGuard], + data: { + permissions: { + only: ["33", "34"], + redirectTo: "/forbidden", + }, + }, }, { path: "user", component: ClientUserManageComponent, + canActivate: [ngxPermissionsGuard], + data: { + permissions: { + only: ["35", "36", "37"], + redirectTo: "/forbidden", + }, + }, }, ], }, ], }, + + { + path: "**", + component: NotfoundComponent, + }, ]; @NgModule({ diff --git a/projects/client/src/app/app.module.ts b/projects/client/src/app/app.module.ts index c3a0cc5..4720cdc 100644 --- a/projects/client/src/app/app.module.ts +++ b/projects/client/src/app/app.module.ts @@ -36,6 +36,7 @@ import { } from "./pages"; import { HTTPInterceptor } from "./services/http.interceptor"; import { IngredientModule } from "@cdk/ingredient/ingredient.module"; +import { NgxPermissionsModule } from "ngx-permissions"; registerLocaleData(zh); @@ -71,6 +72,8 @@ registerLocaleData(zh); SharedModule, IngredientModule, TableListModule, + + NgxPermissionsModule.forRoot(), ], providers: [ { provide: PROJECT_NAME, useValue: "client" }, diff --git a/projects/client/src/app/components/app-layout/app-layout.component.html b/projects/client/src/app/components/app-layout/app-layout.component.html index 41e3b62..a67c3d1 100644 --- a/projects/client/src/app/components/app-layout/app-layout.component.html +++ b/projects/client/src/app/components/app-layout/app-layout.component.html @@ -35,41 +35,52 @@
    -
  • +
  • 使用流程
  • -
  • +
  • 大屏显示
  • -
  • +
  • 配餐设置
  • -
  • +
  • 食材管理
  • -
  • +
  • 菜品管理
  • -
  • +
    • -
    • 食谱库
    • -
    • 食谱发布计划
    • +
    • 食谱库
    • +
    • 食谱发布计划
  • -
  • +
    • -
    • 单位信息设置
    • +
    • 单位信息设置
      -
    • 用户管理
    • +
    • 用户管理
diff --git a/projects/client/src/app/pages/data-vis/data-vis.component.html b/projects/client/src/app/pages/data-vis/data-vis.component.html index 113ec00..df38170 100644 --- a/projects/client/src/app/pages/data-vis/data-vis.component.html +++ b/projects/client/src/app/pages/data-vis/data-vis.component.html @@ -12,8 +12,8 @@
-->
-
-
+
+
今日带量食谱
@@ -59,18 +59,35 @@ -
-
+
+
今日食材种类
- +
+
+
+ {{type.key}} : {{type.value}} 种 +
+
+
-
今日营养分析
+
+ + 今日营养分析 + + + + +
diff --git a/projects/client/src/app/pages/data-vis/data-vis.component.less b/projects/client/src/app/pages/data-vis/data-vis.component.less index 076ccee..8f68583 100644 --- a/projects/client/src/app/pages/data-vis/data-vis.component.less +++ b/projects/client/src/app/pages/data-vis/data-vis.component.less @@ -226,6 +226,18 @@ i { top: -1px; } +.select { + background-color: transparent; + color: #fff; + border: none; + outline: none; + + option { + background-color: #fff; + color: #012059; + } +} + .boxnav { flex: 1; diff --git a/projects/client/src/app/pages/data-vis/data-vis.component.ts b/projects/client/src/app/pages/data-vis/data-vis.component.ts index 8fd48ce..7266766 100644 --- a/projects/client/src/app/pages/data-vis/data-vis.component.ts +++ b/projects/client/src/app/pages/data-vis/data-vis.component.ts @@ -35,6 +35,10 @@ export class DataVisComponent implements AfterViewInit { scroll: Record = {}; + people = ""; + + menuId!: number; + ngOnInit(): void { this.orgName = this.api.account?.vender?.name ?? ""; interval(1000) @@ -47,12 +51,13 @@ export class DataVisComponent implements AfterViewInit { const dishs = res.body; if (Array.isArray(dishs)) { this.peoples = Object.keys(dishs?.[0]?.ingredient?.[0]?.value); - + this.people = this.peoples[0]; if (!this.peoples) { console.error("dishs?.[0]?.ingredient?.[0]?.value 数据错误:", dishs); return; } - this.getAnalysis(dishs?.[0]?.menu); + this.menuId = dishs?.[0]?.menu; + this.getAnalysis(); dishs.forEach((i: any) => { // 把每个食材按照不同的人群将重量加起来 @@ -109,9 +114,9 @@ export class DataVisComponent implements AfterViewInit { }); } - getAnalysis(menu: number) { + getAnalysis() { this.api - .getAnalysis(menu) + .getAnalysis(this.menuId, void 0, this.people) .pipe( finalize(() => { this.analysisLoading = false; @@ -119,9 +124,9 @@ export class DataVisComponent implements AfterViewInit { ) .subscribe((res) => { this.analysis = res.body; - setTimeout(() => { - this.autoScroll(this.nutritionEl.nativeElement, "2"); - }, 1000); + // setTimeout(() => { + // this.autoScroll(this.nutritionEl.nativeElement, "2"); + // }, 1000); }); } } diff --git a/projects/client/src/app/pages/dish/dish.component.html b/projects/client/src/app/pages/dish/dish.component.html index e1cda24..3febf4d 100644 --- a/projects/client/src/app/pages/dish/dish.component.html +++ b/projects/client/src/app/pages/dish/dish.component.html @@ -1,7 +1,7 @@
-
+
diff --git a/projects/client/src/app/pages/dish/dish.component.ts b/projects/client/src/app/pages/dish/dish.component.ts index 6395918..b9f29d5 100644 --- a/projects/client/src/app/pages/dish/dish.component.ts +++ b/projects/client/src/app/pages/dish/dish.component.ts @@ -151,11 +151,20 @@ export class DishComponent { this.msg.loading("数据请求中,请不要刷新页面", { nzDuration: 0, }); - this.api.getDishLabel(v.id).subscribe((res) => { - this.printData = res.body[0]; - this.printRef.print(); - this.msg.remove(); - }); + this.api + .getDishLabel(v.id) + .pipe( + finalize(() => { + setTimeout(() => { + this.msg.remove(); + }, 1000); + }) + ) + .subscribe((res) => { + this.printData = res.body[0]; + this.printRef.print(); + this.msg.remove(); + }); } showFoodForm(data?: any) { diff --git a/projects/client/src/app/pages/ingredients/ingredient-form/ingredient-form.component.html b/projects/client/src/app/pages/ingredients/ingredient-form/ingredient-form.component.html index 74bb5a1..5474dd9 100644 --- a/projects/client/src/app/pages/ingredients/ingredient-form/ingredient-form.component.html +++ b/projects/client/src/app/pages/ingredients/ingredient-form/ingredient-form.component.html @@ -19,7 +19,7 @@
- - + [nzBodyStyle]="{padding:'1px 0 0 0',flex:'1', 'overflow':'hidden'}"> +
+ +
+ +
diff --git a/projects/client/src/app/pages/system/user-manage/user-manage.component.ts b/projects/client/src/app/pages/system/user-manage/user-manage.component.ts index f45ed3d..4bfaa8d 100644 --- a/projects/client/src/app/pages/system/user-manage/user-manage.component.ts +++ b/projects/client/src/app/pages/system/user-manage/user-manage.component.ts @@ -30,7 +30,7 @@ export class ClientUserManageComponent { public roleForm = new FormGroup({ roleId: new FormControl(""), roleName: new FormControl("", [FormValidators.required("请输入角色名称")]), - items: new FormControl([]), + items: new FormControl(), }); public allPerms: PermItemDTO[] = []; diff --git a/projects/client/src/app/services/permisson.guard.ts b/projects/client/src/app/services/permisson.guard.ts new file mode 100644 index 0000000..658e612 --- /dev/null +++ b/projects/client/src/app/services/permisson.guard.ts @@ -0,0 +1,36 @@ +import { inject } from "@angular/core"; +import { + ActivatedRoute, + ActivatedRouteSnapshot, + CanActivateChildFn, + CanActivateFn, + Route, + Router, + RouterStateSnapshot, +} from "@angular/router"; +import { ClientAccountDTO } from "@cdk/dtos"; +import { ApiService } from "@cdk/services"; +import { NgxPermissionsService } from "ngx-permissions"; + +export const PermissionLoadGuard: CanActivateFn = async (route: ActivatedRouteSnapshot, state: RouterStateSnapshot) => { + const permissionsService = inject(NgxPermissionsService); + const api = inject(ApiService); + const auth = localStorage.getItem(api.accountKey); + + if (auth) { + try { + const authData = JSON.parse(auth) as ClientAccountDTO; + if (Array.isArray(authData.roleItems)) { + const permissionList = authData.roleItems; + const permissions = permissionList.reduce((a, c) => { + if (c.itemType === "业务端") { + return a.concat(String(c.id)); + } + return a; + }, [] as string[]); + permissionsService.loadPermissions(permissions); + } + } catch (error) {} + } + return true; +}; diff --git a/projects/client/src/favicon.ico b/projects/client/src/favicon.ico index 997406a..016b266 100644 Binary files a/projects/client/src/favicon.ico and b/projects/client/src/favicon.ico differ diff --git a/projects/client/src/index.html b/projects/client/src/index.html index 4e14dac..31373cf 100644 --- a/projects/client/src/index.html +++ b/projects/client/src/index.html @@ -1,5 +1,5 @@ - + diff --git a/projects/client/src/styles.less b/projects/client/src/styles.less index 34659f3..08cc723 100644 --- a/projects/client/src/styles.less +++ b/projects/client/src/styles.less @@ -113,4 +113,18 @@ li { border: 1px solid #000; font-weight: normal; } +} + +.analysis-drawer { + + .ant-drawer-header-title { + position: absolute; + right: 0; + top: 24px; + } + + .ant-drawer-body { + padding-top: 0; + } + } \ No newline at end of file