chenc 4 роки тому
батько
коміт
94fa55f9b0
27 змінених файлів з 3038 додано та 57 видалено
  1. 34 18
      src/app/routes/project-manage-archives/add/add.component.ts
  2. 19 19
      src/app/routes/project-manage-archives/add/business-affairs/business-affairs.component.html
  3. 4 3
      src/app/routes/project-manage-archives/add/business-affairs/business-affairs.component.ts
  4. 2 0
      src/app/routes/project-manage-archives/list/list.component.html
  5. 53 14
      src/app/routes/project-manage-archives/list/list.component.ts
  6. 3 1
      src/app/routes/project-manage-archives/project-manage-archives-routing.module.ts
  7. 14 2
      src/app/routes/project-manage-archives/project-manage-archives.module.ts
  8. 1 0
      src/app/routes/project-manage-archives/project-node-tree.ts
  9. 484 0
      src/app/routes/project-manage-archives/update/business-affairs/business-affairs.component.html
  10. 24 0
      src/app/routes/project-manage-archives/update/business-affairs/business-affairs.component.spec.ts
  11. 232 0
      src/app/routes/project-manage-archives/update/business-affairs/business-affairs.component.ts
  12. 142 0
      src/app/routes/project-manage-archives/update/development/development.component.html
  13. 24 0
      src/app/routes/project-manage-archives/update/development/development.component.spec.ts
  14. 214 0
      src/app/routes/project-manage-archives/update/development/development.component.ts
  15. 192 0
      src/app/routes/project-manage-archives/update/essential-information/essential-information.component.html
  16. 24 0
      src/app/routes/project-manage-archives/update/essential-information/essential-information.component.spec.ts
  17. 284 0
      src/app/routes/project-manage-archives/update/essential-information/essential-information.component.ts
  18. 141 0
      src/app/routes/project-manage-archives/update/implementation/implementation.component.html
  19. 24 0
      src/app/routes/project-manage-archives/update/implementation/implementation.component.spec.ts
  20. 228 0
      src/app/routes/project-manage-archives/update/implementation/implementation.component.ts
  21. 142 0
      src/app/routes/project-manage-archives/update/serviceta/serviceta.component.html
  22. 24 0
      src/app/routes/project-manage-archives/update/serviceta/serviceta.component.spec.ts
  23. 215 0
      src/app/routes/project-manage-archives/update/serviceta/serviceta.component.ts
  24. 46 0
      src/app/routes/project-manage-archives/update/update.component.html
  25. 24 0
      src/app/routes/project-manage-archives/update/update.component.spec.ts
  26. 401 0
      src/app/routes/project-manage-archives/update/update.component.ts
  27. 43 0
      src/app/services/project-manage-archives/project-manage-archives.service.ts

+ 34 - 18
src/app/routes/project-manage-archives/add/add.component.ts

@@ -13,6 +13,8 @@ import { BaseArchivesMilestone } from 'app/entity/basedata/base-archives-milesto
 import { BaseArchivesMilestoneService } from 'app/services/basedata/base-archives-milestone.service';
 import { ProjectManageArchives } from 'app/entity/project-manage-archives/project-manage-archives';
 import { I18NService } from '@core';
