From 8be281a6db69b01e61d8bb6c942ab8fa21a5b1ea Mon Sep 17 00:00:00 2001 From: kely Date: Mon, 9 Dec 2024 00:29:48 +0800 Subject: [PATCH] v2 --- web-admin-app/README.md | 1 - web-admin-app/src/app/app.component.ts | 24 +- web-admin-app/src/app/app.routes.ts | 12 + .../address-tree/address-tree.component.html | 66 +++ .../address-tree/address-tree.component.less | 7 + .../address-tree/address-tree.component.ts | 164 ++++++ .../asset-business-allot-form.component.html | 12 +- .../asset-business-allot-form.component.ts | 2 +- .../asset-business-borrow-form.component.html | 11 + .../asset-business-borrow-form.component.ts | 2 +- .../asset-business-collection.component.html | 11 + .../asset-business-collection.component.ts | 1 + .../asset-business-retirement.component.html | 12 +- .../asset-business-retirement.component.ts | 2 +- .../asset-business-return-form.component.html | 11 + .../asset-business-return-form.component.ts | 1 + .../asset-business-revert-form.component.html | 12 + .../asset-business-revert-form.component.ts | 2 +- ...asset-business-storage-form.component.html | 13 +- .../asset-business-storage-form.component.ts | 3 +- ...sset-business-transfer-form.component.html | 12 +- .../asset-business-transfer-form.component.ts | 2 +- .../asset-form/asset-form.component.html | 67 ++- .../asset-form/asset-form.component.ts | 40 +- .../asset-inspection-record.component.ts | 7 +- .../asset-maintenance-record.component.ts | 7 +- .../asset-operation-records.component.html | 4 +- .../asset-operation-records.component.ts | 12 +- .../asset-operational-statistics.component.ts | 101 ++-- .../asset-repair-records.component.ts | 8 +- .../asset-stocktaking-record.component.ts | 7 +- .../flow-list-by-type.component.html | 36 ++ .../flow-list-by-type.component.ts | 429 +++++++++++++- .../calendar-list.component.html | 2 +- .../handle-task-asset-item.component.html | 60 +- .../handle-task-asset-item.component.ts | 72 ++- .../handle-task/handle-task.component.html | 2 +- .../handle-task/handle-task.component.ts | 9 +- .../plan-form/plan-form.component.html | 11 + .../plan-form/plan-form.component.ts | 1 + .../plan-list/plan-list.component.ts | 12 +- .../task-list/task-list.component.ts | 25 +- web-admin-app/src/app/constants/index.ts | 35 +- .../pages/dashboard/dashboard.component.ts | 46 +- .../pages/data-vis/data-vis.component.html | 2 +- .../pages/data-vis/data-vis.component.less | 8 +- .../app/pages/data-vis/data-vis.component.ts | 78 ++- .../alert-borrow/alert-borrow.component.html | 3 + .../alert-borrow/alert-borrow.component.ts | 24 +- .../alert-inventory-down.component.ts | 14 +- .../alert-inventory-safety.component.ts | 30 +- .../alert-maintenance.component.html | 3 + .../alert-maintenance.component.ts | 18 +- .../asset-management.component.html | 37 +- .../asset-management.component.ts | 45 +- .../basic-category.component.html | 333 ++++++----- .../basic-category.component.ts | 35 +- .../basic-flow-form-manage.component.html | 254 ++++---- .../basic-flow-form-manage.component.ts | 51 +- .../basic-flow-form.component.ts | 18 +- .../maintain-on-off.component.html | 3 +- .../maintain-on-off.component.ts | 10 +- .../on-off-records.component.html | 31 +- .../on-off-records.component.ts | 21 +- .../fixed-asset-manage.component.ts | 4 +- .../registration/registration.component.html | 6 +- .../registration/registration.component.ts | 21 +- .../flow/flow-main/flow-main.component.html | 6 +- .../flow/flow-main/flow-main.component.ts | 6 +- .../flow-report/flow-report.component.html | 342 ++++++++--- .../flow-report/flow-report.component.less | 136 +---- .../flow/flow-report/flow-report.component.ts | 540 +++++++++++++++--- .../src/app/pages/login/login.component.html | 4 +- .../src/app/pages/login/login.component.less | 5 +- .../src/app/pages/login/login.component.ts | 10 + .../pages/msg/flow-msg/flow-msg.component.ts | 19 +- .../msg/system-log/system-log.component.ts | 19 +- .../display-config.component.html | 54 ++ .../display-config.component.less | 0 .../display-config.component.ts | 59 ++ .../pages/system/index/system.component.html | 14 +- .../system-address.component.html | 38 +- .../system-address.component.ts | 12 +- web-admin-app/src/app/services/api.service.ts | 126 +++- .../components/header/header.component.html | 12 +- .../components/header/header.component.ts | 7 +- .../components/upload/upload.component.html | 20 +- .../components/upload/upload.component.ts | 32 +- web-admin-app/src/app/utils/index.ts | 2 +- web-admin-app/src/assets/favicon.ico | Bin 0 -> 4158 bytes web-admin-app/src/index.html | 1 + web-admin-app/src/styles.less | 41 ++ web-admin-app/t.html | 19 + 93 files changed, 3006 insertions(+), 943 deletions(-) create mode 100644 web-admin-app/src/app/components/address-tree/address-tree.component.html create mode 100644 web-admin-app/src/app/components/address-tree/address-tree.component.less create mode 100644 web-admin-app/src/app/components/address-tree/address-tree.component.ts create mode 100644 web-admin-app/src/app/pages/system/display-config/display-config.component.html create mode 100644 web-admin-app/src/app/pages/system/display-config/display-config.component.less create mode 100644 web-admin-app/src/app/pages/system/display-config/display-config.component.ts create mode 100644 web-admin-app/src/assets/favicon.ico create mode 100644 web-admin-app/t.html diff --git a/web-admin-app/README.md b/web-admin-app/README.md index 0d4a2f8..1d4a7aa 100644 --- a/web-admin-app/README.md +++ b/web-admin-app/README.md @@ -167,4 +167,3 @@ Excel导出 /api/v2/sysFormTemp/importByExcel 13、工作报表 api/flFormItem/workReport 富文本 + html转word api/flFormItem/h52word 或者api/flFormItem/h5str2word - diff --git a/web-admin-app/src/app/app.component.ts b/web-admin-app/src/app/app.component.ts index 1bfc048..bbc5aa1 100644 --- a/web-admin-app/src/app/app.component.ts +++ b/web-admin-app/src/app/app.component.ts @@ -1,11 +1,23 @@ import { Component } from '@angular/core' import { SharedModule } from './shared/shared.module' +import { ApiService } from './services' @Component({ - selector: 'app-root', - standalone: true, - imports: [SharedModule], - templateUrl: './app.component.html', - styleUrl: './app.component.less', + selector: 'app-root', + standalone: true, + imports: [SharedModule], + templateUrl: './app.component.html', + styleUrl: './app.component.less', }) -export class AppComponent {} +export class AppComponent { + constructor(private api: ApiService) {} + + ngOnInit() { + this.api.getSysDisplayConfig().subscribe((res) => { + if (res.favicon) { + console.log('res.favicon', res.favicon) + ;(document.querySelector('#favicon') as HTMLLinkElement).href = res.favicon + } + }) + } +} diff --git a/web-admin-app/src/app/app.routes.ts b/web-admin-app/src/app/app.routes.ts index d5ed155..956a39b 100644 --- a/web-admin-app/src/app/app.routes.ts +++ b/web-admin-app/src/app/app.routes.ts @@ -86,6 +86,7 @@ import { MsgLayoutComponent } from './pages/msg/msg-layout/msg-layout.component' import { FlowManagementComponent } from './pages/flow/flow-management/flow-management.component' import { FlowReportComponent } from './pages/flow/flow-report/flow-report.component' import { DataVisComponent } from './pages/data-vis/data-vis.component' +import { DisplayConfigComponent } from './pages/system/display-config/display-config.component' export const routes: Routes = [ { @@ -202,6 +203,17 @@ export const routes: Routes = [ }, }, }, + { + path: 'display', + component: DisplayConfigComponent, + canActivate: [permissionGuard], + title: '展示设置', + data: { + // permission: { + // only: ['system-display:view'], + // }, + }, + }, { path: 'place', title: '场所地址', diff --git a/web-admin-app/src/app/components/address-tree/address-tree.component.html b/web-admin-app/src/app/components/address-tree/address-tree.component.html new file mode 100644 index 0000000..5c7c345 --- /dev/null +++ b/web-admin-app/src/app/components/address-tree/address-tree.component.html @@ -0,0 +1,66 @@ +
+
+
+ + + + + + +
+ @if (createable) { + + } +
+
+ + +
+
+ @switch (origin.organizationType) { + @case ('0') { + + } + @case ('1') { + + } + @case ('2') { + + } + } + {{ node.title }} +
+ @if (createable) { + + +
    +
  • 添加同级分类
  • +
  • 添加下级分类
  • +
  • +
  • 删除
  • +
+
+ } +
+
+
+
+
diff --git a/web-admin-app/src/app/components/address-tree/address-tree.component.less b/web-admin-app/src/app/components/address-tree/address-tree.component.less new file mode 100644 index 0000000..fcd4a28 --- /dev/null +++ b/web-admin-app/src/app/components/address-tree/address-tree.component.less @@ -0,0 +1,7 @@ +.tree { + ::ng-deep { + .ant-tree-switcher { + align-self: center; + } + } +} \ No newline at end of file diff --git a/web-admin-app/src/app/components/address-tree/address-tree.component.ts b/web-admin-app/src/app/components/address-tree/address-tree.component.ts new file mode 100644 index 0000000..3d8be7f --- /dev/null +++ b/web-admin-app/src/app/components/address-tree/address-tree.component.ts @@ -0,0 +1,164 @@ +import { CommonModule } from '@angular/common' +import { Component, EventEmitter, Input, OnInit, Output, TemplateRef } from '@angular/core' +import { FormBuilder, FormGroup, FormsModule, ReactiveFormsModule } from '@angular/forms' +import { ApiService } from 'app/services' +import { SharedModule } from 'app/shared/shared.module' +import { FormValidators } from 'app/utils' +import { NzButtonModule } from 'ng-zorro-antd/button' +import { NzSafeAny } from 'ng-zorro-antd/core/types' +import { NzDrawerRef, NzDrawerService } from 'ng-zorro-antd/drawer' +import { NzDropDownModule } from 'ng-zorro-antd/dropdown' +import { NzIconModule } from 'ng-zorro-antd/icon' +import { NzInputModule } from 'ng-zorro-antd/input' +import { NzMessageService } from 'ng-zorro-antd/message' +import { NzModalService } from 'ng-zorro-antd/modal' +import { NzFormatEmitEvent, NzTreeModule, NzTreeNodeOptions } from 'ng-zorro-antd/tree' + +interface CateGoryInterface { + createTime: string + depth: string + name: string + parentId: number + positionId: number +} +export function buildCateTree(organizations: CateGoryInterface[]): NzTreeNodeOptions[] { + const map: { [parentId: number]: NzTreeNodeOptions[] } = {} + + organizations.forEach((org) => { + if (!map[org.parentId]) { + map[org.parentId] = [] + } + const treeNode: NzTreeNodeOptions = { + ...org, + title: org.name, + key: org.positionId.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) +} + +@Component({ + selector: 'app-component-address-tree', + standalone: true, + imports: [ + NzDropDownModule, + NzTreeModule, + NzInputModule, + NzIconModule, + CommonModule, + FormsModule, + ReactiveFormsModule, + NzButtonModule, + ], + templateUrl: './address-tree.component.html', + styleUrl: './address-tree.component.less', +}) +export class AddressTreeComponent { + constructor( + private api: ApiService, + private drawer: NzDrawerService, + private fb: FormBuilder, + private msg: NzMessageService, + private modal: NzModalService, + ) {} + + @Input() createable = true + + @Output() onSelectedChange = new EventEmitter() + + @Input() defaultName?: string = '新地址' + + drawerRef?: NzDrawerRef + + searchValue = '' + + parentId?: number + + nodes: NzSafeAny[] = [] + + expandedKeys: string[] = [] + + selectedKeys: string[] = [] + + initTree() { + this.api.getBasicPositionTree().subscribe((res) => { + this.nodes = buildCateTree(res.body) + this.expandedKeys = [...this.expandedKeys] + if (this.selectedKeys.length === 0) { + this.selectedKeys = [this.nodes[0].key] + } else { + this.selectedKeys = [...this.selectedKeys] + } + + const node = res.body.find((node: NzSafeAny) => String(node.positionId) === this.selectedKeys[0]) + this.onSelectedChange.emit(node) + }) + } + + ngOnInit(): void { + this.initTree() + } + + nzEvent(event: NzFormatEmitEvent): void { + if (event.eventName === 'click') { + const { node } = event + this.selectedKeys = event.keys ?? [] + this.onSelectedChange.emit(node?.origin) + } + } + + onExpandChange(e: NzFormatEmitEvent) { + this.expandedKeys = e.keys ?? [] + } + + onSelectedKeysChange(e: string[]) { + console.log('e', e) + } + + onCreate(parentId: number) { + this.api + .saveBasicPosition({ + depth: '', + + parentId, + name: this.defaultName, + }) + .subscribe((res) => { + this.expandedKeys.push(String(parentId)) + this.initTree() + this.msg.success(res.desc) + }) + } + + onDelete(id: number) { + this.modal.confirm({ + nzTitle: '警告', + nzContent: '是否要删除该分类?', + nzOnOk: () => { + this.api.deleteBasicPosition([id]).subscribe((res) => { + if (this.selectedKeys.includes(String(id))) { + this.selectedKeys = [] + } + this.msg.success(res.desc) + this.initTree() + }) + }, + }) + } +} diff --git a/web-admin-app/src/app/components/asset-business-allot-form/asset-business-allot-form.component.html b/web-admin-app/src/app/components/asset-business-allot-form/asset-business-allot-form.component.html index 3277b94..fcaa507 100644 --- a/web-admin-app/src/app/components/asset-business-allot-form/asset-business-allot-form.component.html +++ b/web-admin-app/src/app/components/asset-business-allot-form/asset-business-allot-form.component.html @@ -42,7 +42,17 @@ - +
+ + 紧急程度 + + + + + + + +
附件 diff --git a/web-admin-app/src/app/components/asset-business-allot-form/asset-business-allot-form.component.ts b/web-admin-app/src/app/components/asset-business-allot-form/asset-business-allot-form.component.ts index 2c5d939..c6db480 100644 --- a/web-admin-app/src/app/components/asset-business-allot-form/asset-business-allot-form.component.ts +++ b/web-admin-app/src/app/components/asset-business-allot-form/asset-business-allot-form.component.ts @@ -54,7 +54,7 @@ export class AssetBusinessAllotFormComponent { notes: this.fb.control(null, []), inWarehouseId: this.fb.control(null, [FormValidators.required('请选择')]), // outWarehouseId: this.fb.control(null, [FormValidators.required('请选择')]), - + urgency: this.fb.control(1, []), attach: this.fb.control('', []), assetIdList: this.fb.control([], []), diff --git a/web-admin-app/src/app/components/asset-business-borrow-form/asset-business-borrow-form.component.html b/web-admin-app/src/app/components/asset-business-borrow-form/asset-business-borrow-form.component.html index f5e8737..0e3edda 100644 --- a/web-admin-app/src/app/components/asset-business-borrow-form/asset-business-borrow-form.component.html +++ b/web-admin-app/src/app/components/asset-business-borrow-form/asset-business-borrow-form.component.html @@ -50,6 +50,17 @@
+
+ + 紧急程度 + + + + + + + +
diff --git a/web-admin-app/src/app/components/asset-business-borrow-form/asset-business-borrow-form.component.ts b/web-admin-app/src/app/components/asset-business-borrow-form/asset-business-borrow-form.component.ts index 2ed7333..f570b57 100644 --- a/web-admin-app/src/app/components/asset-business-borrow-form/asset-business-borrow-form.component.ts +++ b/web-admin-app/src/app/components/asset-business-borrow-form/asset-business-borrow-form.component.ts @@ -49,7 +49,7 @@ export class AssetBusinessBorrowFormComponent { // useOrganizationId: this.fb.control(null, [FormValidators.required('请选择')]), businessGeneratedDate: this.fb.control(null, [FormValidators.required('请选择')]), returnTime: this.fb.control(null, [FormValidators.required('请选择')]), - + urgency: this.fb.control(1, []), notes: this.fb.control(null, []), attach: this.fb.control('', []), diff --git a/web-admin-app/src/app/components/asset-business-collection/asset-business-collection.component.html b/web-admin-app/src/app/components/asset-business-collection/asset-business-collection.component.html index 9b840ca..beb4917 100644 --- a/web-admin-app/src/app/components/asset-business-collection/asset-business-collection.component.html +++ b/web-admin-app/src/app/components/asset-business-collection/asset-business-collection.component.html @@ -58,6 +58,17 @@
+
+ + 紧急程度 + + + + + + + +
附件 diff --git a/web-admin-app/src/app/components/asset-business-collection/asset-business-collection.component.ts b/web-admin-app/src/app/components/asset-business-collection/asset-business-collection.component.ts index 3e3420d..e407c85 100644 --- a/web-admin-app/src/app/components/asset-business-collection/asset-business-collection.component.ts +++ b/web-admin-app/src/app/components/asset-business-collection/asset-business-collection.component.ts @@ -55,6 +55,7 @@ export class AssetBusinessCollectionComponent { notes: this.fb.control(null, []), positionId: this.fb.control(null, []), + urgency: this.fb.control(1, []), attach: this.fb.control('', []), positionDetail: this.fb.control('', []), applicant: this.fb.control({ value: '', disabled: true }, []), diff --git a/web-admin-app/src/app/components/asset-business-retirement/asset-business-retirement.component.html b/web-admin-app/src/app/components/asset-business-retirement/asset-business-retirement.component.html index 05bac22..1624915 100644 --- a/web-admin-app/src/app/components/asset-business-retirement/asset-business-retirement.component.html +++ b/web-admin-app/src/app/components/asset-business-retirement/asset-business-retirement.component.html @@ -45,7 +45,17 @@
- +
+ + 紧急程度 + + + + + + + +
附件 diff --git a/web-admin-app/src/app/components/asset-business-retirement/asset-business-retirement.component.ts b/web-admin-app/src/app/components/asset-business-retirement/asset-business-retirement.component.ts index fc4bdca..a61f045 100644 --- a/web-admin-app/src/app/components/asset-business-retirement/asset-business-retirement.component.ts +++ b/web-admin-app/src/app/components/asset-business-retirement/asset-business-retirement.component.ts @@ -52,7 +52,7 @@ export class AssetBusinessRetirementComponent { // useUserId: this.fb.control(null, [FormValidators.required('请选择')]), type: this.fb.control(null, []), businessGeneratedDate: this.fb.control(null, [FormValidators.required('请选择')]), - + urgency: this.fb.control(1, []), expeditedStatus: this.fb.control(0, []), notes: this.fb.control(null, []), // positionId: this.fb.control(null, []), diff --git a/web-admin-app/src/app/components/asset-business-return-form/asset-business-return-form.component.html b/web-admin-app/src/app/components/asset-business-return-form/asset-business-return-form.component.html index 7d549fc..2fde1b0 100644 --- a/web-admin-app/src/app/components/asset-business-return-form/asset-business-return-form.component.html +++ b/web-admin-app/src/app/components/asset-business-return-form/asset-business-return-form.component.html @@ -66,6 +66,17 @@
+
+ + 紧急程度 + + + + + + + +
附件 diff --git a/web-admin-app/src/app/components/asset-business-return-form/asset-business-return-form.component.ts b/web-admin-app/src/app/components/asset-business-return-form/asset-business-return-form.component.ts index 3e87b36..9beb91c 100644 --- a/web-admin-app/src/app/components/asset-business-return-form/asset-business-return-form.component.ts +++ b/web-admin-app/src/app/components/asset-business-return-form/asset-business-return-form.component.ts @@ -53,6 +53,7 @@ export class AssetBusinessReturnFormComponent { warehouseId: this.fb.control(null, [FormValidators.required('请选择')]), notes: this.fb.control(null, []), + urgency: this.fb.control(1, []), positionId: this.fb.control(null, [FormValidators.required('请选择')]), attach: this.fb.control('', []), positionDetail: this.fb.control('', []), diff --git a/web-admin-app/src/app/components/asset-business-revert-form/asset-business-revert-form.component.html b/web-admin-app/src/app/components/asset-business-revert-form/asset-business-revert-form.component.html index 2d104ae..19d49da 100644 --- a/web-admin-app/src/app/components/asset-business-revert-form/asset-business-revert-form.component.html +++ b/web-admin-app/src/app/components/asset-business-revert-form/asset-business-revert-form.component.html @@ -67,6 +67,18 @@
+ +
+ + 紧急程度 + + + + + + + +
附件 diff --git a/web-admin-app/src/app/components/asset-business-revert-form/asset-business-revert-form.component.ts b/web-admin-app/src/app/components/asset-business-revert-form/asset-business-revert-form.component.ts index 4d7c2c6..1637698 100644 --- a/web-admin-app/src/app/components/asset-business-revert-form/asset-business-revert-form.component.ts +++ b/web-admin-app/src/app/components/asset-business-revert-form/asset-business-revert-form.component.ts @@ -54,7 +54,7 @@ export class AssetBusinessRevertFormComponent { positionId: this.fb.control(null, []), attach: this.fb.control('', []), positionDetail: this.fb.control('', []), - + urgency: this.fb.control(1, []), assetIdList: this.fb.control([], []), applicant: this.fb.control({ value: '', disabled: true }, []), }) diff --git a/web-admin-app/src/app/components/asset-business-storage-form/asset-business-storage-form.component.html b/web-admin-app/src/app/components/asset-business-storage-form/asset-business-storage-form.component.html index 2d3be6a..dfb2247 100644 --- a/web-admin-app/src/app/components/asset-business-storage-form/asset-business-storage-form.component.html +++ b/web-admin-app/src/app/components/asset-business-storage-form/asset-business-storage-form.component.html @@ -30,7 +30,7 @@ 业务日期 - +
@@ -42,6 +42,17 @@ +
+ + 紧急程度 + + + + + + + +
附件 diff --git a/web-admin-app/src/app/components/asset-business-storage-form/asset-business-storage-form.component.ts b/web-admin-app/src/app/components/asset-business-storage-form/asset-business-storage-form.component.ts index c3aa114..5d56c79 100644 --- a/web-admin-app/src/app/components/asset-business-storage-form/asset-business-storage-form.component.ts +++ b/web-admin-app/src/app/components/asset-business-storage-form/asset-business-storage-form.component.ts @@ -51,7 +51,8 @@ export class AssetBusinessStorageFormComponent { name: this.fb.control('', [FormValidators.required('请输入')]), warehouseId: this.fb.control('', [FormValidators.required('请输入')]), manager: this.fb.control(null, []), - createTime: this.fb.control(null, []), + urgency: this.fb.control(1, []), + businessGeneratedDate: this.fb.control(null, []), supplierVendorId: this.fb.control(null, []), notes: this.fb.control(null, []), assetIdList: this.fb.control([], []), diff --git a/web-admin-app/src/app/components/asset-business-transfer-form/asset-business-transfer-form.component.html b/web-admin-app/src/app/components/asset-business-transfer-form/asset-business-transfer-form.component.html index a3651ee..82001d1 100644 --- a/web-admin-app/src/app/components/asset-business-transfer-form/asset-business-transfer-form.component.html +++ b/web-admin-app/src/app/components/asset-business-transfer-form/asset-business-transfer-form.component.html @@ -66,7 +66,17 @@
- +
+ + 紧急程度 + + + + + + + +
附件 diff --git a/web-admin-app/src/app/components/asset-business-transfer-form/asset-business-transfer-form.component.ts b/web-admin-app/src/app/components/asset-business-transfer-form/asset-business-transfer-form.component.ts index e49fa82..b839944 100644 --- a/web-admin-app/src/app/components/asset-business-transfer-form/asset-business-transfer-form.component.ts +++ b/web-admin-app/src/app/components/asset-business-transfer-form/asset-business-transfer-form.component.ts @@ -55,7 +55,7 @@ export class AssetBusinessTransferFormComponent { managerId: this.fb.control(null, [FormValidators.required('请选择')]), inUseOrganizationId: this.fb.control(null, [FormValidators.required('请选择')]), outUseOrganizationId: this.fb.control(null, [FormValidators.required('请选择')]), - + urgency: this.fb.control(1, []), attach: this.fb.control('', []), positionId: this.fb.control('', []), positionDetail: this.fb.control('', []), 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 index 78f6abd..464f7f6 100644 --- 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 @@ -10,7 +10,7 @@ --> - + @@ -219,8 +219,8 @@ @if (extraFields.length > 0) {
扩展信息
- @for (item of extraFields; track item.key) { -
+ @for (item of extraFields; track item.key; let fid = $index) { +
{{ item.name }} @@ -245,6 +245,63 @@ } + @case ('LIST') { + + + + + @for (item of fields; track $index) { + {{ item }} + } + 操作 + + + + + + + + + + + + + + + + + + + + + + } @case ('NUMBER') { 财务分类 - - + + @for (item of financialCategory; track $index) { a.sort - b.sort) .map((i) => { let val = i.value - if (i.type === 'RADIO') { + if (i.type === 'RADIO' || i.type === 'LIST') { val = i.value?.value } else if (i.type === 'DATE') { val = new Date(i.value) } + const listValue = + i.type === 'LIST' + ? (val ?? []).map((c: NzSafeAny) => + this.fb.group( + i.value.fields.reduce((a: any, f: any) => { + a[f] = c[f] + return a + }, {}), + ), + ) + : [] this.extInfo.push( this.fb.group({ @@ -167,12 +178,33 @@ export class AssetFormComponent implements OnInit { remark: this.fb.control(i.remark), sort: this.fb.control(i.sort), type: this.fb.control(i.type), - value: this.fb.control(val), - fields: this.fb.control(i.type === 'RADIO' ? i.value?.fields : []), + value: i.type === 'LIST' ? this.fb.array(listValue) : this.fb.control(val), + fields: this.fb.control(['RADIO', 'LIST'].includes(i.type) ? i.value?.fields : []), }), ) return i }) + + console.log('this.extInfo', this.extInfo) + } + + getListValue(fid: number) { + return (this.extInfo.at(fid) as FormArray).get('value') as FormArray + } + addRow(fidx: number, fields: string[]) { + const row = this.getListValue(fidx) + row.push( + this.fb.group( + fields.reduce((a: any, f: any) => { + a[f] = this.fb.control('') + return a + }, {}), + ), + ) + } + removeRow(fidx: number, ridx: number) { + const row = this.getListValue(fidx) + row.removeAt(ridx) } patchValues() { @@ -214,7 +246,7 @@ export class AssetFormComponent implements OnInit { useOrganizationId: v.useOrganizationId, responsiblePerson: v.responsiblePerson?.[0], _extInfo: this.extInfo.value.map((v: any) => { - if (v.type === 'RADIO') { + if (v.type === 'RADIO' || v.type === 'LIST') { return { ...v, value: { diff --git a/web-admin-app/src/app/components/asset-inspection-record/asset-inspection-record.component.ts b/web-admin-app/src/app/components/asset-inspection-record/asset-inspection-record.component.ts index 8dce3f4..a1c5c0a 100644 --- a/web-admin-app/src/app/components/asset-inspection-record/asset-inspection-record.component.ts +++ b/web-admin-app/src/app/components/asset-inspection-record/asset-inspection-record.component.ts @@ -46,11 +46,10 @@ export class AssetInspectionRecordComponent { cacheKey: 'asset-repair-records.component', }) .setColumn([ - { key: 'id', title: '主键', width: '100px' }, + { key: 'idx', title: '编号', width: '100px' }, { key: 'businessId', title: '业务编号', width: '170px' }, - { key: 'name', title: '名称' }, - { key: '_repairType', title: '维修类型' }, - { key: 'plannedDate', title: '计划完成时间' }, + { key: 'remark', title: '操作内容' }, + { key: 'operationType', title: '操作类型' }, // { key: 'createTime', title: '创建时间' }, ]) diff --git a/web-admin-app/src/app/components/asset-maintenance-record/asset-maintenance-record.component.ts b/web-admin-app/src/app/components/asset-maintenance-record/asset-maintenance-record.component.ts index ba3f53c..116abbf 100644 --- a/web-admin-app/src/app/components/asset-maintenance-record/asset-maintenance-record.component.ts +++ b/web-admin-app/src/app/components/asset-maintenance-record/asset-maintenance-record.component.ts @@ -46,11 +46,10 @@ export class AssetMaintenanceRecordComponent { cacheKey: 'asset-repair-records.component', }) .setColumn([ - { key: 'id', title: '主键', width: '100px' }, + { key: 'idx', title: '编号', width: '100px' }, { key: 'businessId', title: '业务编号', width: '170px' }, - { key: 'name', title: '名称' }, - { key: '_repairType', title: '维修类型' }, - { key: 'plannedDate', title: '计划完成时间' }, + { key: 'remark', title: '操作内容' }, + { key: 'operationType', title: '操作类型' }, // { key: 'createTime', title: '创建时间' }, ]) diff --git a/web-admin-app/src/app/components/asset-operation-records/asset-operation-records.component.html b/web-admin-app/src/app/components/asset-operation-records/asset-operation-records.component.html index fc8002d..c670b1c 100644 --- a/web-admin-app/src/app/components/asset-operation-records/asset-operation-records.component.html +++ b/web-admin-app/src/app/components/asset-operation-records/asset-operation-records.component.html @@ -15,7 +15,7 @@ } - +
diff --git a/web-admin-app/src/app/components/asset-operation-records/asset-operation-records.component.ts b/web-admin-app/src/app/components/asset-operation-records/asset-operation-records.component.ts index 9715936..57b2df4 100644 --- a/web-admin-app/src/app/components/asset-operation-records/asset-operation-records.component.ts +++ b/web-admin-app/src/app/components/asset-operation-records/asset-operation-records.component.ts @@ -8,7 +8,7 @@ import { NzSafeAny } from 'ng-zorro-antd/core/types' 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 { lastValueFrom, tap } from 'rxjs' import { FormValidators } from 'app/utils' @Component({ @@ -47,9 +47,9 @@ export class AssetOperationRecordsComponent { cacheKey: 'asset-operation-records.component', }) .setColumn([ - { key: 'id', title: '主键', width: '100px' }, + { key: 'idx', title: '编号', width: '100px' }, { key: 'businessId', title: '业务编号', width: '170px' }, - { key: 'operationNotes', title: '操作内容' }, + { key: 'remark', title: '操作内容' }, { key: 'operationType', title: '操作类型' }, // { key: 'createTime', title: '创建时间' }, @@ -58,6 +58,10 @@ export class AssetOperationRecordsComponent { } fetchData(p: {}, q: AnyObject) { - return this.api.getAssetLog({ ...p, ...q, assetId: this.assetId }) + return this.api.getAssetLog({ ...p, ...q, assetId: this.assetId }).pipe( + tap((res) => { + console.log(res) + }), + ) } } diff --git a/web-admin-app/src/app/components/asset-operational-statistics/asset-operational-statistics.component.ts b/web-admin-app/src/app/components/asset-operational-statistics/asset-operational-statistics.component.ts index e5c8818..a4ed3bf 100644 --- a/web-admin-app/src/app/components/asset-operational-statistics/asset-operational-statistics.component.ts +++ b/web-admin-app/src/app/components/asset-operational-statistics/asset-operational-statistics.component.ts @@ -91,63 +91,64 @@ export class AssetOperationalStatisticsComponent { if (this.runningStatusChart?.nativeElement) { if (!this.pieRef) { this.pieRef = init(this.runningStatusChart?.nativeElement) - let data: NzSafeAny[] = [] - const odata: NzSafeAny[] = this.data?.runLogs ?? [] - const total = odata.reduce((a: number, b: any) => a + Math.abs(b.value), 0) + } + let data: NzSafeAny[] = [] + const odata: NzSafeAny[] = this.data?.runLogs ?? [] + const total = odata.reduce((a: number, b: any) => a + Math.abs(b.value), 0) - data = odata.map((i: NzSafeAny) => { - const value = Math.abs(i.value) - const percent = ((value / total) * 100).toFixed(2) + data = odata.map((i: NzSafeAny) => { + const value = Math.abs(i.value) + const percent = ((value / total) * 100).toFixed(2) - return { - ...i, - percent, - value, - } - }) - this.pieRef.setOption({ - tooltip: { - trigger: 'item', - }, - legend: { - orient: 'scroll', + return { + ...i, + percent, + value, + } + }) + console.log('data', data) + this.pieRef.setOption({ + tooltip: { + trigger: 'item', + }, + legend: { + orient: 'scroll', - formatter: function (name: string, d: any) { - const item = data.find((i: NzSafeAny) => i.name === name) - return name + ' | ' + item?.percent + '%' + ' ' + item?.value + '天' - }, + formatter: function (name: string, d: any) { + const item = data.find((i: NzSafeAny) => i.name === name) + return name + ' | ' + item?.percent + '%' + ' ' + item?.value + '小时' }, - series: [ - { - name: '运行状态', - type: 'pie', - radius: ['40%', '70%'], - // center: ['40%', '50%'], - avoidLabelOverlap: false, - itemStyle: { - borderRadius: 10, - borderColor: '#fff', - borderWidth: 2, - }, + }, + series: [ + { + name: '运行状态', + type: 'pie', + radius: ['40%', '70%'], + // center: ['40%', '50%'], + avoidLabelOverlap: false, + itemStyle: { + borderRadius: 10, + borderColor: '#fff', + borderWidth: 2, + }, + label: { + show: false, + position: 'center', + }, + emphasis: { label: { - show: false, - position: 'center', - }, - emphasis: { - label: { - show: true, - fontSize: 30, - fontWeight: 'bold', - }, - }, - labelLine: { - show: false, + show: true, + fontSize: 30, + fontWeight: 'bold', }, - data: data, }, - ], - }) - } + labelLine: { + show: false, + }, + data: data, + }, + ], + }) } } } diff --git a/web-admin-app/src/app/components/asset-repair-records/asset-repair-records.component.ts b/web-admin-app/src/app/components/asset-repair-records/asset-repair-records.component.ts index e309ccf..49db2ac 100644 --- a/web-admin-app/src/app/components/asset-repair-records/asset-repair-records.component.ts +++ b/web-admin-app/src/app/components/asset-repair-records/asset-repair-records.component.ts @@ -46,12 +46,10 @@ export class AssetRepairRecordsComponent { cacheKey: 'asset-repair-records.component', }) .setColumn([ - { key: 'id', title: '主键', width: '100px' }, + { key: 'idx', title: '编号', width: '100px' }, { key: 'businessId', title: '业务编号', width: '170px' }, - { key: 'name', title: '名称' }, - { key: '_repairType', title: '维修类型' }, - { key: 'plannedDate', title: '计划完成时间' }, - + { key: 'remark', title: '操作内容' }, + { key: 'operationType', title: '操作类型' }, // { key: 'createTime', title: '创建时间' }, ]) this.initQueryForm() diff --git a/web-admin-app/src/app/components/asset-stocktaking-record/asset-stocktaking-record.component.ts b/web-admin-app/src/app/components/asset-stocktaking-record/asset-stocktaking-record.component.ts index 83363ea..b2e8267 100644 --- a/web-admin-app/src/app/components/asset-stocktaking-record/asset-stocktaking-record.component.ts +++ b/web-admin-app/src/app/components/asset-stocktaking-record/asset-stocktaking-record.component.ts @@ -46,11 +46,10 @@ export class AssetStocktakingRecordComponent { cacheKey: 'asset-repair-records.component', }) .setColumn([ - { key: 'id', title: '主键', width: '100px' }, + { key: 'idx', title: '编号', width: '100px' }, { key: 'businessId', title: '业务编号', width: '170px' }, - { key: 'name', title: '名称' }, - { key: '_repairType', title: '维修类型' }, - { key: 'plannedDate', title: '计划完成时间' }, + { key: 'remark', title: '操作内容' }, + { key: 'operationType', title: '操作类型' }, // { key: 'createTime', title: '创建时间' }, ]) diff --git a/web-admin-app/src/app/components/flow-list-by-type/flow-list-by-type.component.html b/web-admin-app/src/app/components/flow-list-by-type/flow-list-by-type.component.html index 4321ccf..f32acc4 100644 --- a/web-admin-app/src/app/components/flow-list-by-type/flow-list-by-type.component.html +++ b/web-admin-app/src/app/components/flow-list-by-type/flow-list-by-type.component.html @@ -30,3 +30,39 @@
+ + +
+ + 审批意见 + + + + +
+
+ + +
+ + 任务处置人员 + + + + +
+
+ +
+ + {{ shenhe ? '审批意见' : '驳回意见' }} + + + + +
+
diff --git a/web-admin-app/src/app/components/flow-list-by-type/flow-list-by-type.component.ts b/web-admin-app/src/app/components/flow-list-by-type/flow-list-by-type.component.ts index 3b5d9ad..bac9cf4 100644 --- a/web-admin-app/src/app/components/flow-list-by-type/flow-list-by-type.component.ts +++ b/web-admin-app/src/app/components/flow-list-by-type/flow-list-by-type.component.ts @@ -7,12 +7,14 @@ import { SharedModule } from 'app/shared/shared.module' import { last, lastValueFrom, map, of, tap } from 'rxjs' import { NzSafeAny } from 'ng-zorro-antd/core/types' -import { NzModalService } from 'ng-zorro-antd/modal' +import { NzModalRef, NzModalService } from 'ng-zorro-antd/modal' import { NzMessageService } from 'ng-zorro-antd/message' -import { FormValidators } from 'app/utils' +import { FormValidators, Utils } from 'app/utils' import { AssetEmployeeApplyComponent } from 'app/components' -import { FLOW_STATUS, flowIntStatus } from 'app/constants' +import { FLOW_STATUS, flowIntStatus, flowIntStatusToStr } from 'app/constants' import { comsMap } from 'app/pages/flow/flow-main/flow-main.component' +import { TaskFormComponent } from '../plan-task/task-form/task-form.component' +import { HandleTaskComponent } from '../plan-task/handle-task/handle-task.component' @Component({ selector: 'app-flow-list-by-type', @@ -43,6 +45,8 @@ export class FlowListByTypeComponent { table = new TableOption(this.fetchData.bind(this)) + detailRef?: NzModalRef + assetTotal = 0 deviceTotal = 0 @@ -70,13 +74,278 @@ export class FlowListByTypeComponent { .setRowOperate([ { title: '查看', onClick: this.onDetail.bind(this) }, { - title: '作废', + title: '撤回', onClick: this.cancleFlow.bind(this), visible: (v) => { - return this.page === 'apply' + return this.page === 'apply' && [2, 9].includes(v.status) + }, + }, + { + title: '编辑', + onClick: (v) => { + this.onDetail(v, false) + }, + visible: (v) => { + return this.page === 'apply' && [1, 4, 5].includes(v.status) + }, + }, + { + title: '删除', + onClick: (v) => { + this.onDelete(v) + }, + visible: (v) => { + return this.page === 'apply' && [1, 4, 5].includes(v.status) + }, + }, + + { + title: '受理', + onClick: this.shouli.bind(this), + visible: (v) => { + return this.page === 'todo' && this.type === 'device' && v.status === 'TO_BE_ASSIGNED' + }, + }, + { + title: '指派', + onClick: this.zhipai.bind(this), + premissions: ['ROOT'], + visible: (v) => { + return this.page === 'todo' && this.type === 'device' && v.status === 7 + }, + }, + { + title: '处置', + onClick: this.onHandle.bind(this, true), + visible: (v) => { + return this.page === 'todo' && this.type === 'device' && v.status === 9 + }, + }, + { + title: '审批', + onClick: this.onHandle.bind(this, false), + visible: (v) => { + return this.page === 'todo' && this.type === 'device' && v.status === 2 + }, + }, + { + title: '报表', + onClick: this.onReport.bind(this), + visible: (v) => { + return this.page === 'todo' && this.type === 'device' && v.status === 3 }, }, ]) + + this.api.getAssetTeamAll().subscribe((res) => { + this.teamList = res.body.map((i: NzSafeAny) => { + let users = [] + + try { + users = JSON.parse(i.value) + } catch (error) {} + return { + ...i, + label: i.teamName, + value: i.teamId, + children: users.map((c: NzSafeAny) => { + return { + label: c.userName, + value: c.userId, + isLeaf: true, + } + }), + } + }) + }) + } + + zhipai(item?: NzSafeAny) { + this.modal.create({ + nzTitle: '任务指派', + nzContent: this.zhipaiTpl, + nzOnOk: async () => { + if (!this.assignee) { + this.msg.error('请选择处理人') + return false + } + const res = await lastValueFrom( + this.api.assignTask({ instanceId: item.procInsId, taskId: item.taskId, assignee: this.assignee }), + ) + this.msg.success(res.desc) + this.table.ref.reload() + return true + }, + }) + } + + shouli(item?: NzSafeAny) { + this.modal.confirm({ + nzTitle: '是否确定受理当前设备流程?', + nzContent: `受理后你将作为该任务的责任人,其他人员无法受理!`, + nzOnOk: async () => { + const res = await lastValueFrom(this.api.takeTask({ instanceId: item.procInsId, taskId: item.taskId })) + this.msg.success(res.desc) + this.table.ref.reload() + }, + }) + } + + modalRef?: NzModalRef + + assignee?: string + + shenhe = false + onHandle(chuzhi: boolean, d: NzSafeAny) { + // console.log('chuzhi', chuzhi, data) + let nzTitle = chuzhi ? '处置任务' : '任务审批' + const { procVars: data } = d + // data.id = data.jobId + // console.log('data', data) + const footer: NzSafeAny[] = chuzhi + ? [ + { + label: '提交审核', + type: 'reject', + onClick: async (e: HandleTaskComponent) => { + const vals = e.getValues() + if (vals) { + const res = await lastValueFrom( + this.api.completeProcessFlow({ + variables: { + ...data, + ...vals, + }, + taskId: data.taskId, + instanceId: data.procInsId, + }), + ) + this.msg.success(res.desc) + this.table.ref.reload() + this.modalRef?.close() + } + }, + }, + { + label: '保存', + type: 'primary', + onClick: async (e: HandleTaskComponent) => { + const vals = e.getValues() + if (vals) { + console.log('data', data, d) + const res = await lastValueFrom( + this.api.handleTaskAssetItem( + { + ...data, + ...vals, + taskId: d.taskId, + instanceId: d.procInsId, + }, + d.taskId, + ), + ) + this.msg.success(res.desc) + this.table.ref.reload() + this.modalRef?.close() + } + }, + }, + ] + : [ + { + label: '驳回', + type: 'reject', + + onClick: async (e: HandleTaskComponent) => { + this.shenhe = false + this.onShenpi(data) + }, + }, + { + label: '通过', + type: 'primary', + onClick: async (e: HandleTaskComponent) => { + this.shenhe = true + this.onShenpi(data) + }, + }, + ] + this.modalRef = this.modal.create({ + nzTitle, + nzContent: HandleTaskComponent, + nzWidth: '80vw', + nzWrapClassName: 'modal-lg modal-for-btn', + nzData: { + value: { + ...data, + taskId: d.taskId, + status: flowIntStatusToStr.get(Number(d.status)), + }, + chuzhi, + type: d.procDefKey.split('_').at(-1), + preview: !chuzhi, + }, + nzFooter: footer.concat({ + label: '取消', + onClick: () => { + this.modalRef?.close() + }, + }), + }) + } + + @ViewChild('zhipaiTpl') zhipaiTpl!: TemplateRef + @ViewChild('shenheTpl') shenheTpl!: TemplateRef + + teamList: NzSafeAny[] = [] + onShenpi(item: NzSafeAny) { + const nzTitle = this.shenhe ? '请填写审批意见' : '请填写驳回意见' + this.modal.create({ + nzTitle, + nzContent: this.shenheTpl, + nzOnOk: async () => { + if (!this.comment) { + this.msg.error(nzTitle) + return false + } + if (this.shenhe) { + const res = await lastValueFrom( + this.api.completeProcessFlow({ + instanceId: item.procInsId, + taskId: item.taskId, + assignee: this.assignee, + comment: this.comment, + }), + ) + this.msg.success(res.desc) + } else { + const res = await lastValueFrom( + this.api.rejectProcessFlow({ + instanceId: item.procInsId, + taskId: item.taskId, + assignee: this.assignee, + comment: this.comment, + }), + ) + this.msg.success(res.desc) + } + + this.table.ref.reload() + this.modalRef?.close() + return true + }, + }) + } + onReport(i: NzSafeAny) { + this.msg.loading('下载中...') + this.api.downloadTaskReport(i.id).subscribe((res) => { + Utils.downLoadFile( + res, + 'application/vnd.openxmlformats-officedocument.wordprocessingml.document;charset=utf-8', + ) + this.msg.remove() + this.msg.success('下载成功') + }) } fetchData(p: {}, q: AnyObject) { @@ -101,25 +370,149 @@ export class FlowListByTypeComponent { } } - onDetail(model: NzSafeAny) { - console.log('model', model, comsMap[model.category]) + onDelete(model: NzSafeAny) { + this.modal.confirm({ + nzTitle: '删除', + nzContent: '是否要删除该申请?', + nzOnOk: async () => { + const res = await lastValueFrom( + this.api.deleteAssetFlow({ + instanceId: model.procInsId, + taskId: model.taskId, + }), + ) + this.msg.success('删除成功') + this.table.ref.reload() + }, + }) + } + onDetail(model: NzSafeAny, preview = true) { + if (this.type === 'asset') { + // console.log('model', model, comsMap[model.category]) + let footer: any = null + if (this.page === 'apply') { + if (!preview) { + footer = void 0 + } else { + } + } + if (this.page === 'todo') { + footer = [ + { + label: '通过', + type: 'primary', + onClick: async () => { + this.completeFlow(model) + }, + }, + { + label: '驳回', + danger: true, + type: 'primary', + onClick: async () => { + return this.rejectProcessFlow(model) + }, + }, + ] + } + this.detailRef = this.modal.create({ + nzTitle: preview ? '查看' : '编辑', + nzContent: comsMap[model.category ?? model.procDefKey], + nzWrapClassName: 'modal-lg', + nzWidth: '80vw', + // nzFooter: preview ? null : void 0, + nzFooter: footer, + nzData: { + value: model, + preview, + }, + nzOnOk: async (e: NzSafeAny) => { + const vals = e.getValues() + if (vals) { + const res = await lastValueFrom(this.api.startFlow(vals, model.procDefKey)) + this.msg.success(res.desc) + + return true + } + return false + }, + }) + } else { + let assetIdList = [] + + try { + assetIdList = JSON.parse(model?.procVars?.defects) + } catch (error) {} + this.modal.create({ + nzTitle: '查看', + nzContent: TaskFormComponent, + nzWidth: '80vw', + nzWrapClassName: 'modal-lg', + nzData: { + value: { + ...model.procVars, + assetIdList, + }, + preview: true, + type: model.procVars.jobType, + }, + nzFooter: null, + }) + } + } + + completeFlow(d: NzSafeAny) { this.modal.create({ - nzTitle: '查看', - nzContent: comsMap[model.category], - nzWrapClassName: 'modal-lg', - nzWidth: '80vw', - nzFooter: null, - nzData: { - value: model, - preview: true, + nzTitle: '审核通过', + // nzContent: '是否要审核通过该申请?', + nzContent: this.commentTpl, + nzOnOk: async () => { + await lastValueFrom( + this.api.completeProcessFlow({ + instanceId: d.procInsId, + taskId: d.taskId, + comment: this.comment, + }), + ) + this.msg.success('通过成功') + this.table.ref.reload() + this.detailRef?.close() + }, + }) + } + + @ViewChild('commentTpl') commentTpl!: TemplateRef<{}> + + comment = '' + rejectProcessFlow(d: NzSafeAny) { + this.modal.create({ + nzTitle: '驳回', + nzContent: this.commentTpl, + nzOnOk: async () => { + if (!this.comment) { + this.msg.error('请输入驳回意见') + return false + } + await lastValueFrom( + this.api.rejectProcessFlow({ + instanceId: d.procInsId, + taskId: d.taskId, + comment: this.comment, + }), + ) + + this.msg.success('驳回成功') + this.table.ref.reload() + this.detailRef?.close() + return true }, }) } cancleFlow(d: NzSafeAny) { this.modal.confirm({ - nzTitle: '作废', - nzContent: '是否要作废该申请?', + nzTitle: '撤回', + nzContent: '是否要撤回该申请?', nzOnOk: async () => { const res = await lastValueFrom( this.api.cancelFlow({ @@ -127,7 +520,7 @@ export class FlowListByTypeComponent { taskId: d.taskId, }), ) - this.msg.success('作废成功') + this.msg.success('撤回成功') this.table.ref.reload() }, }) diff --git a/web-admin-app/src/app/components/plan-task/calendar-list/calendar-list.component.html b/web-admin-app/src/app/components/plan-task/calendar-list/calendar-list.component.html index 811df90..652673a 100644 --- a/web-admin-app/src/app/components/plan-task/calendar-list/calendar-list.component.html +++ b/web-admin-app/src/app/components/plan-task/calendar-list/calendar-list.component.html @@ -8,7 +8,7 @@ 任务状态 - + diff --git a/web-admin-app/src/app/components/plan-task/handle-task-asset-item/handle-task-asset-item.component.html b/web-admin-app/src/app/components/plan-task/handle-task-asset-item/handle-task-asset-item.component.html index c453511..2fe8291 100644 --- a/web-admin-app/src/app/components/plan-task/handle-task-asset-item/handle-task-asset-item.component.html +++ b/web-admin-app/src/app/components/plan-task/handle-task-asset-item/handle-task-asset-item.component.html @@ -90,8 +90,8 @@ @if (extraFields.length > 0) {
{{ data.title }}项目
- @for (item of extraFields; track item.key) { -
+ @for (item of extraFields; track item.key; let fid = $index) { +
{{ item.name }} @@ -103,6 +103,61 @@ [formControlName]="'value'" /> } + @case ('LIST') { + + + + + @for (item of fields; track $index) { + {{ item }} + } + 操作 + + + + + + + + + + + + + + + + + + + + + + } @case ('RADIO') { @@ -116,6 +171,7 @@ } + @case ('NUMBER') { = { - inspection: ['待检', '正常', '异常', '取消'], - stocktaking: ['待盘点', '正常', '盘赢', '盘亏'], - maintenance: ['待保养', '正常', '异常', '取消'], - repair: [], + inspection: ['待检', '正常', '异常', '取消'], // 巡检 + stocktaking: ['待盘点', '正常', '盘赢', '盘亏'], // 盘点 + maintenance: ['待保养', '正常', '异常', '取消'], // 保养 + repair: ['待保养', '正常', '异常', '取消'], } @Component({ selector: 'app-asset-form', @@ -94,6 +94,7 @@ export class HandleTaskAssetItemComponent { sparePartsList: this.fb.control([], []), }) + console.log('this.data', this.data) this.patchValues() this.api.getBasicFinancialCategory({}).subscribe((res) => { @@ -147,13 +148,51 @@ export class HandleTaskAssetItemComponent { removeSpareParts(idx: number) { // this.sparePartsList.removeAt(idx) } + setExtraFields(fields: NzSafeAny[]) { this.extInfo.clear() this.extraFields = fields .sort((a, b) => a.sort - b.sort) .map((i) => { let val = i.value - if (i.type === 'RADIO') { + if (i.type === 'RADIO' || i.type === 'LIST') { + val = i.value?.value + } else if (i.type === 'DATE') { + val = new Date(i.value) + } + const listValue = + i.type === 'LIST' + ? (val ?? []).map((c: NzSafeAny) => + this.fb.group( + i.value.fields.reduce((a: any, f: any) => { + a[f] = c[f] + return a + }, {}), + ), + ) + : [] + + this.extInfo.push( + this.fb.group({ + key: this.fb.control(i.key), + name: this.fb.control(i.name), + remark: this.fb.control(i.remark), + sort: this.fb.control(i.sort), + type: this.fb.control(i.type), + value: i.type === 'LIST' ? this.fb.array(listValue) : this.fb.control(val), + fields: this.fb.control(['RADIO', 'LIST'].includes(i.type) ? i.value?.fields : []), + }), + ) + return i + }) + } + setExtraFields1(fields: NzSafeAny[]) { + this.extInfo.clear() + this.extraFields = fields + .sort((a, b) => a.sort - b.sort) + .map((i) => { + let val = i.value + if (i.type === 'RADIO' || i.type === 'LIST') { val = i.value?.value } else if (i.type === 'DATE') { val = i.value ? new Date(i.value) : null @@ -167,7 +206,7 @@ export class HandleTaskAssetItemComponent { sort: this.fb.control(i.sort), type: this.fb.control(i.type), value: this.fb.control(val), - fields: this.fb.control(i.type === 'RADIO' ? i.value?.fields : []), + fields: this.fb.control(['RADIO', 'LIST'].includes(i.type) ? i.value?.fields : []), }), ) @@ -198,7 +237,7 @@ export class HandleTaskAssetItemComponent { ...v, _extInfo: this.extInfo.value.map((v: any) => { - if (v.type === 'RADIO') { + if (v.type === 'RADIO' || v.type === 'LIST') { return { ...v, value: { @@ -213,4 +252,23 @@ export class HandleTaskAssetItemComponent { } return values } + + getListValue(fid: number) { + return (this.extInfo.at(fid) as FormArray).get('value') as FormArray + } + addRow(fidx: number, fields: string[]) { + const row = this.getListValue(fidx) + row.push( + this.fb.group( + fields.reduce((a: any, f: any) => { + a[f] = this.fb.control('') + return a + }, {}), + ), + ) + } + removeRow(fidx: number, ridx: number) { + const row = this.getListValue(fidx) + row.removeAt(ridx) + } } diff --git a/web-admin-app/src/app/components/plan-task/handle-task/handle-task.component.html b/web-admin-app/src/app/components/plan-task/handle-task/handle-task.component.html index 96eff2c..b5b51c2 100644 --- a/web-admin-app/src/app/components/plan-task/handle-task/handle-task.component.html +++ b/web-admin-app/src/app/components/plan-task/handle-task/handle-task.component.html @@ -107,7 +107,7 @@ 待分配 } @default { - {{ data }} + {{ data.value.status | json }} } } diff --git a/web-admin-app/src/app/components/plan-task/handle-task/handle-task.component.ts b/web-admin-app/src/app/components/plan-task/handle-task/handle-task.component.ts index a972000..32d5646 100644 --- a/web-admin-app/src/app/components/plan-task/handle-task/handle-task.component.ts +++ b/web-admin-app/src/app/components/plan-task/handle-task/handle-task.component.ts @@ -9,7 +9,7 @@ import { NzSafeAny } from 'ng-zorro-antd/core/types' import { NZ_MODAL_DATA, NzModalService } from 'ng-zorro-antd/modal' import { ActivatedRoute } from '@angular/router' -import { STOCKTAKING_JOB_STATUS_MAP, taskTypeTitle } from 'app/constants' +import { flowIntStatusToStr, STOCKTAKING_JOB_STATUS_MAP, taskTypeTitle } from 'app/constants' import { AssetSelectComponent, OrgSelectComponent, @@ -94,6 +94,9 @@ export class HandleTaskComponent { defectStatusText = defectStatusText defectStatusTextOnThis: string[] = [] + + flowIntStatusToStr = flowIntStatusToStr + defectStatus = { 0: 'processing', 1: 'success', @@ -137,9 +140,8 @@ export class HandleTaskComponent { return i }), } - console.log('val', val) - const res = await lastValueFrom(this.api.handleTaskAssetItem(val, this.data.value.id)) + const res = await lastValueFrom(this.api.handleTaskAssetItem(val, this.data.value.taskId)) this.data.value = JSON.parse(JSON.stringify(val)) this.msg.success(res.desc) // this.table.ref.reload() @@ -153,6 +155,7 @@ export class HandleTaskComponent { patchValues() { const { value: data, preview, type } = this.data this.title = taskTypeTitle.get(type) + console.log('type====', data) this.defectStatusTextOnThis = this.defectStatusText[type as PlanTaskType] if (data) { this.formGroup.patchValue({ diff --git a/web-admin-app/src/app/components/plan-task/plan-form/plan-form.component.html b/web-admin-app/src/app/components/plan-task/plan-form/plan-form.component.html index 50f2fae..4d29e1f 100644 --- a/web-admin-app/src/app/components/plan-task/plan-form/plan-form.component.html +++ b/web-admin-app/src/app/components/plan-task/plan-form/plan-form.component.html @@ -78,6 +78,16 @@
+
+ + 重复间隔 + + + + + + +
顺序巡检 @@ -95,6 +105,7 @@
+
跳过周末 diff --git a/web-admin-app/src/app/components/plan-task/plan-form/plan-form.component.ts b/web-admin-app/src/app/components/plan-task/plan-form/plan-form.component.ts index c893d8f..79a7571 100644 --- a/web-admin-app/src/app/components/plan-task/plan-form/plan-form.component.ts +++ b/web-admin-app/src/app/components/plan-task/plan-form/plan-form.component.ts @@ -85,6 +85,7 @@ export class PlanFormComponent { businessId: this.fb.control(null, []), remark: this.fb.control(null, []), + interval: this.fb.control(0, []), formTempId: this.fb.control(null, [FormValidators.required('请选择')]), diff --git a/web-admin-app/src/app/components/plan-task/plan-list/plan-list.component.ts b/web-admin-app/src/app/components/plan-task/plan-list/plan-list.component.ts index e90c581..9101432 100644 --- a/web-admin-app/src/app/components/plan-task/plan-list/plan-list.component.ts +++ b/web-admin-app/src/app/components/plan-task/plan-list/plan-list.component.ts @@ -15,6 +15,7 @@ import { ASSET_TYPE } from 'app/constants' import { AssetBasicTeamFormComponent } from 'app/components/asset-basic-team-form/asset-basic-team-form.component' import { StatusTagComponent } from 'app/components/status-tag/status-tag.component' import { PlanFormComponent } from '../plan-form/plan-form.component' +import { Utils } from 'app/utils' @Component({ selector: 'app-plan-list', @@ -82,7 +83,7 @@ export class PlanListComponent { return v.status === '1' }, }, - { title: '报表', onClick: this.deleteItem.bind(this) }, + { title: '报表', onClick: this.baobiao.bind(this) }, ]) } @@ -90,6 +91,15 @@ export class PlanListComponent { return this.api.getPlanPage({ ...p, ...q, planType: this.type }) } + baobiao(i: NzSafeAny) { + this.msg.loading('下载中...') + this.api.exportPlanReport(i.jobId).subscribe((res) => { + Utils.downLoadFile(res, 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8') + this.msg.remove() + this.msg.success('下载成功') + }) + } + changeStatus(d: NzSafeAny) { const action = d.status === '0' ? '停用' : '启用' this.modal.confirm({ diff --git a/web-admin-app/src/app/components/plan-task/task-list/task-list.component.ts b/web-admin-app/src/app/components/plan-task/task-list/task-list.component.ts index e87839e..295a2df 100644 --- a/web-admin-app/src/app/components/plan-task/task-list/task-list.component.ts +++ b/web-admin-app/src/app/components/plan-task/task-list/task-list.component.ts @@ -103,13 +103,13 @@ export class TaskListComponent { return v.status === 'APPROVAL' }, }, - { - title: '报表', - onClick: this.onReport.bind(this), - visible(v) { - return v.status === 'COMPLETED' - }, - }, + // { + // title: '报表', + // onClick: this.onReport.bind(this), + // visible(v) { + // return v.status === 'COMPLETED' + // }, + // }, ]) this.api.getAssetTeamAll().subscribe((res) => { this.teamList = res.body.map((i: NzSafeAny) => { @@ -263,6 +263,8 @@ export class TaskListComponent { onHandle(chuzhi: boolean, data: NzSafeAny) { // console.log('chuzhi', chuzhi, data) let nzTitle = chuzhi ? '处置任务' : '任务审批' + + console.log('data', data) const footer: NzSafeAny[] = chuzhi ? [ { @@ -296,14 +298,13 @@ export class TaskListComponent { const res = await lastValueFrom( this.api.handleTaskAssetItem( { - variables: { - ...data, - ...vals, - }, + ...data, + ...vals, + taskId: data.taskId, instanceId: data.procInsId, }, - data.id, + data.taskId, ), ) this.msg.success(res.desc) diff --git a/web-admin-app/src/app/constants/index.ts b/web-admin-app/src/app/constants/index.ts index 9635142..3fdfe9a 100644 --- a/web-admin-app/src/app/constants/index.ts +++ b/web-admin-app/src/app/constants/index.ts @@ -2,8 +2,10 @@ import { PlanTaskType } from 'app/types' export const MAX_PAGE_SIZE = 10000000 +export const VERSION = 'V1' export const LOCALSTORAGKEY = { - quickAction: 'QUICKACTION', + quickAction: `QUICKACTION_${VERSION}`, + report: `REPORT_${VERSION}`, } export const ASSET_STATUS = [ @@ -17,12 +19,25 @@ export const ASSET_STATUS = [ { label: '库存', value: 7 }, { label: '已报废', value: 8 }, ] +// 1-起草 2-审批中 3-已结束 4-已驳回 5-已废弃 6-流程异常 7-待指派 8-已挂起, 9-待处置 +export const ASSET_STATUS_V2 = [ + { label: '起草', value: 1 }, + { label: '审批中', value: 2 }, + { label: '已结束', value: 3 }, + { label: '已驳回', value: 4 }, + { label: '已废弃', value: 5 }, + { label: '流程异常', value: 6 }, + { label: '待指派', value: 7 }, + { label: '已挂起', value: 8 }, + { label: '待处置', value: 9 }, +] export const FLOW_FORM_TYPES = [ { value: 'DATE', label: '日期' }, { value: 'NUMBER', label: '数字' }, { value: 'RADIO', label: '单选' }, { value: 'STRING', label: '文本' }, + { value: 'LIST', label: '列表' }, ] export const ASSET_STATUS_MAP = () => { return ASSET_STATUS.reduce( @@ -170,11 +185,10 @@ export const flowStatus = new Map([ // REJECTED(4, "已驳回"), // DISCARDED(5, "已废弃"), // EXCEPTION(6, "流程异常"), -// TO_BE_ASSIGNED(7,"待指派"), +// TO_BE_ASSIGNED(7,"待指派"), 受理 | 指派 // SUSPENDED(8,"已挂起"), -// // -// DISPOSE(9,"待处置"), -// ; +// DISPOSE(9,"待处置"), 处置 | 挂起 + export const flowIntStatus = new Map([ [1, '起草'], [2, '审批中'], @@ -186,3 +200,14 @@ export const flowIntStatus = new Map([ [8, '已挂起'], [9, '待处置'], ]) +export const flowIntStatusToStr = new Map([ + [1, 'DRAFTING'], + [2, 'APPROVAL'], + [3, 'COMPLETED'], + [4, 'REJECTED'], + [5, 'DISCARDED'], + [6, 'EXCEPTION'], + [7, 'TO_BE_ASSIGNED'], + [8, 'SUSPENDED'], + [9, 'DISPOSE'], +]) diff --git a/web-admin-app/src/app/pages/dashboard/dashboard.component.ts b/web-admin-app/src/app/pages/dashboard/dashboard.component.ts index 8abf0f3..0e0440c 100644 --- a/web-admin-app/src/app/pages/dashboard/dashboard.component.ts +++ b/web-admin-app/src/app/pages/dashboard/dashboard.component.ts @@ -23,19 +23,32 @@ const antvColor = [ ] const defaultAction = [ - { icon: 'database', title: '资产管理', link: '/fixed-asset/manage/list' }, - { icon: 'download', title: '资产入库', link: '/fixed-asset/manage/entry' }, - { icon: 'user-add', title: '资产领用', link: '/fixed-asset/manage/distribution' }, - { icon: 'import', title: '资产退库', link: '/fixed-asset/manage/return' }, - { icon: 'node-expand', title: '资产借用', link: '/fixed-asset/manage/borrow' }, - { icon: 'node-collapse', title: '资产归还', link: '/fixed-asset/manage/revert' }, - { icon: 'node-index', title: '资产调拨', link: '/fixed-asset/manage/allot' }, - { icon: 'sync', title: '资产转换', link: '/fixed-asset/manage/transfer' }, - { icon: 'delete', title: '资产报废', link: '/fixed-asset/manage/scrap' }, - { icon: 'profile', title: '盘点计划', link: '/fixed-asset/stocktaking/plan' }, - { icon: 'file-protect', title: '盘点任务', link: '/fixed-asset/stocktaking/job/list' }, - { icon: 'carry-out', title: '维修登记', link: '/fixed-asset/repair/list' }, - { icon: 'alert', title: '故障登记', link: '/fixed-asset/repair/fault' }, + { icon: 'appstore', title: '资产管理', link: '/fixed-asset/management' }, + { icon: 'appstore', title: '资产台账', link: '/fixed-asset/ledger/asset-search' }, + { icon: 'appstore', title: '资产登记', link: '/fixed-asset/registration' }, + { icon: 'appstore', title: '维修登记', link: '/fixed-asset/maintain/record' }, + { icon: 'appstore', title: '开关机', link: '/fixed-asset/maintain/on-off' }, + { icon: 'appstore', title: '巡检计划', link: '/fixed-asset/inspection/plan' }, + { icon: 'appstore', title: '巡检任务', link: '/fixed-asset/inspection/task' }, + { icon: 'appstore', title: '巡检日历', link: '/fixed-asset/inspection/calendar' }, + { icon: 'appstore', title: '保养计划', link: '/fixed-asset/maintenance/plan' }, + { icon: 'appstore', title: '保养任务', link: '/fixed-asset/maintenance/task' }, + { icon: 'appstore', title: '保养日历', link: '/fixed-asset/maintenance/calendar' }, + { icon: 'appstore', title: '盘点计划', link: '/fixed-asset/stocktaking/plan' }, + { icon: 'appstore', title: '盘点任务', link: '/fixed-asset/stocktaking/task' }, + { icon: 'appstore', title: '盘点日历', link: '/fixed-asset/stocktaking/calendar' }, + // { icon: 'download', title: '资产入库', link: '/fixed-asset/manage/entry' }, + // { icon: 'user-add', title: '资产领用', link: '/fixed-asset/manage/distribution' }, + // { icon: 'import', title: '资产退库', link: '/fixed-asset/manage/return' }, + // { icon: 'node-expand', title: '资产借用', link: '/fixed-asset/manage/borrow' }, + // { icon: 'node-collapse', title: '资产归还', link: '/fixed-asset/manage/revert' }, + // { icon: 'node-index', title: '资产调拨', link: '/fixed-asset/manage/allot' }, + // { icon: 'sync', title: '资产转换', link: '/fixed-asset/manage/transfer' }, + // { icon: 'delete', title: '资产报废', link: '/fixed-asset/manage/scrap' }, + // { icon: 'profile', title: '盘点计划', link: '/fixed-asset/stocktaking/plan' }, + // { icon: 'file-protect', title: '盘点任务', link: '/fixed-asset/stocktaking/job/list' }, + // { icon: 'carry-out', title: '维修登记', link: '/fixed-asset/repair/list' }, + // { icon: 'alert', title: '故障登记', link: '/fixed-asset/repair/fault' }, ] @Component({ @@ -131,6 +144,7 @@ export class DashboardComponent implements OnInit, AfterViewInit { ngOnInit(): void { this.api.getHomeData().subscribe((res) => { this.data = res.body + this.count = res.body.todo this.initChartBar(this.chart1, this.data.assetStatusChart, 1) this.initChartBar(this.chart2, this.data.assetPositionChart, 2) this.initChartBar(this.chart3, this.data.assetCategoryChart, 3) @@ -138,9 +152,9 @@ export class DashboardComponent implements OnInit, AfterViewInit { this.initChartBar(this.chart5, this.data.assetOwnChart, 5) this.initChartBar(this.chart6, this.data.assetUseChart, 6) }) - this.api.getHomeTodocountData().subscribe((res) => { - this.count = res.body - }) + // this.api.getHomeTodocountData().subscribe((res) => { + // this.count = res.body + // }) this.initQuickAction() } diff --git a/web-admin-app/src/app/pages/data-vis/data-vis.component.html b/web-admin-app/src/app/pages/data-vis/data-vis.component.html index 5913909..969b12b 100644 --- a/web-admin-app/src/app/pages/data-vis/data-vis.component.html +++ b/web-admin-app/src/app/pages/data-vis/data-vis.component.html @@ -3,7 +3,7 @@
{{ time | date: 'yyyy-MM-dd HH:mm:ss' }}
-
EAM数据可视化
+
{{ data?.bigScreenName }}
{{ data?.slogan }}
diff --git a/web-admin-app/src/app/pages/data-vis/data-vis.component.less b/web-admin-app/src/app/pages/data-vis/data-vis.component.less index 5621eeb..6b3c3f2 100644 --- a/web-admin-app/src/app/pages/data-vis/data-vis.component.less +++ b/web-admin-app/src/app/pages/data-vis/data-vis.component.less @@ -7,11 +7,10 @@ background-repeat: no-repeat; background-position: 0 0 / cover; background-color: #101129; + overflow: hidden; } - html { - font-size: 21.1375px !important; - } + * { margin: 0; @@ -59,6 +58,7 @@ max-width: 1920px; min-height: 780px; margin: 0 auto; + background-color: #101129; background: url(/assets/data-vis/images/logo.png) no-repeat 0 0 / contain; display: flex; padding: 3.667rem 0.833rem 0; @@ -318,7 +318,7 @@ /* 地图 */ .map { - height: 24.1rem; + height: 23.1rem; margin-bottom: 0.833rem; display: flex; flex-direction: column; diff --git a/web-admin-app/src/app/pages/data-vis/data-vis.component.ts b/web-admin-app/src/app/pages/data-vis/data-vis.component.ts index 52cb682..998455c 100644 --- a/web-admin-app/src/app/pages/data-vis/data-vis.component.ts +++ b/web-admin-app/src/app/pages/data-vis/data-vis.component.ts @@ -1,9 +1,10 @@ -import { Component, ElementRef, ViewChild } from '@angular/core' +import { Component, ElementRef, HostListener, Inject, Renderer2, ViewChild } from '@angular/core' import { ApiService } from 'app/services' import { SharedModule } from 'app/shared/shared.module' import { NzSafeAny } from 'ng-zorro-antd/core/types' -import { interval } from 'rxjs' +import { debounceTime, fromEvent, interval, Subscription } from 'rxjs' import { init, EChartsType } from 'echarts' +import { DOCUMENT } from '@angular/common' @Component({ selector: 'app-data-vis', @@ -13,7 +14,11 @@ import { init, EChartsType } from 'echarts' styleUrl: './data-vis.component.less', }) export class DataVisComponent { - constructor(private api: ApiService) {} + constructor( + private api: ApiService, + private renderer: Renderer2, + @Inject(DOCUMENT) private document: Document, + ) {} @ViewChild('cateTpl') cateTpl?: ElementRef @ViewChild('statusTpl') statusTpl?: ElementRef @@ -30,7 +35,37 @@ export class DataVisComponent { data: NzSafeAny time = new Date() + + private setFontSize() { + const html = this.document.documentElement + + // 计算基于视口宽度和高度的 font-size,取最小值并适当缩放 + const fontSize = `${Math.min(window.innerWidth, window.innerHeight) / 44.5}px` + + // 将计算后的 font-size 应用于根元素 + this.renderer.setStyle(html, 'font-size', fontSize) + } + @HostListener('window:resize') + onResize() { + this.cateRef?.resize() + this.statusRef?.resize() + this.changeRef?.resize() + this.posRef?.resize() + this.flowRef?.resize() + + this.setFontSize() + } + + fullscreenSubscription!: Subscription + + ngOnDestroy(): void { + this.fullscreenSubscription.unsubscribe() + } ngOnInit(): void { + this.setFontSize() + this.fullscreenSubscription = fromEvent(this.document, 'fullscreenchange') + .pipe(debounceTime(100)) + .subscribe(() => this.setFontSize()) this.api.bigScreen().subscribe((res) => { this.data = res.body setTimeout(() => { @@ -64,7 +99,7 @@ export class DataVisComponent { legend: { bottom: 'bottom', left: 'center', - type: 'scroll', + // type: 'scroll', textStyle: { color: '#ffffff', }, @@ -73,14 +108,16 @@ export class DataVisComponent { series: [ { type: 'pie', - radius: [10, 100], + // radius: [10, 100], label: { formatter: '{b}-{c}', // position: 'inside', + color: '#fff', }, itemStyle: { - borderRadius: 8, + // borderRadius: 8, }, + bottom: '40', data: this.data.flowTypeChart.map((i: any) => { return { value: i.total, @@ -104,6 +141,8 @@ export class DataVisComponent { name.push(i.name) val.push(i.total) }) + + console.log('name', name, val) this.posRef.setOption({ grid: { top: '5%', @@ -113,7 +152,7 @@ export class DataVisComponent { }, xAxis: { type: 'category', - boundaryGap: false, + // boundaryGap: false, data: name, splitLine: { show: false, @@ -134,8 +173,6 @@ export class DataVisComponent { { data: val, type: 'bar', - areaStyle: {}, - smooth: true, }, ], }) @@ -201,7 +238,7 @@ export class DataVisComponent { legend: { bottom: 'bottom', left: 'center', - type: 'scroll', + // type: 'scroll', textStyle: { color: '#ffffff', }, @@ -210,11 +247,11 @@ export class DataVisComponent { series: [ { type: 'pie', - radius: [10, 100], + // radius: [10, 100], - roseType: 'area', + // roseType: 'area', itemStyle: { - borderRadius: 8, + // borderRadius: 8, }, data: this.data.assetStatusChart.map((i: any) => { return { @@ -222,6 +259,10 @@ export class DataVisComponent { name: i.name, } }), + bottom: '30', + label: { + color: '#fff', + }, }, ], }) @@ -235,10 +276,12 @@ export class DataVisComponent { } const name: string[] = [] const val: number[] = [] - this.data.assetCategoryChart.forEach((i: any) => { - name.push(i.name) - val.push(i.total) - }) + this.data.assetCategoryChart + // .sort((a: any, b: any) => a.total - b.total) + .forEach((i: any) => { + name.push(i.name) + val.push(i.total) + }) this.cateRef.setOption({ grid: { top: 0, @@ -255,6 +298,7 @@ export class DataVisComponent { yAxis: { type: 'category', data: name, + inverse: true, axisLabel: { show: true, color: '#ffffff', diff --git a/web-admin-app/src/app/pages/fixed-asset/alert/alert-borrow/alert-borrow.component.html b/web-admin-app/src/app/pages/fixed-asset/alert/alert-borrow/alert-borrow.component.html index 524bc28..9ad1475 100644 --- a/web-admin-app/src/app/pages/fixed-asset/alert/alert-borrow/alert-borrow.component.html +++ b/web-admin-app/src/app/pages/fixed-asset/alert/alert-borrow/alert-borrow.component.html @@ -3,6 +3,9 @@ @switch (key) { + @case ('alarmType') { + 借用超期 + } @case ('_useUser') { {{ data?.userName ?? '-' }} } diff --git a/web-admin-app/src/app/pages/fixed-asset/alert/alert-borrow/alert-borrow.component.ts b/web-admin-app/src/app/pages/fixed-asset/alert/alert-borrow/alert-borrow.component.ts index 30dc20d..fd17350 100644 --- a/web-admin-app/src/app/pages/fixed-asset/alert/alert-borrow/alert-borrow.component.ts +++ b/web-admin-app/src/app/pages/fixed-asset/alert/alert-borrow/alert-borrow.component.ts @@ -5,7 +5,7 @@ import { AnyObject, TableOption } from 'app/shared/components/server-paginated-t import { ApiService } from 'app/services' import { SharedModule } from 'app/shared/shared.module' import { format } from 'date-fns' -import { lastValueFrom, of } from 'rxjs' +import { lastValueFrom, map, of } from 'rxjs' import { NzSafeAny } from 'ng-zorro-antd/core/types' import { NzModalService } from 'ng-zorro-antd/modal' import { NzMessageService } from 'ng-zorro-antd/message' @@ -42,20 +42,34 @@ export class AlertBorrowComponent { // rowKey: 'id', // }) .setColumn([ + { key: 'index', title: '序号', visible: true, width: '60px' }, + { key: 'alarmType', title: '报警类型', visible: true }, + { key: 'createTime', title: '告警时间', visible: true }, + { key: 'returnTime', title: '归还时间', visible: true }, + { key: 'businessId', title: '借用业务编号', visible: true }, + { key: 'name', title: '名称', visible: true }, { key: '_category', title: '资产分类', visible: true }, { key: 'assetCode', title: '资产编号', visible: true }, - { key: 'name', title: '名称', visible: true }, + { key: 'model', title: '规格型号', visible: true }, { key: 'serialNumber', title: '序列号', visible: true }, { key: 'notes', title: '备注', visible: true }, - { key: 'returnTime', title: '归还时间', visible: true }, - { key: 'businessId', title: '借用业务编号', visible: true }, + // { key: 'createTime', title: '创建时间', visible: true }, ]) } fetchData(p: {}, q: AnyObject) { - return this.api.getAlertBorrow({ ...p, ...q }) + return this.api.getAlertBorrow({ ...p, ...q }).pipe( + map((r) => { + r.body.rows = r.body.rows.map((item: NzSafeAny, idx: number) => { + item.index = idx + 1 + + return item + }) + return r + }), + ) } } diff --git a/web-admin-app/src/app/pages/fixed-asset/alert/alert-inventory-down/alert-inventory-down.component.ts b/web-admin-app/src/app/pages/fixed-asset/alert/alert-inventory-down/alert-inventory-down.component.ts index 2523a0f..be1ba39 100644 --- a/web-admin-app/src/app/pages/fixed-asset/alert/alert-inventory-down/alert-inventory-down.component.ts +++ b/web-admin-app/src/app/pages/fixed-asset/alert/alert-inventory-down/alert-inventory-down.component.ts @@ -5,7 +5,7 @@ import { AnyObject, TableOption } from 'app/shared/components/server-paginated-t import { ApiService } from 'app/services' import { SharedModule } from 'app/shared/shared.module' import { format } from 'date-fns' -import { lastValueFrom, of } from 'rxjs' +import { lastValueFrom, map, of } from 'rxjs' import { NzSafeAny } from 'ng-zorro-antd/core/types' import { NzModalService } from 'ng-zorro-antd/modal' import { NzMessageService } from 'ng-zorro-antd/message' @@ -40,6 +40,7 @@ export class AlertInventoryDownComponent { // rowKey: 'id', // }) .setColumn([ + { key: 'index', title: '序号', visible: true, width: '60px' }, { key: 'categoryName', title: '资产分类', visible: true }, { key: 'assetCode', title: '资产编号', visible: true }, { key: 'name', title: '名称', visible: true }, @@ -55,6 +56,15 @@ export class AlertInventoryDownComponent { } fetchData(p: {}, q: AnyObject) { - return this.api.getAlertSafetyDown({ ...p, ...q }) + return this.api.getAlertSafetyDown({ ...p, ...q }).pipe( + map((r) => { + r.body.rows = r.body.rows.map((item: NzSafeAny, idx: number) => { + item.index = idx + 1 + + return item + }) + return r + }), + ) } } diff --git a/web-admin-app/src/app/pages/fixed-asset/alert/alert-inventory-safety/alert-inventory-safety.component.ts b/web-admin-app/src/app/pages/fixed-asset/alert/alert-inventory-safety/alert-inventory-safety.component.ts index 2984df8..b5e66e9 100644 --- a/web-admin-app/src/app/pages/fixed-asset/alert/alert-inventory-safety/alert-inventory-safety.component.ts +++ b/web-admin-app/src/app/pages/fixed-asset/alert/alert-inventory-safety/alert-inventory-safety.component.ts @@ -5,7 +5,7 @@ import { AnyObject, TableOption } from 'app/shared/components/server-paginated-t import { ApiService } from 'app/services' import { SharedModule } from 'app/shared/shared.module' import { format } from 'date-fns' -import { lastValueFrom, of } from 'rxjs' +import { lastValueFrom, map, of } from 'rxjs' import { NzSafeAny } from 'ng-zorro-antd/core/types' import { NzModalService } from 'ng-zorro-antd/modal' import { NzMessageService } from 'ng-zorro-antd/message' @@ -40,21 +40,37 @@ export class AlertInventorySafetyComponent { // rowKey: 'id', // }) .setColumn([ - { key: 'categoryName', title: '资产分类', visible: true }, - { key: 'assetCode', title: '资产编号', visible: true }, - { key: 'name', title: '名称', visible: true }, - { key: 'model', title: '规格型号', visible: true }, + // 序号-报警类型-告警时间-资产信息-超期/数量等信息 + { key: 'index', title: '序号', visible: true, width: '60px' }, - { key: 'warehouseName', title: '仓库', visible: true }, + { key: 'alarmType', title: '报警类型', visible: true }, + { key: 'createTime', title: '告警时间', visible: true }, { key: 'count', title: '库存数量', visible: true, width: '100px' }, { key: 'safetyLimit', title: '安全库存', visible: true, width: '100px' }, { key: 'upperLimit', title: '库存上限', visible: true, width: '100px' }, { key: 'lowerLimit', title: '库存下限', visible: true, width: '100px' }, + { key: 'name', title: '名称', visible: true }, + { key: 'categoryName', title: '资产分类', visible: true }, + { key: 'assetCode', title: '资产编号', visible: true }, + + { key: 'model', title: '规格型号', visible: true }, + + { key: 'warehouseName', title: '仓库', visible: true }, + // { key: 'createTime', title: '创建时间', visible: true }, ]) } fetchData(p: {}, q: AnyObject) { - return this.api.getAlertSafety({ ...p, ...q }) + return this.api.getAlertSafety({ ...p, ...q }).pipe( + map((r) => { + r.body.rows = r.body.rows.map((item: NzSafeAny, idx: number) => { + item.index = idx + 1 + + return item + }) + return r + }), + ) } } diff --git a/web-admin-app/src/app/pages/fixed-asset/alert/alert-maintenance/alert-maintenance.component.html b/web-admin-app/src/app/pages/fixed-asset/alert/alert-maintenance/alert-maintenance.component.html index 524bc28..e8b36f3 100644 --- a/web-admin-app/src/app/pages/fixed-asset/alert/alert-maintenance/alert-maintenance.component.html +++ b/web-admin-app/src/app/pages/fixed-asset/alert/alert-maintenance/alert-maintenance.component.html @@ -3,6 +3,9 @@ @switch (key) { + @case ('alarmType') { + 维保到期 + } @case ('_useUser') { {{ data?.userName ?? '-' }} } diff --git a/web-admin-app/src/app/pages/fixed-asset/alert/alert-maintenance/alert-maintenance.component.ts b/web-admin-app/src/app/pages/fixed-asset/alert/alert-maintenance/alert-maintenance.component.ts index c9fe1f1..ad902d0 100644 --- a/web-admin-app/src/app/pages/fixed-asset/alert/alert-maintenance/alert-maintenance.component.ts +++ b/web-admin-app/src/app/pages/fixed-asset/alert/alert-maintenance/alert-maintenance.component.ts @@ -5,7 +5,7 @@ import { AnyObject, TableOption } from 'app/shared/components/server-paginated-t import { ApiService } from 'app/services' import { SharedModule } from 'app/shared/shared.module' import { format } from 'date-fns' -import { lastValueFrom, of } from 'rxjs' +import { lastValueFrom, map, of } from 'rxjs' import { NzSafeAny } from 'ng-zorro-antd/core/types' import { NzModalService } from 'ng-zorro-antd/modal' import { NzMessageService } from 'ng-zorro-antd/message' @@ -39,7 +39,10 @@ export class AlertMaintenanceComponent { // rowKey: 'id', // }) .setColumn([ - { key: '_category', title: '资产分类', visible: true }, + { key: 'index', title: '序号', visible: true, width: '60px' }, + { key: 'alarmType', title: '报警类型', visible: true }, + { key: 'createTime', title: '告警时间', visible: true }, + { key: 'maintenanceEndDate', title: '维保到期时间', visible: true }, { key: 'assetCode', title: '资产编号', visible: true }, { key: 'name', title: '名称', visible: true }, { key: 'model', title: '规格型号', visible: true }, @@ -50,6 +53,15 @@ export class AlertMaintenanceComponent { } fetchData(p: {}, q: AnyObject) { - return this.api.getAlertMaintenance({ ...p, ...q }) + return this.api.getAlertMaintenance({ ...p, ...q }).pipe( + map((r) => { + r.body.rows = r.body.rows.map((item: NzSafeAny, idx: number) => { + item.index = idx + 1 + + return item + }) + return r + }), + ) } } diff --git a/web-admin-app/src/app/pages/fixed-asset/asset-management/asset-management.component.html b/web-admin-app/src/app/pages/fixed-asset/asset-management/asset-management.component.html index 74d0c99..e09ddcc 100644 --- a/web-admin-app/src/app/pages/fixed-asset/asset-management/asset-management.component.html +++ b/web-admin-app/src/app/pages/fixed-asset/asset-management/asset-management.component.html @@ -30,32 +30,20 @@ @switch (key) { @case ('status') { - {{ ASSET_STATUS_MAP[data] }} + {{ ASSET_STATUS_V2_MAP(data) }} } @case ('type') { - + {{ businessType.get(data) }} } - @case ('_warehouse') { - {{ data?.name ?? '-' }} - } - @case ('_position') { - {{ data?.name ?? '-' }} - } - @case ('_head') { - {{ data?.userName ?? '-' }} - } - @case ('_ownCompany') { - {{ data?.organizationName ?? '-' }} - } - @case ('_useOrganization') { - {{ data?.organizationName ?? '-' }} - } - @case ('_category') { - {{ data?.categoryName ?? '-' }} + @case ('urgency') { + + {{ data === 2 ? '紧急' : '普通' }} + } + @default { {{ data }} } @@ -77,7 +65,16 @@ - + + + diff --git a/web-admin-app/src/app/pages/fixed-asset/asset-management/asset-management.component.ts b/web-admin-app/src/app/pages/fixed-asset/asset-management/asset-management.component.ts index 41f02a1..7f27d69 100644 --- a/web-admin-app/src/app/pages/fixed-asset/asset-management/asset-management.component.ts +++ b/web-admin-app/src/app/pages/fixed-asset/asset-management/asset-management.component.ts @@ -22,7 +22,7 @@ import { 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, ASSET_TYPE, businessType } from 'app/constants' +import { ASSET_STATUS, ASSET_STATUS_MAP, ASSET_STATUS_V2, ASSET_TYPE, businessType } from 'app/constants' import { Utils } from 'app/utils' @Component({ @@ -52,7 +52,11 @@ export class AssetManagementComponent { ASSET_STATUS_MAP = ASSET_STATUS_MAP() - ASSET_SOURCE_MAP = ASSET_SOURCE_MAP + ASSET_STATUS = ASSET_STATUS_V2 + + ASSET_STATUS_V2_MAP(v: number) { + return ASSET_STATUS_V2.find((f) => f.value === v)?.label ?? '-' + } table = new TableOption(this.fetchData.bind(this)) @@ -71,18 +75,18 @@ export class AssetManagementComponent { .setColumn([ { key: 'businessId', title: '业务编号', visible: true }, { key: 'name', title: '流程名称', visible: true }, - { key: 'type', title: '流程类型', visible: true }, - { key: 'status', title: '流程状态', visible: true }, - { key: '_ownCompany', title: '紧急程度', visible: true }, - { key: '_useOrganization', title: '发起人', visible: true }, + { key: 'type', title: '流程类型', visible: true, width: '120px' }, + { key: 'status', title: '流程状态', visible: true, width: '100px' }, + { key: 'urgency', title: '紧急程度', visible: true, width: '100px' }, + { key: 'applicant', title: '发起人', visible: true }, { key: 'createTime', title: '创建时间', visible: true }, - { key: '_position', title: '当前节点', visible: true }, - { key: '_position', title: '备注', visible: true }, + { key: 'currentNode', title: '当前节点', visible: true }, + { key: 'notes', title: '备注', visible: true }, ]) .setRowOperate([ { title: '查看', onClick: this.itemAction.bind(this, 'preview') }, - { title: '修改', onClick: this.itemAction.bind(this, 'edit') }, - { title: '删除', onClick: this.deleteItem.bind(this) }, + // { title: '修改', onClick: this.itemAction.bind(this, 'edit') }, + // { title: '删除', onClick: this.deleteItem.bind(this) }, ]) } @@ -137,7 +141,12 @@ export class AssetManagementComponent { nzOnOk: async (e) => { const vals = e.getValues() if (vals) { - const res = await lastValueFrom(this.api.saveBusinessStorage(vals)) + const res = await lastValueFrom( + this.api.assetAddByFlow({ + ...vals, + type: 'STORAGE', + }), + ) this.msg.success(res.desc) this.table.ref.reload() return true @@ -163,7 +172,7 @@ export class AssetManagementComponent { nzOnOk: async (e) => { const vals = e.getValues() if (vals) { - const res = await lastValueFrom(this.api.saveBusinessCollection(vals)) + const res = await lastValueFrom(this.api.assetAddByFlow({ ...vals, type: 'COLLECTION' })) this.msg.success(res.desc) this.table.ref.reload() return true @@ -191,7 +200,7 @@ export class AssetManagementComponent { nzOnOk: async (e) => { const vals = e.getValues() if (vals) { - const res = await lastValueFrom(this.api.saveBusinessReturnInventory(vals)) + const res = await lastValueFrom(this.api.assetAddByFlow({ ...vals, type: 'RETURN_INVENTORY' })) this.msg.success(res.desc) this.table.ref.reload() return true @@ -218,7 +227,7 @@ export class AssetManagementComponent { nzOnOk: async (e) => { const vals = e.getValues() if (vals) { - const res = await lastValueFrom(this.api.saveBusinessBorrow(vals)) + const res = await lastValueFrom(this.api.assetAddByFlow({ ...vals, type: 'BORROW' })) this.msg.success(res.desc) this.table.ref.reload() return true @@ -246,7 +255,7 @@ export class AssetManagementComponent { nzOnOk: async (e) => { const vals = e.getValues() if (vals) { - const res = await lastValueFrom(this.api.saveBusinessAllocate(vals)) + const res = await lastValueFrom(this.api.assetAddByFlow({ ...vals, type: 'ALLOCATE' })) this.msg.success(res.desc) this.table.ref.reload() return true @@ -274,7 +283,7 @@ export class AssetManagementComponent { nzOnOk: async (e) => { const vals = e.getValues() if (vals) { - const res = await lastValueFrom(this.api.saveBusinessTransfer(vals)) + const res = await lastValueFrom(this.api.assetAddByFlow({ ...vals, type: 'TRANSFER' })) this.msg.success(res.desc) this.table.ref.reload() return true @@ -302,7 +311,7 @@ export class AssetManagementComponent { nzOnOk: async (e) => { const vals = e.getValues() if (vals) { - const res = await lastValueFrom(this.api.saveBusinessRetirement(vals)) + const res = await lastValueFrom(this.api.assetAddByFlow({ ...vals, type: 'RETIREMENT' })) this.msg.success(res.desc) this.table.ref.reload() return true @@ -329,7 +338,7 @@ export class AssetManagementComponent { nzOnOk: async (e) => { const vals = e.getValues() if (vals) { - const res = await lastValueFrom(this.api.saveBusinessRevert(vals)) + const res = await lastValueFrom(this.api.assetAddByFlow({ ...vals, type: 'RETURN' })) this.msg.success(res.desc) this.table.ref.reload() return true diff --git a/web-admin-app/src/app/pages/fixed-asset/basic/basic-category/basic-category.component.html b/web-admin-app/src/app/pages/fixed-asset/basic/basic-category/basic-category.component.html index f5835d3..253bd4e 100644 --- a/web-admin-app/src/app/pages/fixed-asset/basic/basic-category/basic-category.component.html +++ b/web-admin-app/src/app/pages/fixed-asset/basic/basic-category/basic-category.component.html @@ -100,160 +100,207 @@ - @for (item of formValue.controls; track $index) { - - - - - - - - - - - - - @for (item of FLOW_FORM_TYPES; track $index) { - - } - - - - @switch ( - formValue.controls.at($index)?.get('type')?.value - ) { - @case ('DATE') { - + + + + + + + + + + + + @for (item of FLOW_FORM_TYPES; track $index) { + + } + + + + @switch ( + formValue.controls.at($index)?.get('type')?.value + ) { + @case ('DATE') { + + } + @case ('RADIO') { + + - } - @case ('RADIO') { - - -
-
+
+ + + -
+ +
- - -
- -
- } - @case ('NUMBER') { - - } - @default { - - } +
+
+
+
+ +
+ } + @case ('NUMBER') { + + } + @default { + } - - - - - - - - - } + } + + + + + + + + diff --git a/web-admin-app/src/app/pages/fixed-asset/basic/basic-category/basic-category.component.ts b/web-admin-app/src/app/pages/fixed-asset/basic/basic-category/basic-category.component.ts index 5d5cda8..74fb193 100644 --- a/web-admin-app/src/app/pages/fixed-asset/basic/basic-category/basic-category.component.ts +++ b/web-admin-app/src/app/pages/fixed-asset/basic/basic-category/basic-category.component.ts @@ -52,7 +52,7 @@ export class BasicCategoryComponent { safetyLimit: [0, []], lowerLimit: [0, []], upperLimit: [0, []], - _assetExtTemp: new FormArray([]), + _assetExtTemp: this.fb.array([]), }) } initQueryForm() { @@ -67,10 +67,9 @@ export class BasicCategoryComponent { } onSelectedChange(v: NzSafeAny) { - this.createForm.patchValue({ - ...v, - }) - this.patchFormValue(v._assetExtTemp ?? []) + const { _assetExtTemp, ...r } = v + this.createForm.patchValue(r) + this.patchFormValue(_assetExtTemp ?? []) } get formValue(): FormArray { @@ -80,12 +79,12 @@ export class BasicCategoryComponent { onConfirm() { if (FormValidators.validateFormGroup(this.createForm)) { const { value } = this.createForm - + console.log('value', value) this.api .updateBasicCategoryTree({ ...value, _assetExtTemp: this.formValue.value.map((v: any) => { - if (v.type === 'RADIO') { + if (v.type === 'RADIO' || v.type === 'LIST') { return { ...v, value: { @@ -123,8 +122,9 @@ export class BasicCategoryComponent { this.formValue.clear() e.forEach((v) => { let value = v.value + // console.log('v', v) const fieldsArrays = this.fb.array([]) - if (v.type === 'RADIO') { + if (v.type === 'RADIO' || v.type === 'LIST') { let val = Object.create(null) try { val = typeof v.value === 'string' ? JSON.parse(v.value) : v.value @@ -134,18 +134,23 @@ export class BasicCategoryComponent { }) value = val?.value } + if (v.type === 'DATE') { + value = new Date(v.value) + } + this.formValue.push( - new FormGroup({ - key: new FormControl(v.key, []), - value: new FormControl(value, []), - name: new FormControl(v.name, []), - type: new FormControl(v.type, []), - remark: new FormControl(v.remark, []), - sort: new FormControl(v.sort ?? 0, []), + this.fb.group({ + key: this.fb.control(v.key, []), + value: this.fb.control(value, []), + name: this.fb.control(v.name, []), + type: this.fb.control(v.type, []), + remark: this.fb.control(v.remark, []), + sort: this.fb.control(v.sort ?? 0, []), fields: fieldsArrays, }), ) }) + console.log('this.formValue', this.formValue) } formatRadioValue(fields: string[], value: string) {} diff --git a/web-admin-app/src/app/pages/fixed-asset/basic/basic-flow-form-manage/basic-flow-form-manage.component.html b/web-admin-app/src/app/pages/fixed-asset/basic/basic-flow-form-manage/basic-flow-form-manage.component.html index 7d14eb4..f13d86d 100644 --- a/web-admin-app/src/app/pages/fixed-asset/basic/basic-flow-form-manage/basic-flow-form-manage.component.html +++ b/web-admin-app/src/app/pages/fixed-asset/basic/basic-flow-form-manage/basic-flow-form-manage.component.html @@ -52,15 +52,11 @@ 选择模板 - +
- + 点击下载模板示例 @@ -85,116 +81,138 @@ - @for (item of formValue.controls; track $index) { - - - - - - - - - - - - - @for (item of FLOW_FORM_TYPES; track $index) { - - } - - - - @switch (formValue.controls.at($index)?.get('type')?.value) { - @case ('DATE') { - - } - @case ('RADIO') { - - -
-
+ + + + + + + + + + + + @for (item of FLOW_FORM_TYPES; track $index) { + + } + + + + @switch (formValue.controls.at($index)?.get('type')?.value) { + @case ('DATE') { + + } + @case ('LIST') { + + +
+
+ + -
+ +
-
-
-
- -
- } - @case ('NUMBER') { - - } - @default { - - } +
+ + +
+ +
} - - - - - - - - - } + @case ('RADIO') { + + +
+
+ + +
+
+
+
+
+ +
+ } + @case ('NUMBER') { + + } + @default { + + } + } + + + + + + + + @@ -211,20 +229,20 @@ - 模板示例 + 模板预览 - + - 点击下载模板示例 + 点击下载预览 - + diff --git a/web-admin-app/src/app/pages/fixed-asset/basic/basic-flow-form-manage/basic-flow-form-manage.component.ts b/web-admin-app/src/app/pages/fixed-asset/basic/basic-flow-form-manage/basic-flow-form-manage.component.ts index b437337..3c43e23 100644 --- a/web-admin-app/src/app/pages/fixed-asset/basic/basic-flow-form-manage/basic-flow-form-manage.component.ts +++ b/web-admin-app/src/app/pages/fixed-asset/basic/basic-flow-form-manage/basic-flow-form-manage.component.ts @@ -21,7 +21,7 @@ import { lastValueFrom } from 'rxjs' export class BasicFlowFormManageComponent { constructor(public api: ApiService) {} - step = 2 + step = 0 formJsonData = [] @@ -59,7 +59,7 @@ export class BasicFlowFormManageComponent { this.formGroup.get(k)?.setValue(v) } }) - console.log('this.formGroup', this.formGroup) + // console.log('this.formGroup', this.formGroup) }) } } @@ -83,16 +83,17 @@ export class BasicFlowFormManageComponent { } fb = inject(FormBuilder) - onTplupload(e: NzSafeAny[]) { - this.patchFormValue(e) + onTplupload(e: NzSafeAny) { + this.patchFormValue(e?._formValue ?? []) } patchFormValue(e: NzSafeAny[]) { this.formValue.clear() + e.forEach((v) => { let value = v.value const fieldsArrays = this.fb.array([]) - if (v.type === 'RADIO') { + if (v.type === 'RADIO' || v.type === 'LIST') { let val = Object.create(null) try { val = typeof v.value === 'string' ? JSON.parse(v.value) : v.value @@ -101,7 +102,9 @@ export class BasicFlowFormManageComponent { fieldsArrays.push(this.fb.control(i)) }) value = val?.value + // console.log('fieldsArrays', val) } + this.formValue.push( new FormGroup({ key: new FormControl(v.key, []), @@ -125,11 +128,11 @@ export class BasicFlowFormManageComponent { } if (currentStep === 1) { this.handleSubmit() - } - if (currentStep === 2) { + } else if (currentStep === 2) { this.handleConfirm() + } else { + this.step = currentStep + 1 } - this.step = currentStep + 1 } handleSubmit() { @@ -140,16 +143,27 @@ export class BasicFlowFormManageComponent { nzContent: '确定提交表单?', nzOnOk: async () => { const vals = this.formGroup.value + + const _formValue = vals._formValue!.map((i: any) => { + return { + ...i, + value: ['RADIO', 'LIST'].includes(i.type) ? { fields: i.fields, value: i.value } : i.value, + } + }) const res = await lastValueFrom( this.id ? this.api.updateFlowForm({ ...vals, + _formValue, id: this.id, formTempId: this.id, }) : this.api.addFlowForm(vals), ) this.msg.success(res.desc) + if (!this.id) { + this.id = res.body.formTempId + } // this.router.navigate(['/fixed-asset/basic/flow-form/list']) this.step = 2 }, @@ -158,7 +172,7 @@ export class BasicFlowFormManageComponent { } handleConfirm() { if (FormValidators.validateFormGroup(this.formGroup)) { - if (!this.formValue.value?.templatePath) { + if (!this.formGroup.value?.templatePath) { this.msg.error('请先上传模板') return } @@ -186,7 +200,25 @@ export class BasicFlowFormManageComponent { getRadioFieldsFormArray(index: number): FormArray { return this.formValue.at(index).get('fields') as FormArray } + + previewTpl() { + this.msg.loading('正在下载...', { nzDuration: 0 }) + this.api.preview(this.id!).subscribe((res) => { + Utils.downLoadFile(res, 'application/pdf;charset=utf-8') + // const blob = new Blob([res as any], { type: 'application/pdf;charset=utf-8' }) + // const url = URL.createObjectURL(blob) + + // // 在新窗口打开 PDF 预览 + // window.open(url, '_blank') + + // // 释放 URL 资源,避免内存泄漏(延迟一点时间释放以确保预览完成) + // setTimeout(() => URL.revokeObjectURL(url), 10000) + this.msg.remove() + this.msg.success('下载成功') + }) + } getRadioFields(index: number): any[] { + // console.log('this.getRadioFieldsFormArray(index).controls', this.getRadioFieldsFormArray(index).controls) return this.getRadioFieldsFormArray(index).controls } cancel(currentStep: number) { @@ -229,6 +261,7 @@ export class BasicFlowFormManageComponent { removeFormItem(idx: number) { this.formValue.removeAt(idx) + // console.log('this.formValue', this.formValue.controls, idx) } removeRadioItem(idx: number, idx2: number) { diff --git a/web-admin-app/src/app/pages/fixed-asset/basic/basic-flow-form/basic-flow-form.component.ts b/web-admin-app/src/app/pages/fixed-asset/basic/basic-flow-form/basic-flow-form.component.ts index eed7db8..4cf3512 100644 --- a/web-admin-app/src/app/pages/fixed-asset/basic/basic-flow-form/basic-flow-form.component.ts +++ b/web-admin-app/src/app/pages/fixed-asset/basic/basic-flow-form/basic-flow-form.component.ts @@ -74,7 +74,7 @@ export class BasicFlowFormComponent { { title: '编辑', onClick: this.onEdit.bind(this) }, { title: '删除', onClick: this.onDelete.bind(this) }, { title: '停用', onClick: this.onSetApprover.bind(this) }, - { title: '预览', onClick: this.onSetApprover.bind(this) }, + { title: '预览', onClick: this.onPreview.bind(this) }, ]) } @@ -100,6 +100,22 @@ export class BasicFlowFormComponent { return this.api.getFlowFormsList({ ...p, ...q }).pipe() } + onPreview(data?: NzSafeAny) { + this.msg.loading('正在下载...', { nzDuration: 0 }) + this.api.preview(data.formTempId).subscribe((res) => { + Utils.downLoadFile(res, 'application/pdf;charset=utf-8') + // const blob = new Blob([res as any], { type: 'application/pdf;charset=utf-8' }) + // const url = URL.createObjectURL(blob) + + // // 在新窗口打开 PDF 预览 + // window.open(url, '_blank') + + // // 释放 URL 资源,避免内存泄漏(延迟一点时间释放以确保预览完成) + // setTimeout(() => URL.revokeObjectURL(url), 10000) + this.msg.remove() + this.msg.success('下载成功') + }) + } onSetApprover(data?: NzSafeAny) { if (data) { this.createForm.patchValue({ diff --git a/web-admin-app/src/app/pages/fixed-asset/maintain/maintain-on-off/maintain-on-off.component.html b/web-admin-app/src/app/pages/fixed-asset/maintain/maintain-on-off/maintain-on-off.component.html index baa68a2..2686214 100644 --- a/web-admin-app/src/app/pages/fixed-asset/maintain/maintain-on-off/maintain-on-off.component.html +++ b/web-admin-app/src/app/pages/fixed-asset/maintain/maintain-on-off/maintain-on-off.component.html @@ -63,7 +63,7 @@ - + - diff --git a/web-admin-app/src/app/pages/fixed-asset/maintain/maintain-on-off/maintain-on-off.component.ts b/web-admin-app/src/app/pages/fixed-asset/maintain/maintain-on-off/maintain-on-off.component.ts index e89d2f8..0beebb3 100644 --- a/web-admin-app/src/app/pages/fixed-asset/maintain/maintain-on-off/maintain-on-off.component.ts +++ b/web-admin-app/src/app/pages/fixed-asset/maintain/maintain-on-off/maintain-on-off.component.ts @@ -50,15 +50,13 @@ export class MaintainOnOffComponent { rowKey: 'assetId', }) .setColumn([ - { key: 'serialNumber', title: '序号', visible: true }, { key: 'assetCode', title: '资产编号', visible: true }, { key: 'name', title: '资产名称', visible: true }, - { key: 'deviceStatus', 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 }, + { key: 'deviceStatus', title: '当前状态', visible: true, width: '120px' }, + { key: 'serialNumber', title: '序列号', visible: true }, + { key: 'status', title: '资产状态', visible: true, width: '120px' }, + { key: 'lastTime', title: '最后操作时间', visible: true }, ]) .setRowOperate([ // { title: '修改', onClick: this.onCreate.bind(this) }, diff --git a/web-admin-app/src/app/pages/fixed-asset/maintain/on-off-records/on-off-records.component.html b/web-admin-app/src/app/pages/fixed-asset/maintain/on-off-records/on-off-records.component.html index 46dbdb8..65772df 100644 --- a/web-admin-app/src/app/pages/fixed-asset/maintain/on-off-records/on-off-records.component.html +++ b/web-admin-app/src/app/pages/fixed-asset/maintain/on-off-records/on-off-records.component.html @@ -1,12 +1,23 @@ -
- - @for (item of records; track $index) { - - {{ item.operationType }} - +
+
+ +
+
+ @if (records.length > 0) { + + @for (item of records; track $index) { + +
+ {{ item.createTime }} +
+
+ {{ item.operationType }} +
+
+ } +
+ } @else { + } - +
diff --git a/web-admin-app/src/app/pages/fixed-asset/maintain/on-off-records/on-off-records.component.ts b/web-admin-app/src/app/pages/fixed-asset/maintain/on-off-records/on-off-records.component.ts index 96464d8..a5f49c9 100644 --- a/web-admin-app/src/app/pages/fixed-asset/maintain/on-off-records/on-off-records.component.ts +++ b/web-admin-app/src/app/pages/fixed-asset/maintain/on-off-records/on-off-records.component.ts @@ -3,6 +3,7 @@ import { ApiService } from 'app/services' import { SharedModule } from 'app/shared/shared.module' import { NzSafeAny } from 'ng-zorro-antd/core/types' import { NZ_MODAL_DATA } from 'ng-zorro-antd/modal' +import { format } from 'date-fns' @Component({ selector: 'app-on-off-records', @@ -17,9 +18,27 @@ export class OnOffRecordsComponent implements OnInit { data = inject(NZ_MODAL_DATA) records: NzSafeAny[] = [] + + range: Date[] = [] + + onDateChange() { + this.getRecords() + } ngOnInit(): void { + this.getRecords() + } + + getRecords() { if (this.data) { - this.api.onOffRecord(this.data.assetId).subscribe((res) => { + let d = {} + if (this.range.length > 1) { + let startTime = null + let endTime = null + startTime = this.range[0].getTime() + endTime = this.range[1].getTime() + d = { startTime, endTime } + } + this.api.onOffRecord({ id: this.data.assetId, ...d }).subscribe((res) => { this.records = res.body }) } 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 79792d4..d5d6e88 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 @@ -131,7 +131,9 @@ export class FixedAssetManageComponent { const ids = item ? [item.assetId] : Array.from(this.table.ref.selected) this.modal.confirm({ nzTitle: '警告', - nzContent: `是否要删除${ids.length}个资产?`, + nzContent: `是否要删除当前选中资产?`, + nzOkDanger: true, + nzIconType: '', nzOnOk: async () => { const res = await lastValueFrom(this.api.deleteAsset(ids)) this.msg.success(res.desc) diff --git a/web-admin-app/src/app/pages/fixed-asset/registration/registration.component.html b/web-admin-app/src/app/pages/fixed-asset/registration/registration.component.html index 7f7ef0d..b437000 100644 --- a/web-admin-app/src/app/pages/fixed-asset/registration/registration.component.html +++ b/web-admin-app/src/app/pages/fixed-asset/registration/registration.component.html @@ -257,11 +257,7 @@ 扩展资产表单 - - @for (item of flowForms; track $index) { - - } - + } diff --git a/web-admin-app/src/app/pages/fixed-asset/registration/registration.component.ts b/web-admin-app/src/app/pages/fixed-asset/registration/registration.component.ts index 9b17cb3..3b9ee8d 100644 --- a/web-admin-app/src/app/pages/fixed-asset/registration/registration.component.ts +++ b/web-admin-app/src/app/pages/fixed-asset/registration/registration.component.ts @@ -6,7 +6,12 @@ import { ApiService } from 'app/services' import { SharedModule } from 'app/shared/shared.module' import { format } from 'date-fns' import { lastValueFrom, of } from 'rxjs' -import { AssetFormComponent, ManufacturerSelectComponent, PositionSelectComponent } from 'app/components' +import { + AssetCategorySelectComponent, + 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' @@ -16,7 +21,13 @@ import { Utils } from 'app/utils' @Component({ selector: 'app-fixed-asset-registration', standalone: true, - imports: [SharedModule, AssetFormComponent, PositionSelectComponent, ManufacturerSelectComponent], + imports: [ + SharedModule, + AssetFormComponent, + PositionSelectComponent, + ManufacturerSelectComponent, + AssetCategorySelectComponent, + ], templateUrl: './registration.component.html', styleUrl: './registration.component.less', }) @@ -119,6 +130,7 @@ export class RegistrationComponent { nzContent: AssetFormComponent, nzWidth: '80vw', nzWrapClassName: 'modal-lg', + nzFooter: preview ? null : undefined, nzData: { value: data, preview, @@ -141,7 +153,10 @@ export class RegistrationComponent { const ids = item ? [item.assetId] : Array.from(this.table.ref.selected) this.modal.confirm({ nzTitle: '警告', - nzContent: `是否要删除${ids.length}个资产?`, + + nzContent: `是否要删除当前选中资产?`, + nzOkDanger: true, + nzIconType: 'exclamation-circle', nzOnOk: async () => { const res = await lastValueFrom(this.api.deleteAsset(ids)) this.msg.success(res.desc) diff --git a/web-admin-app/src/app/pages/flow/flow-main/flow-main.component.html b/web-admin-app/src/app/pages/flow/flow-main/flow-main.component.html index a5ed0a4..004b0b7 100644 --- a/web-admin-app/src/app/pages/flow/flow-main/flow-main.component.html +++ b/web-admin-app/src/app/pages/flow/flow-main/flow-main.component.html @@ -35,8 +35,8 @@
- @for (item of assetFlows; track $index) { -
+ @for (i of assetFlows; track $index) { +
@@ -46,7 +46,7 @@
- {{ item.name }} + {{ i.name }}
diff --git a/web-admin-app/src/app/pages/flow/flow-main/flow-main.component.ts b/web-admin-app/src/app/pages/flow/flow-main/flow-main.component.ts index 394501e..6b53bfa 100644 --- a/web-admin-app/src/app/pages/flow/flow-main/flow-main.component.ts +++ b/web-admin-app/src/app/pages/flow/flow-main/flow-main.component.ts @@ -75,7 +75,7 @@ export class FlowMainComponent implements OnInit { res.body.forEach((i: NzSafeAny) => { const enabled = Boolean(comsMap[i.formKey as keyof typeof comsMap]) const formType = (i.formKey as string).split('_').splice(-1)[0] - console.log('formType', formType) + const item = { ...i, enabled, formType } if (i.type === '设备流程') { this.deviceFlows.push(item) @@ -83,6 +83,8 @@ export class FlowMainComponent implements OnInit { this.assetFlows.push(item) } }) + + console.log('this.deviceFlows', this.deviceFlows, this.assetFlows) }) } @@ -92,7 +94,7 @@ export class FlowMainComponent implements OnInit { if (i.type === '设备流程') { this.devicecounter = i } else { - this.assetFlows = i + this.assetcounter = i } }) }) diff --git a/web-admin-app/src/app/pages/flow/flow-report/flow-report.component.html b/web-admin-app/src/app/pages/flow/flow-report/flow-report.component.html index 49c2fdf..117ac22 100644 --- a/web-admin-app/src/app/pages/flow/flow-report/flow-report.component.html +++ b/web-admin-app/src/app/pages/flow/flow-report/flow-report.component.html @@ -1,19 +1,20 @@ -
-
+
+
任务类型 - - - - + + + + @@ -35,101 +36,294 @@
-
+
- 自定义时段 + 开始时间 - + + + +
+
+ + 结束时间 + +
- - - - + + + + +
-
-
-
- 工作报表 -
-
- 日期:{{ data.startDate | date: 'yyyy-MM-dd' }} ~ {{ data.endDate | date: 'yyyy-MM-dd' }} -
-
-
-
-

{{ reportTypeText.get(reportType) }}工作概述

-
-
- -
-
-
    -
  • -

    {{ data.taskCount ?? 0 }}

    -

    累计处理任务数

    -
  • -
  • -

    {{ data.taskCount ?? 0 }}

    -

    已完成任务数

    -
  • -
  • -

    {{ data.taskCount ?? 0 }}

    -

    未完成任务数

    -
  • -
-
+ @if (data) { +
+
+
+ +
+
+ 报告周期:{{ data.startDate | date: 'yyyy-MM-dd' }} ~ + {{ data.endDate | date: 'yyyy-MM-dd' }}
- @for (item of data.taskList; track $index) { -
-

任务执行情况

+
+
+

当期工作概述

-
-

任务执行数据分析

-
-
-
-
- + +
+
+
+
+
+
报修维修任务简报
+
    +
  • +
    + {{ heji.weibao.total }} +
    +
    维修任务数
    +
  • +
  • +
    + {{ heji.weibao.deviceComplete }} +
    +
    已修复设备
    +
  • +
  • +
    + {{ heji.weibao.deviceUnComplete }} +
    +
    未修复设备
    +
  • +
+
+
+ +
+
+
设备巡检任务简报
+
    +
  • +
    + {{ heji.xunjian.total }} +
    +
    巡检任务数
    +
  • +
  • +
    + {{ heji.xunjian.deviceComplete }} +
    +
    已巡设备
    +
  • +
  • +
    + {{ heji.xunjian.deviceUnComplete }} +
    +
    未巡设备
    +
  • +
+
+
+ +
+
+
设备保养任务简报
+
    +
  • +
    + {{ heji.baoyang.total }} +
    +
    保养任务数
    +
  • +
  • +
    + {{ heji.baoyang.deviceComplete }} +
    +
    保养设备
    +
  • +
  • +
    + {{ heji.baoyang.deviceUnComplete }} +
    +
    未处理设备
    +
  • +
+
+
- } + @for (item of taskTypeData | keyvalue; track $index) { + @if (item.value.length) { +
+
+

{{ taskTypeNameMap.get(item.key) }}任务执行情况

+
+
+

任务执行数据分析

+
+
+ +
+ +
+
+
+ +
+
+
+
+ } + } -
-

工作计划

-
-
- +
+

工作计划

+
+
+ +
-
-
-

总结

-
-
- +
+

总结

+
+
+ +
-
- + } @else { + + + + }
diff --git a/web-admin-app/src/app/pages/flow/flow-report/flow-report.component.less b/web-admin-app/src/app/pages/flow/flow-report/flow-report.component.less index c7fc982..23c3f98 100644 --- a/web-admin-app/src/app/pages/flow/flow-report/flow-report.component.less +++ b/web-admin-app/src/app/pages/flow/flow-report/flow-report.component.less @@ -1,127 +1,27 @@ -.report { - - - padding: 24px; - background-color: #fff; - - h1 { - font-size: 22px; - } - - h2 { - font-size: 18x; - } - - .report-title { - position: relative; - - } - - .echart { - height: 205px; - - } - - .pie { - width: 200px; - } - - .line { - flex: 1; - } - - .report-title-left { - font-size: 24px; - text-align: center; - } - - .report-title-right { - position: absolute; - bottom: 5px; - right: 0; - } - - .report-footer { - text-align: right; +::ng-deep { + .uneditable { - &>div { - margin-top: 12px; - } - } - - .report-content-row { - min-height: 220px; + pointer-events: none; - textarea { - width: 100%; - min-height: 150px; - border: 1px solid #ccc; - - &:focus, - &:active, - &:hover { - outline: none; - border: 1px solid #ccc; - } + textarea, + input { + border: none; + outline: none; + resize: none !important; } - } - - .report-content-row-content { - display: flex; - .report-content-row-left { - display: flex; - flex-basis: 60%; - flex-shrink: 0; - } - - .report-content-row-right { - padding-left: 24px; - flex: 1; + .readonly { + position: absolute; + inset: 0; + pointer-events: none; + z-index: 100; + background-color: red; + opacity: .5; } } +} - .counter { - display: flex; - justify-content: center; - - - - - li { - margin: 0 12px; - padding: 24px 0; - flex: 1; - text-align: center; - border: 1px dashed #027db4; - - &.error { - border-color: #d9001b; - - p { - color: #d9001b; - } - } - - &.success { - border-color: #70b603; - - p { - color: #70b603; - } - } - - p { - margin-bottom: 6px; - color: #027db4; - - &:first-child { - - font-size: 20px; - font-weight: bold; - } - } - } - } +.report { + width: 793.92px !important; } \ No newline at end of file diff --git a/web-admin-app/src/app/pages/flow/flow-report/flow-report.component.ts b/web-admin-app/src/app/pages/flow/flow-report/flow-report.component.ts index 96fa60f..823870d 100644 --- a/web-admin-app/src/app/pages/flow/flow-report/flow-report.component.ts +++ b/web-admin-app/src/app/pages/flow/flow-report/flow-report.component.ts @@ -1,4 +1,4 @@ -import { Component, ElementRef, QueryList, ViewChildren } from '@angular/core' +import { Component, ElementRef, inject, QueryList, ViewChild, ViewChildren } from '@angular/core' import { FormControl, FormGroup } from '@angular/forms' import { ApiService } from 'app/services' import { SharedModule } from 'app/shared/shared.module' @@ -13,12 +13,113 @@ import { startOfYear, endOfYear, format, + addDays, + addWeeks, + addMonths, + addYears, + parseISO, } from 'date-fns' -import { finalize } from 'rxjs' +import { finalize, lastValueFrom } from 'rxjs' import { init, EChartsType } from 'echarts' +import { Utils } from 'app/utils' +import { NzMessageService } from 'ng-zorro-antd/message' +import { NzModalService } from 'ng-zorro-antd/modal' +import { LOCALSTORAGKEY } from 'app/constants' -function getDateRange(n: number): { startDate: string; endDate: string } { +type Task = { + createTime: string + deviceComplete: number + deviceTotal: number + formKey: string + status: number + taskName: string + taskTypeName: string +} + +type AnalysisResult = { + dataAfterFormat: { name: string; totalTask: number }[] + analysis: { + averageTaskPerDay: number + maxTasksInADay: number + } +} + +function analyzeTasks(n: number, data: Task[]): AnalysisResult { + const dateFormats = ['yyyy-MM-dd', 'yyyy-MM', 'yyyy'] + const formatDate = (date: string, formatPattern: string) => format(parseISO(date), formatPattern) + + const groupTasksBy = (tasks: Task[], formatPattern: string) => { + return tasks.reduce( + (acc, task) => { + const dateKey = formatDate(task.createTime, formatPattern) + acc[dateKey] = (acc[dateKey] || 0) + 1 + return acc + }, + {} as Record, + ) + } + + let formatPattern: string + if (n === 3) { + formatPattern = dateFormats[1] // "yyyy-MM" for monthly grouping + } else { + formatPattern = dateFormats[0] // "yyyy-MM-dd" for daily grouping + } + + const dateGroup = groupTasksBy(data, formatPattern) + + const dataAfterFormat = Object.entries(dateGroup).map(([name, totalTask]) => ({ + name, + totalTask, + })) + + const totalTasks = dataAfterFormat.reduce((sum, item) => sum + item.totalTask, 0) + const maxTasksInADay = Math.max(...dataAfterFormat.map((item) => item.totalTask)) + const daysCount = Object.keys(dateGroup).length + + const analysis = { + averageTaskPerDay: daysCount ? totalTasks / daysCount : 0, + maxTasksInADay, + } + + return { + dataAfterFormat, + analysis, + } +} + +interface DateRange { + startDate: string + endDate: string +} + +function calculateDateRange(type: number, startTime: Date): DateRange { + let endTime: Date + + switch (type) { + case 0: + endTime = addDays(startTime, 1) + break + case 1: + endTime = addWeeks(startTime, 1) + break + case 2: + endTime = addMonths(startTime, 1) + break + case 3: + endTime = addYears(startTime, 1) + break + default: + throw new Error('Invalid type. Expected 0, 1, 2, or 3.') + } + + return { + startDate: format(startTime, 'yyyy-MM-dd'), + endDate: format(endTime, 'yyyy-MM-dd'), + } +} +function getDateRange1(n: number): { startDate: string; endDate: string } { const today = new Date() let startDate: Date @@ -51,6 +152,17 @@ function getDateRange(n: number): { startDate: string; endDate: string } { } } +const gaisuTpl = `本周执行了{job},合计处置{taskTotal}条任务,涉及设备{deviceTotal}台/次,整体任务完成率{process}%!` + +const taskTpl = `{taskType}执行{taskTotal}条,已完成任务{completed}、未完成任务{uncomplete},整体任务完成率{process}%,平均任务处理数{avgNum},最高日处理任务数{highNum}。 +涉及设备数{deviceTotal},完成处置设备{deviceComplete},待处置设备数{deviceUnComplete}。 +` + +const planTpl = `1、按时保质完成{task}的任务内容 +2、补充完成上周期待处理任务 +3、响应临时或手动指派任务 + ` + @Component({ selector: 'app-flow-report', standalone: true, @@ -61,18 +173,22 @@ function getDateRange(n: number): { startDate: string; endDate: string } { export class FlowReportComponent { constructor(private api: ApiService) {} - formKeys: NzSafeAny[] = [] + formKeys: string[] = ['eam_device_repair', 'eam_device_inspection', 'eam_device_maintenance'] reportType: number = 0 range: Date[] = [] + date = new Date() + data: NzSafeAny loading = false today = format(new Date(), 'yyyy年MM月dd日') + @ViewChild('reportTpl') reportTpl!: ElementRef + reportTypeText = new Map([ [0, '今日'], [1, '本周'], @@ -80,138 +196,410 @@ export class FlowReportComponent { [3, '本年'], ]) - gaishu = ` - 1、本周 - 2、继续对所有锅炉和电梯设备进行定期巡检,确保设备安全稳定运行。 - 3、根据本周巡检结果,对设备维护计划进行必要的调整,以提高设备运行效率和安全性。` + taskTypeNameMap = new Map([ + ['weibao', '报修维修'], + ['xunjian', '设备巡检'], + ['baoyang', '设备保养'], + ]) + + taskTypeData: Record<'weibao' | 'xunjian' | 'baoyang', NzSafeAny[]> = { + weibao: [], + xunjian: [], + baoyang: [], + } + taskTypeLineData: Record = { + weibao: { dataAfterFormat: [], analysis: { averageTaskPerDay: 0, maxTasksInADay: 0 } }, + xunjian: { dataAfterFormat: [], analysis: { averageTaskPerDay: 0, maxTasksInADay: 0 } }, + baoyang: { dataAfterFormat: [], analysis: { averageTaskPerDay: 0, maxTasksInADay: 0 } }, + } + + taskTypeText: Record<'weibao' | 'xunjian' | 'baoyang', string> = { + weibao: '', + xunjian: '', + baoyang: '', + } + + gaishu = '' + + plan = `` + + zongjie = `` - plan = ` - 1、安排专业人员对{锅炉001}进行返修,确保设备尽快恢复正常运行。 - 2、继续对所有锅炉和电梯设备进行定期巡检,确保设备安全稳定运行。 - 3、根据本周巡检结果,对设备维护计划进行必要的调整,以提高设备运行效率和安全性。 - ` + title = '工作报表' - zongjie = ` - 本周的巡检和检修工作总体顺利,除了锅炉001需要返修外,其他设备均运行正常。 - 我们将继续密切关注设备状态,并及时处理任何潜在问题,以确保公司运营的顺畅和安全。 - 请各部门继续配合我们的工作,如有任何问题或建议,请及时与我们联系。 - - ` + footer = '' @ViewChildren('itemElement') itemElements!: QueryList + echartsImgMap = new Map() + ngOnInit() { this.onTypeChange(this.reportType) + this.initReport() } + initReport() { + let cache: any = {} + try { + cache = JSON.parse(localStorage.getItem(LOCALSTORAGKEY.report) || '{}') + } catch (error) {} + if (!cache._v) { + return + } + + const { gaishu, footer, zongjie, plan, title, taskTypeText, ...data } = cache + + this.data = data + this.gaishu = gaishu + this.plan = plan + this.zongjie = zongjie + this.title = title + this.footer = footer + this.taskTypeText = taskTypeText + + this.genReport(true) + } ngAfterViewInit() {} onTypeChange(n: number) { - const { startDate, endDate } = getDateRange(n) - this.range = [new Date(startDate), new Date(endDate)] - this.onChange() + const { endDate } = calculateDateRange(n, this.date) + this.range = [new Date(this.date), new Date(endDate)] } - onChange() { + + onStartDateChange() { + const { endDate } = calculateDateRange(this.reportType, this.date) + this.range = [new Date(this.date), new Date(endDate)] + } + + print() { + this.edited = false + window.print() + } + + msg = inject(NzMessageService) + taskTypeName = new Set() + heji: NzSafeAny = {} + + edited = false + edit() { + if (this.edited) { + this.modal.confirm({ + nzTitle: '请确认是否保存?', + nzContent: '保存将覆盖原有内容', + nzOnOk: async () => { + localStorage.setItem( + LOCALSTORAGKEY.report, + JSON.stringify({ + _v: Date.now(), + ...this.data, + gaishu: this.gaishu, + plan: this.plan, + zongjie: this.zongjie, + title: this.title, + footer: this.footer, + taskTypeText: this.taskTypeText, + }), + ) + this.edited = false + // await this.getReportData() + // this.genReport() + }, + }) + } else { + this.edited = true + } + } + + getRangeDate() { let startDate = '' let endDate = '' - this.loading = true if (this.range.length === 2) { startDate = format(this.range[0], 'yyyy-MM-dd') endDate = format(this.range[1], 'yyyy-MM-dd') } - this.api - .getReportData({ - formKeys: this.formKeys, - reportType: this.reportType, - startDate, - endDate, - }) - .pipe( - finalize(() => { - this.loading = false - }), + return { startDate, endDate } + } + + modal = inject(NzModalService) + onCreate() { + this.modal.confirm({ + nzTitle: '请确认是否生成新报告?', + nzContent: '当前操作会清空报告内容,并重新生成新报告。请对原有报告进行妥善处理', + nzOkText: '确认生成', + nzOnOk: async () => { + await this.getReportData() + this.genReport() + }, + }) + } + + async getReportData() { + this.loading = true + const { startDate, endDate } = this.getRangeDate() + + const res = await lastValueFrom( + this.api + .getReportData({ + formKeys: this.formKeys, + reportType: this.reportType, + startDate, + endDate, + }) + .pipe( + finalize(() => { + this.loading = false + }), + ), + ) + this.data = res.body + } + async genReport(cached = false) { + const odata = this.data + this.heji = { + job: '', + taskTotal: odata.taskList.length, + deviceTotal: 0, + process: 0, + deviceComplete: 0, + weibao: { + total: 0, + complete: 0, + uncomplete: 0, + deviceTotal: 0, + deviceComplete: 0, + deviceUnComplete: 0, + }, + xunjian: { + total: 0, + complete: 0, + uncomplete: 0, + deviceTotal: 0, + deviceComplete: 0, + deviceUnComplete: 0, + }, + baoyang: { + total: 0, + complete: 0, + uncomplete: 0, + deviceTotal: 0, + deviceComplete: 0, + deviceUnComplete: 0, + }, + } as any + + odata.taskList.forEach((i: any) => { + this.heji.deviceTotal += i.deviceTotal + this.heji.deviceComplete += i.deviceComplete + this.taskTypeName.add(i.taskTypeName) + const deviceUnComplete = i.deviceTotal - i.deviceComplete + switch (i.taskTypeName) { + case '设备保养': + this.heji.baoyang.total += 1 + this.heji.baoyang.complete += i.status === 3 ? 1 : 0 + this.heji.baoyang.uncomplete += i.status !== 3 ? 1 : 0 + this.heji.baoyang.deviceComplete += i.status === 3 ? i.deviceComplete : 0 + this.heji.baoyang.deviceUnComplete += i.status === 3 ? deviceUnComplete : 0 + this.heji.baoyang.deviceTotal += i.status === 3 ? i.deviceTotal : 0 + this.taskTypeData.baoyang.push(i) + break + case '设备巡检': + this.heji.xunjian.total += 1 + this.heji.xunjian.complete += i.status === 3 ? 1 : 0 + this.heji.xunjian.uncomplete += i.status !== 3 ? 1 : 0 + this.heji.xunjian.deviceComplete += i.status === 3 ? i.deviceComplete : 0 + this.heji.xunjian.deviceUnComplete += i.status === 3 ? deviceUnComplete : 0 + this.heji.xunjian.deviceTotal += i.status === 3 ? i.deviceTotal : 0 + this.taskTypeData.xunjian.push(i) + break + case '报修维修': + this.heji.weibao.total += 1 + this.heji.weibao.complete += i.status === 3 ? 1 : 0 + this.heji.weibao.uncomplete += i.status !== 3 ? 1 : 0 + this.heji.weibao.deviceComplete += i.status === 3 ? i.deviceComplete : 0 + this.heji.weibao.deviceUnComplete += i.status === 3 ? deviceUnComplete : 0 + this.heji.weibao.deviceTotal += i.status === 3 ? i.deviceTotal : 0 + this.taskTypeData.weibao.push(i) + break + } + }) + this.taskTypeLineData = { + weibao: analyzeTasks(this.reportType, this.taskTypeData.weibao), + xunjian: analyzeTasks(this.reportType, this.taskTypeData.xunjian), + baoyang: analyzeTasks(this.reportType, this.taskTypeData.baoyang), + } + this.heji.job = Array.from(this.taskTypeName).filter(Boolean).join('、') + this.heji.process = Math.round((this.heji.deviceComplete / this.heji.deviceTotal || 0) * 100).toFixed(2) + + if (!cached) { + this.title = '工作报表' + this.zongjie = '' + this.gaishu = gaisuTpl.replace(/\{(.*?)\}/g, (_, key) => this.heji[key] ?? '') + const p: any = { task: this.heji.job } + this.plan = planTpl.replace(/\{(.*?)\}/g, (_, key) => p[key] ?? '') + this.footer = ` + ${odata.organizationName}-${odata.userName} + ${this.today} + ` + } + + Object.entries(this.taskTypeText).forEach(([k, v]) => { + // {taskType}执行{taskTotal}条,已完成任务{completed}、未完成任务{uncomplete},整体任务完成率{process}%,平均处理时间{avgTime}!平均任务处理数{avgNum},最高日处理任务数{highNum}。 + // 涉及设备数{deviceTotal},完成处置设备{deviceComplete},待处置设备数{deviceUnComplete}。 + const analysis = (this.taskTypeLineData[k] as AnalysisResult).analysis + const data: any = { + taskType: this.taskTypeNameMap.get(k), + taskTotal: this.heji[k].total, + completed: this.heji[k].complete, + uncomplete: this.heji[k].uncomplete, + process: Math.round((this.heji[k].complete / this.heji[k].total || 0) * 100).toFixed(2), + + avgNum: analysis.averageTaskPerDay, + highNum: analysis.maxTasksInADay, + deviceTotal: this.heji[k].deviceTotal, + deviceComplete: this.heji[k].deviceComplete, + deviceUnComplete: this.heji[k].deviceTotal - this.heji[k].deviceComplete, + } + this.taskTypeText[k as 'weibao' | 'xunjian' | 'baoyang'] = taskTpl.replace( + /\{(.*?)\}/g, + (_, key) => data[key] ?? '', ) - .subscribe((res) => { - this.data = res.body - setTimeout(() => { - console.log('this.data', this.itemElements) - this.itemElements.forEach((itemElement, index) => { - console.log(`Element ${index}: `, itemElement.nativeElement) - this.renderPie(itemElement.nativeElement, []) - this.renderLine(itemElement.nativeElement, []) - }) - }, 0) + }) + + setTimeout(() => { + this.itemElements.forEach((itemElement, index) => { + const ele = itemElement.nativeElement as HTMLDivElement + const type = ele.dataset['type'] as 'weibao' | 'xunjian' | 'baoyang' + const img = { pie: '', line: '' } + this.echartsImgMap.set(type, img) + this.renderPie(itemElement.nativeElement, [this.heji[type]['total'], this.heji[type]['complete']], img) + this.renderLine(itemElement.nativeElement, this.taskTypeLineData[type].dataAfterFormat, img) }) + }, 0) } - renderLine(el: HTMLElement, data: NzSafeAny[]) { + renderLine(el: HTMLElement, data: NzSafeAny[], img: NzSafeAny) { el = el.querySelector('.line') as HTMLDivElement if (el) { const lineRef = init(el) const name: string[] = [] const value: number[] = [] + data?.forEach((i: NzSafeAny) => { name.push(i.name) - value.push(i.value) + value.push(i.totalTask) }) + lineRef.setOption({ xAxis: { type: 'category', - data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'], + data: name, }, yAxis: { type: 'value', }, series: [ { - data: [820, 932, 901, 934, 1290, 1330, 1320], + data: value, type: 'line', smooth: true, }, ], }) + setTimeout(() => { + img.line = lineRef.getDataURL() + }, 1000) } } - renderPie(el: HTMLElement, data: NzSafeAny[]) { + renderPie(el: HTMLElement, data: NzSafeAny[], img: NzSafeAny) { el = el.querySelector('.pie') as HTMLDivElement if (el) { const pieRef = init(el) - let data: NzSafeAny[] = [] - const odata: NzSafeAny[] = data ?? [] - const total = odata.reduce((a: number, b: any) => a + Math.abs(b.value), 0) - - data = odata.map((i: NzSafeAny) => { - const value = Math.abs(i.value) - const percent = ((value / total) * 100).toFixed(2) - - return { - ...i, - percent, - value, - } - }) + pieRef.setOption({ - title: { - text: '', - }, + // title: [ + // //标题组件,数组里的一个对象表示一个标题组件 + // { text: '任务执行数据分析', top: 'left', textStyle: { color: '#000' } }, + // ], series: [ + //系列 { - name: 'Access From', - type: 'pie', - radius: ['40%', '70%'], - avoidLabelOverlap: false, + name: '任务执行效率', + type: 'pie', //pie类型的图实现环形图 + radius: ['60%', '90%'], //数组的话,表示内圆和外圆的半径大小,相对于宽高中较小的那一个。 + center: ['50%', '50%'], //圆心坐标 + avoidLabelOverlap: false, //是否启用防止标签重叠策略 + startAngle: 270, //第一个数据开始绘制的角度,以正交直角坐标系为标准 label: { - show: false, - position: 'center', + //每个数据的标签 + show: true, //设置为true则显示第一个数据 + position: 'center', //位置居中 + formatter: '任务完成 \n{d}%', //{d}表示数据在总数据中的百分比 + fontSize: 20, + fontWeight: 'bold', + }, + color: ['#695BF9', '#1E3E55'], //系列的颜色 + emphasis: { + scale: false, //表示不放大item + }, + labelLine: { + show: true, }, - data: [ - { value: 1048, name: 'Search Engine' }, - { value: 735, name: 'Direct' }, + { value: data[0] || 0, name: '' }, + { + value: data[1] || 0, + name: '', + emphasis: { + label: { + show: false, //这个数据高亮时不显示label,就不会显示替遮住第一个数据的label值了 + }, + }, + }, ], }, ], }) + setTimeout(() => { + img.pie = pieRef.getDataURL() + }, 1000) } } + + export() { + const { startDate, endDate } = this.getRangeDate() + const vals = { + endDate, + inspectDeviceComplete: this.heji.xunjian.deviceComplete, + inspectDeviceUnComplete: this.heji.xunjian.deviceUnComplete, + inspectTaskAnalysis: this.taskTypeText['xunjian'], + inspectTaskBar: this.echartsImgMap.get('xunjian')?.line, + inspectTaskPie: this.echartsImgMap.get('xunjian')?.pie, + inspectTaskTotal: this.heji.xunjian.total, + maintainDeviceComplete: this.heji.baoyang.deviceComplete, + maintainDeviceUnComplete: this.heji.baoyang.deviceUnComplete, + maintainTaskAnalysis: this.taskTypeText['baoyang'], + maintainTaskBar: this.echartsImgMap.get('baoyang')?.line, + maintainTaskPie: this.echartsImgMap.get('baoyang')?.pie, + maintainTaskTotal: this.heji.baoyang.total, + repairDeviceComplete: this.heji.weibao.deviceComplete, + repairDeviceUnComplete: this.heji.weibao.deviceComplete, + repairTaskAnalysis: this.taskTypeText['weibao'], + repairTaskBar: this.echartsImgMap.get('weibao')?.line, + repairTaskPie: this.echartsImgMap.get('weibao')?.pie, + repairTaskTotal: this.heji.weibao.total, + sign: this.footer, + startDate, + summarize: this.zongjie, + workOverview: this.gaishu, + workPlan: this.plan, + } + this.api.downloadWord(vals).subscribe((res) => { + Utils.downLoadFile( + res, + 'application/vnd.openxmlformats-officedocument.wordprocessingml.document;charset=utf-8', + ) + this.msg.remove() + this.msg.success('下载成功') + }) + } } diff --git a/web-admin-app/src/app/pages/login/login.component.html b/web-admin-app/src/app/pages/login/login.component.html index a691a0a..7b21e68 100644 --- a/web-admin-app/src/app/pages/login/login.component.html +++ b/web-admin-app/src/app/pages/login/login.component.html @@ -1,9 +1,9 @@