From 472495efa60ab26ed308729c14599baf23621011 Mon Sep 17 00:00:00 2001 From: kkerwin Date: Sat, 4 May 2024 00:29:54 +0800 Subject: [PATCH] =?UTF-8?q?=E8=B5=84=E4=BA=A7=E5=85=A5=E5=BA=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- web-admin-app/README.md | 6 + web-admin-app/src/app/app.config.ts | 2 - .../asset-category-select.component.html | 7 + .../asset-category-select.component.less | 0 .../asset-category-select.component.ts | 77 +++++ .../asset-form/asset-form.component.html | 263 ++++++++++++++++++ .../asset-form/asset-form.component.less | 4 + .../asset-form/asset-form.component.ts | 122 ++++++++ ...component-basic-category-tree.component.ts | 4 +- web-admin-app/src/app/components/index.ts | 6 + .../maintenance-select.component.html | 5 + .../maintenance-select.component.less | 0 .../maintenance-select.component.ts | 87 ++++++ .../manufacturer-select.component.html | 10 + .../manufacturer-select.component.less | 0 .../manufacturer-select.component.ts | 78 ++++++ .../org-select/org-select.component.html | 7 + .../org-select/org-select.component.less | 0 .../org-select/org-select.component.ts | 89 ++++++ .../position-select.component.html | 8 + .../position-select.component.less | 0 .../position-select.component.ts | 77 +++++ .../select-user-by-org.component.html | 55 ++-- .../select-user-by-org.component.less | 2 +- .../select-user-by-org.component.ts | 74 ++++- web-admin-app/src/app/constants/index.ts | 44 +++ .../fixed-asset/fixed-asset.component.html | 4 +- .../fixed-asset-manage.component.html | 163 ++++++++--- .../fixed-asset-manage.component.ts | 204 +++++++++++--- .../stockaking-job.component.html | 80 ++++-- .../stockaking-job.component.ts | 110 +++++++- web-admin-app/src/app/services/api.service.ts | 61 +++- .../query-item/query-item.component.less | 11 + .../server-paginated-table.component.ts | 8 +- web-admin-app/src/app/utils/index.ts | 55 ++++ web-admin-app/src/styles.less | 10 + 36 files changed, 1570 insertions(+), 163 deletions(-) create mode 100644 web-admin-app/src/app/components/asset-category-select/asset-category-select.component.html create mode 100644 web-admin-app/src/app/components/asset-category-select/asset-category-select.component.less create mode 100644 web-admin-app/src/app/components/asset-category-select/asset-category-select.component.ts create mode 100644 web-admin-app/src/app/components/asset-form/asset-form.component.html create mode 100644 web-admin-app/src/app/components/asset-form/asset-form.component.less create mode 100644 web-admin-app/src/app/components/asset-form/asset-form.component.ts create mode 100644 web-admin-app/src/app/components/maintenance-select/maintenance-select.component.html create mode 100644 web-admin-app/src/app/components/maintenance-select/maintenance-select.component.less create mode 100644 web-admin-app/src/app/components/maintenance-select/maintenance-select.component.ts create mode 100644 web-admin-app/src/app/components/manufacturer-select/manufacturer-select.component.html create mode 100644 web-admin-app/src/app/components/manufacturer-select/manufacturer-select.component.less create mode 100644 web-admin-app/src/app/components/manufacturer-select/manufacturer-select.component.ts create mode 100644 web-admin-app/src/app/components/org-select/org-select.component.html create mode 100644 web-admin-app/src/app/components/org-select/org-select.component.less create mode 100644 web-admin-app/src/app/components/org-select/org-select.component.ts create mode 100644 web-admin-app/src/app/components/position-select/position-select.component.html create mode 100644 web-admin-app/src/app/components/position-select/position-select.component.less create mode 100644 web-admin-app/src/app/components/position-select/position-select.component.ts create mode 100644 web-admin-app/src/app/constants/index.ts diff --git a/web-admin-app/README.md b/web-admin-app/README.md index e0da971..29c8e7b 100644 --- a/web-admin-app/README.md +++ b/web-admin-app/README.md @@ -29,3 +29,9 @@ -【基础数据】【物品档案】的接口是那个? +## 05-03 + +- 所有列表页分页total 最多10 条, pageSize & pageNum +- 【盘点计划】内容和盘点任务一样 ? +- 【资产】 财务分类 id 从哪里选择? + diff --git a/web-admin-app/src/app/app.config.ts b/web-admin-app/src/app/app.config.ts index 85254a7..20d8ed8 100644 --- a/web-admin-app/src/app/app.config.ts +++ b/web-admin-app/src/app/app.config.ts @@ -15,8 +15,6 @@ import { ServerPaginatedTableService } from './shared/components/server-paginate registerLocaleData(zh) -export const MaxPageSize = 10000000 - export function initializeApp(configService: ServerPaginatedTableService) { return () => { configService.initial() diff --git a/web-admin-app/src/app/components/asset-category-select/asset-category-select.component.html b/web-admin-app/src/app/components/asset-category-select/asset-category-select.component.html new file mode 100644 index 0000000..4a12fcd --- /dev/null +++ b/web-admin-app/src/app/components/asset-category-select/asset-category-select.component.html @@ -0,0 +1,7 @@ + + diff --git a/web-admin-app/src/app/components/asset-category-select/asset-category-select.component.less b/web-admin-app/src/app/components/asset-category-select/asset-category-select.component.less new file mode 100644 index 0000000..e69de29 diff --git a/web-admin-app/src/app/components/asset-category-select/asset-category-select.component.ts b/web-admin-app/src/app/components/asset-category-select/asset-category-select.component.ts new file mode 100644 index 0000000..4be9680 --- /dev/null +++ b/web-admin-app/src/app/components/asset-category-select/asset-category-select.component.ts @@ -0,0 +1,77 @@ +import { ChangeDetectorRef, Component, Input, OnInit, TemplateRef, ViewChild, forwardRef } from '@angular/core' +import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms' + +import { NzSafeAny } from 'ng-zorro-antd/core/types' + +import { NzModalService } from 'ng-zorro-antd/modal' + +import { ApiService } from 'app/services' +import { NzMessageService } from 'ng-zorro-antd/message' + +import { SharedModule } from 'app/shared/shared.module' +import { Utils } from 'app/utils' +import { NzFormatEmitEvent, NzTreeNode } from 'ng-zorro-antd/tree' +import { NzTreeSelectComponent } from 'ng-zorro-antd/tree-select' + +@Component({ + selector: 'app-asset-category-select', + standalone: true, + imports: [SharedModule], + templateUrl: './asset-category-select.component.html', + styleUrl: './asset-category-select.component.less', + providers: [ + { + provide: NG_VALUE_ACCESSOR, + multi: true, + useExisting: forwardRef(() => AssetCategorySelectComponent), + }, + ], +}) +export class AssetCategorySelectComponent implements ControlValueAccessor, OnInit { + constructor( + private modal: NzModalService, + private api: ApiService, + private msg: NzMessageService, + private cdr: ChangeDetectorRef, + ) {} + + @Input() placeholder: string = '请选择' + + @Input() modalTitle: string = '选择' + + @Input() radio: boolean = false + + @ViewChild('el') el!: NzTreeSelectComponent + + assetCategoryTree: NzSafeAny[] = [] + + originTreeData: NzSafeAny[] = [] + + value?: string + + ngOnInit(): void { + this.api.getBasicCategoryTree().subscribe((res) => { + this.originTreeData = res.body + this.assetCategoryTree = Utils.buildTree(this.originTreeData, 'categoryId', 'categoryName') + console.log('this.assetCategoryTree', this.originTreeData, this.assetCategoryTree) + }) + } + + onTouched = () => {} + + onChange(v: NzSafeAny[]) {} + + writeValue(v: NzSafeAny): void { + this.value = v + } + + registerOnChange(fn: any): void { + this.onChange = fn + } + + registerOnTouched(fn: any): void { + this.onTouched = fn + } + + setDisabledState?(isDisabled: boolean): void {} +} diff --git a/web-admin-app/src/app/components/asset-form/asset-form.component.html b/web-admin-app/src/app/components/asset-form/asset-form.component.html new file mode 100644 index 0000000..9c51f32 --- /dev/null +++ b/web-admin-app/src/app/components/asset-form/asset-form.component.html @@ -0,0 +1,263 @@ +
+
+ + + + + + + + + + @switch (groupIndex) { + @case (0) { + + } + @case (1) { + + } + @case (2) { + + } + } + +
+ + +
+
+ + 资产分类 + + + + +
+
+ + 资产名称 + + + + +
+ +
+ + 资产状态 + + + @for (item of ASSET_STATUS; track $index) { + + } + + + +
+
+ + 所属公司 + + + + +
+
+ + 使用组织 + + + + +
+
+ + 管理人员 + + + + + +
+
+ + 使用人员 + + + + +
+
+ + 资产来源 + + + @for (item of ASSET_SOURCE_MAP | keyvalue; track $index) { + + } + + + +
+
+ + 资产厂商 + + + + + +
+
+ + 序列号 + + + + +
+
+ + 规格型号 + + + + +
+
+ + 用途 + + + + +
+
+ + 存放位置 + + + + + +
+
+ + 详细位置 + + + + +
+
+ + 计量单位 + + + + +
+
+
+ +
+
+ + 维保厂商 + + + + +
+
+ + 联系人 + + + + +
+
+ + 联系方式 + + + + +
+
+ + 负责人 + + + + +
+
+ + 维保开始 + + + + +
+
+ + 维保到期 + + + + +
+
+ + 维保状态 + + + @for (item of MAINTENANCE_STATUS | keyvalue; track $index) { + + } + + + +
+
+ + 维保方式 + + + @for (item of MAINTENANCE_TYPE | keyvalue; track $index) { + + } + + + +
+
+ + 建议维保方式 + + + @for (item of MAINTENANCE_TYPE | keyvalue; track $index) { + + } + + + +
+
+ + 维保备注 + + + + +
+
+
+ 3 +
+ + + + diff --git a/web-admin-app/src/app/components/asset-form/asset-form.component.less b/web-admin-app/src/app/components/asset-form/asset-form.component.less new file mode 100644 index 0000000..b5ea3d1 --- /dev/null +++ b/web-admin-app/src/app/components/asset-form/asset-form.component.less @@ -0,0 +1,4 @@ +.asset-form { + height: 80vh; + overflow: auto; +} \ No newline at end of file diff --git a/web-admin-app/src/app/components/asset-form/asset-form.component.ts b/web-admin-app/src/app/components/asset-form/asset-form.component.ts new file mode 100644 index 0000000..7c32de1 --- /dev/null +++ b/web-admin-app/src/app/components/asset-form/asset-form.component.ts @@ -0,0 +1,122 @@ +import { Component, Input, OnInit, inject } from '@angular/core' +import { FormBuilder, FormGroup } from '@angular/forms' +import { ApiService } from 'app/services' +import { SharedModule } from 'app/shared/shared.module' +import { FormValidators, Utils } from 'app/utils' +import { NzMessageService } from 'ng-zorro-antd/message' +import { AssetCategorySelectComponent } from '../asset-category-select/asset-category-select.component' +import { OrgSelectComponent } from '../org-select/org-select.component' +import { ASSET_SOURCE_MAP, ASSET_STATUS, MAINTENANCE_STATUS, MAINTENANCE_TYPE } from 'app/constants' +import { SelectUserByOrgComponent } from '../select-user-by-org/select-user-by-org.component' +import { ManufacturerSelectComponent } from '../manufacturer-select/manufacturer-select.component' +import { PositionSelectComponent } from '../position-select/position-select.component' +import { MaintenanceSelectComponent } from '../maintenance-select/maintenance-select.component' +import { NzSafeAny } from 'ng-zorro-antd/core/types' +import { NZ_MODAL_DATA } from 'ng-zorro-antd/modal' + +@Component({ + selector: 'app-asset-form', + standalone: true, + imports: [ + SharedModule, + AssetCategorySelectComponent, + OrgSelectComponent, + SelectUserByOrgComponent, + ManufacturerSelectComponent, + PositionSelectComponent, + MaintenanceSelectComponent, + ], + templateUrl: './asset-form.component.html', + styleUrl: './asset-form.component.less', +}) +export class AssetFormComponent implements OnInit { + constructor( + private fb: FormBuilder, + private api: ApiService, + private msg: NzMessageService, + ) {} + + readonly data: NzSafeAny = inject(NZ_MODAL_DATA) + + formGroup!: FormGroup + + groupIndex = 0 + + ASSET_STATUS = ASSET_STATUS + + ASSET_SOURCE_MAP = ASSET_SOURCE_MAP + + MAINTENANCE_STATUS = MAINTENANCE_STATUS + + MAINTENANCE_TYPE = MAINTENANCE_TYPE + + ngOnInit(): void { + this.formGroup = this.fb.group({ + assetId: this.fb.control(null, []), + name: this.fb.control('', [FormValidators.required('请输入')]), + categoryId: this.fb.control(null, [FormValidators.required('请选择')]), + ownCompanyId: this.fb.control(null, [FormValidators.required('请选择')]), + status: this.fb.control(null, [FormValidators.required('请选择')]), + sourceId: this.fb.control(null, []), + unit: this.fb.control(null, []), + positionId: this.fb.control(null, []), + positionDetail: this.fb.control(null, []), + serialNumber: this.fb.control(null, []), + manufacturersVendorId: this.fb.control(null, []), + useUserId: this.fb.control(null, []), + useOrganizationId: this.fb.control(null, []), + manager: this.fb.control(null, []), + purpose: this.fb.control(null, []), + model: this.fb.control(null, []), + + maintenanceVendor: this.fb.control(null, []), + contactor: this.fb.control(null, []), + contact: this.fb.control(null, []), + responsiblePerson: this.fb.control(null, []), + maintenanceStartDate: this.fb.control(null, []), + maintenanceEndDate: this.fb.control(null, []), + maintenanceStatus: this.fb.control(null, []), + maintenanceType: this.fb.control(null, []), + suggestMaintenanceType: this.fb.control(null, []), + maintenanceNotes: this.fb.control(null, []), + }) + this.patchValues() + } + + patchValues() { + if (this.data) { + const data = this.data + this.formGroup.patchValue({ + ...data, + + useUserId: data._useUser?.userId ? [data._useUser?.userId] : [], + manager: data._manager?.userId ? [data._manager?.userId] : [], + responsiblePerson: data._responsiblePerson?.userId ? [data._responsiblePerson?.userId] : [], + categoryId: data._category?.categoryId + '', + positionId: data._position?.positionId + '', + ownCompanyId: data._ownCompany?.organizationId + '', + useOrganizationId: data._useOrganization?.organizationId + '', + maintenanceVendor: data._maintenanceVendor?.maintenanceVendorId, + manufacturersVendorId: data._manufacturersVendor?.manufacturersVendorId, + }) + } + } + + public getValues() { + let values = null + if (FormValidators.validateFormGroup(this.formGroup)) { + const v = this.formGroup.getRawValue() + values = { + ...v, + useUserId: v.useUserId?.[0], + manager: v.manager?.[0], + categoryId: v.categoryId?.[0], + ownCompanyId: v.ownCompanyId?.[0], + positionId: v.positionId?.[0], + useOrganizationId: v.useOrganizationId?.[0], + responsiblePerson: v.responsiblePerson?.[0], + } + } + return values + } +} diff --git a/web-admin-app/src/app/components/component-basic-category-tree/component-basic-category-tree.component.ts b/web-admin-app/src/app/components/component-basic-category-tree/component-basic-category-tree.component.ts index 7d233b9..8b85e82 100644 --- a/web-admin-app/src/app/components/component-basic-category-tree/component-basic-category-tree.component.ts +++ b/web-admin-app/src/app/components/component-basic-category-tree/component-basic-category-tree.component.ts @@ -19,7 +19,7 @@ interface CateGoryInterface { safetyLimit: number | null upperLimit: number | null } -function buildTree(organizations: CateGoryInterface[]): NzTreeNodeOptions[] { +export function buildCateTree(organizations: CateGoryInterface[]): NzTreeNodeOptions[] { const map: { [parentId: number]: NzTreeNodeOptions[] } = {} organizations.forEach((org) => { @@ -85,7 +85,7 @@ export class ComponentBasicCategoryTreeComponent { initTree() { this.api.getBasicCategoryTree().subscribe((res) => { - this.nodes = buildTree(res.body) + this.nodes = buildCateTree(res.body) this.expandedKeys = [...this.expandedKeys] console.log('this.selectedKeys', this.selectedKeys) if (this.selectedKeys.length === 0) { diff --git a/web-admin-app/src/app/components/index.ts b/web-admin-app/src/app/components/index.ts index 1d2e804..547c24b 100644 --- a/web-admin-app/src/app/components/index.ts +++ b/web-admin-app/src/app/components/index.ts @@ -1,3 +1,9 @@ export * from './component-org-tree/component-org-tree.component' export * from './component-basic-category-tree/component-basic-category-tree.component' export * from './select-user-by-org/select-user-by-org.component' +export * from './asset-form/asset-form.component' +export * from './asset-category-select/asset-category-select.component' +export * from './org-select/org-select.component' +export * from './manufacturer-select/manufacturer-select.component' +export * from './position-select/position-select.component' +export * from './maintenance-select/maintenance-select.component' diff --git a/web-admin-app/src/app/components/maintenance-select/maintenance-select.component.html b/web-admin-app/src/app/components/maintenance-select/maintenance-select.component.html new file mode 100644 index 0000000..e86026a --- /dev/null +++ b/web-admin-app/src/app/components/maintenance-select/maintenance-select.component.html @@ -0,0 +1,5 @@ + + @for (item of originData; track $index) { + + } + diff --git a/web-admin-app/src/app/components/maintenance-select/maintenance-select.component.less b/web-admin-app/src/app/components/maintenance-select/maintenance-select.component.less new file mode 100644 index 0000000..e69de29 diff --git a/web-admin-app/src/app/components/maintenance-select/maintenance-select.component.ts b/web-admin-app/src/app/components/maintenance-select/maintenance-select.component.ts new file mode 100644 index 0000000..92c7e97 --- /dev/null +++ b/web-admin-app/src/app/components/maintenance-select/maintenance-select.component.ts @@ -0,0 +1,87 @@ +import { + ChangeDetectorRef, + Component, + EventEmitter, + Input, + OnInit, + Output, + TemplateRef, + ViewChild, + forwardRef, +} from '@angular/core' +import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms' + +import { NzSafeAny } from 'ng-zorro-antd/core/types' + +import { NzModalService } from 'ng-zorro-antd/modal' + +import { ApiService } from 'app/services' +import { NzMessageService } from 'ng-zorro-antd/message' + +import { SharedModule } from 'app/shared/shared.module' +import { Utils } from 'app/utils' +import { NzFormatEmitEvent, NzTreeNode } from 'ng-zorro-antd/tree' +import { NzTreeSelectComponent } from 'ng-zorro-antd/tree-select' +import { MAX_PAGE_SIZE } from 'app/constants' + +@Component({ + selector: 'app-maintenance-select', + standalone: true, + imports: [SharedModule], + templateUrl: './maintenance-select.component.html', + styleUrl: './maintenance-select.component.less', + providers: [ + { + provide: NG_VALUE_ACCESSOR, + multi: true, + useExisting: forwardRef(() => MaintenanceSelectComponent), + }, + ], +}) +export class MaintenanceSelectComponent { + constructor(private api: ApiService) {} + + @Input() placeholder: string = '请选择' + + @Input() modalTitle: string = '选择' + + @Input() radio: boolean = false + + @Output() onSelected = new EventEmitter() + + @ViewChild('el') el!: NzTreeSelectComponent + + originData: NzSafeAny[] = [] + + value?: string + + ngOnInit(): void { + this.api.getBasicMaintenanceVendorPage({ pageSize: MAX_PAGE_SIZE, pageNum: 1 }).subscribe((res) => { + this.originData = res.body.rows + }) + } + + onModelChange(v: NzSafeAny) { + const item = this.originData.find((f) => f.maintenanceVendorId === v) + this.onSelected.emit(item) + this.onChange(v) + } + + onTouched = () => {} + + onChange(v: NzSafeAny[]) {} + + writeValue(v: NzSafeAny): void { + this.value = v + } + + registerOnChange(fn: any): void { + this.onChange = fn + } + + registerOnTouched(fn: any): void { + this.onTouched = fn + } + + setDisabledState?(isDisabled: boolean): void {} +} diff --git a/web-admin-app/src/app/components/manufacturer-select/manufacturer-select.component.html b/web-admin-app/src/app/components/manufacturer-select/manufacturer-select.component.html new file mode 100644 index 0000000..711d985 --- /dev/null +++ b/web-admin-app/src/app/components/manufacturer-select/manufacturer-select.component.html @@ -0,0 +1,10 @@ + + @for (item of originData; track $index) { + + } + diff --git a/web-admin-app/src/app/components/manufacturer-select/manufacturer-select.component.less b/web-admin-app/src/app/components/manufacturer-select/manufacturer-select.component.less new file mode 100644 index 0000000..e69de29 diff --git a/web-admin-app/src/app/components/manufacturer-select/manufacturer-select.component.ts b/web-admin-app/src/app/components/manufacturer-select/manufacturer-select.component.ts new file mode 100644 index 0000000..1035a0d --- /dev/null +++ b/web-admin-app/src/app/components/manufacturer-select/manufacturer-select.component.ts @@ -0,0 +1,78 @@ +import { ChangeDetectorRef, Component, Input, OnInit, TemplateRef, ViewChild, forwardRef } from '@angular/core' +import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms' + +import { NzSafeAny } from 'ng-zorro-antd/core/types' + +import { NzModalService } from 'ng-zorro-antd/modal' + +import { ApiService } from 'app/services' +import { NzMessageService } from 'ng-zorro-antd/message' + +import { SharedModule } from 'app/shared/shared.module' +import { Utils } from 'app/utils' +import { NzFormatEmitEvent, NzTreeNode } from 'ng-zorro-antd/tree' +import { NzTreeSelectComponent } from 'ng-zorro-antd/tree-select' +import { MAX_PAGE_SIZE } from 'app/constants' + +@Component({ + selector: 'app-manufacturer-select', + standalone: true, + imports: [SharedModule], + templateUrl: './manufacturer-select.component.html', + styleUrl: './manufacturer-select.component.less', + providers: [ + { + provide: NG_VALUE_ACCESSOR, + multi: true, + useExisting: forwardRef(() => ManufacturerSelectComponent), + }, + ], +}) +export class ManufacturerSelectComponent { + constructor( + private modal: NzModalService, + private api: ApiService, + private msg: NzMessageService, + private cdr: ChangeDetectorRef, + ) {} + + @Input() placeholder: string = '请选择' + + @Input() modalTitle: string = '选择' + + @Input() radio: boolean = false + + @ViewChild('el') el!: NzTreeSelectComponent + + originData: NzSafeAny[] = [] + + value?: string + + ngOnInit(): void { + this.api.getBasicManufacturersVendorPage({ pageSize: MAX_PAGE_SIZE, pageNum: 1 }).subscribe((res) => { + this.originData = res.body.rows + }) + } + + onModelChange(v: NzSafeAny) { + this.onChange(v) + } + + onTouched = () => {} + + onChange(v: NzSafeAny[]) {} + + writeValue(v: NzSafeAny): void { + this.value = v + } + + registerOnChange(fn: any): void { + this.onChange = fn + } + + registerOnTouched(fn: any): void { + this.onTouched = fn + } + + setDisabledState?(isDisabled: boolean): void {} +} diff --git a/web-admin-app/src/app/components/org-select/org-select.component.html b/web-admin-app/src/app/components/org-select/org-select.component.html new file mode 100644 index 0000000..a209e8a --- /dev/null +++ b/web-admin-app/src/app/components/org-select/org-select.component.html @@ -0,0 +1,7 @@ + + diff --git a/web-admin-app/src/app/components/org-select/org-select.component.less b/web-admin-app/src/app/components/org-select/org-select.component.less new file mode 100644 index 0000000..e69de29 diff --git a/web-admin-app/src/app/components/org-select/org-select.component.ts b/web-admin-app/src/app/components/org-select/org-select.component.ts new file mode 100644 index 0000000..c21851d --- /dev/null +++ b/web-admin-app/src/app/components/org-select/org-select.component.ts @@ -0,0 +1,89 @@ +import { ChangeDetectorRef, Component, Input, OnInit, TemplateRef, ViewChild, forwardRef } from '@angular/core' +import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms' + +import { NzSafeAny } from 'ng-zorro-antd/core/types' + +import { NzModalService } from 'ng-zorro-antd/modal' + +import { ApiService } from 'app/services' +import { NzMessageService } from 'ng-zorro-antd/message' + +import { SharedModule } from 'app/shared/shared.module' +import { Utils } from 'app/utils' +import { NzFormatEmitEvent, NzTreeNode } from 'ng-zorro-antd/tree' +import { NzTreeSelectComponent } from 'ng-zorro-antd/tree-select' + +@Component({ + selector: 'app-org-select', + standalone: true, + imports: [SharedModule], + templateUrl: './org-select.component.html', + styleUrl: './org-select.component.less', + providers: [ + { + provide: NG_VALUE_ACCESSOR, + multi: true, + useExisting: forwardRef(() => OrgSelectComponent), + }, + ], +}) +export class OrgSelectComponent implements ControlValueAccessor, OnInit { + constructor( + private modal: NzModalService, + private api: ApiService, + private msg: NzMessageService, + private cdr: ChangeDetectorRef, + ) {} + + @Input() placeholder: string = '请选择' + + @Input() company: boolean = false + + originTreeData: NzSafeAny[] = [] + + orgTree: NzSafeAny[] = [] + + value?: string + + ngOnInit(): void { + this.api.getOrgTree().subscribe((res) => { + this.originTreeData = res.body + + const c: NzSafeAny[] = [] + res.body.forEach((i: NzSafeAny) => { + if (this.company) { + if (i.organizationType === '0') { + c.push(i) + } + } else { + if (['1', '0'].includes(i.organizationType)) { + c.push(i) + } + } + }) + this.orgTree = Utils.buildTree(c, 'organizationId', 'organizationName') + }) + } + + onSelect(e: NzFormatEmitEvent) { + // this.onChange(e.keys ?? []) + } + + onTouched = () => {} + + onChange(v: NzSafeAny[]) {} + + writeValue(v: NzSafeAny): void { + this.value = v + } + + registerOnChange(fn: any): void { + this.onChange = fn + } + + registerOnTouched(fn: any): void { + this.onTouched = fn + } + + setDisabledState?(isDisabled: boolean): void {} +} diff --git a/web-admin-app/src/app/components/position-select/position-select.component.html b/web-admin-app/src/app/components/position-select/position-select.component.html new file mode 100644 index 0000000..0c40dff --- /dev/null +++ b/web-admin-app/src/app/components/position-select/position-select.component.html @@ -0,0 +1,8 @@ + + diff --git a/web-admin-app/src/app/components/position-select/position-select.component.less b/web-admin-app/src/app/components/position-select/position-select.component.less new file mode 100644 index 0000000..e69de29 diff --git a/web-admin-app/src/app/components/position-select/position-select.component.ts b/web-admin-app/src/app/components/position-select/position-select.component.ts new file mode 100644 index 0000000..79a8a5a --- /dev/null +++ b/web-admin-app/src/app/components/position-select/position-select.component.ts @@ -0,0 +1,77 @@ +import { ChangeDetectorRef, Component, Input, OnInit, TemplateRef, ViewChild, forwardRef } from '@angular/core' +import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms' + +import { NzSafeAny } from 'ng-zorro-antd/core/types' + +import { NzModalService } from 'ng-zorro-antd/modal' + +import { ApiService } from 'app/services' +import { NzMessageService } from 'ng-zorro-antd/message' + +import { SharedModule } from 'app/shared/shared.module' +import { Utils } from 'app/utils' +import { NzFormatEmitEvent, NzTreeNode } from 'ng-zorro-antd/tree' +import { NzTreeSelectComponent } from 'ng-zorro-antd/tree-select' +import { MAX_PAGE_SIZE } from 'app/constants' + +@Component({ + selector: 'app-position-select', + standalone: true, + imports: [SharedModule], + templateUrl: './position-select.component.html', + styleUrl: './position-select.component.less', + providers: [ + { + provide: NG_VALUE_ACCESSOR, + multi: true, + useExisting: forwardRef(() => PositionSelectComponent), + }, + ], +}) +export class PositionSelectComponent { + constructor( + private modal: NzModalService, + private api: ApiService, + private msg: NzMessageService, + private cdr: ChangeDetectorRef, + ) {} + + @Input() placeholder: string = '请选择' + + @Input() modalTitle: string = '选择' + + @Input() radio: boolean = false + + @ViewChild('el') el!: NzTreeSelectComponent + + originData: NzSafeAny[] = [] + + positionTree: NzSafeAny[] = [] + + value?: string + + ngOnInit(): void { + this.api.getBasicPositionTree().subscribe((res) => { + this.originData = res.body + this.positionTree = Utils.buildTree(res.body, 'positionId', 'name') + }) + } + + onTouched = () => {} + + onChange(v: NzSafeAny[]) {} + + writeValue(v: NzSafeAny): void { + this.value = v + } + + registerOnChange(fn: any): void { + this.onChange = fn + } + + registerOnTouched(fn: any): void { + this.onTouched = fn + } + + setDisabledState?(isDisabled: boolean): void {} +} diff --git a/web-admin-app/src/app/components/select-user-by-org/select-user-by-org.component.html b/web-admin-app/src/app/components/select-user-by-org/select-user-by-org.component.html index b215a75..b34ef98 100644 --- a/web-admin-app/src/app/components/select-user-by-org/select-user-by-org.component.html +++ b/web-admin-app/src/app/components/select-user-by-org/select-user-by-org.component.html @@ -1,30 +1,29 @@ -
+ -
- +
+ @for (uid of tempSelectedKeys; track $index) { + + {{ allGetedDataMap.get(uid)?.userName ?? '-' }} + + }
@@ -42,14 +41,18 @@
- 全选 - + @if (radio) { + 选择 + } @else { + 全选 + + }
    @@ -60,7 +63,7 @@ nz-checkbox (nzCheckedChange)="onUserCheckedChange($event, item.userId)" [nzValue]="item.userId" - [nzChecked]="selectedKeys.has(item.userId)" + [nzChecked]="tempSelectedKeys.has(item.userId)" > diff --git a/web-admin-app/src/app/components/select-user-by-org/select-user-by-org.component.less b/web-admin-app/src/app/components/select-user-by-org/select-user-by-org.component.less index 0ad5565..57a8272 100644 --- a/web-admin-app/src/app/components/select-user-by-org/select-user-by-org.component.less +++ b/web-admin-app/src/app/components/select-user-by-org/select-user-by-org.component.less @@ -1,4 +1,4 @@ -.trigger { +.temp { border: 1px dashed #e0e0e0; } diff --git a/web-admin-app/src/app/components/select-user-by-org/select-user-by-org.component.ts b/web-admin-app/src/app/components/select-user-by-org/select-user-by-org.component.ts index 12e1680..58b991a 100644 --- a/web-admin-app/src/app/components/select-user-by-org/select-user-by-org.component.ts +++ b/web-admin-app/src/app/components/select-user-by-org/select-user-by-org.component.ts @@ -1,5 +1,5 @@ import { CommonModule } from '@angular/common' -import { Component, Input, OnInit, TemplateRef, forwardRef } from '@angular/core' +import { ChangeDetectorRef, Component, Input, OnInit, TemplateRef, forwardRef } from '@angular/core' import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms' import { NzCardModule } from 'ng-zorro-antd/card' import { NzSafeAny } from 'ng-zorro-antd/core/types' @@ -11,7 +11,7 @@ import { NzButtonModule } from 'ng-zorro-antd/button' import { NzCheckboxModule } from 'ng-zorro-antd/checkbox' import { ApiService } from 'app/services' import { NzMessageModule, NzMessageService } from 'ng-zorro-antd/message' -import { MaxPageSize } from 'app/app.config' +import { MAX_PAGE_SIZE } from 'app/constants' import { NzTagModule } from 'ng-zorro-antd/tag' @Component({ @@ -44,16 +44,23 @@ export class SelectUserByOrgComponent implements ControlValueAccessor, OnInit { private modal: NzModalService, private api: ApiService, private msg: NzMessageService, + private cdr: ChangeDetectorRef, ) {} @Input() placeholder: string = '请选择' @Input() modalTitle: string = '选择' + @Input() radio: boolean = true + + @Input() size: 'small' | 'default' = 'default' + allGetedDataMap = new Map() currentUsers: NzSafeAny[] = [] + tempSelectedKeys = new Set() + selectedKeys = new Set() indeterminate = false @@ -63,58 +70,95 @@ export class SelectUserByOrgComponent implements ControlValueAccessor, OnInit { ngOnInit(): void {} onTriggerClick(nzContent: TemplateRef) { + this.tempSelectedKeys = new Set([...this.selectedKeys]) this.modal.create({ nzTitle: this.modalTitle, nzContent, nzWidth: '660px', + nzOnOk: () => { + this.selectedKeys = new Set([...this.tempSelectedKeys]) + this.onChange(Array.from(this.selectedKeys)) + }, + nzOnCancel: () => { + this.tempSelectedKeys.clear() + }, }) } - onOrgSelectedChange(v: NzSafeAny) { + onOrgSelectedChange(v?: NzSafeAny, uid?: number) { this.api - .getUserPage({ pageSize: MaxPageSize, pageNum: 1, organizationId: v.organizationId }) + .getUserPage({ pageSize: MAX_PAGE_SIZE, pageNum: 1, userId: uid, organizationId: v?.organizationId }) .subscribe((res) => { if (Array.isArray(res.body?.rows) && res.body.rows.length > 0) { res.body.rows.forEach((element: NzSafeAny) => { this.currentUsers = res.body.rows this.allGetedDataMap.set(element.userId, element) + this.statusChange() + console.log('this.allGetedDataMap', this.allGetedDataMap) }) } }) } onUserCheckedChange(e: boolean, v: number) { - if (e) { - this.selectedKeys.add(v) + if (this.radio) { + this.tempSelectedKeys.clear() + if (e) { + this.tempSelectedKeys.add(v) + } } else { - this.selectedKeys.delete(v) + if (e) { + this.tempSelectedKeys.add(v) + } else { + this.tempSelectedKeys.delete(v) + } } this.statusChange() } statusChange() { - this.allChecked = this.selectedKeys.size === this.currentUsers.length - this.indeterminate = this.selectedKeys.size > 0 && this.selectedKeys.size < this.currentUsers.length + const currentSelected = this.currentUsers.filter((f) => this.tempSelectedKeys.has(f.userId)) + this.allChecked = currentSelected.length === this.currentUsers.length + + this.indeterminate = + this.currentUsers.length !== 0 && + currentSelected.length > 0 && + currentSelected.length < this.currentUsers.length } onAllCheckedChange(e: boolean) { if (e) { this.currentUsers.forEach((element) => { - this.selectedKeys.add(element.userId) + this.tempSelectedKeys.add(element.userId) }) } else { - this.selectedKeys.clear() + this.tempSelectedKeys.clear() } this.statusChange() } + getUserById(id: number) { + this.api.getUserDetail(id).subscribe((res) => { + this.allGetedDataMap.set(id, res.body) + }) + } + onTouched = () => {} - onChange(v: string[]) { - console.log('v', v) - } + onChange(v: NzSafeAny[]) {} - writeValue(v: any): void {} + writeValue(v: NzSafeAny[]): void { + // console.log('this.selectedKeys writeValue', v) + if (Array.isArray(v) && v.length > 0) { + this.tempSelectedKeys.clear() + this.selectedKeys.clear() + v.forEach((element) => { + this.getUserById(element) + this.selectedKeys.add(element) + this.tempSelectedKeys.add(element) + }) + } + } registerOnChange(fn: any): void { this.onChange = fn diff --git a/web-admin-app/src/app/constants/index.ts b/web-admin-app/src/app/constants/index.ts new file mode 100644 index 0000000..9fca6d1 --- /dev/null +++ b/web-admin-app/src/app/constants/index.ts @@ -0,0 +1,44 @@ +export const MAX_PAGE_SIZE = 10000000 + +export const ASSET_STATUS = [ + { label: '闲置', value: 0 }, + { label: '在用', value: 1 }, + { label: '借用中', value: 2 }, + { label: '维修中', value: 3 }, + { label: '调拨中', value: 4 }, + { label: '待报废', value: 5 }, + { label: '已处置', value: 6 }, + { label: '库存', value: 7 }, + { label: '已报废', value: 8 }, +] + +export const ASSET_STATUS_MAP = () => { + return ASSET_STATUS.reduce( + (map, item) => { + map[item.value] = item.label + return map + }, + {} as Record, + ) +} + +export const ASSET_SOURCE_MAP = new Map([ + [0, '捐赠'], + [1, '赠送'], + [2, '其他'], + [3, '采购'], + [4, '自建'], + [4, '自购'], +]) + +export const MAINTENANCE_STATUS = new Map([ + [0, '不需要'], + [1, '脱保'], + [2, '在保'], + [3, '未知'], +]) + +export const MAINTENANCE_TYPE = new Map([ + [0, '原厂'], + [1, '第三方'], +]) diff --git a/web-admin-app/src/app/pages/fixed-asset/fixed-asset.component.html b/web-admin-app/src/app/pages/fixed-asset/fixed-asset.component.html index b37b3a0..dfc0a92 100644 --- a/web-admin-app/src/app/pages/fixed-asset/fixed-asset.component.html +++ b/web-admin-app/src/app/pages/fixed-asset/fixed-asset.component.html @@ -101,10 +101,10 @@
    • - 盘点计划 + 盘点任务
    • - 盘点任务 + 盘点计划
  • diff --git a/web-admin-app/src/app/pages/fixed-asset/manage/fixed-asset-manage/fixed-asset-manage.component.html b/web-admin-app/src/app/pages/fixed-asset/manage/fixed-asset-manage/fixed-asset-manage.component.html index 91e9523..834e1f3 100644 --- a/web-admin-app/src/app/pages/fixed-asset/manage/fixed-asset-manage/fixed-asset-manage.component.html +++ b/web-admin-app/src/app/pages/fixed-asset/manage/fixed-asset-manage/fixed-asset-manage.component.html @@ -1,78 +1,124 @@ - + - + + - + + + + 文件 + + + + +
+
+ diff --git a/web-admin-app/src/app/pages/fixed-asset/manage/fixed-asset-manage/fixed-asset-manage.component.ts b/web-admin-app/src/app/pages/fixed-asset/manage/fixed-asset-manage/fixed-asset-manage.component.ts index 8ae9f18..5352dc4 100644 --- a/web-admin-app/src/app/pages/fixed-asset/manage/fixed-asset-manage/fixed-asset-manage.component.ts +++ b/web-admin-app/src/app/pages/fixed-asset/manage/fixed-asset-manage/fixed-asset-manage.component.ts @@ -1,85 +1,197 @@ -import { Component } from '@angular/core' +import { Component, TemplateRef, ViewChild } from '@angular/core' import { FormControl, FormGroup } from '@angular/forms' import { AnyObject, TableOption } from 'app/shared/components/server-paginated-table' import { ApiService } from 'app/services' import { SharedModule } from 'app/shared/shared.module' import { format } from 'date-fns' -import { of } from 'rxjs' +import { lastValueFrom, of } from 'rxjs' +import { AssetFormComponent, ManufacturerSelectComponent, PositionSelectComponent } from 'app/components' +import { NzModalRef, NzModalService } from 'ng-zorro-antd/modal' +import { NzMessageService } from 'ng-zorro-antd/message' +import { NzSafeAny } from 'ng-zorro-antd/core/types' +import { ASSET_SOURCE_MAP, ASSET_STATUS, ASSET_STATUS_MAP } from 'app/constants' +import { Utils } from 'app/utils' @Component({ selector: 'app-fixed-asset-manage', standalone: true, - imports: [SharedModule], + imports: [SharedModule, AssetFormComponent, PositionSelectComponent, ManufacturerSelectComponent], templateUrl: './fixed-asset-manage.component.html', styleUrl: './fixed-asset-manage.component.less', }) export class FixedAssetManageComponent { - constructor(private api: ApiService) {} + constructor( + private api: ApiService, + private modal: NzModalService, + private msg: NzMessageService, + ) {} queryForm = new FormGroup({ - name: new FormControl(''), - type: new FormControl(''), - status: new FormControl(''), - date: new FormControl(''), + name: new FormControl(), + model: new FormControl(), + status: new FormControl(), + assetCode: new FormControl(), + serialNumber: new FormControl(), + sourceId: new FormControl(), + positionId: new FormControl(), + manufacturersVendorId: new FormControl(), }) + @ViewChild('copyTpl') copyTpl!: TemplateRef + + ASSET_STATUS_MAP = ASSET_STATUS_MAP() + + ASSET_SOURCE_MAP = ASSET_SOURCE_MAP + table = new TableOption(this.fetchData.bind(this)) + copyNum = 1 + ngOnInit(): void { this.table .setConfig({ selectable: true, + rowKey: 'assetId', }) .setColumn([ - { key: '办理状态', title: '办理状态', visible: true }, - { key: '资产编号', title: '资产编号', visible: true }, - { key: '资产状态', title: '资产状态', visible: true }, - { key: '资产分类', title: '资产分类', visible: true }, - { key: '资产名称', title: '资产名称', visible: true }, - { key: '规格型号', title: '规格型号', visible: true }, - { key: '所属公司', title: '所属公司', visible: true }, - { key: '使用组织', title: '使用组织', visible: true }, - { key: '存放位置', title: '存放位置', visible: true }, + { key: 'assetCode', title: '资产编号', visible: true }, + { key: 'name', title: '资产名称', visible: true }, + { key: '_category', title: '资产分类', visible: true }, + { key: 'status', title: '资产状态', visible: true }, + { key: '_ownCompany', title: '所属公司', visible: true }, + { key: '_useOrganization', title: '使用组织', visible: true }, + { key: '_position', title: '存放位置', visible: true }, ]) .setRowOperate([ - { title: '查看', premissions: [] }, - { title: '修改' }, - { title: '复制' }, - { title: '密文箱' }, + { title: '查看' }, + { title: '修改', onClick: this.onCreate.bind(this) }, + { title: '复制', onClick: this.onCopy.bind(this) }, { title: '折旧记录' }, - { title: '二维码' }, + { title: '二维码', onClick: this.qrcode.bind(this) }, { title: '操作明细' }, - { title: '删除' }, + { title: '删除', onClick: this.deleteItem.bind(this) }, ]) } fetchData(p: {}, q: AnyObject) { - if (Array.isArray(q['createTime'])) { - const createTimeStart = q['createTime']?.[0] - const createTimeEnd = q['createTime']?.[1] + return this.api.getAssetPage({ ...p, ...q }) + } - q['createTimeStart'] = createTimeStart ? format(new Date(createTimeStart), 'yyyy-MM-dd HH:mm:ss') : '' - q['createTimeEnd'] = createTimeEnd ? format(new Date(createTimeEnd), 'yyyy-MM-dd HH:mm:ss') : '' - } - return of({ - data: { - total: 5, - records: [ - { - id: 1, - name: '沙滩', - price: 590, - type: 0, - lifespan: 6, - number: 20, - max: 20, - status: 1, - createTime: '2024-05-01', - }, - ], + onCopy(data: NzSafeAny) { + this.modal.create({ + nzTitle: '复制资产', + nzWidth: 600, + nzContent: this.copyTpl, + nzOnOk: async () => { + if (!this.copyNum) { + this.msg.error('请输入复制数量') + return false + } + const res = await lastValueFrom(this.api.copyAsset(this.copyNum, data.assetId)) + this.msg.success(res.desc) + this.table.ref.reload() + return true + }, + }) + } + + onCreate(data?: NzSafeAny) { + this.modal.create({ + nzTitle: data ? '编辑资产' : '添加资产', + nzContent: AssetFormComponent, + nzWidth: '80vw', + nzWrapClassName: 'modal-lg', + nzData: data, + nzOnOk: async (e) => { + const vals = e.getValues() + if (vals) { + const res = await lastValueFrom(this.api.saveAsset(vals)) + this.msg.success(res.desc) + this.table.ref.reload() + return true + } + + return false + }, + }) + } + + deleteItem(item?: NzSafeAny) { + const ids = item ? [item.assetId] : Array.from(this.table.ref.selected) + this.modal.confirm({ + nzTitle: '警告', + nzContent: `是否要删除${ids.length}个资产?`, + nzOnOk: async () => { + const res = await lastValueFrom(this.api.deleteAsset(ids)) + this.msg.success(res.desc) + this.table.ref.reload() + }, + }) + } + + confirmAsset() { + const ids = Array.from(this.table.ref.selected).map((i) => Number(i)) + this.modal.confirm({ + nzTitle: '警告', + nzContent: `是否对选择的${ids.length}个资产进行确认?`, + nzOnOk: async () => { + const res = await lastValueFrom(this.api.confirmAsset(ids)) + this.msg.success(res.desc) + this.table.ref.reload() }, }) - return this.api.getEntityPage(p, q) + } + + qrcode(d: NzSafeAny) { + this.msg.loading('二维码生成中...') + this.api.assetQrcode(d.assetId).subscribe((res) => { + Utils.downLoadFile(res, 'application/pdf') + this.msg.remove() + this.msg.success('二维码生成成功') + }) + } + + downloadTemplate() { + this.msg.loading('模板下载中...') + this.api.downloadAssetTemplate().subscribe((res) => { + Utils.downLoadFile(res, 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8') + this.msg.remove() + this.msg.success('模板下载成功') + }) + } + + importModalRef?: NzModalRef + importExcel(nzContent: TemplateRef<{}>) { + this.importModalRef = this.modal.create({ + nzTitle: '资产数据导入', + nzContent, + nzFooter: null, + }) + } + + onFileChange(e: Event) { + const target = e.target as HTMLInputElement + const file = target.files![0] + target.value = '' + const formdata = new FormData() + formdata.append('file', file) + this.api.uploadAsset(formdata).subscribe((res) => { + this.importModalRef?.close() + this.msg.success(res.desc) + this.table.ref.reload() + }) + } + exportExcel() { + const ids = Array.from(this.table.ref.selected).map((i) => Number(i)) + if (ids.length === 0) { + return + } + this.msg.loading('Excel生成中...') + this.api.exportAsset(ids).subscribe((res) => { + Utils.downLoadFile(res, 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8') + this.msg.remove() + this.msg.success('Excel生成成功') + }) } } diff --git a/web-admin-app/src/app/pages/fixed-asset/stocktaking/stockaking-job/stockaking-job.component.html b/web-admin-app/src/app/pages/fixed-asset/stocktaking/stockaking-job/stockaking-job.component.html index 8c07129..5de3863 100644 --- a/web-admin-app/src/app/pages/fixed-asset/stocktaking/stockaking-job/stockaking-job.component.html +++ b/web-admin-app/src/app/pages/fixed-asset/stocktaking/stockaking-job/stockaking-job.component.html @@ -40,7 +40,30 @@ } } } - + @case ('_stocktakingUser') { + {{ data?.userName ?? '-' }} + } + @case ('_useUser') { + {{ data?.userName ?? '-' }} + } + @case ('_warehouse') { + {{ data?.name ?? '-' }} + } + @case ('_position') { + {{ data?.name ?? '-' }} + } + @case ('_head') { + {{ data?.userName ?? '-' }} + } + @case ('_ownCompany') { + {{ data?.organizationName ?? '-' }} + } + @case ('_useOrganization') { + {{ data?.organizationName ?? '-' }} + } + @case ('_category') { + {{ data?.categoryName ?? '-' }} + } @default { {{ data }} } @@ -63,11 +86,23 @@ - - + + - - + + + + + + + @@ -101,12 +136,14 @@ 负责人 - + 盘点人 - + + + @@ -120,55 +157,66 @@ 购置开始日期 - + 购置结束日期 - + 资产分类 - + 资产状态 - + + @for (item of ASSET_STATUS; track $index) { + + } + 位置 - + + 仓库 - + + @for (item of warehouse; track $index) { + + } + 所属公司 - + + 使用公司/部门 - + + 保管人 - + diff --git a/web-admin-app/src/app/pages/fixed-asset/stocktaking/stockaking-job/stockaking-job.component.ts b/web-admin-app/src/app/pages/fixed-asset/stocktaking/stockaking-job/stockaking-job.component.ts index df8e92d..6bb98aa 100644 --- a/web-admin-app/src/app/pages/fixed-asset/stocktaking/stockaking-job/stockaking-job.component.ts +++ b/web-admin-app/src/app/pages/fixed-asset/stocktaking/stockaking-job/stockaking-job.component.ts @@ -8,8 +8,9 @@ import { NzModalService } from 'ng-zorro-antd/modal' import { NzMessageService } from 'ng-zorro-antd/message' import { NzDrawerRef, NzDrawerService } from 'ng-zorro-antd/drawer' import { lastValueFrom } from 'rxjs' -import { FormValidators } from 'app/utils' -import { SelectUserByOrgComponent } from 'app/components' +import { FormValidators, Utils } from 'app/utils' +import { SelectUserByOrgComponent, buildCateTree } from 'app/components' +import { ASSET_STATUS, MAX_PAGE_SIZE } from 'app/constants' @Component({ selector: 'app-stockaking-job', @@ -39,21 +40,42 @@ export class StockakingJobComponent { @ViewChild('formContentTpl') formContentTpl!: TemplateRef + ASSET_STATUS = ASSET_STATUS + + assetCategoryTree: NzSafeAny[] = [] + + positionTree: NzSafeAny[] = [] + + warehouse: NzSafeAny[] = [] + + companyTree: NzSafeAny[] = [] + + orgTree: NzSafeAny[] = [] + initCreateForm() { this.createForm = this.fb.group({ stocktakingJobId: [], name: ['', [FormValidators.required('请输入')]], notes: ['', []], + stocktakingUserId: [[], []], + head: [[], []], fullStocktaking: [1, []], stocktakingStartDate: [null, []], stocktakingEndDate: [null, []], + categoryId: [null, []], + warehouseId: [null, []], + positionId: [null, []], + ownCompanyId: [null, []], + useOrganizationId: [null, []], + useUserId: [null, []], + assetStatus: [0, []], }) } initQueryForm() { this.queryForm = this.fb.group({ - name: [''], - uscc: [''], - code: [''], + name: [], + status: [], + notes: [], }) } @@ -67,21 +89,61 @@ export class StockakingJobComponent { { key: 'name', title: '名称' }, { key: 'fullStocktaking', title: '全员盘点' }, { key: 'status', title: '盘点状态' }, - { key: 'head', title: '负责人' }, - { key: 'stocktakingUserId', title: '盘点人' }, + { key: '_head', title: '负责人', width: '150px' }, + { key: '_stocktakingUser', title: '盘点人', width: '150px' }, + { key: 'countPending', title: '待盘点', width: '100px' }, + { key: 'countCompleted', title: '已盘点', width: '100px' }, + { key: 'countLoss', title: '盘亏', width: '100px' }, + { key: 'countSurplus', title: '盘盈', width: '100px' }, + { key: 'countException', title: '异常数据', width: '100px' }, + { key: '_category', title: '资产分类' }, + { key: '_ownCompany', title: '所属公司' }, + { key: '_useOrganization', title: '使用公司/部门' }, + { key: '_useUser', title: '保管人', width: '150px' }, + { key: '_warehouse', title: '仓库' }, + { key: '_position', title: '存放位置' }, { key: 'stocktakingStartDate', title: '购置开始日期', width: '180px' }, { key: 'stocktakingEndDate', title: '购置结束日期', width: '180px' }, { key: 'createTime', title: '创建时间', width: '180px' }, - { key: 'createUser', title: '创建人' }, + { key: 'createUser', title: '创建人', width: '150px' }, { key: 'notes', title: '备注' }, ]) .setRowOperate([ - { title: '编辑', onClick: this.onCreate.bind(this) }, + { title: '明细', onClick: this.onCreate.bind(this) }, + // { title: '详情', onClick: this.onDetail.bind(this) }, { title: '编辑', onClick: this.onCreate.bind(this) }, { title: '删除', onClick: this.deleteItem.bind(this) }, ]) this.initQueryForm() this.initCreateForm() + this.api.getBasicCategoryTree().subscribe((res) => { + this.assetCategoryTree = Utils.buildTree(res.body, 'categoryId', 'categoryName') + }) + this.api.getBasicPositionTree().subscribe((res) => { + this.positionTree = Utils.buildTree(res.body, 'positionId', 'name') + }) + this.api.getBasicWarehousePage({ pageSize: MAX_PAGE_SIZE, pageNum: 1 }).subscribe((r) => { + this.warehouse = r.body.rows.map((i: NzSafeAny) => { + return { + label: i.name, + value: i.warehouseId, + } + }) + }) + this.api.getOrgTree().subscribe((res) => { + const c: NzSafeAny[] = [] + const o: NzSafeAny[] = [] + res.body.forEach((i: NzSafeAny) => { + if (i.organizationType === '0') { + c.push(i) + } + if (['1', '0'].includes(i.organizationType)) { + o.push(i) + } + }) + this.orgTree = Utils.buildTree(o, 'organizationId', 'organizationName') + this.companyTree = Utils.buildTree(c, 'organizationId', 'organizationName') + }) } fetchData(p: {}, q: AnyObject) { @@ -90,7 +152,17 @@ export class StockakingJobComponent { onCreate(data?: NzSafeAny) { if (data) { - this.createForm.patchValue(data) + this.createForm.patchValue({ + ...data, + stocktakingUserId: data._stocktakingUser?.userId ? [data._stocktakingUser?.userId] : [], + head: data._head?.userId ? [data._head?.userId] : [], + useUserId: data._useUser?.userId ? [data._useUser?.userId] : [], + categoryId: data._category?.categoryId + '', + positionId: data._position?.positionId + '', + ownCompanyId: data._ownCompany?.organizationId + '', + useOrganizationId: data._useOrganization?.organizationId + '', + warehouseId: data._warehouse?.warehouseId, + }) } this.drawerRef = this.drawer.create({ nzTitle: data ? '编辑盘点任务' : '新增盘点任务', @@ -100,6 +172,15 @@ export class StockakingJobComponent { nzOnCancel: this.onCancel.bind(this), }) } + onDetail(data: NzSafeAny) { + this.drawerRef = this.drawer.create({ + nzTitle: data ? '编辑盘点任务' : '新增盘点任务', + nzContent: this.formContentTpl, + nzFooter: this.drawerFooterTpl, + nzWidth: 600, + nzOnCancel: this.onCancel.bind(this), + }) + } onConfirm() { if (FormValidators.validateFormGroup(this.createForm)) { @@ -108,8 +189,9 @@ export class StockakingJobComponent { this.api .saveStocktakingJob({ ...value, - - // stocktakingJobId: value.stocktakingJobId ?? 0, + stocktakingUserId: value.stocktakingUserId?.[0], + head: value.head?.[0], + useUserId: value.useUserId?.[0], }) .subscribe((res) => { this.msg.success(res.desc) @@ -121,7 +203,9 @@ export class StockakingJobComponent { async onCancel() { this.drawerRef?.close() - this.createForm.reset({}) + this.createForm.reset({ + fullStocktaking: 1, + }) } deleteItem(item: NzSafeAny) { diff --git a/web-admin-app/src/app/services/api.service.ts b/web-admin-app/src/app/services/api.service.ts index dee21c5..87b364b 100644 --- a/web-admin-app/src/app/services/api.service.ts +++ b/web-admin-app/src/app/services/api.service.ts @@ -89,6 +89,9 @@ export class ApiService { getUserPage(data: {}) { return this.http.post('/api/umsUser/list', data) } + getUserDetail(id: number) { + return this.http.post(`/api/umsUser/query?userId=${id}`, null) + } deleteUser(ids: number[]) { return this.http.post(`/api/umsUser/delete`, ids) @@ -101,9 +104,52 @@ export class ApiService { return this.http.post('/api/umsUser/update', data) } + getAssetPage(data: {}) { + return this.http.post('/api/eamAsset/list', data) + } + copyAsset(num: number, id: number) { + return this.http.post(`/api/eamAsset/copyByNum?num=${num}&id=${id}`, null) + } + deleteAsset(ids: number[]) { + return this.http.post('/api/eamAsset/delete', ids) + } + uploadAsset(data: FormData) { + return this.http.post('/api/eamAsset/importData', data) + } + confirmAsset(ids: number[]) { + return this.http.post('/api/eamAsset/confirm', ids) + } + assetQrcode(id: number) { + return this.http.post(`/api/qr/generate?id=${id}`, null, { + observe: 'response', + responseType: 'blob' as 'json', + }) + } + downloadAssetTemplate() { + return this.http.post(`/api/eamAsset/importTemplate`, null, { + observe: 'response', + responseType: 'blob' as 'json', + }) + } + exportAsset(ids: number[]) { + return this.http.post(`/api/eamAsset/export`, ids, { + observe: 'response', + responseType: 'blob' as 'json', + }) + } + saveAsset(data: NzSafeAny) { + if (Utils.isEmpty(data.assetId)) { + return this.http.post('/api/eamAsset/add', data) + } + return this.http.post('/api/eamAsset/update', data) + } + getBasicPositionPage(data: {}) { return this.http.post('/api/eamBasicPosition/list', data) } + getBasicPositionTree() { + return this.http.post('/api/eamBasicPosition/tree', null) + } saveBasicPosition(data: NzSafeAny) { if (Utils.isEmpty(data.positionId)) { return this.http.post('/api/eamBasicPosition/add', data) @@ -166,8 +212,19 @@ export class ApiService { return this.http.post(`/api/eamBasicWarehouse/delete`, ids) } - getBasicCategoryTree() { - return this.http.post('/api/eamBasicCategory/tree', null) + categoryTree: NzSafeAny[] = [] + + getBasicCategoryTree(force?: boolean) { + if (this.categoryTree.length > 0 && !force) { + return of({ + body: this.categoryTree, + } as JwResponse) + } + return this.http.post('/api/eamBasicCategory/tree', null).pipe( + tap((res) => { + this.categoryTree = res.body + }), + ) } addBasicCategoryTree(data: {}) { return this.http.post('/api/eamBasicCategory/add', data) diff --git a/web-admin-app/src/app/shared/components/server-paginated-table/query-item/query-item.component.less b/web-admin-app/src/app/shared/components/server-paginated-table/query-item/query-item.component.less index 1241bfe..ca2d647 100644 --- a/web-admin-app/src/app/shared/components/server-paginated-table/query-item/query-item.component.less +++ b/web-admin-app/src/app/shared/components/server-paginated-table/query-item/query-item.component.less @@ -4,5 +4,16 @@ min-width: 100px; width: 100%; } + + nz-tree-select, + nz-select { + width: auto !important; + + } + + .ant-select:not(.ant-select-customize-input) .ant-select-selector { + border: none; + } + } } \ No newline at end of file diff --git a/web-admin-app/src/app/shared/components/server-paginated-table/server-paginated-table.component.ts b/web-admin-app/src/app/shared/components/server-paginated-table/server-paginated-table.component.ts index d634843..611029d 100644 --- a/web-admin-app/src/app/shared/components/server-paginated-table/server-paginated-table.component.ts +++ b/web-admin-app/src/app/shared/components/server-paginated-table/server-paginated-table.component.ts @@ -347,17 +347,21 @@ export class ServerPaginatedTableComponent implements OnInit, OnChanges { } else { this.selected.clear() } + this.onSelectChange() } onRowSelected(selected: boolean, row: any) { const id = String(row[this.options.config.rowKey!]) - console.log('selected', selected, id) if (selected) { this.selected.add(id) } else { this.selected.delete(id) } - console.log('this.selected', this.selected) + this.onSelectChange() + } + + onSelectChange() { + console.log('this.pagination.data', this.pagination.data) this.indeterminate = this.selected.size > 0 && this.selected.size < this.pagination.data.length } } diff --git a/web-admin-app/src/app/utils/index.ts b/web-admin-app/src/app/utils/index.ts index 7cab614..156beb2 100644 --- a/web-admin-app/src/app/utils/index.ts +++ b/web-admin-app/src/app/utils/index.ts @@ -1,3 +1,7 @@ +import { HttpResponse } from '@angular/common/http' +import { AnyObject } from 'app/shared/components/server-paginated-table' +import { NzTreeNodeOptions } from 'ng-zorro-antd/tree' + export * from './form' export * from './storage' @@ -56,4 +60,55 @@ export class Utils { }) return params } + + static buildTree( + organizations: T[], + keyName: string = 'key', + titleName: string = 'title', + ): NzTreeNodeOptions[] { + const map: { [parentId: number]: NzTreeNodeOptions[] } = {} + + organizations.forEach((org) => { + if (!map[org.parentId]) { + map[org.parentId] = [] + } + const treeNode: NzTreeNodeOptions = { + ...org, + title: org[titleName], + key: org[keyName].toString(), + } + map[org.parentId].push(treeNode) + }) + + const build = (parentId: number): NzTreeNodeOptions[] => { + if (!map[parentId]) { + return [] + } + return map[parentId].map((node) => { + const children = build(parseInt(node.key)) + return { + ...node, + isLeaf: children.length === 0, + children, + } + }) + } + + return build(0) + } + static downLoadFile(response: HttpResponse, type: string, ext: string = 'pdf') { + const fileNameFromHeader = response.headers.get('Content-Disposition') + let fileName = '' + if (fileNameFromHeader) { + fileName = fileNameFromHeader.trim().split('=')[1].replace(/"/g, '') + } + console.log('fileName', fileName) + const blob = new Blob([response.body as any], { type }) + const downloadLink = document.createElement('a') + downloadLink.href = URL.createObjectURL(blob) + downloadLink.download = decodeURIComponent(fileName) + document.body.appendChild(downloadLink) + downloadLink.click() + document.body.removeChild(downloadLink) + } } diff --git a/web-admin-app/src/styles.less b/web-admin-app/src/styles.less index 630a37f..7b542ac 100644 --- a/web-admin-app/src/styles.less +++ b/web-admin-app/src/styles.less @@ -63,6 +63,16 @@ body { background-color: rgba(0, 0, 0, .171) } +.modal-lg { + .ant-modal { + top: 5vh !important; + + &-body { + padding: 0; + } + } +} + .upload-btn { position: relative;