+import { ProjectManageArchivesService } from 'app/services/project-manage-archives/project-manage-archives.service';
+import { DatePipe } from '@angular/common';
 
 @Component({
   selector: 'app-project-manage-archives-add',
@@ -41,6 +43,8 @@ export class ProjectManageArchivesAddComponent implements OnInit {
     private baseArchivesMilestoneService: BaseArchivesMilestoneService,
     private nzNotificationService: NzNotificationService,
     private i18NService: I18NService,
+    private projectManageArchivesService:ProjectManageArchivesService,
+    private datePipe:DatePipe
   ) {}
 
   ngOnInit(): void {
@@ -187,17 +191,21 @@ export class ProjectManageArchivesAddComponent implements OnInit {
     });
   }
 
+  /**
+   * 保存接口
+   */
   save() {
     return new Promise(resolve => {
+      this.isLoadingSave=true;
       //基本信息中的
       this.essentialInformation.submitForm();
       //基本信息
       let projectManageArchives = this.essentialInformation.projectManageArchivesa;
-      //已回款金额
-      projectManageArchives.received;
       //组织
       projectManageArchives.pkOrg = sessionStorage.getItem('pkOrg');
       ////////////商务页签的计划表格数据
+      //已回款金额
+      projectManageArchives.received=this.businessAffairs.projectManageArchives.received;
       let bsInfo: any = {};
       bsInfo.coPlanList = this.businessAffairs.collectionPlanList; //收款计划
       bsInfo.coSituationList = this.businessAffairs.paymentCollectionList; //收款情况
@@ -225,14 +233,16 @@ export class ProjectManageArchivesAddComponent implements OnInit {
       this.getMileItem(this.serviceta, serviceta);
       seInfo.planList = serviceta;
       projectManageArchives.seInfo = seInfo;
-      this.baseArchivesMilestoneService.add(projectManageArchives).then(response => {
+      this.projectManageArchivesService.add(projectManageArchives).then(response => {
         if (response.success) {
           //保存成功
+          this.isLoadingSave=false;
           this.nzNotificationService.success(this.i18NService.fanyi('save.ok'), '');
-          this.drawerRef.close();
+          this.drawerRef.close(true);
           resolve();
         } else {
           //保存失败
+          this.isLoadingSave=false;
           this.nzNotificationService.error(this.i18NService.fanyi('save.not'), '');
         }
       });
@@ -247,26 +257,32 @@ export class ProjectManageArchivesAddComponent implements OnInit {
   getMileItem(component, list) {
     component.listOfMapData.forEach(item => {
       component.mapOfExpandedData[item.key].forEach(element => {
+        element.startDate = this.datePipe.transform(element.startDate, 'yyyy-MM-dd HH:mm:ss');
+        element.endDate = this.datePipe.transform(element.endDate, 'yyyy-MM-dd HH:mm:ss');
         let names = ''; //人员名称
         let ids = ''; //人员id
         //获取执行人的名称和id
-        element.executors.forEach(element => {
-          component.personnelList.forEach(pkOrg => {
-            pkOrg.children.forEach(depart => {
-              depart.children.forEach(personnel => {
-                if (personnel.key === element) {
-                  if (names === '') {
-                    names = personnel.name;
-                    ids = personnel.key;
-                  } else {
-                    names = names + '、' + personnel.name;
-                    ids = ids + '、' + personnel.key;
+        if (element.executors) {
+          element.executors.forEach(element => {
+            component.personnelList.forEach(pkOrg => {
+              pkOrg.children.forEach(depart => {
+                depart.children.forEach(personnel => {
+                  if (personnel.key === element) {
+                    if (names === '') {
+                      names = personnel.name;
+                      ids = personnel.key;
+                    } else {
+                      names = names + '、' + personnel.name;
+                      ids = ids + '、' + personnel.key;
+                    }
                   }
-                }
+                });
               });
             });
           });
-        });
+        }
+        element.muilesName=element.name;
+        element.keyId=element.key;
         element.executor = names;
         element.executorId = ids;
         list.push(element);
@@ -275,6 +291,6 @@ export class ProjectManageArchivesAddComponent implements OnInit {
   }
 
   close() {
-    this.drawerRef.close();
+    this.drawerRef.close(true);
   }
 }

+ 19 - 19
src/app/routes/project-manage-archives/add/business-affairs/business-affairs.component.html

@@ -93,7 +93,7 @@
             <td style="width: 5%;">
               <nz-select style="width: 100%;" nzShowSearch nzAllowClear [(ngModel)]="data.mileId2" nzPlaceHolder="请选择"
                 [nzDropdownMatchSelectWidth]="false">
-                <nz-option *ngFor="let i of milestoneList" [nzValue]="i.value" [nzLabel]="i.text"></nz-option>
+                <nz-option *ngFor="let i of milestoneList" [nzValue]="i.id" [nzLabel]="i.name"></nz-option>
               </nz-select>
             </td>
             <td style="width: 5%;">
@@ -107,7 +107,7 @@
             <td style="width: 5%;">
               <nz-select style="width: 100%;" nzShowSearch nzAllowClear [(ngModel)]="data.mileId3" nzPlaceHolder="请选择"
                 [nzDropdownMatchSelectWidth]="false">
-                <nz-option *ngFor="let i of milestoneList" [nzValue]="i.value" [nzLabel]="i.text"></nz-option>
+                <nz-option *ngFor="let i of milestoneList" [nzValue]="i.id" [nzLabel]="i.name"></nz-option>
               </nz-select>
             </td>
             <td style="width: 5%;">
@@ -121,7 +121,7 @@
             <td style="width: 5%;">
               <nz-select style="width: 100%;" nzShowSearch nzAllowClear [(ngModel)]="data.mileId4" nzPlaceHolder="请选择"
                 [nzDropdownMatchSelectWidth]="false">
-                <nz-option *ngFor="let i of milestoneList" [nzValue]="i.value" [nzLabel]="i.text"></nz-option>
+                <nz-option *ngFor="let i of milestoneList" [nzValue]="i.id" [nzLabel]="i.name"></nz-option>
               </nz-select>
             </td>
             <td style="width: 5%;">
@@ -135,7 +135,7 @@
             <td style="width: 5%;">
               <nz-select style="width: 100%;" nzShowSearch nzAllowClear [(ngModel)]="data.mileId5" nzPlaceHolder="请选择"
                 [nzDropdownMatchSelectWidth]="false">
-                <nz-option *ngFor="let i of milestoneList" [nzValue]="i.value" [nzLabel]="i.text"></nz-option>
+                <nz-option *ngFor="let i of milestoneList" [nzValue]="i.id" [nzLabel]="i.name"></nz-option>
               </nz-select>
             </td>
             <td style="width: 5%;">
@@ -190,7 +190,7 @@
             <td style="width: 5%;">
               <nz-select style="width: 100%;" nzShowSearch nzAllowClear [(ngModel)]="data.mileId1" nzPlaceHolder="请选择"
                 [nzDropdownMatchSelectWidth]="false" (ngModelChange)="mileChange(data)">
-                <nz-option *ngFor="let i of milestoneList" [nzValue]="i.value" [nzLabel]="i.text"></nz-option>
+                <nz-option *ngFor="let i of milestoneList" [nzValue]="i.id" [nzLabel]="i.name"></nz-option>
               </nz-select>
             </td>
             <td style="width: 5%;">
@@ -204,7 +204,7 @@
             <td style="width: 5%;">
               <nz-select style="width: 100%;" nzShowSearch nzAllowClear [(ngModel)]="data.mileId2" nzPlaceHolder="请选择"
                 [nzDropdownMatchSelectWidth]="false" (ngModelChange)="mileChange(data)">
-                <nz-option *ngFor="let i of milestoneList" [nzValue]="i.value" [nzLabel]="i.text"></nz-option>
+                <nz-option *ngFor="let i of milestoneList" [nzValue]="i.id" [nzLabel]="i.name"></nz-option>
               </nz-select>
             </td>
             <td style="width: 5%;">
@@ -218,7 +218,7 @@
             <td style="width: 5%;">
               <nz-select style="width: 100%;" nzShowSearch nzAllowClear [(ngModel)]="data.mileId3" nzPlaceHolder="请选择"
                 [nzDropdownMatchSelectWidth]="false" (ngModelChange)="mileChange(data)">
-                <nz-option *ngFor="let i of milestoneList" [nzValue]="i.value" [nzLabel]="i.text"></nz-option>
+                <nz-option *ngFor="let i of milestoneList" [nzValue]="i.id" [nzLabel]="i.name"></nz-option>
               </nz-select>
             </td>
             <td style="width: 5%;">
@@ -232,7 +232,7 @@
             <td style="width: 5%;">
               <nz-select style="width: 100%;" nzShowSearch nzAllowClear [(ngModel)]="data.mileId4" nzPlaceHolder="请选择"
                 [nzDropdownMatchSelectWidth]="false" (ngModelChange)="mileChange(data)">
-                <nz-option *ngFor="let i of milestoneList" [nzValue]="i.value" [nzLabel]="i.text"></nz-option>
+                <nz-option *ngFor="let i of milestoneList" [nzValue]="i.id" [nzLabel]="i.name"></nz-option>
               </nz-select>
             </td>
             <td style="width: 5%;">
@@ -246,7 +246,7 @@
             <td style="width: 5%;">
               <nz-select style="width: 100%;" nzShowSearch nzAllowClear [(ngModel)]="data.mileId5" nzPlaceHolder="请选择"
                 [nzDropdownMatchSelectWidth]="false" (ngModelChange)="mileChange(data)">
-                <nz-option *ngFor="let i of milestoneList" [nzValue]="i.value" [nzLabel]="i.text"></nz-option>
+                <nz-option *ngFor="let i of milestoneList" [nzValue]="i.id" [nzLabel]="i.name"></nz-option>
               </nz-select>
             </td>
             <td style="width: 5%;">
@@ -301,7 +301,7 @@
             <td style="width: 5%;">
               <nz-select style="width: 100%;" nzShowSearch nzAllowClear [(ngModel)]="data.mileId1" nzPlaceHolder="请选择"
                 [nzDropdownMatchSelectWidth]="false">
-                <nz-option *ngFor="let i of milestoneList" [nzValue]="i.value" [nzLabel]="i.text"></nz-option>
+                <nz-option *ngFor="let i of milestoneList" [nzValue]="i.id" [nzLabel]="i.name"></nz-option>
               </nz-select>
             </td>
             <td style="width: 5%;">
@@ -315,7 +315,7 @@
             <td style="width: 5%;">
               <nz-select style="width: 100%;" nzShowSearch nzAllowClear [(ngModel)]="data.mileId2" nzPlaceHolder="请选择"
                 [nzDropdownMatchSelectWidth]="false">
-                <nz-option *ngFor="let i of milestoneList" [nzValue]="i.value" [nzLabel]="i.text"></nz-option>
+                <nz-option *ngFor="let i of milestoneList" [nzValue]="i.id" [nzLabel]="i.name"></nz-option>
               </nz-select>
             </td>
             <td style="width: 5%;">
@@ -329,7 +329,7 @@
             <td style="width: 5%;">
               <nz-select style="width: 100%;" nzShowSearch nzAllowClear [(ngModel)]="data.mileId3" nzPlaceHolder="请选择"
                 [nzDropdownMatchSelectWidth]="false">
-                <nz-option *ngFor="let i of milestoneList" [nzValue]="i.value" [nzLabel]="i.text"></nz-option>
+                <nz-option *ngFor="let i of milestoneList" [nzValue]="i.id" [nzLabel]="i.name"></nz-option>
               </nz-select>
             </td>
             <td style="width: 5%;">
@@ -343,7 +343,7 @@
             <td style="width: 5%;">
               <nz-select style="width: 100%;" nzShowSearch nzAllowClear [(ngModel)]="data.mileId4" nzPlaceHolder="请选择"
                 [nzDropdownMatchSelectWidth]="false">
-                <nz-option *ngFor="let i of milestoneList" [nzValue]="i.value" [nzLabel]="i.text"></nz-option>
+                <nz-option *ngFor="let i of milestoneList" [nzValue]="i.id" [nzLabel]="i.name"></nz-option>
               </nz-select>
             </td>
             <td style="width: 5%;">
@@ -357,7 +357,7 @@
             <td style="width: 5%;">
               <nz-select style="width: 100%;" nzShowSearch nzAllowClear [(ngModel)]="data.mileId5" nzPlaceHolder="请选择"
                 [nzDropdownMatchSelectWidth]="false">
-                <nz-option *ngFor="let i of milestoneList" [nzValue]="i.value" [nzLabel]="i.text"></nz-option>
+                <nz-option *ngFor="let i of milestoneList" [nzValue]="i.id" [nzLabel]="i.name"></nz-option>
               </nz-select>
             </td>
             <td style="width: 5%;">
@@ -412,7 +412,7 @@
             <td style="width: 5%;">
               <nz-select style="width: 100%;" nzShowSearch nzAllowClear [(ngModel)]="data.mileId1" nzPlaceHolder="请选择"
                 [nzDropdownMatchSelectWidth]="false">
-                <nz-option *ngFor="let i of milestoneList" [nzValue]="i.value" [nzLabel]="i.text"></nz-option>
+                <nz-option *ngFor="let i of milestoneList" [nzValue]="i.id" [nzLabel]="i.name"></nz-option>
               </nz-select>
             </td>
             <td style="width: 5%;">
@@ -426,7 +426,7 @@
             <td style="width: 5%;">
               <nz-select style="width: 100%;" nzShowSearch nzAllowClear [(ngModel)]="data.mileId2" nzPlaceHolder="请选择"
                 [nzDropdownMatchSelectWidth]="false">
-                <nz-option *ngFor="let i of milestoneList" [nzValue]="i.value" [nzLabel]="i.text"></nz-option>
+                <nz-option *ngFor="let i of milestoneList" [nzValue]="i.id" [nzLabel]="i.name"></nz-option>
               </nz-select>
             </td>
             <td style="width: 5%;">
@@ -440,7 +440,7 @@
             <td style="width: 5%;">
               <nz-select style="width: 100%;" nzShowSearch nzAllowClear [(ngModel)]="data.mileId3" nzPlaceHolder="请选择"
                 [nzDropdownMatchSelectWidth]="false">
-                <nz-option *ngFor="let i of milestoneList" [nzValue]="i.value" [nzLabel]="i.text"></nz-option>
+                <nz-option *ngFor="let i of milestoneList" [nzValue]="i.id" [nzLabel]="i.name"></nz-option>
               </nz-select>
             </td>
             <td style="width: 5%;">
@@ -454,7 +454,7 @@
             <td style="width: 5%;">
               <nz-select style="width: 100%;" nzShowSearch nzAllowClear [(ngModel)]="data.mileId4" nzPlaceHolder="请选择"
                 [nzDropdownMatchSelectWidth]="false">
-                <nz-option *ngFor="let i of milestoneList" [nzValue]="i.value" [nzLabel]="i.text"></nz-option>
+                <nz-option *ngFor="let i of milestoneList" [nzValue]="i.id" [nzLabel]="i.name"></nz-option>
               </nz-select>
             </td>
             <td style="width: 5%;">
@@ -468,7 +468,7 @@
             <td style="width: 5%;">
               <nz-select style="width: 100%;" nzShowSearch nzAllowClear [(ngModel)]="data.mileId5" nzPlaceHolder="请选择"
                 [nzDropdownMatchSelectWidth]="false">
-                <nz-option *ngFor="let i of milestoneList" [nzValue]="i.value" [nzLabel]="i.text"></nz-option>
+                <nz-option *ngFor="let i of milestoneList" [nzValue]="i.id" [nzLabel]="i.name"></nz-option>
               </nz-select>
             </td>
             <td style="width: 5%;">

+ 4 - 3
src/app/routes/project-manage-archives/add/business-affairs/business-affairs.component.ts

@@ -123,7 +123,7 @@ export class ProjectManageArchivesAddBusinessAffairsComponent implements OnInit
         price4: 0,
         price5: 0,
         sort: this.paymentPlanSort,
-        planType: '3',
+        planType: '4',
       },
     ];
     this.paymentPlanSort++;
@@ -146,14 +146,15 @@ export class ProjectManageArchivesAddBusinessAffairsComponent implements OnInit
     if (type === '2') {
       //获取收款计划的金额
       this.getCollectionPlanPrice(this.collectionPlanList,data);
-      //回写数据到实施、开发、服务页签的回款信息
-      this.getRemittanceInformationChange(data);
+      
     }
     //如果是付款情况表格中下来触发
     if (type === '4') {
       //获取付款计划中的金额
       this.getCollectionPlanPrice(this.paymentPlanList,data);
     }
+    //回写数据到实施、开发、服务页签的回款信息
+    this.getRemittanceInformationChange(data);
   }
 
   /**

+ 2 - 0
src/app/routes/project-manage-archives/list/list.component.html

@@ -51,6 +51,8 @@
           <tr *ngFor="let data of basicTable.data">
             <td>{{ data.proCode }}</td>
             <td>{{ data.proName }}</td>
+            <td>{{ data.cusName }}</td>
+            <td>{{ data.totalPrice }}</td>
             <td>
               <a (click)="update(data)" acl [acl-ability]="'base-archives-cost:update'">修改</a>
               <nz-divider nzType="vertical" acl [acl-ability]="'base-archives-cost:update'"></nz-divider>

+ 53 - 14
src/app/routes/project-manage-archives/list/list.component.ts

@@ -3,9 +3,11 @@ import { _HttpClient, ModalHelper } from '@delon/theme';
 import { STColumn, STComponent } from '@delon/abc';
 import { SFSchema } from '@delon/form';
 import { ProjectManageArchives } from 'app/entity/project-manage-archives/project-manage-archives';
-import { NzDrawerService } from 'ng-zorro-antd';
+import { NzDrawerService, NzNotificationService } from 'ng-zorro-antd';
 import { I18NService } from '@core';
 import { ProjectManageArchivesAddComponent } from '../add/add.component';
+import { ProjectManageArchivesService } from 'app/services/project-manage-archives/project-manage-archives.service';
+import { ProjectManageArchivesUpdateComponent } from '../update/update.component';
 
 @Component({
   selector: 'app-project-manage-archives-list',
@@ -16,10 +18,14 @@ export class ProjectManageArchivesListComponent implements OnInit {
 
   constructor(
     private nzDrawerService:NzDrawerService,
-    private i18NService:I18NService
+    private i18NService:I18NService,
+    private projectManageArchivesService:ProjectManageArchivesService,
+    private nzNotificationService:NzNotificationService
   ) { }
 
-  ngOnInit() { }
+  ngOnInit() { 
+    this.getList();
+  }
 
   listOfData = [];
   projectManageArchives: ProjectManageArchives={}; //对象
@@ -41,9 +47,9 @@ export class ProjectManageArchivesListComponent implements OnInit {
   getList(){
     // this.isSpinning=true;
     this.projectManageArchives.pkOrg=sessionStorage.getItem("pkOrg");//组织
-    // this.baseArchivesCostService.getList(this.baseArchivesCost).then((response)=>{
-    //   this.listOfData=response.result.records
-    // })
+    this.projectManageArchivesService.getList(this.projectManageArchives).then((response)=>{
+      this.listOfData=response.result.records
+    })
   }
 
   /**
@@ -70,19 +76,52 @@ export class ProjectManageArchivesListComponent implements OnInit {
     });
 
     //关闭抽屉的回调
-    // drawerRef.afterClose.subscribe((isRefresh) => {
-    //   if (isRefresh) {//刷新list列表
-    //     this.getProjectQuotation();
-    //   }
-    // });
+    drawerRef.afterClose.subscribe((isRefresh) => {
+      if (isRefresh) {//刷新list列表
+        this.getList();
+      }
+    });
   }
 
-  update(){
+  /**
+   * 修改
+   */
+  update(data){
+    const drawerRef = this.nzDrawerService.create<ProjectManageArchivesUpdateComponent, { id: string }, string>({
+      nzTitle: this.i18NService.fanyi("table.update"),//修改标题
+      nzContent: ProjectManageArchivesUpdateComponent,
+      nzWidth: window.innerWidth,
+      nzBodyStyle: { height: 'calc(100% - 55px)', overflow: 'auto', 'padding-bottom': '53px' },
+      nzContentParams: {
+        //模板id
+        id: data.id
+      }
+    });
 
+    //关闭抽屉的回调
+    drawerRef.afterClose.subscribe((isRefresh) => {
+      if (isRefresh) {//刷新list列表
+        this.getList();
+      }
+    });
   }
 
-  delete(){
-
+  /**
+   * 删除按钮
+   */
+  delete(id){
+    let projectManageArchives=new ProjectManageArchives();
+    projectManageArchives.id=id;
+    this.projectManageArchivesService.delete(projectManageArchives).then((response)=>{
+      if (response.success) {
+        //删除成功
+        this.nzNotificationService.success(this.i18NService.fanyi('successful.deletion'), '');
+        this.getList();
+      } else {
+        //删除失败
+        this.nzNotificationService.error(this.i18NService.fanyi('delete.failed'), '');
+      }
+    })
   }
 
 }

+ 3 - 1
src/app/routes/project-manage-archives/project-manage-archives-routing.module.ts

@@ -1,10 +1,12 @@
 import { NgModule } from '@angular/core';
 import { Routes, RouterModule } from '@angular/router';
 import { ProjectManageArchivesListComponent } from './list/list.component';
+import { ProjectManageArchivesUpdateComponent } from './update/update.component';
 
 const routes: Routes = [
 
-  { path: 'list', component: ProjectManageArchivesListComponent }];
+  { path: 'list', component: ProjectManageArchivesListComponent },
+  { path: 'update', component: ProjectManageArchivesUpdateComponent }];
 
 @NgModule({
   imports: [RouterModule.forChild(routes)],

+ 14 - 2
src/app/routes/project-manage-archives/project-manage-archives.module.ts

@@ -8,17 +8,29 @@ import { ProjectManageArchivesAddBusinessAffairsComponent } from './add/business
 import { ProjectManageArchivesAddImplementationComponent } from './add/implementation/implementation.component';
 import { ProjectManageArchivesAddDevelopmentComponent } from './add/development/development.component';
 import { ProjectManageArchivesAddServicetaComponent } from './add/serviceta/serviceta.component';
+import { ProjectManageArchivesUpdateComponent } from './update/update.component';
+import { ProjectManageArchivesUpdateBusinessAffairsComponent } from './update/business-affairs/business-affairs.component';
+import { ProjectManageArchivesUpdateDevelopmentComponent } from './update/development/development.component';
+import { ProjectManageArchivesUpdateEssentialInformationComponent } from './update/essential-information/essential-information.component';
+import { ProjectManageArchivesUpdateImplementationComponent } from './update/implementation/implementation.component';
+import { ProjectManageArchivesUpdateServicetaComponent } from './update/serviceta/serviceta.component';
 
 const COMPONENTS = [
   ProjectManageArchivesListComponent
-  ];
+  ,
+  ProjectManageArchivesUpdateComponent];
 const COMPONENTS_NOROUNT = [
   ProjectManageArchivesAddComponent,
   ProjectManageArchivesAddEssentialInformationComponent,
   ProjectManageArchivesAddBusinessAffairsComponent,
   ProjectManageArchivesAddImplementationComponent,
   ProjectManageArchivesAddDevelopmentComponent,
-  ProjectManageArchivesAddServicetaComponent];
+  ProjectManageArchivesAddServicetaComponent,
+  ProjectManageArchivesUpdateBusinessAffairsComponent,
+  ProjectManageArchivesUpdateDevelopmentComponent,
+  ProjectManageArchivesUpdateEssentialInformationComponent,
+  ProjectManageArchivesUpdateImplementationComponent,
+  ProjectManageArchivesUpdateServicetaComponent];
 
 @NgModule({
   imports: [

+ 1 - 0
src/app/routes/project-manage-archives/project-node-tree.ts

@@ -17,4 +17,5 @@ export interface ProjectNodeTree {
     parentId?:string;
     executor?:string;
     executorId?:string;
+    keyId?:string;
   }

+ 484 - 0
src/app/routes/project-manage-archives/update/business-affairs/business-affairs.component.html

@@ -0,0 +1,484 @@
+<!-- 开发 -->
+<form nz-form>
+  <div nz-row [nzGutter]="24">
+    <div nz-col [nzSpan]="6">
+      <nz-form-item>
+        <nz-form-label [nzSpan]="8">客户编码</nz-form-label>
+        <nz-form-control [nzSm]="16" [nzXs]="24">{{projectManageArchives.cusCode}}</nz-form-control>
+      </nz-form-item>
+    </div>
+    <div nz-col [nzSpan]="6">
+      <nz-form-item>
+        <nz-form-label [nzSpan]="8">客户名称</nz-form-label>
+        <nz-form-control [nzSm]="16" [nzXs]="24">{{projectManageArchives.cusName}}</nz-form-control>
+      </nz-form-item>
+    </div>
+    <div nz-col [nzSpan]="6">
+      <nz-form-item>
+        <nz-form-label [nzSpan]="8">销售经理</nz-form-label>
+        <nz-form-control [nzSm]="16" [nzXs]="24">{{projectManageArchives.saleManager}}</nz-form-control>
+      </nz-form-item>
+    </div>
+    <div nz-col [nzSpan]="6">
+      <nz-form-item>
+        <nz-form-label [nzSpan]="8">业务员</nz-form-label>
+        <nz-form-control [nzSm]="16" [nzXs]="24">{{projectManageArchives.saleMan}}</nz-form-control>
+      </nz-form-item>
+    </div>
+  </div>
+  <div nz-row [nzGutter]="24">
+    <div nz-col [nzSpan]="6">
+      <nz-form-item>
+        <nz-form-label [nzSpan]="8">项目总金额</nz-form-label>
+        <nz-form-control [nzSm]="16" [nzXs]="24">{{projectManageArchives.totalPrice}}</nz-form-control>
+      </nz-form-item>
+    </div>
+    <div nz-col [nzSpan]="6">
+      <nz-form-item>
+        <nz-form-label [nzSpan]="8">已回款金额</nz-form-label>
+        <nz-form-control [nzSm]="16" [nzXs]="24">{{projectManageArchives.received}}</nz-form-control>
+      </nz-form-item>
+    </div>
+  </div>
+</form>
+<!-- 收款计划 -->
+<nz-card nzTitle="收款计划" nzSize="small">
+  <div nz-row [nzGutter]="24">
+    <div nz-col [nzSpan]="24">
+      <!-- 新增按钮 -->
+      <button (click)="collectionPlanAdd()" nz-button nzType="primary">{{ 'button.add' | translate }}</button>
+    </div>
+  </div>
+  <div nz-row [nzGutter]="24">
+    <div nz-col [nzSpan]="24">
+      <nz-table style="padding-top: 5px;" nzSize="small" class="tableTdPadding" #basicTable
+        [nzData]="collectionPlanList" [nzFrontPagination]="false" [nzShowPagination]="false" [nzScroll]="{x:'123vw'}">
+        <!-- <thead>
+          <tr>
+            <th>{{ 'customer.contacts.name' | translate }}</th>
+            <th>{{ 'customer.contacts.telephone' | translate }}</th>
+            <th>{{ 'customer.contacts.mail' | translate }}</th>
+            <th>{{ 'customer.is.it.default' | translate }}</th>
+            <th>{{ 'customer.contacts.client.address' | translate }}</th>
+            <th>{{ 'table.operation' | translate }}</th>
+          </tr>
+        </thead> -->
+        <tbody>
+          <tr *ngFor="let data of basicTable.data">
+            <td style="width: 7%;">
+              <nz-select style="width: 100%;" nzShowSearch nzAllowClear [(ngModel)]="data.planId" nzPlaceHolder="请选择"
+                [nzDropdownMatchSelectWidth]="false" (ngModelChange)="planIdChange(data,'1')">
+                <nz-option *ngFor="let i of planList" [nzValue]="i.value" [nzLabel]="i.text"></nz-option>
+              </nz-select>
+            </td>
+            <td style="width: 4%;">第一笔</td>
+            <td style="width: 4%;">
+              <nz-input-number [(ngModel)]="data.price1" [nzMin]="0" [nzStep]="1" [nzFormatter]="formatterDollar"
+                [nzParser]="parserDollar"></nz-input-number>
+            </td>
+            <td style="width: 5%;">
+              <nz-select style="width: 100%;" nzShowSearch nzAllowClear [(ngModel)]="data.mileId1" nzPlaceHolder="请选择"
+                [nzDropdownMatchSelectWidth]="false">
+                <nz-option *ngFor="let i of milestoneList" [nzValue]="i.id" [nzLabel]="i.name"></nz-option>
+              </nz-select>
+            </td>
+            <td style="width: 5%;">
+              <input [(ngModel)]="data.desc1" nz-input />
+            </td>
+            <td style="width: 4%;">第二笔</td>
+            <td style="width: 4%;">
+              <nz-input-number [(ngModel)]="data.price2" [nzMin]="0" [nzStep]="1" [nzFormatter]="formatterDollar"
+                [nzParser]="parserDollar"></nz-input-number>
+            </td>
+            <td style="width: 5%;">
+              <nz-select style="width: 100%;" nzShowSearch nzAllowClear [(ngModel)]="data.mileId2" nzPlaceHolder="请选择"
+                [nzDropdownMatchSelectWidth]="false">
+                <nz-option *ngFor="let i of milestoneList" [nzValue]="i.id" [nzLabel]="i.name"></nz-option>
+              </nz-select>
+            </td>
+            <td style="width: 5%;">
+              <input [(ngModel)]="data.desc2" nz-input />
+            </td>
+            <td style="width: 4%;">第三笔</td>
+            <td style="width: 4%;">
+              <nz-input-number [(ngModel)]="data.price3" [nzMin]="0" [nzStep]="1" [nzFormatter]="formatterDollar"
+                [nzParser]="parserDollar"></nz-input-number>
+            </td>
+            <td style="width: 5%;">
+              <nz-select style="width: 100%;" nzShowSearch nzAllowClear [(ngModel)]="data.mileId3" nzPlaceHolder="请选择"
+                [nzDropdownMatchSelectWidth]="false">
+                <nz-option *ngFor="let i of milestoneList" [nzValue]="i.id" [nzLabel]="i.name"></nz-option>
+              </nz-select>
+            </td>
+            <td style="width: 5%;">
+              <input [(ngModel)]="data.desc3" nz-input />
+            </td>
+            <td style="width: 4%;">第四笔</td>
+            <td style="width: 4%;">
+              <nz-input-number [(ngModel)]="data.price4" [nzMin]="0" [nzStep]="1" [nzFormatter]="formatterDollar"
+                [nzParser]="parserDollar"></nz-input-number>
+            </td>
+            <td style="width: 5%;">
+              <nz-select style="width: 100%;" nzShowSearch nzAllowClear [(ngModel)]="data.mileId4" nzPlaceHolder="请选择"
+                [nzDropdownMatchSelectWidth]="false">
+                <nz-option *ngFor="let i of milestoneList" [nzValue]="i.id" [nzLabel]="i.name"></nz-option>
+              </nz-select>
+            </td>
+            <td style="width: 5%;">
+              <input [(ngModel)]="data.desc4" nz-input />
+            </td>
+            <td style="width: 4%;">第五笔</td>
+            <td style="width: 4%;">
+              <nz-input-number [(ngModel)]="data.price5" [nzMin]="0" [nzStep]="1" [nzFormatter]="formatterDollar"
+                [nzParser]="parserDollar"></nz-input-number>
+            </td>
+            <td style="width: 5%;">
+              <nz-select style="width: 100%;" nzShowSearch nzAllowClear [(ngModel)]="data.mileId5" nzPlaceHolder="请选择"
+                [nzDropdownMatchSelectWidth]="false">
+                <nz-option *ngFor="let i of milestoneList" [nzValue]="i.id" [nzLabel]="i.name"></nz-option>
+              </nz-select>
+            </td>
+            <td style="width: 5%;">
+              <input [(ngModel)]="data.desc5" nz-input />
+            </td>
+            <td nzRight="0"><a nz-popconfirm nzTitle="是否删除?"
+                (nzOnConfirm)="collectionPlanDelete(data.sort)">{{'table.delete'|translate}}</a></td>
+          </tr>
+        </tbody>
+      </nz-table>
+    </div>
+  </div>
+</nz-card>
+
+
+<!-- 回款情况 -->
+<nz-card nzTitle="回款情况" nzSize="small">
+  <div nz-row [nzGutter]="24">
+    <div nz-col [nzSpan]="24">
+      <!-- 新增按钮 -->
+      <button (click)="paymentCollectionAdd()" nz-button nzType="primary">{{ 'button.add' | translate }}</button>
+    </div>
+  </div>
+  <div nz-row [nzGutter]="24">
+    <div nz-col [nzSpan]="24">
+      <nz-table style="padding-top: 5px;" nzSize="small" class="tableTdPadding" #basicTable2
+        [nzData]="paymentCollectionList" [nzFrontPagination]="false" [nzShowPagination]="false"
+        [nzScroll]="{x:'123vw'}">
+        <!-- <thead>
+          <tr>
+            <th>{{ 'customer.contacts.name' | translate }}</th>
+            <th>{{ 'customer.contacts.telephone' | translate }}</th>
+            <th>{{ 'customer.contacts.mail' | translate }}</th>
+            <th>{{ 'customer.is.it.default' | translate }}</th>
+            <th>{{ 'customer.contacts.client.address' | translate }}</th>
+            <th>{{ 'table.operation' | translate }}</th>
+          </tr>
+        </thead> -->
+        <tbody>
+          <tr *ngFor="let data of basicTable2.data">
+            <td style="width: 7%;">
+              <nz-select style="width: 100%;" nzShowSearch nzAllowClear [(ngModel)]="data.planId" nzPlaceHolder="请选择"
+                [nzDropdownMatchSelectWidth]="false" (ngModelChange)="planIdChange(data,'2')">
+                <nz-option *ngFor="let i of planList" [nzValue]="i.value" [nzLabel]="i.text"></nz-option>
+              </nz-select>
+            </td>
+            <td style="width: 4%;">第一笔</td>
+            <td style="width: 4%;">
+              <nz-input-number [(ngModel)]="data.price1" [nzMin]="0" [nzStep]="1" [nzFormatter]="formatterDollar"
+                [nzParser]="parserDollar"  ></nz-input-number>
+            </td>
+            <td style="width: 5%;">
+              <nz-select style="width: 100%;" nzShowSearch nzAllowClear [(ngModel)]="data.mileId1" nzPlaceHolder="请选择"
+                [nzDropdownMatchSelectWidth]="false" (ngModelChange)="mileChange(data)">
+                <nz-option *ngFor="let i of milestoneList" [nzValue]="i.id" [nzLabel]="i.name"></nz-option>
+              </nz-select>
+            </td>
+            <td style="width: 5%;">
+              <input [(ngModel)]="data.desc1" nz-input />
+            </td>
+            <td style="width: 4%;">第二笔</td>
+            <td style="width: 4%;">
+              <nz-input-number [(ngModel)]="data.price2" [nzMin]="0" [nzStep]="1" [nzFormatter]="formatterDollar"
+                [nzParser]="parserDollar"></nz-input-number>
+            </td>
+            <td style="width: 5%;">
+              <nz-select style="width: 100%;" nzShowSearch nzAllowClear [(ngModel)]="data.mileId2" nzPlaceHolder="请选择"
+                [nzDropdownMatchSelectWidth]="false" (ngModelChange)="mileChange(data)">
+                <nz-option *ngFor="let i of milestoneList" [nzValue]="i.id" [nzLabel]="i.name"></nz-option>
+              </nz-select>
+            </td>
+            <td style="width: 5%;">
+              <input [(ngModel)]="data.desc2" nz-input />
+            </td>
+            <td style="width: 4%;">第三笔</td>
+            <td style="width: 4%;">
+              <nz-input-number [(ngModel)]="data.price3" [nzMin]="0" [nzStep]="1" [nzFormatter]="formatterDollar"
+                [nzParser]="parserDollar"></nz-input-number>
+            </td>
+            <td style="width: 5%;">
+              <nz-select style="width: 100%;" nzShowSearch nzAllowClear [(ngModel)]="data.mileId3" nzPlaceHolder="请选择"
+                [nzDropdownMatchSelectWidth]="false" (ngModelChange)="mileChange(data)">
+                <nz-option *ngFor="let i of milestoneList" [nzValue]="i.id" [nzLabel]="i.name"></nz-option>
+              </nz-select>
+            </td>
+            <td style="width: 5%;">
+              <input [(ngModel)]="data.desc3" nz-input />
+            </td>
+            <td style="width: 4%;">第四笔</td>
+            <td style="width: 4%;">
+              <nz-input-number [(ngModel)]="data.price4" [nzMin]="0" [nzStep]="1" [nzFormatter]="formatterDollar"
+                [nzParser]="parserDollar"></nz-input-number>
+            </td>
+            <td style="width: 5%;">
+              <nz-select style="width: 100%;" nzShowSearch nzAllowClear [(ngModel)]="data.mileId4" nzPlaceHolder="请选择"
+                [nzDropdownMatchSelectWidth]="false" (ngModelChange)="mileChange(data)">
+                <nz-option *ngFor="let i of milestoneList" [nzValue]="i.id" [nzLabel]="i.name"></nz-option>
+              </nz-select>
+            </td>
+            <td style="width: 5%;">
+              <input [(ngModel)]="data.desc4" nz-input />
+            </td>
+            <td style="width: 4%;">第五笔</td>
+            <td style="width: 4%;">
+              <nz-input-number [(ngModel)]="data.price5" [nzMin]="0" [nzStep]="1" [nzFormatter]="formatterDollar"
+                [nzParser]="parserDollar"></nz-input-number>
+            </td>
+            <td style="width: 5%;">
+              <nz-select style="width: 100%;" nzShowSearch nzAllowClear [(ngModel)]="data.mileId5" nzPlaceHolder="请选择"
+                [nzDropdownMatchSelectWidth]="false" (ngModelChange)="mileChange(data)">
+                <nz-option *ngFor="let i of milestoneList" [nzValue]="i.id" [nzLabel]="i.name"></nz-option>
+              </nz-select>
+            </td>
+            <td style="width: 5%;">
+              <input [(ngModel)]="data.desc5" nz-input />
+            </td>
+            <td nzRight="0"><a nz-popconfirm nzTitle="是否删除?"
+              (nzOnConfirm)="paymentCollectionDelete(data.sort)">{{'table.delete'|translate}}</a></td>
+          </tr>
+        </tbody>
+      </nz-table>
+    </div>
+  </div>
+</nz-card>
+
+
+<!-- 付款计划 -->
+<nz-card nzTitle="付款计划" nzSize="small">
+  <div nz-row [nzGutter]="24">
+    <div nz-col [nzSpan]="24">
+      <!-- 新增按钮 -->
+      <button (click)="paymentPlanAdd()" nz-button nzType="primary">{{ 'button.add' | translate }}</button>
+    </div>
+  </div>
+  <div nz-row [nzGutter]="24">
+    <div nz-col [nzSpan]="24">
+      <nz-table style="padding-top: 5px;" nzSize="small" class="tableTdPadding" #basicTable3
+        [nzData]="paymentPlanList" [nzFrontPagination]="false" [nzShowPagination]="false"
+        [nzScroll]="{x:'123vw'}">
+        <!-- <thead>
+          <tr>
+            <th>{{ 'customer.contacts.name' | translate }}</th>
+            <th>{{ 'customer.contacts.telephone' | translate }}</th>
+            <th>{{ 'customer.contacts.mail' | translate }}</th>
+            <th>{{ 'customer.is.it.default' | translate }}</th>
+            <th>{{ 'customer.contacts.client.address' | translate }}</th>
+            <th>{{ 'table.operation' | translate }}</th>
+          </tr>
+        </thead> -->
+        <tbody>
+          <tr *ngFor="let data of basicTable3.data">
+            <td style="width: 7%;">
+              <nz-select style="width: 100%;" nzShowSearch nzAllowClear [(ngModel)]="data.planId" nzPlaceHolder="请选择"
+                [nzDropdownMatchSelectWidth]="false" (ngModelChange)="planIdChange(data,'3')">
+                <nz-option *ngFor="let i of planList" [nzValue]="i.value" [nzLabel]="i.text"></nz-option>
+              </nz-select>
+            </td>
+            <td style="width: 4%;">第一笔</td>
+            <td style="width: 4%;">
+              <nz-input-number [(ngModel)]="data.price1" [nzMin]="0" [nzStep]="1" [nzFormatter]="formatterDollar"
+                [nzParser]="parserDollar"></nz-input-number>
+            </td>
+            <td style="width: 5%;">
+              <nz-select style="width: 100%;" nzShowSearch nzAllowClear [(ngModel)]="data.mileId1" nzPlaceHolder="请选择"
+                [nzDropdownMatchSelectWidth]="false">
+                <nz-option *ngFor="let i of milestoneList" [nzValue]="i.id" [nzLabel]="i.name"></nz-option>
+              </nz-select>
+            </td>
+            <td style="width: 5%;">
+              <input [(ngModel)]="data.desc1" nz-input />
+            </td>
+            <td style="width: 4%;">第二笔</td>
+            <td style="width: 4%;">
+              <nz-input-number [(ngModel)]="data.price2" [nzMin]="0" [nzStep]="1" [nzFormatter]="formatterDollar"
+                [nzParser]="parserDollar"></nz-input-number>
+            </td>
+            <td style="width: 5%;">
+              <nz-select style="width: 100%;" nzShowSearch nzAllowClear [(ngModel)]="data.mileId2" nzPlaceHolder="请选择"
+                [nzDropdownMatchSelectWidth]="false">
+                <nz-option *ngFor="let i of milestoneList" [nzValue]="i.id" [nzLabel]="i.name"></nz-option>
+              </nz-select>
+            </td>
+            <td style="width: 5%;">
+              <input [(ngModel)]="data.desc2" nz-input />
+            </td>
+            <td style="width: 4%;">第三笔</td>
+            <td style="width: 4%;">
+              <nz-input-number [(ngModel)]="data.price3" [nzMin]="0" [nzStep]="1" [nzFormatter]="formatterDollar"
+                [nzParser]="parserDollar"></nz-input-number>
+            </td>
+            <td style="width: 5%;">
+              <nz-select style="width: 100%;" nzShowSearch nzAllowClear [(ngModel)]="data.mileId3" nzPlaceHolder="请选择"
+                [nzDropdownMatchSelectWidth]="false">
+                <nz-option *ngFor="let i of milestoneList" [nzValue]="i.id" [nzLabel]="i.name"></nz-option>
+              </nz-select>
+            </td>
+            <td style="width: 5%;">
+              <input [(ngModel)]="data.desc3" nz-input />
+            </td>
+            <td style="width: 4%;">第四笔</td>
+            <td style="width: 4%;">
+              <nz-input-number [(ngModel)]="data.price4" [nzMin]="0" [nzStep]="1" [nzFormatter]="formatterDollar"
+                [nzParser]="parserDollar"></nz-input-number>
+            </td>
+            <td style="width: 5%;">
+              <nz-select style="width: 100%;" nzShowSearch nzAllowClear [(ngModel)]="data.mileId4" nzPlaceHolder="请选择"
+                [nzDropdownMatchSelectWidth]="false">
+                <nz-option *ngFor="let i of milestoneList" [nzValue]="i.id" [nzLabel]="i.name"></nz-option>
+              </nz-select>
+            </td>
+            <td style="width: 5%;">
+              <input [(ngModel)]="data.desc4" nz-input />
+            </td>
+            <td style="width: 4%;">第五笔</td>
+            <td style="width: 4%;">
+              <nz-input-number [(ngModel)]="data.price5" [nzMin]="0" [nzStep]="1" [nzFormatter]="formatterDollar"
+                [nzParser]="parserDollar"></nz-input-number>
+            </td>
+            <td style="width: 5%;">
+              <nz-select style="width: 100%;" nzShowSearch nzAllowClear [(ngModel)]="data.mileId5" nzPlaceHolder="请选择"
+                [nzDropdownMatchSelectWidth]="false">
+                <nz-option *ngFor="let i of milestoneList" [nzValue]="i.id" [nzLabel]="i.name"></nz-option>
+              </nz-select>
+            </td>
+            <td style="width: 5%;">
+              <input [(ngModel)]="data.desc5" nz-input />
+            </td>
+            <td nzRight="0"><a nz-popconfirm nzTitle="是否删除?"
+              (nzOnConfirm)="paymentPlanDelete(data.sort)">{{'table.delete'|translate}}</a></td>
+          </tr>
+        </tbody>
+      </nz-table>
+    </div>
+  </div>
+</nz-card>
+
+
+<!-- 付款情况 -->
+<nz-card nzTitle="付款情况" nzSize="small">
+  <div nz-row [nzGutter]="24">
+    <div nz-col [nzSpan]="24">
+      <!-- 新增按钮 -->
+      <button (click)="paymentStatusAdd()" nz-button nzType="primary">{{ 'button.add' | translate }}</button>
+    </div>
+  </div>
+  <div nz-row [nzGutter]="24">
+    <div nz-col [nzSpan]="24">
+      <nz-table style="padding-top: 5px;" nzSize="small" class="tableTdPadding" #basicTable4
+        [nzData]="paymentStatusList" [nzFrontPagination]="false" [nzShowPagination]="false"
+        [nzScroll]="{x:'123vw'}">
+        <!-- <thead>
+          <tr>
+            <th>{{ 'customer.contacts.name' | translate }}</th>
+            <th>{{ 'customer.contacts.telephone' | translate }}</th>
+            <th>{{ 'customer.contacts.mail' | translate }}</th>
+            <th>{{ 'customer.is.it.default' | translate }}</th>
+            <th>{{ 'customer.contacts.client.address' | translate }}</th>
+            <th>{{ 'table.operation' | translate }}</th>
+          </tr>
+        </thead> -->
+        <tbody>
+          <tr *ngFor="let data of basicTable4.data">
+            <td style="width: 7%;">
+              <nz-select style="width: 100%;" nzShowSearch nzAllowClear [(ngModel)]="data.planId" nzPlaceHolder="请选择"
+                [nzDropdownMatchSelectWidth]="false" (ngModelChange)="planIdChange(data,'4')">
+                <nz-option *ngFor="let i of planList" [nzValue]="i.value" [nzLabel]="i.text"></nz-option>
+              </nz-select>
+            </td>
+            <td style="width: 4%;">第一笔</td>
+            <td style="width: 4%;">
+              <nz-input-number [(ngModel)]="data.price1" [nzMin]="0" [nzStep]="1" [nzFormatter]="formatterDollar"
+                [nzParser]="parserDollar"></nz-input-number>
+            </td>
+            <td style="width: 5%;">
+              <nz-select style="width: 100%;" nzShowSearch nzAllowClear [(ngModel)]="data.mileId1" nzPlaceHolder="请选择"
+                [nzDropdownMatchSelectWidth]="false">
+                <nz-option *ngFor="let i of milestoneList" [nzValue]="i.id" [nzLabel]="i.name"></nz-option>
+              </nz-select>
+            </td>
+            <td style="width: 5%;">
+              <input [(ngModel)]="data.desc1" nz-input />
+            </td>
+            <td style="width: 4%;">第二笔</td>
+            <td style="width: 4%;">
+              <nz-input-number [(ngModel)]="data.price2" [nzMin]="0" [nzStep]="1" [nzFormatter]="formatterDollar"
+                [nzParser]="parserDollar"></nz-input-number>
+            </td>
+            <td style="width: 5%;">
+              <nz-select style="width: 100%;" nzShowSearch nzAllowClear [(ngModel)]="data.mileId2" nzPlaceHolder="请选择"
+                [nzDropdownMatchSelectWidth]="false">
+                <nz-option *ngFor="let i of milestoneList" [nzValue]="i.id" [nzLabel]="i.name"></nz-option>
+              </nz-select>
+            </td>
+            <td style="width: 5%;">
+              <input [(ngModel)]="data.desc2" nz-input />
+            </td>
+            <td style="width: 4%;">第三笔</td>
+            <td style="width: 4%;">
+              <nz-input-number [(ngModel)]="data.price3" [nzMin]="0" [nzStep]="1" [nzFormatter]="formatterDollar"
+                [nzParser]="parserDollar"></nz-input-number>
+            </td>
+            <td style="width: 5%;">
+              <nz-select style="width: 100%;" nzShowSearch nzAllowClear [(ngModel)]="data.mileId3" nzPlaceHolder="请选择"
+                [nzDropdownMatchSelectWidth]="false">
+                <nz-option *ngFor="let i of milestoneList" [nzValue]="i.id" [nzLabel]="i.name"></nz-option>
+              </nz-select>
+            </td>
+            <td style="width: 5%;">
+              <input [(ngModel)]="data.desc3" nz-input />
+            </td>
+            <td style="width: 4%;">第四笔</td>
+            <td style="width: 4%;">
+              <nz-input-number [(ngModel)]="data.price4" [nzMin]="0" [nzStep]="1" [nzFormatter]="formatterDollar"
+                [nzParser]="parserDollar"></nz-input-number>
+            </td>
+            <td style="width: 5%;">
+              <nz-select style="width: 100%;" nzShowSearch nzAllowClear [(ngModel)]="data.mileId4" nzPlaceHolder="请选择"
+                [nzDropdownMatchSelectWidth]="false">
+                <nz-option *ngFor="let i of milestoneList" [nzValue]="i.id" [nzLabel]="i.name"></nz-option>
+              </nz-select>
+            </td>
+            <td style="width: 5%;">
+              <input [(ngModel)]="data.desc4" nz-input />
+            </td>
+            <td style="width: 4%;">第五笔</td>
+            <td style="width: 4%;">
+              <nz-input-number [(ngModel)]="data.price5" [nzMin]="0" [nzStep]="1" [nzFormatter]="formatterDollar"
+                [nzParser]="parserDollar"></nz-input-number>
+            </td>
+            <td style="width: 5%;">
+              <nz-select style="width: 100%;" nzShowSearch nzAllowClear [(ngModel)]="data.mileId5" nzPlaceHolder="请选择"
+                [nzDropdownMatchSelectWidth]="false">
+                <nz-option *ngFor="let i of milestoneList" [nzValue]="i.id" [nzLabel]="i.name"></nz-option>
+              </nz-select>
+            </td>
+            <td style="width: 5%;">
+              <input [(ngModel)]="data.desc5" nz-input />
+            </td>
+            <td nzRight="0"><a nz-popconfirm nzTitle="是否删除?"
+              (nzOnConfirm)="paymentStatusDelete(data.sort)">{{'table.delete'|translate}}</a></td>
+          </tr>
+        </tbody>
+      </nz-table>
+    </div>
+  </div>
+</nz-card>

+ 24 - 0
src/app/routes/project-manage-archives/update/business-affairs/business-affairs.component.spec.ts

@@ -0,0 +1,24 @@
+import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+import { ProjectManageArchivesUpdateBusinessAffairsComponent } from './business-affairs.component';
+
+describe('ProjectManageArchivesUpdateBusinessAffairsComponent', () => {
+  let component: ProjectManageArchivesUpdateBusinessAffairsComponent;
+  let fixture: ComponentFixture<ProjectManageArchivesUpdateBusinessAffairsComponent>;
+
+  beforeEach(async(() => {
+    TestBed.configureTestingModule({
+      declarations: [ ProjectManageArchivesUpdateBusinessAffairsComponent ]
+    })
+    .compileComponents();
+  }));
+
+  beforeEach(() => {
+    fixture = TestBed.createComponent(ProjectManageArchivesUpdateBusinessAffairsComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});

+ 232 - 0
src/app/routes/project-manage-archives/update/business-affairs/business-affairs.component.ts

@@ -0,0 +1,232 @@
+import { Component, OnInit, Output, EventEmitter } from '@angular/core';
+import { NzModalRef, NzMessageService } from 'ng-zorro-antd';
+import { _HttpClient } from '@delon/theme';
+import { BaseArchivesMilestoneService } from 'app/services/basedata/base-archives-milestone.service';
+import { ProjectManageArchives } from 'app/entity/project-manage-archives/project-manage-archives';
+
+@Component({
+  selector: 'app-project-manage-archives-update-business-affairs',
+  templateUrl: './business-affairs.component.html',
+})
+export class ProjectManageArchivesUpdateBusinessAffairsComponent implements OnInit {
+  constructor(
+    private baseArchivesMilestoneService:BaseArchivesMilestoneService
+  ) {}
+
+  ngOnInit(): void {
+  }
+
+  projectManageArchives: ProjectManageArchives = {}; //项目档案实体对象
+  collectionPlanList = []; //收款计划数据
+  paymentCollectionList = []; //回款情况数据
+  paymentPlanList = []; //付款计划
+  paymentStatusList = []; //付款情况
+  planList = []; //计划下来集合数据
+  formatterDollar = (value: number) => `$ ${value}`;
+  parserDollar = (value: string) => value.replace('$ ', '');
+  milestoneList :any= []; //里程碑集合数据
+
+  /**
+   * 
+   收款计划新增
+   */
+  collectionPlanSort = 0; //收款计划排序
+  collectionPlanAdd() {
+    this.collectionPlanList = [
+      ...this.collectionPlanList,
+      {
+        price1: 0,
+        price2: 0,
+        price3: 0,
+        price4: 0,
+        price5: 0,
+        sort: this.collectionPlanSort,
+        planType: '1',
+      },
+    ];
+    this.collectionPlanSort++;
+  }
+
+  /**
+   * 收款删除按钮
+   */
+  collectionPlanDelete(sort) {
+    this.collectionPlanList = this.collectionPlanList.filter(d => d.sort !== sort);
+  }
+
+  /**
+   * 回款计划新增
+   */
+  paymentCollectionSort = 0; //回款情况排序
+  paymentCollectionAdd() {
+    this.paymentCollectionList = [
+      ...this.paymentCollectionList,
+      {
+        price1: 0,
+        price2: 0,
+        price3: 0,
+        price4: 0,
+        price5: 0,
+        sort: this.paymentCollectionSort,
+        planType: '2',
+      },
+    ];
+    this.paymentCollectionSort++;
+  }
+
+  /**
+   * 回款删除按钮
+   */
+  paymentCollectionDelete(sort) {
+    this.paymentCollectionList = this.paymentCollectionList.filter(d => d.sort !== sort);
+  }
+
+  /**
+   * 付款计划新增
+   */
+  paymentPlanSort = 0;
+  paymentPlanAdd() {
+    this.paymentPlanList = [
+      ...this.paymentPlanList,
+      {
+        price1: 0,
+        price2: 0,
+        price3: 0,
+        price4: 0,
+        price5: 0,
+        sort: this.paymentPlanSort,
+        planType: '3',
+      },
+    ];
+    this.paymentPlanSort++;
+  }
+
+  /**
+   * 付款计划删除按钮
+   */
+  paymentPlanDelete(sort) {
+    this.paymentPlanList = this.paymentPlanList.filter(d => d.sort !== sort);
+  }
+
+  /**
+   * 付款情况
+   */
+  paymentStatusSort = 0;
+  paymentStatusAdd() {
+    this.paymentStatusList = [
+      ...this.paymentStatusList,
+      {
+        price1: 0,
+        price2: 0,
+        price3: 0,
+        price4: 0,
+        price5: 0,
+        sort: this.paymentPlanSort,
+        planType: '3',
+      },
+    ];
+    this.paymentPlanSort++;
+  }
+
+  /**
+   * 付款情况删除按钮
+   */
+  paymentStatusDelete(sort) {
+    this.paymentStatusList = this.paymentStatusList.filter(d => d.sort !== sort);
+  }
+
+  /**
+   * 类型触发事件
+   */
+  planIdChange(data, type) {
+    //获取类型名称
+    this.getPlanName(data);
+    //如果是回款情况表格中下拉触发
+    if (type === '2') {
+      //获取收款计划的金额
+      this.getCollectionPlanPrice(this.collectionPlanList,data);
+      
+    }
+    //如果是付款情况表格中下来触发
+    if (type === '4') {
+      //获取付款计划中的金额
+      this.getCollectionPlanPrice(this.paymentPlanList,data);
+    }
+    //回写数据到实施、开发、服务页签的回款信息
+    this.getRemittanceInformationChange(data);
+  }
+
+  /**
+   * 获取类型名称
+   * @param data 计划对象
+   */
+  getPlanName(data) {
+    this.planList.forEach(element => {
+      if (element.value === data.planId) {
+        data.planName = element.text;
+      }
+    });
+  }
+
+  /**
+   * 根据回款情况类型获取对应的收款计划金额
+   * @param list 表格数据
+   * @param data 表格中的对象
+   */
+  getCollectionPlanPrice(list,data) {
+    list.forEach(element => {
+      if (data.planId === element.planId) {
+        data.price1 = element.price1;
+        data.price2 = element.price2;
+        data.price3 = element.price3;
+        data.price4 = element.price4;
+        data.price5 = element.price5;
+      }
+    });
+  }
+
+  /**
+   * 里程碑选择事件
+   * @param data
+   */
+  mileChange(data) {
+    //已汇款金额
+    this.getReceived();
+    //回写数据到实施、开发、服务页签的回款信息
+    this.getRemittanceInformationChange(data);
+  }
+
+  /**
+   * 获取回款情况中的回款金额累加(已汇款金额)
+   */
+  getReceived() {
+    let received = 0;
+    this.paymentCollectionList.forEach(element => {
+      if (element.desc1 && !isNaN(Number(element.desc1))) {
+        received += Number(element.desc1);
+      }
+      if (element.desc2 && !isNaN(Number(element.desc2))) {
+        received += Number(element.desc2);
+      }
+      if (element.desc3 && !isNaN(Number(element.desc3))) {
+        received += Number(element.desc3);
+      }
+      if (element.desc4 && !isNaN(Number(element.desc4))) {
+        received += Number(element.desc4);
+      }
+      if (element.desc5 && !isNaN(Number(element.desc5))) {
+        received += Number(element.desc5);
+      }
+    });
+    this.projectManageArchives.received = received;
+  }
+
+  /**
+   * 回写数据到实施、开发、服务页签的回款信息
+   * @param 对象
+   */
+  @Output() remittanceInformationChange = new EventEmitter<{}>();
+  getRemittanceInformationChange(data) {
+    this.remittanceInformationChange.emit(data);
+  }
+}

+ 142 - 0
src/app/routes/project-manage-archives/update/development/development.component.html

@@ -0,0 +1,142 @@
+<!-- 商务 -->
+<form nz-form>
+  <div nz-row [nzGutter]="24">
+    <div nz-col [nzSpan]="6">
+      <nz-form-item>
+        <nz-form-label [nzSpan]="8">客户编码</nz-form-label>
+        <nz-form-control [nzSm]="16" [nzXs]="24">{{projectManageArchives.cusCode}}</nz-form-control>
+      </nz-form-item>
+    </div>
+    <div nz-col [nzSpan]="6">
+      <nz-form-item>
+        <nz-form-label [nzSpan]="8">客户名称</nz-form-label>
+        <nz-form-control [nzSm]="16" [nzXs]="24">{{projectManageArchives.cusName}}</nz-form-control>
+      </nz-form-item>
+    </div>
+    <div nz-col [nzSpan]="6">
+      <nz-form-item>
+        <nz-form-label [nzSpan]="8">开发项目经理</nz-form-label>
+        <nz-form-control [nzSm]="16" [nzXs]="24">{{projectManageArchives.deManager}}</nz-form-control>
+      </nz-form-item>
+    </div>
+    <div nz-col [nzSpan]="6">
+      <nz-form-item>
+        <nz-form-label [nzSpan]="8">开发工程师</nz-form-label>
+        <nz-form-control [nzSm]="16" [nzXs]="24">{{projectManageArchives.deEngineer}}</nz-form-control>
+      </nz-form-item>
+    </div>
+  </div>
+</form>
+
+<!-- 汇款信息 -->
+<nz-card nzTitle="回款信息" nzSize="small">
+  <nz-table nzBordered nzSize="small" [nzNoResult]="' '" [nzShowPagination]="false">
+    <tbody>
+      <tr>
+        <td><strong>开发金额</strong></td>
+        <td>第一笔</td>
+        <td>{{remittanceInformation.price1}}</td>
+        <td>第二笔</td>
+        <td>{{remittanceInformation.price2}}</td>
+        <td>第三笔</td>
+        <td>{{remittanceInformation.price3}}</td>
+        <td>第四笔</td>
+        <td>{{remittanceInformation.price4}}</td>
+        <td>第五笔</td>
+        <td>{{remittanceInformation.price5}}</td>
+      </tr>
+      <tr>
+        <td><strong>实际回款</strong></td>
+        <td>{{remittanceInformation.milestone1}}</td>
+        <td>{{remittanceInformation.desc1}}</td>
+        <td>{{remittanceInformation.milestone2}}</td>
+        <td>{{remittanceInformation.desc2}}</td>
+        <td>{{remittanceInformation.milestone3}}</td>
+        <td>{{remittanceInformation.desc3}}</td>
+        <td>{{remittanceInformation.milestone4}}</td>
+        <td>{{remittanceInformation.desc4}}</td>
+        <td>{{remittanceInformation.milestone5}}</td>
+        <td>{{remittanceInformation.desc5}}</td>
+      </tr>
+    </tbody>
+  </nz-table>
+</nz-card>
+
+<!-- 实施计划 -->
+<nz-card nzTitle="开发计划" nzSize="small">
+  <div nz-row [nzGutter]="24">
+    <div nz-col [nzSpan]="24">
+      <!-- 新增按钮 -->
+      <button (click)="addParent()" nz-button nzType="primary">{{ 'button.add' | translate }}</button>
+    </div>
+  </div>
+  <div nz-row [nzGutter]="24">
+    <div nz-col [nzSpan]="24">
+      <nz-table style="padding-top: 5px;" nzSize="small" class="tableTdPadding" #expandTable [nzData]="listOfMapData"
+        nzTableLayout="fixed" [nzShowPagination]="false" [nzFrontPagination]="false">
+        <thead>
+          <tr>
+            <th></th>
+            <th style="width: 10%;">里程碑</th>
+            <th style="width: 20%;">开始时间</th>
+            <th style="width: 20%;">结束时间</th>
+            <th style="width: 10%;">计划人天</th>
+            <th style="width: 20%;">执行人</th>
+            <th style="width: 10%;">实际人天</th>
+            <th style="width: 10%;">操作</th>
+          </tr>
+        </thead>
+        <tbody>
+          <ng-container *ngFor="let data of expandTable.data">
+            <ng-container *ngFor="let item of mapOfExpandedData[data.key]">
+
+
+              <tr *ngIf="(item.parent && item.parent.expand) || !item.parent">
+                <td [nzIndentSize]="item.level! * 20" [nzShowExpand]="!!item.children" [(nzExpand)]="item.expand"
+                  (nzExpandChange)="collapse(mapOfExpandedData[data.key], item, $event)">
+                </td>
+                <td>
+                  <ng-container *ngIf="item.id">
+                    {{ item.muilesName }}
+                  </ng-container>
+                  <ng-container *ngIf="!item.id">
+                    <input nz-input [(ngModel)]="item.muilesName" />
+                  </ng-container>
+                </td>
+                <td>
+                  <nz-date-picker [(ngModel)]="item.startDate"></nz-date-picker>
+                </td>
+                <td>
+                  <nz-date-picker [(ngModel)]="item.endDate"></nz-date-picker>
+                </td>
+                <td>
+                  <nz-input-number [(ngModel)]="item.planTime" [nzMin]="0" [nzStep]="1"></nz-input-number>
+                </td>
+                <td>
+                  <!-- <nz-select style="width: 100%;" [nzMaxTagCount]="3" nzMode="multiple" nzPlaceHolder="请选择"
+                    [(ngModel)]="item.executor">
+                    <nz-option *ngFor="let item of personnelList" [nzLabel]="item.id" [nzValue]="item.name"></nz-option>
+                  </nz-select> -->
+                  <nz-tree-select style="width: 100%" [nzNodes]="personnelList" nzShowSearch [nzMultiple]="true"
+                  nzPlaceHolder="请选择"
+                  [(ngModel)]="item.executors" [nzMaxTagCount]="3" [nzAllowClear]="true">
+                </nz-tree-select>
+                </td>
+                <td>
+                  <nz-input-number [(ngModel)]="item.realTime" [nzMin]="0" [nzStep]="1"></nz-input-number>
+                </td>
+                <td>
+                  <a (click)="addChild(item.key)">{{ 'button.leve.lower' | translate }}</a>
+                  <nz-divider nzType="vertical"></nz-divider>
+                  <a nz-popconfirm nzTitle="{{'isdelete'|translate}}" nzOkText="{{ 'yes' | translate }}"
+                    nzCancelText="{{ 'no' | translate }}"
+                    (nzOnConfirm)="deleteRow(mapOfExpandedData[data.key],item,item.key)">{{ 'milestone.delete' | translate }}</a>
+                </td>
+              </tr>
+            </ng-container>
+          </ng-container>
+        </tbody>
+      </nz-table>
+    </div>
+  </div>
+</nz-card>

+ 24 - 0
src/app/routes/project-manage-archives/update/development/development.component.spec.ts

@@ -0,0 +1,24 @@
+import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+import { ProjectManageArchivesUpdateDevelopmentComponent } from './development.component';
+
+describe('ProjectManageArchivesUpdateDevelopmentComponent', () => {
+  let component: ProjectManageArchivesUpdateDevelopmentComponent;
+  let fixture: ComponentFixture<ProjectManageArchivesUpdateDevelopmentComponent>;
+
+  beforeEach(async(() => {
+    TestBed.configureTestingModule({
+      declarations: [ ProjectManageArchivesUpdateDevelopmentComponent ]
+    })
+    .compileComponents();
+  }));
+
+  beforeEach(() => {
+    fixture = TestBed.createComponent(ProjectManageArchivesUpdateDevelopmentComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});

+ 214 - 0
src/app/routes/project-manage-archives/update/development/development.component.ts

@@ -0,0 +1,214 @@
+import { Component, OnInit } from '@angular/core';
+import { NzModalRef, NzMessageService } from 'ng-zorro-antd';
+import { _HttpClient } from '@delon/theme';
+import { BaseArchivesMilestoneService } from 'app/services/basedata/base-archives-milestone.service';
+import { ProjectManageArchives } from 'app/entity/project-manage-archives/project-manage-archives';
+import { ProjectNodeTree } from '../../project-node-tree';
+
+@Component({
+  selector: 'app-project-manage-archives-update-development',
+  templateUrl: './development.component.html',
+})
+export class ProjectManageArchivesUpdateDevelopmentComponent implements OnInit {
+  constructor(private baseArchivesMilestoneService: BaseArchivesMilestoneService) {}
+
+  ngOnInit(): void {
+    this.getTreeList();
+  }
+
+  projectManageArchives: ProjectManageArchives = {}; //项目档案主表实体
+  listOfMapData: any = []; //树形集合
+  personnelList = []; //人员下拉列表
+  remittanceInformation: any = {}; //回款信息实体
+
+  /**
+   * 获取树形集合
+   */
+  getTreeList() {
+    // let baseArchivesMilestone=new BaseArchivesMilestone();
+    // baseArchivesMilestone.pkOrg=sessionStorage.getItem("pkOrg");//组织
+    // baseArchivesMilestone.typeId="3";
+    // this.baseArchivesMilestoneService.getTreeList(baseArchivesMilestone).then((response)=>{
+    //   if(response.result){
+    //     this.listOfMapData=response.result
+    //     this.getLoding();
+    //   }
+    // })
+  }
+
+  /**
+   * 初始化树形
+   */
+  getLoding() {
+    this.listOfMapData.forEach(item => {
+      this.mapOfExpandedData[item.key] = this.convertTreeToList(item);
+    });
+  }
+
+  /**
+   * 新增父级
+   */
+  //uuid
+  S4() {
+    return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1);
+  }
+  guid() {
+    return this.S4() + this.S4() + this.S4() + this.S4() + this.S4() + this.S4() + this.S4() + this.S4();
+  }
+  // 随机数
+  add() {
+    return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1);
+  }
+  adding() {
+    return this.add() + this.add() + this.add() + this.add() + this.add() + this.add() + this.add() + this.add();
+  }
+  addParent() {
+    this.listOfMapData.forEach(item => {
+      console.log(this.mapOfExpandedData[item.key]);
+    });
+    this.listOfMapData = [...this.listOfMapData, { key: this.adding() }];
+    // this.getLoding();
+    this.initialValue();
+  }
+
+  /**
+   * 新增子集
+   * @param parentId 父级id
+   * @param data 操作对象
+   */
+  addChild(parentId) {
+    this.getChild(this.listOfMapData, parentId);
+    this.initialValue();
+  }
+
+  /**
+   * 递归查询子集增加
+   */
+  getChild(children, parentId) {
+    var keyId = this.adding();
+    children.forEach(element => {
+      // 是否和点击的数据相等
+      // 相等则在此条数据加子数据
+      if (element.key == parentId) {
+        // 是否存在自数据不存在则创建child
+        if (element.children == null) {
+          element.children = [];
+        }
+        // 添加一条空的子数据到child
+        element.children = [...element.children, { key: keyId, parentId: parentId }];
+        // this.mapOfExpandedData[element.key] = this.convertTreeToList(null);
+        // this.initialValue();
+      } else {
+        if (element.children != null) {
+          this.getChild(element.children, parentId);
+        }
+      }
+    });
+  }
+
+  /**
+   * 删除行
+   */
+  deleteRow(array: ProjectNodeTree[], data: ProjectNodeTree, key) {
+    this.getdeleteRow(key, this.listOfMapData);
+    this.initialValue();
+  }
+
+  /**
+   * 递归删除
+   * @param itemsId 对象id
+   * @param list 需要删除对象的集合
+   * @param parent 父级对象
+   */
+  getdeleteRow(itemsId: string, list?: any, parent?: any) {
+    list.forEach((element, i) => {
+      //判断选中得数据是否有找到
+      if (element.key == itemsId) {
+        //找到则先判断对象是否有子集,有则删除
+        if (element.children != null && element.children.length > 0) {
+          element.children.splice(0, element.children.length);
+        }
+        //然后删除父极对象
+        list.splice(i, 1);
+        //判断父极是否存在子集
+        if (list.length == 0 && parent) {
+          parent.children = null;
+        }
+        this.listOfMapData = [...this.listOfMapData];
+        // this.getDataInitialization2();
+        // this.initialValue();
+      } else {
+        //没有则判断是否有子集 有则递归同样判断
+        if (element.children != null && element.children.length > 0) {
+          this.getdeleteRow(itemsId, element.children, element);
+        }
+      }
+    });
+  }
+
+  initialValue() {
+    this.listOfMapData.forEach(item => {
+      const data = this.mapOfExpandedData[item.key];
+      this.mapOfExpandedData[item.key] = this.convertTreeToList(item);
+      const mapData = this.mapOfExpandedData[item.key];
+      if (data && mapData) {
+        mapData.forEach(el => {
+          data.forEach(element => {
+            if (element.key === el.key) {
+              el.muilesId = element.muilesId;
+              el.muilesName = element.muilesName;
+              el.startDate = element.startDate;
+              el.endDate = element.endDate;
+              el.planTime = element.planTime;
+              el.executors = element.executors;
+              el.realTime = element.realTime;
+            }
+          });
+        });
+      }
+    });
+  }
+
+  ///////////////////////////树形配置
+  mapOfExpandedData: { [key: string]: ProjectNodeTree[] } = {};
+
+  collapse(array: ProjectNodeTree[], data: ProjectNodeTree, $event: boolean): void {
+    if (!$event) {
+      if (data.children) {
+        data.children.forEach(d => {
+          const target = array.find(a => a.key === d.key)!;
+          target.expand = false;
+          this.collapse(array, target, false);
+        });
+      } else {
+        return;
+      }
+    }
+  }
+
+  convertTreeToList(root: ProjectNodeTree): ProjectNodeTree[] {
+    const stack: ProjectNodeTree[] = [];
+    const array: ProjectNodeTree[] = [];
+    const hashMap = {};
+    stack.push({ ...root, level: 0, expand: true });
+
+    while (stack.length !== 0) {
+      const node = stack.pop()!;
+      this.visitNode(node, hashMap, array);
+      if (node.children) {
+        for (let i = node.children.length - 1; i >= 0; i--) {
+          stack.push({ ...node.children[i], level: node.level! + 1, expand: true, parent: node });
+        }
+      }
+    }
+
+    return array;
+  }
+
+  visitNode(node: ProjectNodeTree, hashMap: { [key: string]: boolean }, array: ProjectNodeTree[]): void {
+    if (!hashMap[node.key]) {
+      hashMap[node.key] = true;
+      array.push(node);
+    }
+  }
+}

+ 192 - 0
src/app/routes/project-manage-archives/update/essential-information/essential-information.component.html

@@ -0,0 +1,192 @@
+<!-- 基本信息 -->
+<form nz-form [formGroup]="validateForm" (ngSubmit)="submitForm()">
+  <div nz-row [nzGutter]="24">
+    <div nz-col [nzSpan]="6">
+      <nz-form-item>
+        <nz-form-label [nzSpan]="'vertical' ? 24 : null" nzRequired>项目编码</nz-form-label>
+        <nz-form-control [nzSm]="24" [nzXs]="24">
+          <!-- <nz-select style="widows: 100%;" nzShowSearch nzAllowClear formControlName="proId" id="proId"
+            [(ngModel)]="projectManageArchivesa.proId" nzPlaceHolder="请选择">
+            <nz-option *ngFor="let i of proList" [nzValue]="i.id" [nzLabel]="i.code"></nz-option>
+          </nz-select> -->
+          <nz-tree-select style="width: 100%" [nzNodes]="proList" nzShowSearch [nzMultiple]="false"
+            formControlName="proId" id="proId" nzPlaceHolder="请选择" [(ngModel)]="projectManageArchivesa.proId"
+            [nzMaxTagCount]="3" [nzAllowClear]="true" (ngModelChange)="proChange($event)">
+          </nz-tree-select>
+          <nz-form-explain *ngIf="validateForm.get('proId')?.dirty && validateForm.get('proId')?.errors">
+            请选择项目
+          </nz-form-explain>
+        </nz-form-control>
+      </nz-form-item>
+    </div>
+    <div nz-col [nzSpan]="6">
+      <nz-form-item>
+        <nz-form-label [nzSpan]="'vertical' ? 24 : null" [nzXs]="24">项目名称</nz-form-label>
+        <nz-form-control [nzSm]="24" [nzXs]="24">
+          {{projectManageArchivesa.proName}}
+        </nz-form-control>
+      </nz-form-item>
+    </div>
+    <div nz-col [nzSpan]="6">
+      <nz-form-item>
+        <nz-form-label [nzSpan]="'vertical' ? 24 : null" [nzXs]="24">客户编码</nz-form-label>
+        <nz-form-control [nzSm]="24" [nzXs]="24">
+          <nz-select style="widows: 100%;" nzShowSearch nzAllowClear formControlName="cusId" id="cusId"
+            [(ngModel)]="projectManageArchivesa.cusId" nzPlaceHolder="请选择" (ngModelChange)="cusChange($event)">
+            <nz-option *ngFor="let i of cusList" [nzValue]="i.id" [nzLabel]="i.name"></nz-option>
+          </nz-select>
+          <nz-form-explain *ngIf="validateForm.get('cusId')?.dirty && validateForm.get('cusId')?.errors">
+            请选择客户
+          </nz-form-explain>
+        </nz-form-control>
+      </nz-form-item>
+    </div>
+    <div nz-col [nzSpan]="6">
+      <nz-form-item>
+        <nz-form-label [nzSpan]="'vertical' ? 24 : null" [nzXs]="24">客户名称</nz-form-label>
+        <nz-form-control [nzSm]="24" [nzXs]="24">
+          {{projectManageArchivesa.cusName}}
+        </nz-form-control>
+      </nz-form-item>
+    </div>
+  </div>
+  <div nz-row [nzGutter]="24">
+    <div nz-col [nzSpan]="6">
+      <nz-form-item>
+        <nz-form-label [nzSpan]="'vertical' ? 24 : null" [nzXs]="24" nzRequired>项目总金额</nz-form-label>
+        <nz-form-control [nzSm]="24" [nzXs]="24">
+          <nz-input-number [(ngModel)]="projectManageArchivesa.totalPrice" formControlName="totalPrice" id="totalPrice"
+            [nzMin]="0" [nzStep]="1" [nzFormatter]="formatterDollar" [nzParser]="parserDollar"
+            (keyup)="getProjectManageArchivesa()"></nz-input-number>
+          <nz-form-explain *ngIf="validateForm.get('totalPrice')?.dirty && validateForm.get('totalPrice')?.errors">
+            请输入项目总金额
+          </nz-form-explain>
+        </nz-form-control>
+
+      </nz-form-item>
+    </div>
+    <div nz-col [nzSpan]="6">
+      <nz-form-item>
+        <nz-form-label [nzSpan]="'vertical' ? 24 : null" [nzXs]="24" nzRequired>里程碑类型</nz-form-label>
+        <nz-form-control [nzSm]="24" [nzXs]="24">
+          <nz-select style="widows: 100%;" nzShowSearch nzAllowClear formControlName="milestoneId" id="milestoneId"
+            [(ngModel)]="projectManageArchivesa.milestoneId" nzPlaceHolder="请选择"
+            (ngModelChange)="milestoneChange($event)">
+            <nz-option *ngFor="let i of milestoneList" [nzValue]="i.value" [nzLabel]="i.text"></nz-option>
+          </nz-select>
+          <nz-form-explain *ngIf="validateForm.get('milestoneId')?.dirty && validateForm.get('milestoneId')?.errors">
+            请选择里程碑
+          </nz-form-explain>
+        </nz-form-control>
+      </nz-form-item>
+    </div>
+  </div>
+  <div nz-row [nzGutter]="24">
+    <div nz-col [nzSpan]="6">
+      <nz-form-item>
+        <nz-form-label [nzSpan]="'vertical' ? 24 : null" [nzXs]="24">销售经理</nz-form-label>
+        <nz-form-control [nzSm]="24" [nzXs]="24">
+          <nz-tree-select style="width: 100%" [nzNodes]="saleManagerList" nzShowSearch [nzMultiple]="false"
+            formControlName="saleManagerId" id="saleManagerId" nzPlaceHolder="请选择"
+            [(ngModel)]="projectManageArchivesa.saleManagerId" [nzMaxTagCount]="3" [nzAllowClear]="true"
+            (ngModelChange)="managerChange($event,'1')">
+          </nz-tree-select>
+        </nz-form-control>
+      </nz-form-item>
+    </div>
+    <div nz-col [nzSpan]="18">
+      <nz-form-item>
+        <nz-form-label [nzSpan]="'vertical' ? 24 : null" [nzXs]="24">业务员</nz-form-label>
+        <nz-form-control [nzSm]="24" [nzXs]="24">
+          <!-- <nz-select [nzMaxTagCount]="3" nzMode="multiple" nzPlaceHolder="请选择" formControlName="saleManIds"
+            id="saleManIds" [(ngModel)]="saleManIds">
+            <nz-option *ngFor="let item of personnelList" [nzLabel]="item.id" [nzValue]="item.name"></nz-option>
+          </nz-select> -->
+          <nz-tree-select style="width: 100%" [nzNodes]="personnelList" nzShowSearch [nzMultiple]="true"
+            formControlName="saleManIds" id="saleManIds" nzPlaceHolder="请选择" [(ngModel)]="saleManIds"
+            [nzMaxTagCount]="3" [nzAllowClear]="true" (ngModelChange)="personnelChange($event,'1')">
+          </nz-tree-select>
+        </nz-form-control>
+      </nz-form-item>
+    </div>
+  </div>
+  <div nz-row [nzGutter]="24">
+    <div nz-col [nzSpan]="6">
+      <nz-form-item>
+        <nz-form-label [nzSpan]="'vertical' ? 24 : null" [nzXs]="24">实施项目经理</nz-form-label>
+        <nz-form-control [nzSm]="24" [nzXs]="24">
+          <nz-tree-select style="width: 100%" [nzNodes]="impManagerList" nzShowSearch [nzMultiple]="false"
+            formControlName="impManagerId" id="impManagerId" nzPlaceHolder="请选择"
+            [(ngModel)]="projectManageArchivesa.impManagerId" [nzMaxTagCount]="3" [nzAllowClear]="true"
+            (ngModelChange)="managerChange($event,'2')">
+          </nz-tree-select>
+        </nz-form-control>
+      </nz-form-item>
+    </div>
+    <div nz-col [nzSpan]="18">
+      <nz-form-item>
+        <nz-form-label [nzSpan]="'vertical' ? 24 : null" [nzXs]="24">实施顾问</nz-form-label>
+        <nz-form-control [nzSm]="24" [nzXs]="24">
+          <!-- <nz-select [nzMaxTagCount]="3" nzMode="multiple" nzPlaceHolder="请选择" formControlName="impConsultantIds"
+            id="impConsultantIds" [(ngModel)]="impConsultantIds">
+            <nz-option *ngFor="let item of personnelList" [nzLabel]="item.id" [nzValue]="item.name"></nz-option>
+          </nz-select> -->
+          <nz-tree-select style="width: 100%" [nzNodes]="personnelList" nzShowSearch [nzMultiple]="true"
+            formControlName="impConsultantIds" id="impConsultantIds" nzPlaceHolder="请选择" [(ngModel)]="impConsultantIds"
+            [nzMaxTagCount]="3" [nzAllowClear]="true" (ngModelChange)="personnelChange($event,'2')">
+          </nz-tree-select>
+        </nz-form-control>
+      </nz-form-item>
+    </div>
+  </div>
+  <div nz-row [nzGutter]="24">
+    <div nz-col [nzSpan]="6">
+      <nz-form-item>
+        <nz-form-label [nzSpan]="'vertical' ? 24 : null" [nzXs]="24">开发项目经理</nz-form-label>
+        <nz-form-control [nzSm]="24" [nzXs]="24">
+          <nz-tree-select style="width: 100%" [nzNodes]="deManagerList" nzShowSearch [nzMultiple]="false"
+            formControlName="deManagerId" id="deManagerId" nzPlaceHolder="请选择"
+            [(ngModel)]="projectManageArchivesa.deManagerId" [nzMaxTagCount]="3" [nzAllowClear]="true"
+            (ngModelChange)="managerChange($event,'3')">
+          </nz-tree-select>
+        </nz-form-control>
+      </nz-form-item>
+    </div>
+    <div nz-col [nzSpan]="18">
+      <nz-form-item>
+        <nz-form-label [nzSpan]="'vertical' ? 24 : null" [nzXs]="24">开发工程师</nz-form-label>
+        <nz-form-control [nzSm]="24" [nzXs]="24">
+          <nz-tree-select style="width: 100%" [nzNodes]="personnelList" nzShowSearch [nzMultiple]="true"
+            formControlName="deEngineerIds" id="deEngineerIds" nzPlaceHolder="请选择" [(ngModel)]="deEngineerIds"
+            [nzMaxTagCount]="3" [nzAllowClear]="true" (ngModelChange)="personnelChange($event,'3')">
+          </nz-tree-select>
+        </nz-form-control>
+      </nz-form-item>
+    </div>
+  </div>
+  <div nz-row [nzGutter]="24">
+    <div nz-col [nzSpan]="6">
+      <nz-form-item>
+        <nz-form-label [nzSpan]="'vertical' ? 24 : null" [nzXs]="24">服务经理</nz-form-label>
+        <nz-form-control [nzSm]="24" [nzXs]="24">
+          <nz-tree-select style="width: 100%" [nzNodes]="seManagerList" nzShowSearch [nzMultiple]="false"
+            formControlName="seManagerId" id="seManagerId" nzPlaceHolder="请选择"
+            [(ngModel)]="projectManageArchivesa.seManagerId" [nzMaxTagCount]="3" [nzAllowClear]="true"
+            (ngModelChange)="managerChange($event,'4')">
+          </nz-tree-select>
+        </nz-form-control>
+      </nz-form-item>
+    </div>
+    <div nz-col [nzSpan]="18">
+      <nz-form-item>
+        <nz-form-label [nzSpan]="'vertical' ? 24 : null" [nzXs]="24">服务工程师</nz-form-label>
+        <nz-form-control [nzSm]="24" [nzXs]="24">
+          <nz-tree-select style="width: 100%" [nzNodes]="personnelList" nzShowSearch [nzMultiple]="true"
+            formControlName="seEngineerIds" id="seEngineerIds" nzPlaceHolder="请选择" [(ngModel)]="seEngineerIds"
+            [nzMaxTagCount]="3" [nzAllowClear]="true" (ngModelChange)="personnelChange($event,'4')">
+          </nz-tree-select>
+        </nz-form-control>
+      </nz-form-item>
+    </div>
+  </div>
+</form>

+ 24 - 0
src/app/routes/project-manage-archives/update/essential-information/essential-information.component.spec.ts

@@ -0,0 +1,24 @@
+import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+import { ProjectManageArchivesUpdateEssentialInformationComponent } from './essential-information.component';
+
+describe('ProjectManageArchivesUpdateEssentialInformationComponent', () => {
+  let component: ProjectManageArchivesUpdateEssentialInformationComponent;
+  let fixture: ComponentFixture<ProjectManageArchivesUpdateEssentialInformationComponent>;
+
+  beforeEach(async(() => {
+    TestBed.configureTestingModule({
+      declarations: [ ProjectManageArchivesUpdateEssentialInformationComponent ]
+    })
+    .compileComponents();
+  }));
+
+  beforeEach(() => {
+    fixture = TestBed.createComponent(ProjectManageArchivesUpdateEssentialInformationComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});

+ 284 - 0
src/app/routes/project-manage-archives/update/essential-information/essential-information.component.ts

@@ -0,0 +1,284 @@
+import { Component, OnInit, EventEmitter, Output } from '@angular/core';
+import { NzModalRef, NzMessageService } from 'ng-zorro-antd';
+import { _HttpClient } from '@delon/theme';
+import { FormBuilder, Validators, FormGroup } from '@angular/forms';
+import { BaseArchivesProjectApprovalService } from 'app/services/basedata/base-archives-project-approval.service';
+import { CustomerService } from 'app/services/basedata/customer.service';
+import { PersonnelService } from 'app/services/basedata/personnel.service';
+import { ProjectManageArchives } from 'app/entity/project-manage-archives/project-manage-archives';
+import { BaseArchivesProjectApproval } from 'app/entity/basedata/base-archives-project-approval';
+import { Customer } from 'app/entity/basedata/customer';
+
+@Component({
+  selector: 'app-project-manage-archives-update-essential-information',
+  templateUrl: './essential-information.component.html',
+})
+export class ProjectManageArchivesUpdateEssentialInformationComponent implements OnInit {
+  constructor(
+    private fb: FormBuilder,
+    private baseArchivesProjectApprovalService: BaseArchivesProjectApprovalService,
+    private customerService: CustomerService,
+    private personnelService: PersonnelService,
+  ) {}
+
+  ngOnInit(): void {
+    //初始化表单
+    this.validateForm = this.fb.group({
+      proId: [null, [Validators.required]],
+      cusId: [null, [Validators.required]],
+      totalPrice: [null, [Validators.required]],
+      saleManagerId: [null],
+      saleManIds: [null],
+      impManagerId: [null],
+      impConsultantIds: [null],
+      deManagerId: [null],
+      deEngineerIds: [null],
+      seManagerId: [null],
+      seEngineerIds: [null],
+      milestoneId: [null, [Validators.required]],
+    });
+    this.getProList();
+    this.getCusList();
+    this.getPersonnelList();
+  }
+
+  validateForm!: FormGroup;
+  projectManageArchivesa: ProjectManageArchives = {
+    totalPrice: 0,
+  }; //项目档案主表对象
+  proList: any = []; //项目立项档案数据集合
+  cusList = []; //客户档案数据集合
+  //金额格式化
+  formatterDollar = (value: number) => `$ ${value}`;
+  parserDollar = (value: string) => value.replace('$ ', '');
+  personnelList = []; //人员下拉数据
+  saleManIds = []; //业务员id绑定
+  impConsultantIds = []; //实施顾问下拉选择绑定
+  deEngineerIds = []; //开发工程师下拉选择绑定
+  seEngineerIds = []; //服务工程师下拉选择绑定
+  milestoneList = []; //里程碑类型下拉数据
+
+  /**
+   * 查询项目立项
+   */
+  getProList() {
+    return new Promise(resolve => {
+      let baseArchivesProjectApproval = new BaseArchivesProjectApproval();
+      baseArchivesProjectApproval.pkOrg = sessionStorage.getItem('pkOrg');
+      this.baseArchivesProjectApprovalService.getTreeList(baseArchivesProjectApproval).then(response => {
+        this.proList = response.result;
+        resolve();
+      });
+    });
+  }
+
+  /**
+   * 里程碑类型选择事件
+   */
+  //回写里程碑类型到其他页签查询明细
+  @Output() milestone = new EventEmitter<{}>();
+  milestoneChange(event) {
+    if (event) {
+      this.milestoneList.forEach(element => {
+        if (element.value === event) {
+          this.projectManageArchivesa.milestoneType = element.text;
+        }
+      });
+      this.milestone.emit(this.projectManageArchivesa);
+    }
+  }
+
+  /**
+   * 项目立项选择事件
+   * @param event 立项id
+   */
+  proChange(event) {
+    this.getChild(this.proList, event);
+  }
+
+  //递归查找项目名称
+  getChild(list, event) {
+    list.forEach(element => {
+      if (event === element.id) {
+        this.projectManageArchivesa.proCode = element.code;
+        this.projectManageArchivesa.proName = element.title;
+      } else {
+        //如果没找到则进入子集查找
+        if (element.children && element.children.length > 0) {
+          this.getChild(element.children, event);
+        }
+      }
+    });
+  }
+
+  /**
+   * 客户档案数据
+   */
+  getCusList() {
+    return new Promise(resolve => {
+      let customer = new Customer();
+      customer.pkOrg = sessionStorage.getItem('pkOrg');
+      customer.pageSize = 20000;
+      this.customerService.getCustomer1(customer).then(response => {
+        this.cusList = response.result.records;
+        resolve();
+      });
+    });
+  }
+
+  /**
+   * 客户档案选择事件
+   */
+  cusChange(event) {
+    this.cusList.forEach(element => {
+      if (event === element.id) {
+        this.projectManageArchivesa.cusCode = element.code;
+        this.projectManageArchivesa.cusName = element.name;
+      }
+    });
+    this.getProjectManageArchivesa();
+  }
+
+  /**
+   * 人员下拉查询
+   */
+  saleManagerList = []; //销售经理下拉数据
+  impManagerList = []; //实施经理下拉数据
+  deManagerList = []; //开发项目经理数据
+  seManagerList = []; //服务项目经理数据
+  getPersonnelList() {
+    // return new Promise(resolve => {
+    //   this.personnelService.queryApprover(sessionStorage.getItem('pkOrg')).then(response => {
+    //     this.personnelList = JSON.parse(JSON.stringify(response.result));
+    //     this.saleManagerList = JSON.parse(JSON.stringify(response.result));
+    //     this.impManagerList = JSON.parse(JSON.stringify(response.result));
+    //     this.deManagerList = JSON.parse(JSON.stringify(response.result));
+    //     this.seManagerList = JSON.parse(JSON.stringify(response.result));
+    //     recursiveQuery(this.personnelList);
+    //     recursiveQuery(this.saleManagerList);
+    //     recursiveQuery(this.impManagerList);
+    //     recursiveQuery(this.deManagerList);
+    //     recursiveQuery(this.seManagerList);
+    //     resolve();
+    //   });
+    // });
+  }
+
+  /**
+   *  经理选择触发事件
+   * @param event 经理id
+   * @param type 经理类型
+   */
+  managerChange(event, type) {
+    if (event) {
+      this.saleManagerList.forEach(pkOrg => {
+        pkOrg.children.forEach(depart => {
+          depart.children.forEach(personnel => {
+            if (personnel.key === event) {
+              if (type === '1') {
+                //销售经理名称
+                this.projectManageArchivesa.saleManager = personnel.name;
+              } else if (type === '2') {
+                //实施项目经理名称
+                this.projectManageArchivesa.impManager = personnel.name;
+              } else if (type === '3') {
+                //开发项目经理名称
+                this.projectManageArchivesa.deManager = personnel.name;
+              } else if (type === '4') {
+                //服务经理名称
+                this.projectManageArchivesa.seManager = personnel.name;
+              }
+            }
+          });
+        });
+      });
+      this.getProjectManageArchivesa();
+    }
+  }
+
+  /**
+   * 人员多选触发事件
+   * @param event 人员id
+   * @param type 经理类型
+   */
+  personnelChange(event, type) {
+    if (event) {
+      let names = '';
+      let ids = '';
+      let sort = 0;
+      //根据下拉数据获取名称
+      event.forEach(element => {
+        this.saleManagerList.forEach(pkOrg => {
+          pkOrg.children.forEach(depart => {
+            depart.children.forEach(personnel => {
+              if (personnel.key === element) {
+                if (names === '') {
+                  names = personnel.name;
+                  ids = personnel.key;
+                } else {
+                  names = names + '、' + personnel.name;
+                  ids = ids + '、' + personnel.key;
+                }
+                sort++;
+              }
+            });
+          });
+        });
+      });
+      //有数据则正常赋值
+      if (sort > 0) {
+        if (type === '1') {
+          //业务员
+          this.projectManageArchivesa.saleManId = ids;
+          this.projectManageArchivesa.saleMan = names;
+        } else if (type === '2') {
+          //实施顾问
+          this.projectManageArchivesa.impConsultantId = ids;
+          this.projectManageArchivesa.impConsultant = names;
+        } else if (type === '3') {
+          //开发工程师
+          this.projectManageArchivesa.deEngineerId = ids;
+          this.projectManageArchivesa.deEngineer = names;
+        } else if (type === '4') {
+          //服务工程师
+          this.projectManageArchivesa.seEngineerId = ids;
+          this.projectManageArchivesa.seEngineer = names;
+        }
+      } else {
+        //没数据则清空
+        if (type === '1') {
+          //业务员
+          this.projectManageArchivesa.saleManId = '';
+          this.projectManageArchivesa.saleMan = '';
+        } else if (type === '2') {
+          //实施顾问
+          this.projectManageArchivesa.impConsultantId = '';
+          this.projectManageArchivesa.impConsultant = '';
+        } else if (type === '3') {
+          //开发工程师
+          this.projectManageArchivesa.deEngineerId = '';
+          this.projectManageArchivesa.deEngineer = '';
+        } else if (type === '4') {
+          //服务工程师
+          this.projectManageArchivesa.seEngineerId = '';
+          this.projectManageArchivesa.seEngineer = '';
+        }
+      }
+      this.getProjectManageArchivesa();
+    }
+  }
+
+  //基本信息回写到其他页签
+  @Output() projectManageArchivesaEntiy = new EventEmitter<{}>();
+  getProjectManageArchivesa() {
+    this.projectManageArchivesaEntiy.emit(this.projectManageArchivesa);
+  }
+
+  submitForm() {
+    for (const i in this.validateForm.controls) {
+      this.validateForm.controls[i].markAsDirty();
+      this.validateForm.controls[i].updateValueAndValidity();
+    }
+    let valid = this.validateForm.valid;
+  }
+}

+ 141 - 0
src/app/routes/project-manage-archives/update/implementation/implementation.component.html

@@ -0,0 +1,141 @@
+<!-- 商务 -->
+<form nz-form>
+  <div nz-row [nzGutter]="24">
+    <div nz-col [nzSpan]="6">
+      <nz-form-item>
+        <nz-form-label [nzSpan]="8">客户编码</nz-form-label>
+        <nz-form-control [nzSm]="16" [nzXs]="24">{{projectManageArchives.cusCode}}</nz-form-control>
+      </nz-form-item>
+    </div>
+    <div nz-col [nzSpan]="6">
+      <nz-form-item>
+        <nz-form-label [nzSpan]="8">客户名称</nz-form-label>
+        <nz-form-control [nzSm]="16" [nzXs]="24">{{projectManageArchives.cusName}}</nz-form-control>
+      </nz-form-item>
+    </div>
+    <div nz-col [nzSpan]="6">
+      <nz-form-item>
+        <nz-form-label [nzSpan]="8">实施项目经理</nz-form-label>
+        <nz-form-control [nzSm]="16" [nzXs]="24">{{projectManageArchives.impManager}}</nz-form-control>
+      </nz-form-item>
+    </div>
+    <div nz-col [nzSpan]="6">
+      <nz-form-item>
+        <nz-form-label [nzSpan]="8">实施顾问</nz-form-label>
+        <nz-form-control [nzSm]="16" [nzXs]="24">{{projectManageArchives.impConsultant}}</nz-form-control>
+      </nz-form-item>
+    </div>
+  </div>
+</form>
+
+<!-- 汇款信息 -->
+<nz-card nzTitle="回款信息" nzSize="small">
+  <nz-table nzBordered nzSize="small" [nzNoResult]="' '" [nzShowPagination]="false">
+    <tbody>
+      <tr>
+        <td><strong>实施金额</strong></td>
+        <td>第一笔</td>
+        <td>{{remittanceInformation.price1}}</td>
+        <td>第二笔</td>
+        <td>{{remittanceInformation.price2}}</td>
+        <td>第三笔</td>
+        <td>{{remittanceInformation.price3}}</td>
+        <td>第四笔</td>
+        <td>{{remittanceInformation.price4}}</td>
+        <td>第五笔</td>
+        <td>{{remittanceInformation.price5}}</td>
+      </tr>
+      <tr>
+        <td><strong>实际回款</strong></td>
+        <td>{{remittanceInformation.milestone1}}</td>
+        <td>{{remittanceInformation.desc1}}</td>
+        <td>{{remittanceInformation.milestone2}}</td>
+        <td>{{remittanceInformation.desc2}}</td>
+        <td>{{remittanceInformation.milestone3}}</td>
+        <td>{{remittanceInformation.desc3}}</td>
+        <td>{{remittanceInformation.milestone4}}</td>
+        <td>{{remittanceInformation.desc4}}</td>
+        <td>{{remittanceInformation.milestone5}}</td>
+        <td>{{remittanceInformation.desc5}}</td>
+      </tr>
+    </tbody>
+  </nz-table>
+</nz-card>
+
+<!-- 实施计划 -->
+<nz-card nzTitle="实施计划" nzSize="small">
+  <div nz-row [nzGutter]="24">
+    <div nz-col [nzSpan]="24">
+      <!-- 新增按钮 -->
+      <button (click)="addParent()" nz-button nzType="primary">{{ 'button.add' | translate }}</button>
+    </div>
+  </div>
+  <div nz-row [nzGutter]="24">
+    <div nz-col [nzSpan]="24">
+      <nz-table style="padding-top: 5px;" nzSize="small" class="tableTdPadding" #expandTable [nzData]="listOfMapData"
+        nzTableLayout="fixed" [nzShowPagination]="false" [nzFrontPagination]="false">
+        <thead>
+          <tr>
+            <th nzAlign="center"></th>
+            <th style="width: 10%;">里程碑</th>
+            <th style="width: 20%;">开始时间</th>
+            <th style="width: 20%;">结束时间</th>
+            <th style="width: 10%;">计划人天</th>
+            <th style="width: 20%;">执行人</th>
+            <th style="width: 10%;">实际人天</th>
+            <th style="width: 10%;">操作</th>
+          </tr>
+        </thead>
+        <tbody>
+          <ng-container *ngFor="let data of expandTable.data">
+            <ng-container *ngFor="let item of mapOfExpandedData[data.key]">
+
+
+              <tr *ngIf="(item.parent && item.parent.expand) || !item.parent">
+                <td [nzIndentSize]="item.level! * 20" [nzShowExpand]="!!item.children" [(nzExpand)]="item.expand"
+                  (nzExpandChange)="collapse(mapOfExpandedData[data.key], item, $event)">
+                </td>
+                <td>
+                  <ng-container *ngIf="item.id">
+                    {{ item.muilesName }}
+                  </ng-container>
+                  <ng-container *ngIf="!item.id">
+                    <input nz-input [(ngModel)]="item.muilesName" />
+                  </ng-container>
+                </td>
+                <td>
+                  <nz-date-picker [(ngModel)]="item.startDate"></nz-date-picker>
+                </td>
+                <td>
+                  <nz-date-picker [(ngModel)]="item.endDate"></nz-date-picker>
+                </td>
+                <td>
+                  <nz-input-number [(ngModel)]="item.planTime" [nzMin]="0" [nzStep]="1"></nz-input-number>
+                </td>
+                <td>
+                  <!-- <nz-select style="width: 100%;" [nzMaxTagCount]="3" nzMode="multiple" nzPlaceHolder="请选择"
+                    [(ngModel)]="item.executor">
+                    <nz-option *ngFor="let item of personnelList" [nzLabel]="item.id" [nzValue]="item.name"></nz-option>
+                  </nz-select> -->
+                  <nz-tree-select style="width: 100%" [nzNodes]="personnelList" nzShowSearch [nzMultiple]="true"
+                    nzPlaceHolder="请选择" [(ngModel)]="item.executors" [nzMaxTagCount]="3" [nzAllowClear]="true">
+                  </nz-tree-select>
+                </td>
+                <td>
+                  <nz-input-number [(ngModel)]="item.realTime" [nzMin]="0" [nzStep]="1"></nz-input-number>
+                </td>
+                <td>
+                  <a (click)="addChild(item.key)">{{ 'button.leve.lower' | translate }}</a>
+                  <nz-divider nzType="vertical"></nz-divider>
+                  <a nz-popconfirm nzTitle="{{'isdelete'|translate}}" nzOkText="{{ 'yes' | translate }}"
+                    nzCancelText="{{ 'no' | translate }}"
+                    (nzOnConfirm)="deleteRow(mapOfExpandedData[data.key],item,item.key)">{{ 'milestone.delete' | translate }}</a>
+                </td>
+              </tr>
+            </ng-container>
+          </ng-container>
+        </tbody>
+      </nz-table>
+    </div>
+  </div>
+</nz-card>

+ 24 - 0
src/app/routes/project-manage-archives/update/implementation/implementation.component.spec.ts

@@ -0,0 +1,24 @@
+import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+import { ProjectManageArchivesUpdateImplementationComponent } from './implementation.component';
+
+describe('ProjectManageArchivesUpdateImplementationComponent', () => {
+  let component: ProjectManageArchivesUpdateImplementationComponent;
+  let fixture: ComponentFixture<ProjectManageArchivesUpdateImplementationComponent>;
+
+  beforeEach(async(() => {
+    TestBed.configureTestingModule({
+      declarations: [ ProjectManageArchivesUpdateImplementationComponent ]
+    })
+    .compileComponents();
+  }));
+
+  beforeEach(() => {
+    fixture = TestBed.createComponent(ProjectManageArchivesUpdateImplementationComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});

+ 228 - 0
src/app/routes/project-manage-archives/update/implementation/implementation.component.ts

@@ -0,0 +1,228 @@
+import { Component, OnInit } from '@angular/core';
+import { NzModalRef, NzMessageService } from 'ng-zorro-antd';
+import { _HttpClient } from '@delon/theme';
+import { BaseArchivesMilestoneService } from 'app/services/basedata/base-archives-milestone.service';
+import { ProjectManageArchives } from 'app/entity/project-manage-archives/project-manage-archives';
+import { ProjectNodeTree } from '../../project-node-tree';
+
+@Component({
+  selector: 'app-project-manage-archives-update-implementation',
+  templateUrl: './implementation.component.html',
+})
+export class ProjectManageArchivesUpdateImplementationComponent implements OnInit {
+  constructor(
+    private baseArchivesMilestoneService:BaseArchivesMilestoneService
+  ) { }
+
+  ngOnInit(): void {
+    this.getTreeList();
+  }
+  
+
+  projectManageArchives:ProjectManageArchives={};//项目档案主表实体
+  listOfMapData:any=[];//树形集合
+  personnelList=[];//人员下拉列表
+  remittanceInformation:any={};//回款信息实体
+
+
+  /**
+   * 获取树形集合
+   */
+  getTreeList() {
+    // let baseArchivesMilestone=new BaseArchivesMilestone();
+    // baseArchivesMilestone.pkOrg=sessionStorage.getItem("pkOrg");//组织
+    // baseArchivesMilestone.typeId="2";
+    // this.baseArchivesMilestoneService.getTreeList(baseArchivesMilestone).then((response)=>{
+    //   if(response.result){
+    //     this.listOfMapData=response.result
+    //     this.getLoding();
+    //   }
+    // })
+  }
+
+  /**
+   * 初始化树形
+   */
+  getLoding(){
+    this.listOfMapData.forEach(item => {
+      this.mapOfExpandedData[item.key] = this.convertTreeToList(item);
+    });
+  }
+
+  /**
+   * 新增父级
+   */
+  //uuid
+  S4() {
+    return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1);
+  };
+  guid() {
+    return (this.S4() + this.S4() + this.S4() + this.S4() + this.S4() + this.S4() + this.S4() + this.S4());
+  };
+  // 随机数
+  add() {
+    return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1);
+  };
+  adding() {
+    return (this.add() + this.add() + this.add() + this.add() + this.add() + this.add() + this.add() + this.add());
+  };
+  addParent(){
+    this.listOfMapData.forEach(item => {
+      console.log(this.mapOfExpandedData[item.key]);
+    });
+    this.listOfMapData=[
+      ...this.listOfMapData,
+      {key:this.adding()}
+    ]
+    // this.getLoding();
+    this.initialValue();
+  }
+
+  /**
+   * 新增子集
+   * @param parentId 父级id
+   * @param data 操作对象
+   */
+  addChild(parentId){
+    this.getChild(this.listOfMapData, parentId);
+    this.initialValue();
+  }
+
+  /**
+   * 递归查询子集增加
+   */
+  getChild(children, parentId) {
+    var keyId = this.adding();
+    children.forEach(element => {
+      // 是否和点击的数据相等
+      // 相等则在此条数据加子数据
+      if (element.key == parentId) {
+        // 是否存在自数据不存在则创建child
+        if (element.children == null) {
+          element.children = []
+        }
+        // 添加一条空的子数据到child
+        element.children = [
+          ...element.children,
+          { key: keyId, parentId: parentId,children:null}
+        ]
+        // this.mapOfExpandedData[element.key] = this.convertTreeToList(null);
+        // this.initialValue();
+      } else {
+        if (element.children != null) {
+          this.getChild(element.children, parentId);
+        }
+      }
+    });
+  }
+
+ /**
+   * 删除行
+   */
+  deleteRow(array: ProjectNodeTree[], data: ProjectNodeTree, key){
+    this.getdeleteRow(key, this.listOfMapData);
+    this.initialValue()
+  }
+
+  /**
+   * 递归删除
+   * @param itemsId 对象id
+   * @param list 需要删除对象的集合
+   * @param parent 父级对象
+   */
+  getdeleteRow(itemsId: string, list?: any,parent?:any) {
+    list.forEach((element, i) => {
+      //判断选中得数据是否有找到
+      if (element.key == itemsId) {
+        //找到则先判断对象是否有子集,有则删除
+        if (element.children != null && element.children.length > 0) {
+          element.children.splice(0, element.children.length);
+        }
+        //然后删除父极对象
+        list.splice(i, 1);
+        //判断父极是否存在子集
+        if (list.length == 0&&parent) {
+          parent.children = null;
+        }
+        this.listOfMapData=[
+          ...this.listOfMapData
+        ]
+        // this.getDataInitialization2();
+        // this.initialValue();
+      } else {
+        //没有则判断是否有子集 有则递归同样判断
+        if (element.children != null && element.children.length > 0) {
+          this.getdeleteRow(itemsId, element.children,element);
+        }
+      }
+    });
+  }
+
+
+
+  initialValue(){
+    this.listOfMapData.forEach(item => {
+      const data = this.mapOfExpandedData[item.key];
+      this.mapOfExpandedData[item.key] = this.convertTreeToList(item);
+      const mapData = this.mapOfExpandedData[item.key];
+      if (data && mapData) {
+        mapData.forEach(el => {
+          data.forEach(element => {
+            if (element.key === el.key) {
+              el.muilesId = element.muilesId;
+              el.muilesName = element.muilesName;
+              el.startDate = element.startDate;
+              el.endDate = element.endDate;
+              el.planTime = element.planTime;
+              el.executors = element.executors;
+              el.realTime = element.realTime;
+            }
+          })
+        })
+      }
+    });
+  }
+
+  ///////////////////////////树形配置
+  mapOfExpandedData: { [key: string]: ProjectNodeTree[] } = {};
+
+  collapse(array: ProjectNodeTree[], data: ProjectNodeTree, $event: boolean): void {
+    if (!$event) {
+      if (data.children) {
+        data.children.forEach(d => {
+          const target = array.find(a => a.key === d.key)!;
+          target.expand = false;
+          this.collapse(array, target, false);
+        });
+      } else {
+        return;
+      }
+    }
+  }
+
+  convertTreeToList(root: ProjectNodeTree): ProjectNodeTree[] {
+    const stack: ProjectNodeTree[] = [];
+    const array: ProjectNodeTree[] = [];
+    const hashMap = {};
+    stack.push({ ...root, level: 0, expand: true });
+
+    while (stack.length !== 0) {
+      const node = stack.pop()!;
+      this.visitNode(node, hashMap, array);
+      if (node.children) {
+        for (let i = node.children.length - 1; i >= 0; i--) {
+          stack.push({ ...node.children[i], level: node.level! + 1, expand: true, parent: node });
+        }
+      }
+    }
+
+    return array;
+  }
+
+  visitNode(node: ProjectNodeTree, hashMap: { [key: string]: boolean }, array: ProjectNodeTree[]): void {
+    if (!hashMap[node.key]) {
+      hashMap[node.key] = true;
+      array.push(node);
+    }
+  }
+}

+ 142 - 0
src/app/routes/project-manage-archives/update/serviceta/serviceta.component.html

@@ -0,0 +1,142 @@
+<!-- 服务 -->
+<form nz-form>
+  <div nz-row [nzGutter]="24">
+    <div nz-col [nzSpan]="6">
+      <nz-form-item>
+        <nz-form-label [nzSpan]="8">客户编码</nz-form-label>
+        <nz-form-control [nzSm]="16" [nzXs]="24">{{projectManageArchives.cusCode}}</nz-form-control>
+      </nz-form-item>
+    </div>
+    <div nz-col [nzSpan]="6">
+      <nz-form-item>
+        <nz-form-label [nzSpan]="8">客户名称</nz-form-label>
+        <nz-form-control [nzSm]="16" [nzXs]="24">{{projectManageArchives.cusName}}</nz-form-control>
+      </nz-form-item>
+    </div>
+    <div nz-col [nzSpan]="6">
+      <nz-form-item>
+        <nz-form-label [nzSpan]="8">服务项目经理</nz-form-label>
+        <nz-form-control [nzSm]="16" [nzXs]="24">{{projectManageArchives.seManager}}</nz-form-control>
+      </nz-form-item>
+    </div>
+    <div nz-col [nzSpan]="6">
+      <nz-form-item>
+        <nz-form-label [nzSpan]="8">服务工程师</nz-form-label>
+        <nz-form-control [nzSm]="16" [nzXs]="24">{{projectManageArchives.seEngineer}}</nz-form-control>
+      </nz-form-item>
+    </div>
+  </div>
+</form>
+
+<!-- 汇款信息 -->
+<nz-card nzTitle="回款信息" nzSize="small">
+  <nz-table nzBordered nzSize="small" [nzNoResult]="' '" [nzShowPagination]="false">
+    <tbody>
+      <tr>
+        <td><strong>服务金额</strong></td>
+        <td>第一笔</td>
+        <td>{{remittanceInformation.price1}}</td>
+        <td>第二笔</td>
+        <td>{{remittanceInformation.price2}}</td>
+        <td>第三笔</td>
+        <td>{{remittanceInformation.price3}}</td>
+        <td>第四笔</td>
+        <td>{{remittanceInformation.price4}}</td>
+        <td>第五笔</td>
+        <td>{{remittanceInformation.price5}}</td>
+      </tr>
+      <tr>
+        <td><strong>实际回款</strong></td>
+        <td>{{remittanceInformation.milestone1}}</td>
+        <td>{{remittanceInformation.desc1}}</td>
+        <td>{{remittanceInformation.milestone2}}</td>
+        <td>{{remittanceInformation.desc2}}</td>
+        <td>{{remittanceInformation.milestone3}}</td>
+        <td>{{remittanceInformation.desc3}}</td>
+        <td>{{remittanceInformation.milestone4}}</td>
+        <td>{{remittanceInformation.desc4}}</td>
+        <td>{{remittanceInformation.milestone5}}</td>
+        <td>{{remittanceInformation.desc5}}</td>
+      </tr>
+    </tbody>
+  </nz-table>
+</nz-card>
+
+<!-- 实施计划 -->
+<nz-card nzTitle="服务计划" nzSize="small">
+  <div nz-row [nzGutter]="24">
+    <div nz-col [nzSpan]="24">
+      <!-- 新增按钮 -->
+      <button (click)="addParent()" nz-button nzType="primary">{{ 'button.add' | translate }}</button>
+    </div>
+  </div>
+  <div nz-row [nzGutter]="24">
+    <div nz-col [nzSpan]="24">
+      <nz-table style="padding-top: 5px;" nzSize="small" class="tableTdPadding" #expandTable [nzData]="listOfMapData"
+        nzTableLayout="fixed" [nzShowPagination]="false" [nzFrontPagination]="false">
+        <thead>
+          <tr>
+            <th></th>
+            <th style="width: 10%;">里程碑</th>
+            <th style="width: 20%;">开始时间</th>
+            <th style="width: 20%;">结束时间</th>
+            <th style="width: 10%;">计划人天</th>
+            <th style="width: 20%;">执行人</th>
+            <th style="width: 10%;">实际人天</th>
+            <th style="width: 10%;">操作</th>
+          </tr>
+        </thead>
+        <tbody>
+          <ng-container *ngFor="let data of expandTable.data">
+            <ng-container *ngFor="let item of mapOfExpandedData[data.key]">
+
+
+              <tr *ngIf="(item.parent && item.parent.expand) || !item.parent">
+                <td [nzIndentSize]="item.level! * 20" [nzShowExpand]="!!item.children" [(nzExpand)]="item.expand"
+                  (nzExpandChange)="collapse(mapOfExpandedData[data.key], item, $event)">
+                </td>
+                <td>
+                  <ng-container *ngIf="item.id">
+                    {{ item.muilesName }}
+                  </ng-container>
+                  <ng-container *ngIf="!item.id">
+                    <input nz-input [(ngModel)]="item.muilesName" />
+                  </ng-container>
+                </td>
+                <td>
+                  <nz-date-picker [(ngModel)]="item.startDate"></nz-date-picker>
+                </td>
+                <td>
+                  <nz-date-picker [(ngModel)]="item.endDate"></nz-date-picker>
+                </td>
+                <td>
+                  <nz-input-number [(ngModel)]="item.planTime" [nzMin]="0" [nzStep]="1"></nz-input-number>
+                </td>
+                <td>
+                  <!-- <nz-select style="width: 100%;" [nzMaxTagCount]="3" nzMode="multiple" nzPlaceHolder="请选择"
+                    [(ngModel)]="item.executor">
+                    <nz-option *ngFor="let item of personnelList" [nzLabel]="item.id" [nzValue]="item.name"></nz-option>
+                  </nz-select> -->
+                  <nz-tree-select style="width: 100%" [nzNodes]="personnelList" nzShowSearch [nzMultiple]="true"
+                  nzPlaceHolder="请选择"
+                  [(ngModel)]="item.executors" [nzMaxTagCount]="3" [nzAllowClear]="true">
+                </nz-tree-select>
+                </td>
+                <td>
+                  <nz-input-number [(ngModel)]="item.realTime" [nzMin]="0" [nzStep]="1"></nz-input-number>
+                </td>
+                <td>
+                  <a (click)="addChild(item.key)">{{ 'button.leve.lower' | translate }}</a>
+                  <nz-divider nzType="vertical"></nz-divider>
+                  <a nz-popconfirm nzTitle="{{'isdelete'|translate}}" nzOkText="{{ 'yes' | translate }}"
+                    nzCancelText="{{ 'no' | translate }}"
+                    (nzOnConfirm)="deleteRow(mapOfExpandedData[data.key],item,item.key)">{{ 'milestone.delete' | translate }}</a>
+                </td>
+              </tr>
+            </ng-container>
+          </ng-container>
+        </tbody>
+      </nz-table>
+    </div>
+  </div>
+</nz-card>

+ 24 - 0
src/app/routes/project-manage-archives/update/serviceta/serviceta.component.spec.ts

@@ -0,0 +1,24 @@
+import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+import { ProjectManageArchivesUpdateServicetaComponent } from './serviceta.component';
+
+describe('ProjectManageArchivesUpdateServicetaComponent', () => {
+  let component: ProjectManageArchivesUpdateServicetaComponent;
+  let fixture: ComponentFixture<ProjectManageArchivesUpdateServicetaComponent>;
+
+  beforeEach(async(() => {
+    TestBed.configureTestingModule({
+      declarations: [ ProjectManageArchivesUpdateServicetaComponent ]
+    })
+    .compileComponents();
+  }));
+
+  beforeEach(() => {
+    fixture = TestBed.createComponent(ProjectManageArchivesUpdateServicetaComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});

+ 215 - 0
src/app/routes/project-manage-archives/update/serviceta/serviceta.component.ts

@@ -0,0 +1,215 @@
+import { Component, OnInit } from '@angular/core';
+import { NzModalRef, NzMessageService } from 'ng-zorro-antd';
+import { _HttpClient } from '@delon/theme';
+import { BaseArchivesMilestoneService } from 'app/services/basedata/base-archives-milestone.service';
+import { ProjectManageArchives } from 'app/entity/project-manage-archives/project-manage-archives';
+import { ProjectNodeTree } from '../../project-node-tree';
+
+@Component({
+  selector: 'app-project-manage-archives-update-serviceta',
+  templateUrl: './serviceta.component.html',
+})
+export class ProjectManageArchivesUpdateServicetaComponent implements OnInit {
+  constructor(private baseArchivesMilestoneService: BaseArchivesMilestoneService) {}
+
+  ngOnInit(): void {
+    this.getTreeList();
+  }
+
+  projectManageArchives: ProjectManageArchives = {}; //项目档案主表实体
+  listOfMapData: any = []; //树形集合
+  personnelList = []; //人员下拉列表
+  remittanceInformation: any = {}; //回款信息实体
+
+  /**
+   * 获取树形集合
+   */
+  getTreeList() {
+    
+    // let baseArchivesMilestone = new BaseArchivesMilestone();
+    // baseArchivesMilestone.pkOrg = sessionStorage.getItem('pkOrg'); //组织
+    // baseArchivesMilestone.typeId = '4';
+    // this.baseArchivesMilestoneService.getTreeList(baseArchivesMilestone).then(response => {
+    //   if (response.result) {
+    //     this.listOfMapData = response.result;
+    //     this.getLoding();
+    //   }
+    // });
+  }
+
+  /**
+   * 初始化树形
+   */
+  getLoding() {
+    this.listOfMapData.forEach(item => {
+      this.mapOfExpandedData[item.key] = this.convertTreeToList(item);
+    });
+  }
+
+  /**
+   * 新增父级
+   */
+  //uuid
+  S4() {
+    return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1);
+  }
+  guid() {
+    return this.S4() + this.S4() + this.S4() + this.S4() + this.S4() + this.S4() + this.S4() + this.S4();
+  }
+  // 随机数
+  add() {
+    return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1);
+  }
+  adding() {
+    return this.add() + this.add() + this.add() + this.add() + this.add() + this.add() + this.add() + this.add();
+  }
+  addParent() {
+    this.listOfMapData.forEach(item => {
+      console.log(this.mapOfExpandedData[item.key]);
+    });
+    this.listOfMapData = [...this.listOfMapData, { key: this.adding() }];
+    // this.getLoding();
+    this.initialValue();
+  }
+
+  /**
+   * 新增子集
+   * @param parentId 父级id
+   * @param data 操作对象
+   */
+  addChild(parentId) {
+    this.getChild(this.listOfMapData, parentId);
+    this.initialValue();
+  }
+
+  /**
+   * 递归查询子集增加
+   */
+  getChild(children, parentId) {
+    var keyId = this.adding();
+    children.forEach(element => {
+      // 是否和点击的数据相等
+      // 相等则在此条数据加子数据
+      if (element.key == parentId) {
+        // 是否存在自数据不存在则创建child
+        if (element.children == null) {
+          element.children = [];
+        }
+        // 添加一条空的子数据到child
+        element.children = [...element.children, { key: keyId, parentId: parentId }];
+        // this.mapOfExpandedData[element.key] = this.convertTreeToList(null);
+        // this.initialValue();
+      } else {
+        if (element.children != null) {
+          this.getChild(element.children, parentId);
+        }
+      }
+    });
+  }
+
+  /**
+   * 删除行
+   */
+  deleteRow(array: ProjectNodeTree[], data: ProjectNodeTree, key) {
+    this.getdeleteRow(key, this.listOfMapData);
+    this.initialValue();
+  }
+
+  /**
+   * 递归删除
+   * @param itemsId 对象id
+   * @param list 需要删除对象的集合
+   * @param parent 父级对象
+   */
+  getdeleteRow(itemsId: string, list?: any, parent?: any) {
+    list.forEach((element, i) => {
+      //判断选中得数据是否有找到
+      if (element.key == itemsId) {
+        //找到则先判断对象是否有子集,有则删除
+        if (element.children != null && element.children.length > 0) {
+          element.children.splice(0, element.children.length);
+        }
+        //然后删除父极对象
+        list.splice(i, 1);
+        //判断父极是否存在子集
+        if (list.length == 0 && parent) {
+          parent.children = null;
+        }
+        this.listOfMapData = [...this.listOfMapData];
+        // this.getDataInitialization2();
+        // this.initialValue();
+      } else {
+        //没有则判断是否有子集 有则递归同样判断
+        if (element.children != null && element.children.length > 0) {
+          this.getdeleteRow(itemsId, element.children, element);
+        }
+      }
+    });
+  }
+
+  initialValue() {
+    this.listOfMapData.forEach(item => {
+      const data = this.mapOfExpandedData[item.key];
+      this.mapOfExpandedData[item.key] = this.convertTreeToList(item);
+      const mapData = this.mapOfExpandedData[item.key];
+      if (data && mapData) {
+        mapData.forEach(el => {
+          data.forEach(element => {
+            if (element.key === el.key) {
+              el.muilesId = element.muilesId;
+              el.muilesName = element.muilesName;
+              el.startDate = element.startDate;
+              el.endDate = element.endDate;
+              el.planTime = element.planTime;
+              el.executors = element.executors;
+              el.realTime = element.realTime;
+            }
+          });
+        });
+      }
+    });
+  }
+
+  ///////////////////////////树形配置
+  mapOfExpandedData: { [key: string]: ProjectNodeTree[] } = {};
+
+  collapse(array: ProjectNodeTree[], data: ProjectNodeTree, $event: boolean): void {
+    if (!$event) {
+      if (data.children) {
+        data.children.forEach(d => {
+          const target = array.find(a => a.key === d.key)!;
+          target.expand = false;
+          this.collapse(array, target, false);
+        });
+      } else {
+        return;
+      }
+    }
+  }
+
+  convertTreeToList(root: ProjectNodeTree): ProjectNodeTree[] {
+    const stack: ProjectNodeTree[] = [];
+    const array: ProjectNodeTree[] = [];
+    const hashMap = {};
+    stack.push({ ...root, level: 0, expand: true });
+
+    while (stack.length !== 0) {
+      const node = stack.pop()!;
+      this.visitNode(node, hashMap, array);
+      if (node.children) {
+        for (let i = node.children.length - 1; i >= 0; i--) {
+          stack.push({ ...node.children[i], level: node.level! + 1, expand: true, parent: node });
+        }
+      }
+    }
+
+    return array;
+  }
+
+  visitNode(node: ProjectNodeTree, hashMap: { [key: string]: boolean }, array: ProjectNodeTree[]): void {
+    if (!hashMap[node.key]) {
+      hashMap[node.key] = true;
+      array.push(node);
+    }
+  }
+}

+ 46 - 0
src/app/routes/project-manage-archives/update/update.component.html

@@ -0,0 +1,46 @@
+<nz-spin [nzSpinning]="isLoadingSave">
+  <nz-tabset nzTabPosition="left">
+    <!-- 基本信息 -->
+    <nz-tab nzTitle="{{'essential.information'|translate}}">
+      <app-project-manage-archives-update-essential-information #essentialInformation (projectManageArchivesaEntiy)="projectManageArchivesaEntiy($event)"
+      (milestone)="milestone($event)">
+
+      </app-project-manage-archives-update-essential-information>
+    </nz-tab>
+    <!-- 商务 -->
+    <nz-tab nzTitle="{{'business.affairs'|translate}}">
+      <app-project-manage-archives-update-business-affairs #businessAffairs (remittanceInformationChange)="remittanceInformationChange($event)">
+
+      </app-project-manage-archives-update-business-affairs>
+    </nz-tab>
+    <!-- 实施 -->
+    <nz-tab nzTitle="{{'implementation'|translate}}">
+      <app-project-manage-archives-update-implementation #implementation>
+
+      </app-project-manage-archives-update-implementation>
+    </nz-tab>
+    <!-- 开发 -->
+    <nz-tab nzTitle="{{'development'|translate}}">
+      <app-project-manage-archives-update-development #development>
+
+      </app-project-manage-archives-update-development>
+    </nz-tab>
+    <!-- 服务 -->
+    <nz-tab nzTitle="{{'service'|translate}}">
+      <app-project-manage-archives-update-serviceta #serviceta>
+
+      </app-project-manage-archives-update-serviceta>
+    </nz-tab>
+  </nz-tabset>
+</nz-spin>
+<!-- 按钮 -->
+<div class="base">
+  <!-- 关闭按钮 -->
+  <a nz-popconfirm nzTitle="{{'pm.contract.contract.add.button.cancel'|translate}}" (nzOnConfirm)="close()"
+    style="padding-right: 8px">
+    <button nz-button>{{'pm.quotation.cancel'|translate}}</button>
+  </a>
+  <!-- 保存按钮 -->
+  <button nz-button nzType="primary" class="ant-btn ant-btn-primary" (click)="save()"
+    [nzLoading]="isLoadingSave"><span>{{'pm.finish' | translate}}</span></button>
+</div>

+ 24 - 0
src/app/routes/project-manage-archives/update/update.component.spec.ts

@@ -0,0 +1,24 @@
+import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+import { ProjectManageArchivesUpdateComponent } from './update.component';
+
+describe('ProjectManageArchivesUpdateComponent', () => {
+  let component: ProjectManageArchivesUpdateComponent;
+  let fixture: ComponentFixture<ProjectManageArchivesUpdateComponent>;
+
+  beforeEach(async(() => {
+    TestBed.configureTestingModule({
+      declarations: [ ProjectManageArchivesUpdateComponent ]
+    })
+    .compileComponents();
+  }));
+
+  beforeEach(() => {
+    fixture = TestBed.createComponent(ProjectManageArchivesUpdateComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});

+ 401 - 0
src/app/routes/project-manage-archives/update/update.component.ts

@@ -0,0 +1,401 @@
+import { Component, OnInit, ViewChild } from '@angular/core';
+import { _HttpClient, ModalHelper } from '@delon/theme';
+import { STColumn, STComponent } from '@delon/abc';
+import { SFSchema } from '@delon/form';
+import { NzDrawerRef, NzNotificationService } from 'ng-zorro-antd';
+import { DictService } from 'app/services/dict.service';
+import { PersonnelService } from 'app/services/basedata/personnel.service';
+import { BaseArchivesMilestoneService } from 'app/services/basedata/base-archives-milestone.service';
+import { I18NService } from '@core';
+import { ProjectManageArchivesService } from 'app/services/project-manage-archives/project-manage-archives.service';
+import { DatePipe } from '@angular/common';
+import { ProjectManageArchivesUpdateEssentialInformationComponent } from './essential-information/essential-information.component';
+import { ProjectManageArchivesUpdateBusinessAffairsComponent } from './business-affairs/business-affairs.component';
+import { ProjectManageArchivesUpdateImplementationComponent } from './implementation/implementation.component';
+import { ProjectManageArchivesUpdateDevelopmentComponent } from './development/development.component';
+import { ProjectManageArchivesUpdateServicetaComponent } from './serviceta/serviceta.component';
+import { ProjectManageArchives } from 'app/entity/project-manage-archives/project-manage-archives';
+import { BaseArchivesMilestone } from 'app/entity/basedata/base-archives-milestone';
+import { recursiveQuery } from '@shared/utils/yuan copy';
+
+@Component({
+  selector: 'app-project-manage-archives-update',
+  templateUrl: './update.component.html',
+  styles: [
+    `
+      .base {
+        position: absolute;
+        bottom: 0px;
+        width: 100%;
+        border-top: 1px solid rgb(232, 232, 232);
+        padding: 6px 16px;
+        text-align: right;
+        left: 0px;
+        background: #fff;
+        z-index: 99;
+      }
+    `,
+  ],
+})
+export class ProjectManageArchivesUpdateComponent implements OnInit {
+  constructor(
+    private drawerRef: NzDrawerRef,
+    private dictService: DictService,
+    private personnelService: PersonnelService,
+    private baseArchivesMilestoneService: BaseArchivesMilestoneService,
+    private nzNotificationService: NzNotificationService,
+    private i18NService: I18NService,
+    private projectManageArchivesService: ProjectManageArchivesService,
+    private datePipe: DatePipe,
+  ) {}
+
+  ngOnInit(): void {
+    this.isLoadingSave=true;
+    //计划类型
+    this.getPlanType().then(()=>{
+      //人员下拉
+      return this.getPersonnelList();
+    }).then(()=>{
+      //里程碑类型
+      return this.getTypeList();
+    }).then(()=>{
+      return this.getById();
+    }).then(()=>{
+      this.isLoadingSave=false;
+    })
+    
+  }
+
+  isLoadingSave = false; //保存加载
+  //基本信息
+  @ViewChild('essentialInformation') essentialInformation: ProjectManageArchivesUpdateEssentialInformationComponent;
+  //商务
+  @ViewChild('businessAffairs') businessAffairs: ProjectManageArchivesUpdateBusinessAffairsComponent;
+  //实施
+  @ViewChild('implementation') implementation: ProjectManageArchivesUpdateImplementationComponent;
+  //开发
+  @ViewChild('development') development: ProjectManageArchivesUpdateDevelopmentComponent;
+  //服务
+  @ViewChild('serviceta') serviceta: ProjectManageArchivesUpdateServicetaComponent;
+
+  /**
+   * 计划类型查询
+   */
+  getPlanType() {
+    return new Promise(resolve => {
+      this.dictService.getByDictCode('plan_type').then(response => {
+        //商务计划类型
+        this.businessAffairs.planList = response.result;
+        resolve();
+      });
+    });
+  }
+
+  /**
+   * 根据类型id回写数据到实施、开发、服务页签的汇款信息
+   * @param data 计划对象
+   */
+  remittanceInformationChange(data) {
+    //实施页签
+    if (data.planId === '2') {
+      this.implementation.remittanceInformation = data;
+    } else if (data.planId === '3') {
+      //开发
+      this.development.remittanceInformation = data;
+    } else if (data.planId === '4') {
+      //服务
+      this.serviceta.remittanceInformation = data;
+    }
+  }
+
+  /**
+   * 基本信息的信息回写到其他页签
+   */
+  projectManageArchivesaEntiy(event) {
+    //商务
+    this.businessAffairs.projectManageArchives = event;
+    //实施
+    this.implementation.projectManageArchives = event;
+    //开发
+    this.development.projectManageArchives = event;
+    //服务
+    this.serviceta.projectManageArchives = event;
+  }
+
+  /**
+   * 获取人员下拉数据到各个页签中
+   */
+  getPersonnelList() {
+    return new Promise(resolve => {
+      this.personnelService.queryApprover(sessionStorage.getItem('pkOrg')).then(response => {
+        //基本信息页签人员
+        this.essentialInformation.personnelList = JSON.parse(JSON.stringify(response.result));
+        this.essentialInformation.saleManagerList = JSON.parse(JSON.stringify(response.result));
+        this.essentialInformation.impManagerList = JSON.parse(JSON.stringify(response.result));
+        this.essentialInformation.deManagerList = JSON.parse(JSON.stringify(response.result));
+        this.essentialInformation.seManagerList = JSON.parse(JSON.stringify(response.result));
+        //实施页签
+        this.implementation.personnelList = JSON.parse(JSON.stringify(response.result));
+        //开发页签
+        this.development.personnelList = JSON.parse(JSON.stringify(response.result));
+        //服务页签
+        this.serviceta.personnelList = JSON.parse(JSON.stringify(response.result));
+        recursiveQuery(this.essentialInformation.personnelList);
+        recursiveQuery(this.essentialInformation.saleManagerList);
+        recursiveQuery(this.essentialInformation.impManagerList);
+        recursiveQuery(this.essentialInformation.deManagerList);
+        recursiveQuery(this.essentialInformation.seManagerList);
+        //禁用公司、部分不可选
+        //实施
+        recursiveQuery(this.implementation.personnelList);
+        //开发
+        recursiveQuery(this.development.personnelList);
+        //服务
+        recursiveQuery(this.serviceta.personnelList);
+        resolve();
+      });
+    });
+  }
+
+  /**
+   * 获取里程碑类型到基本信息中
+   */
+  getTypeList() {
+    return new Promise((resolve)=>{
+      this.dictService.getByDictCode('base_archives_milestone_type').then(response => {
+        this.essentialInformation.milestoneList = response.result;
+        resolve();
+      });
+    })
+    
+  }
+
+  /**
+   * 根据里程碑类型查询商务的里程碑下拉数据以及实施、开发、服务的里程碑明细
+   */
+  milestone(event: ProjectManageArchives) {
+    //商务里程碑下拉数据
+    //查询条件
+    this.getPartentList(event.milestoneId);
+    //计划里程碑
+    //查询条件
+    // let baseArchivesMilestone2 = new BaseArchivesMilestone();
+    // baseArchivesMilestone2.pkOrg = sessionStorage.getItem('pkOrg'); //组织
+    // baseArchivesMilestone2.typeId = event.milestoneId;
+    // //查询数据
+    // this.baseArchivesMilestoneService.getTreeList(baseArchivesMilestone2).then(response => {
+    //   if (response.result) {
+    //     //实施
+    //     this.implementation.listOfMapData = JSON.parse(JSON.stringify(response.result));
+    //     this.implementation.getLoding();
+    //     //开发
+    //     this.development.listOfMapData = JSON.parse(JSON.stringify(response.result));
+    //     this.development.getLoding();
+    //     //服务
+    //     this.serviceta.listOfMapData = JSON.parse(JSON.stringify(response.result));
+    //     this.serviceta.getLoding();
+    //   }
+    // });
+  }
+
+  /**
+   * 商务中里程碑下拉数据
+   * @param milestoneId 里程碑类型id
+   */
+  getPartentList(milestoneId) {
+    //查询条件
+    let baseArchivesMilestone = new BaseArchivesMilestone();
+    baseArchivesMilestone.parentId = '0';
+    baseArchivesMilestone.typeId = milestoneId; //里程碑档案类型
+    //查询数据
+    this.baseArchivesMilestoneService.getAllParent(baseArchivesMilestone).then(response => {
+      if (response.result) {
+        this.businessAffairs.milestoneList = response.result;
+      }
+    });
+  }
+
+  /**
+   * 保存接口
+   */
+  save() {
+    return new Promise(resolve => {
+      this.isLoadingSave=true;
+      //基本信息中的
+      this.essentialInformation.submitForm();
+      //基本信息
+      let projectManageArchives = this.essentialInformation.projectManageArchivesa;
+      //组织
+      projectManageArchives.pkOrg = sessionStorage.getItem('pkOrg');
+      ////////////商务页签的计划表格数据
+      //已回款金额
+      projectManageArchives.received=this.businessAffairs.projectManageArchives.received;
+      let bsInfo: any = {};
+      bsInfo.coPlanList = this.businessAffairs.collectionPlanList; //收款计划
+      bsInfo.coSituationList = this.businessAffairs.paymentCollectionList; //收款情况
+      bsInfo.payPlanList = this.businessAffairs.paymentPlanList; //付款计划
+      bsInfo.paySituationList = this.businessAffairs.paymentStatusList; //付款情况
+      projectManageArchives.bsInfo = bsInfo;
+      ////////////实施页签的计划树形表格数据
+      let ipInfo: any = {};
+      let implementation = [];
+      //获取计划里程碑明细
+      this.getMileItem(this.implementation, implementation);
+      ipInfo.planList = implementation;
+      projectManageArchives.ipInfo = ipInfo;
+      ////////////实施页签的计划树形表格数据
+      let deInfo: any = {};
+      let development = [];
+      //获取计划里程碑明细
+      this.getMileItem(this.development, development);
+      deInfo.planList = development;
+      projectManageArchives.deInfo = deInfo;
+      ////////////实施页签的计划树形表格数据
+      let seInfo: any = {};
+      let serviceta = [];
+      //获取计划里程碑明细
+      this.getMileItem(this.serviceta, serviceta);
+      seInfo.planList = serviceta;
+      projectManageArchives.seInfo = seInfo;
+      this.projectManageArchivesService.update(projectManageArchives).then(response => {
+        if (response.success) {
+          //保存成功
+          this.isLoadingSave=false;
+          this.nzNotificationService.success(this.i18NService.fanyi('save.ok'), '');
+          this.drawerRef.close(true);
+          resolve();
+        } else {
+          //保存失败
+          this.isLoadingSave=false;
+          this.nzNotificationService.error(this.i18NService.fanyi('save.not'), '');
+        }
+      });
+    });
+  }
+
+  /**
+   * 获取计划里程碑明细数据
+   * @param component 页签组件对象
+   * @param list 需要的保存集合
+   */
+  getMileItem(component, list) {
+    component.listOfMapData.forEach(item => {
+      component.mapOfExpandedData[item.key].forEach(element => {
+        element.startDate = this.datePipe.transform(element.startDate, 'yyyy-MM-dd HH:mm:ss');
+        element.endDate = this.datePipe.transform(element.endDate, 'yyyy-MM-dd HH:mm:ss');
+        let names = ''; //人员名称
+        let ids = ''; //人员id
+        //获取执行人的名称和id
+        if (element.executors) {
+          element.executors.forEach(element => {
+            component.personnelList.forEach(pkOrg => {
+              pkOrg.children.forEach(depart => {
+                depart.children.forEach(personnel => {
+                  if (personnel.key === element) {
+                    if (names === '') {
+                      names = personnel.name;
+                      ids = personnel.key;
+                    } else {
+                      names = names + '、' + personnel.name;
+                      ids = ids + '、' + personnel.key;
+                    }
+                  }
+                });
+              });
+            });
+          });
+        }
+        element.keyId = element.key;
+        element.executor = names;
+        element.executorId = ids;
+        list.push(element);
+      });
+    });
+  }
+
+  close() {
+    this.drawerRef.close(true);
+  }
+
+  /**
+   * 修改根据id获取所有数据
+   */
+  id = '';
+  getById() {
+    return new Promise(resolve => {
+      this.projectManageArchivesService.getListById(this.id).then(response => {
+        if (response.result) {
+          let projectManageArchives = JSON.parse(JSON.stringify(response.result));
+          // //基本信息
+          // this.projectManageArchivesaEntiy(projectManageArchives);
+          ///////////////基本信息页签
+          this.essentialInformation.projectManageArchivesa = projectManageArchives;
+          //业务员多选数据
+          this.essentialInformation.saleManIds=this.getPeronnelIds(projectManageArchives.saleManId);
+          //实施顾问多选数据
+          this.essentialInformation.impConsultantIds=this.getPeronnelIds(projectManageArchives.impConsultantId);
+          //开发工程师多选数据
+          this.essentialInformation.deEngineerIds=this.getPeronnelIds(projectManageArchives.deEngineerId);
+          //服务工程师多选数据
+          this.essentialInformation.seEngineerIds=this.getPeronnelIds(projectManageArchives.seEngineerId);
+          ///////////////商务页签
+          //主表数据
+          // this.businessAffairs.projectManageArchives = projectManageArchives;
+          //收款计划
+          if(projectManageArchives.bsInfo.coPlanList){
+            this.businessAffairs.collectionPlanList = projectManageArchives.bsInfo.coPlanList;
+            this.businessAffairs.collectionPlanSort=projectManageArchives.bsInfo.coPlanList.length+1;
+          }
+          //回款情况
+          if(projectManageArchives.bsInfo.coSituationList){
+            this.businessAffairs.paymentCollectionList = projectManageArchives.bsInfo.coSituationList;
+            this.businessAffairs.paymentCollectionSort=projectManageArchives.bsInfo.coSituationList.length+1;
+          }
+          //付款计划
+          if(projectManageArchives.bsInfo.payPlanList){
+            this.businessAffairs.paymentPlanList = projectManageArchives.bsInfo.payPlanList;
+            this.businessAffairs.paymentPlanSort=projectManageArchives.bsInfo.payPlanList.length+1;
+          }
+          //付款情况
+          if(projectManageArchives.bsInfo.paySituationList){
+            this.businessAffairs.paymentStatusList = projectManageArchives.bsInfo.paySituationList;
+            this.businessAffairs.paymentStatusSort=projectManageArchives.bsInfo.paySituationList.length+1;
+          }
+          //对应的收款情况
+          this.businessAffairs.paymentCollectionList.forEach(element => {
+            this.remittanceInformationChange(element)
+          });
+          /////////////////实施
+          //主表基本数据
+          // this.implementation.projectManageArchives=projectManageArchives
+          //里程碑明细
+          this.implementation.listOfMapData = projectManageArchives.ipInfo.planList;
+          this.implementation.getLoding();
+          ////////////////开发
+          this.development.listOfMapData = projectManageArchives.deInfo.planList;
+          this.development.getLoding();
+          ////////////////服务
+          this.serviceta.listOfMapData = projectManageArchives.seInfo.planList;
+          this.serviceta.getLoding();
+          resolve();
+        }
+      });
+    });
+  }
+
+  /**
+   * 获取多选下拉列表中绑定的id数组
+   * @param personnels 多选人员id字符
+   */
+  getPeronnelIds(personnels):any{
+    if(personnels){
+      //截取为数组
+      let personnelIdList=personnels.split("、");
+      return personnelIdList;
+    }else{
+      return [];
+    }
+  }
+}
+
+

+ 43 - 0
src/app/services/project-manage-archives/project-manage-archives.service.ts

@@ -0,0 +1,43 @@
+import { Injectable } from '@angular/core';
+import { HttpClient } from '@angular/common/http';
+import { BaseResponse } from 'app/entity/baseResponse';
+import { Result } from 'app/entity/Result';
+import { ProjectManageArchives } from 'app/entity/project-manage-archives/project-manage-archives';
+
+@Injectable({
+  providedIn: 'root'
+})
+/**
+ * 项目档案
+ */
+export class ProjectManageArchivesService {
+
+  constructor(private http:HttpClient) { }
+
+  //分页查询
+  async getList(body: any): Promise<BaseResponse<Result<any>>> {
+    return await this.http
+      .get<BaseResponse<Result<any>>>('/archives/projectManageArchives/list', { params: body })
+      .toPromise();
+  }
+
+  //新增
+  async add(body: ProjectManageArchives): Promise<BaseResponse<any>> {
+    return await this.http.post<BaseResponse<any>>('archives/projectManageArchives/add', body).toPromise();
+  }
+
+  //根据id查询
+  async getListById(id: string): Promise<BaseResponse<any>> {
+    return await this.http.get<BaseResponse<any>>("archives/projectManageArchives/getListById", { params: { id: id } }).toPromise();
+  }
+
+  //修改
+  async update(body: ProjectManageArchives): Promise<BaseResponse<any>> {
+    return await this.http.post<BaseResponse<any>>('archives/projectManageArchives/edit', body).toPromise();
+  }
+
+  //删除
+  async delete(body:any):Promise<BaseResponse<any>>{
+    return await this.http.post<BaseResponse<any>>('archives/projectManageArchives/delete',body).toPromise();
+  }
+}