diff --git a/projects/admin/src/app/components/app-layout/app-layout.component.ts b/projects/admin/src/app/components/app-layout/app-layout.component.ts index 4b583fb..0687661 100644 --- a/projects/admin/src/app/components/app-layout/app-layout.component.ts +++ b/projects/admin/src/app/components/app-layout/app-layout.component.ts @@ -1,5 +1,5 @@ import { ApiService } from "@admin/app/services"; -import { Component } from "@angular/core"; +import { Component, OnInit } from "@angular/core"; import { NavigationEnd, Router, RouterModule } from "@angular/router"; import { NzMessageService } from "ng-zorro-antd/message"; @@ -11,7 +11,7 @@ import { Subject, filter, lastValueFrom, takeUntil } from "rxjs"; templateUrl: "./app-layout.component.html", styleUrls: ["./app-layout.component.less"], }) -export class AppLayoutComponent { +export class AppLayoutComponent implements OnInit { constructor( private router: Router, private modal: NzModalService, @@ -27,6 +27,7 @@ export class AppLayoutComponent { this.currentUrl = e.url; }); } + ngOnInit(): void {} unSubscribe$ = new Subject(); diff --git a/projects/admin/src/app/components/food-form/food-form.component.html b/projects/admin/src/app/components/food-form/food-form.component.html index 3800034..0392ebc 100644 --- a/projects/admin/src/app/components/food-form/food-form.component.html +++ b/projects/admin/src/app/components/food-form/food-form.component.html @@ -43,11 +43,17 @@
+ +
- +
diff --git a/projects/admin/src/app/components/food-form/food-form.component.ts b/projects/admin/src/app/components/food-form/food-form.component.ts index 4c52d46..a71f882 100644 --- a/projects/admin/src/app/components/food-form/food-form.component.ts +++ b/projects/admin/src/app/components/food-form/food-form.component.ts @@ -1,3 +1,4 @@ +import { ApiService } from "@admin/app/services"; import { Component, OnInit } from "@angular/core"; import { FormArray, FormBuilder, FormGroup } from "@angular/forms"; import { FormValidators } from "@cdk/validators"; @@ -8,10 +9,12 @@ import { FormValidators } from "@cdk/validators"; styleUrls: ["./food-form.component.less"], }) export class FoodFormComponent implements OnInit { - constructor(private fb: FormBuilder) {} + constructor(private fb: FormBuilder, private api: ApiService) {} formGroup!: FormGroup; + public globalEnum = this.api.globalEnum; + get nutrition(): FormArray { return this.formGroup.get("nutrition") as FormArray; } @@ -23,6 +26,14 @@ export class FoodFormComponent implements OnInit { type: this.fb.control("", [FormValidators.required()]), nutrition: this.fb.array([], [FormValidators.required()]), }); + this.api.getAllEnum().subscribe((r) => {}); + } + + nutritionChange(v: string, idx: number) { + const nutrient = this.globalEnum.nutrient.find((f) => f.key === v); + this.nutrition.at(idx).patchValue({ + measurement: nutrient?.measurement, + }); } createNutrition() { @@ -30,6 +41,7 @@ export class FoodFormComponent implements OnInit { this.fb.group({ nutritionName: this.fb.control("", [FormValidators.required()]), nutritionNum: this.fb.control(0, [FormValidators.required()]), + measurement: this.fb.control("", [FormValidators.required()]), }) ); } diff --git a/projects/admin/src/app/components/user-list/user-list.component.html b/projects/admin/src/app/components/user-list/user-list.component.html index 0f1fedd..652eb83 100644 --- a/projects/admin/src/app/components/user-list/user-list.component.html +++ b/projects/admin/src/app/components/user-list/user-list.component.html @@ -7,7 +7,7 @@ - + @@ -25,7 +25,7 @@
- + 账号 @@ -42,9 +42,9 @@ {{data.roleName}} {{data.time | date:'yyyy-MM-dd HH:mm:ss'}} - 编辑 + 编辑 - 删除 + 删除 diff --git a/projects/admin/src/app/components/user-list/user-list.component.ts b/projects/admin/src/app/components/user-list/user-list.component.ts index 4319668..d64c7a7 100644 --- a/projects/admin/src/app/components/user-list/user-list.component.ts +++ b/projects/admin/src/app/components/user-list/user-list.component.ts @@ -1,6 +1,16 @@ import { UserDTO, UserRoleDTO } from "@admin/app/dtos/user.dto"; import { ApiService } from "@admin/app/services"; -import { Component, Input, OnInit, TemplateRef, ViewChild } from "@angular/core"; +import { + Component, + EventEmitter, + Input, + OnChanges, + OnInit, + Output, + SimpleChanges, + TemplateRef, + ViewChild, +} from "@angular/core"; import { FormControl, FormGroup } from "@angular/forms"; import { ActivatedRoute } from "@angular/router"; import { AnyObject, FormValidators, TableListOption, Utils } from "@cdk/public-api"; @@ -14,7 +24,7 @@ import { lastValueFrom } from "rxjs"; templateUrl: "./user-list.component.html", styleUrls: ["./user-list.component.less"], }) -export class UserListComponent { +export class UserListComponent implements OnChanges { constructor( private api: ApiService, private route: ActivatedRoute, @@ -28,6 +38,12 @@ export class UserListComponent { @Input() role!: UserRoleDTO; + @Output() onReload = new EventEmitter(); + + searchValue = ""; + + visibledUsers: UserDTO[] = []; + public userFrom = new FormGroup({ uid: new FormControl("", [FormValidators.required("请输入账号")]), name: new FormControl("", [FormValidators.required("请输入姓名")]), @@ -36,22 +52,68 @@ export class UserListComponent { ngOnInit(): void {} - deleteItem() {} + ngOnChanges(changes: SimpleChanges): void { + const u = changes["users"]?.currentValue; + if (Array.isArray(u)) { + this.onSearch(this.searchValue); + } + } + + onSearch(kw: string) { + this.visibledUsers = this.users.filter((f) => f.name.includes(kw) || f.uid.includes(kw)); + } + + deleteItem(uid: string) { + this.modal.confirm({ + nzTitle: "警告", + nzContent: "是否要删除该用户?", + nzOkDanger: true, + nzOnOk: async () => { + const res = await lastValueFrom(this.api.deleteUser(uid)); + if (res.success) { + this.msg.success(res.desc); + this.onReload.emit(); + return true; + } + return false; + }, + }); + } + + resetUserForm() { + this.userFrom.reset(); + } openForm(item?: any) { + if (item) { + this.userFrom.patchValue(item); + } this.modal.create({ nzTitle: item ? "编辑用户" : "新增用户", nzContent: this.userFormTpl, + nzOnCancel: () => { + this.resetUserForm(); + }, nzOnOk: async () => { if (Utils.validateFormGroup(this.userFrom)) { const user = { ...this.userFrom.value, roleId: this.role.id }; user["password"] = MD5(user.password!).toString().substring(16).toUpperCase(); - // const check = await lastValueFrom(this.api.checkUid(user.uid!)); - // if (check.body) { - const res = await lastValueFrom(this.api.saveUser(user)); - this.msg.success(res.desc); - return true; - // } + let notExist = true; + if ((item && item.uid !== user.uid) || !item) { + const check = await lastValueFrom(this.api.checkUid(user.uid!)); + notExist = check.body; + } + + if (notExist) { + const res = await lastValueFrom(this.api.saveUser(user, Boolean(item))); + this.msg.success(res.desc); + this.onReload.emit(); + this.resetUserForm(); + return true; + } else { + this.msg.error("账号重复"); + return false; + } } return false; }, diff --git a/projects/admin/src/app/dtos/enum.dto.ts b/projects/admin/src/app/dtos/enum.dto.ts new file mode 100644 index 0000000..a9a8493 --- /dev/null +++ b/projects/admin/src/app/dtos/enum.dto.ts @@ -0,0 +1,20 @@ +export type GlobalEnum = { + category: CategoryDTO[]; + mark: MarkDTO[]; + nutrient: NutrientDTO[]; +}; + +export type CategoryDTO = { + key: string; + value: string; +}; +export type MarkDTO = { + key: string; + value: string; +}; +export type NutrientDTO = { + key: string; + value: string; + measurement: string; + nrv: number; +}; diff --git a/projects/admin/src/app/dtos/index.ts b/projects/admin/src/app/dtos/index.ts index c4be6d6..d8a4e8f 100644 --- a/projects/admin/src/app/dtos/index.ts +++ b/projects/admin/src/app/dtos/index.ts @@ -1,2 +1,3 @@ export * from "./org.dto"; export * from "./user.dto"; +export * from "./enum.dto"; diff --git a/projects/admin/src/app/pages/food/food.component.html b/projects/admin/src/app/pages/food/food.component.html index 6763960..bc22512 100644 --- a/projects/admin/src/app/pages/food/food.component.html +++ b/projects/admin/src/app/pages/food/food.component.html @@ -10,27 +10,18 @@
-
- +
+ diff --git a/projects/admin/src/app/pages/food/food.component.ts b/projects/admin/src/app/pages/food/food.component.ts index 03bd907..f52d6ee 100644 --- a/projects/admin/src/app/pages/food/food.component.ts +++ b/projects/admin/src/app/pages/food/food.component.ts @@ -1,4 +1,5 @@ import { FoodFormComponent } from "@admin/app/components"; +import { GlobalEnum } from "@admin/app/dtos"; import { ApiService } from "@admin/app/services"; import { Component, OnDestroy, OnInit, TemplateRef, ViewChild } from "@angular/core"; import { FormControl, FormGroup } from "@angular/forms"; @@ -23,6 +24,8 @@ export class FoodComponent implements OnInit, OnDestroy { selectable: true, }); + public globalEnum = this.api.globalEnum; + public queryForm = new FormGroup({ name: new FormControl(""), }); @@ -38,6 +41,7 @@ export class FoodComponent implements OnInit, OnDestroy { this.tableList.getState$.pipe(takeUntil(this.destroy$)).subscribe((res) => { this.selectedIds = res.selectedKeys as Array; }); + console.log("this.globalEnum", this.globalEnum); } ngOnDestroy(): void { diff --git a/projects/admin/src/app/pages/organization/organization-form/organization-form.component.ts b/projects/admin/src/app/pages/organization/organization-form/organization-form.component.ts index 0f18f2e..e20c2a9 100644 --- a/projects/admin/src/app/pages/organization/organization-form/organization-form.component.ts +++ b/projects/admin/src/app/pages/organization/organization-form/organization-form.component.ts @@ -22,11 +22,14 @@ export class OrganizationFormComponent { private router: Router, private route: ActivatedRoute ) { - const data = this.router.getCurrentNavigation()?.extras; - if (data) { - this.state = data.state; - } else { - this.router.navigate(["/organization/list"]); + const id = this.route.snapshot.paramMap.get("id"); + if (id !== "create") { + const data = this.router.getCurrentNavigation()?.extras; + if (data) { + this.state = data.state; + } else { + this.router.navigate(["/organization/list"]); + } } } @@ -53,26 +56,26 @@ export class OrganizationFormComponent { phone: this.fb.control("", []), email: this.fb.control("", []), }); - console.log("this.state", this.state); this.formGroup.patchValue(this.state); } async onSubmit() { if (Utils.validateFormGroup(this.formGroup)) { - const org = { ...this.formGroup.value }; + const org = { ...(this.state ?? {}), ...this.formGroup.value }; org["password"] = MD5(org.password!).toString().substring(16).toUpperCase(); org["expire"] = format(org["expire"], "yyyy-MM-dd"); - const account = await lastValueFrom(this.api.checkOrgAccount(org.account!)); - const name = await lastValueFrom(this.api.checkOrgName(org.name!)); + org["venderId"] = org.id; + // const account = await lastValueFrom(this.api.checkOrgAccount(org.account!)); + // const name = await lastValueFrom(this.api.checkOrgName(org.name!)); - if (!account.body) { - this.msg.error("账号重复"); - return; - } - if (!name.body) { - this.msg.error("单位名称重复"); - return; - } + // if (!account.body) { + // this.msg.error("账号重复"); + // return; + // } + // if (!name.body) { + // this.msg.error("单位名称重复"); + // return; + // } const res = await lastValueFrom(this.api.saveOrg(org)); this.msg.success(res.desc); @@ -84,25 +87,13 @@ export class OrganizationFormComponent { 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]; + this.formGroup.patchValue({ + icon: base64, + }); }; - 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); - // }); + fileReader.readAsDataURL(file); } } diff --git a/projects/admin/src/app/pages/organization/organization-list/organization-list.component.html b/projects/admin/src/app/pages/organization/organization-list/organization-list.component.html index ffb9d03..fb8f095 100644 --- a/projects/admin/src/app/pages/organization/organization-list/organization-list.component.html +++ b/projects/admin/src/app/pages/organization/organization-list/organization-list.component.html @@ -60,7 +60,7 @@ 编辑 - 删除 + 删除 diff --git a/projects/admin/src/app/pages/organization/organization-list/organization-list.component.ts b/projects/admin/src/app/pages/organization/organization-list/organization-list.component.ts index 3a768ce..e896e8d 100644 --- a/projects/admin/src/app/pages/organization/organization-list/organization-list.component.ts +++ b/projects/admin/src/app/pages/organization/organization-list/organization-list.component.ts @@ -6,6 +6,9 @@ import { DishFormComponent } from "@admin/app/components"; import { ApiService } from "@admin/app/services"; import { OrgDTO } from "@admin/app/dtos"; import { Router } from "@angular/router"; +import { NzModalService } from "ng-zorro-antd/modal"; +import { lastValueFrom } from "rxjs"; +import { NzMessageService } from "ng-zorro-antd/message"; @Component({ selector: "app-organization-list", @@ -13,14 +16,23 @@ import { Router } from "@angular/router"; styleUrls: ["./organization-list.component.less"], }) export class OrganizationListComponent { - constructor(private router: Router, private api: ApiService) {} + constructor( + private router: Router, + private api: ApiService, + private modal: NzModalService, + private msg: NzMessageService + ) {} originalOrgList: OrgDTO[] = []; + orgList: OrgDTO[] = []; ngOnInit(): void { + this.getList(); + } + + getList() { this.api.getOrgList().subscribe((res) => { - console.log("res", res); this.originalOrgList = res.body ?? []; this.orgList = this.originalOrgList; }); @@ -32,5 +44,21 @@ export class OrganizationListComponent { }); } - deleteItem() {} + deleteItem(id: number) { + this.modal.confirm({ + nzTitle: "警告", + nzContent: "是否要删除该单位?", + nzOkDanger: true, + nzOnOk: async () => { + const res = await lastValueFrom(this.api.deleteOrg(id)); + if (res.success) { + this.msg.success(res.desc); + this.originalOrgList = this.originalOrgList.filter((f) => f.id !== id); + this.orgList = this.orgList.filter((f) => f.id !== id); + return true; + } + return false; + }, + }); + } } diff --git a/projects/admin/src/app/pages/system/user-manage/user-manage.component.html b/projects/admin/src/app/pages/system/user-manage/user-manage.component.html index 7873a82..1cf3a7a 100644 --- a/projects/admin/src/app/pages/system/user-manage/user-manage.component.html +++ b/projects/admin/src/app/pages/system/user-manage/user-manage.component.html @@ -54,7 +54,8 @@ + [role]="role" + (onReload)="reloadUserList()"> { this.allPerms = res.body; }); + this.getRoleList(); + this.getUserList(); + } + + getUserList(reload?: boolean) { this.api.getUserList().subscribe((res) => { this.userList = res.body; + this.currentUserList = this.userList.filter((f) => Number(f.roleId) === Number(this.role!.id)); }); - this.getRoleList(); + } + + reloadUserList() { + this.getUserList(true); } getRoleList() { diff --git a/projects/admin/src/app/services/api.service.ts b/projects/admin/src/app/services/api.service.ts index 9d6a749..32f43ea 100644 --- a/projects/admin/src/app/services/api.service.ts +++ b/projects/admin/src/app/services/api.service.ts @@ -2,9 +2,9 @@ import { HttpClient, HttpParams } from "@angular/common/http"; import { Injectable } from "@angular/core"; import { AnyObject, ResponseType } from "@cdk/types"; import { Utils } from "@cdk/utils"; -import { map } from "rxjs"; +import { Observable, map, of, tap } from "rxjs"; import { PermItemDTO, UserDTO, UserRoleDTO } from "../dtos/user.dto"; -import { OrgDTO } from "../dtos"; +import { GlobalEnum, OrgDTO } from "../dtos"; @Injectable({ providedIn: "root", @@ -12,6 +12,8 @@ import { OrgDTO } from "../dtos"; export class ApiService { constructor(private http: HttpClient) {} + globalEnum!: GlobalEnum; + page(v: {}, q: {}) { return this.http.get("https://jsonplaceholder.typicode.com/users", v).pipe( map((r) => { @@ -23,6 +25,20 @@ export class ApiService { ); } + getAllEnum(force?: boolean): Observable { + if (this.globalEnum && !force) { + return of(this.globalEnum); + } + return this.http.get>("/api/basic/enum").pipe( + map((res) => { + return res.body; + }), + tap((r) => { + this.globalEnum = r; + }) + ); + } + login(v: {}) { const params = Utils.objectToHttpParams(v); return this.http.get("/api/login", { params }); @@ -64,12 +80,19 @@ export class ApiService { }); } - saveUser(user: AnyObject) { + saveUser(user: AnyObject, edit: boolean) { const body = Utils.objectToFormData(user); - const method = user["id"] ? "post" : "put"; + const method = edit ? "post" : "put"; return this.http[method]("/api/user", body); } + deleteUser(uid: string) { + const params = new HttpParams().set("uid", uid); + return this.http.delete("/api/user", { + params, + }); + } + getOrgList() { return this.http.get>("/api/vender"); } @@ -88,9 +111,20 @@ export class ApiService { }); } + deleteOrg(id: number) { + const params = new HttpParams().set("vender", id); + return this.http.delete("/api/vender", { + params, + }); + } + saveOrg(org: AnyObject) { const body = Utils.objectToFormData(org); const method = org["id"] ? "post" : "put"; return this.http[method]("/api/vender", body); } + + // getOrgConfig() { + // return this.http.get("/api/vender/config"); + // } } diff --git a/projects/admin/src/app/services/auth.guard.ts b/projects/admin/src/app/services/auth.guard.ts index fa0bc45..281fc37 100644 --- a/projects/admin/src/app/services/auth.guard.ts +++ b/projects/admin/src/app/services/auth.guard.ts @@ -1,17 +1,19 @@ import { inject } from "@angular/core"; import { Router } from "@angular/router"; import { map } from "rxjs"; +import { ApiService } from "./api.service"; const accountTokenName = "account"; export const authGuard = () => { const router = inject(Router); const token = localStorage.getItem(accountTokenName); + const api = inject(ApiService); if (!token) { router.navigate(["/login"]); return false; - } else { - return true; } + + return api.getAllEnum(); }; diff --git a/projects/admin/src/app/services/http.interceptor.ts b/projects/admin/src/app/services/http.interceptor.ts index 5c12c86..778c650 100644 --- a/projects/admin/src/app/services/http.interceptor.ts +++ b/projects/admin/src/app/services/http.interceptor.ts @@ -22,7 +22,6 @@ export class HTTPInterceptor implements HttpInterceptor { intercept(req: HttpRequest, next: HttpHandler): Observable> { const token = localStorage.getItem(this.localStroageKey); - console.log("req.body", req); if (token) { req = req.clone({ // headers: req.headers.set('Authorization', `Bearer ${token}`),