Browse Source

实施日志

chenc 4 years ago
parent
commit
f4428f13fa

+ 6 - 0
src/app/entity/project-work/pro-work-logic.ts

@@ -17,6 +17,8 @@ export class ProWorkLogic extends Page{
 	startDate?:string;
 	//结束日期
 	endDate?:string;
+	//汇报人id
+	reporterId?:string;
 	//汇报人
 	reporter?:string;
 	//里程碑id
@@ -27,4 +29,8 @@ export class ProWorkLogic extends Page{
 	currentUser?:string;
 	//组织
 	pkOrg?:string;
+	//创建时间
+	createTime?:string;
+	//明细数据
+	detailList?:any[];
 }

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

@@ -43,8 +43,8 @@ export class ProjectManageArchivesAddComponent implements OnInit {
     private baseArchivesMilestoneService: BaseArchivesMilestoneService,
     private nzNotificationService: NzNotificationService,
     private i18NService: I18NService,
-    private projectManageArchivesService:ProjectManageArchivesService,
-    private datePipe:DatePipe
+    private projectManageArchivesService: ProjectManageArchivesService,
+    private datePipe: DatePipe,
   ) {}
 
   ngOnInit(): void {
@@ -196,57 +196,57 @@ export class ProjectManageArchivesAddComponent implements OnInit {
    */
   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.add(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'), '');
-        }
-      });
+      if (this.essentialInformation.submitForm()) {
+        this.isLoadingSave = true;
+        //基本信息
+        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.add(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'), '');
+          }
+        });
+      }
     });
   }
 
@@ -282,8 +282,8 @@ export class ProjectManageArchivesAddComponent implements OnInit {
             });
           });
         }
-        element.muilesName=element.name;
-        element.keyId=element.key;
+        element.muilesName = element.name;
+        element.keyId = element.key;
         element.executor = names;
         element.executorId = ids;
         list.push(element);

+ 1 - 0
src/app/routes/project-manage-archives/add/essential-information/essential-information.component.ts

@@ -281,5 +281,6 @@ export class ProjectManageArchivesAddEssentialInformationComponent implements On
       this.validateForm.controls[i].updateValueAndValidity();
     }
     let valid = this.validateForm.valid;
+    return valid;
   }
 }

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

@@ -280,5 +280,6 @@ export class ProjectManageArchivesUpdateEssentialInformationComponent implements
       this.validateForm.controls[i].updateValueAndValidity();
     }
     let valid = this.validateForm.valid;
+    return valid;
   }
 }

+ 86 - 85
src/app/routes/project-manage-archives/update/update.component.ts

@@ -50,20 +50,23 @@ export class ProjectManageArchivesUpdateComponent implements OnInit {
   ) {}
 
   ngOnInit(): void {
-    this.isLoadingSave=true;
+    this.isLoadingSave = true;
     //计划类型
-    this.getPlanType().then(()=>{
-      //人员下拉
-      return this.getPersonnelList();
-    }).then(()=>{
-      //里程碑类型
-      return this.getTypeList();
-    }).then(()=>{
-      return this.getById();
-    }).then(()=>{
-      this.isLoadingSave=false;
-    })
-    
+    this.getPlanType()
+      .then(() => {
+        //人员下拉
+        return this.getPersonnelList();
+      })
+      .then(() => {
+        //里程碑类型
+        return this.getTypeList();
+      })
+      .then(() => {
+        return this.getById();
+      })
+      .then(() => {
+        this.isLoadingSave = false;
+      });
   }
 
   isLoadingSave = false; //保存加载
@@ -161,13 +164,12 @@ export class ProjectManageArchivesUpdateComponent implements OnInit {
    * 获取里程碑类型到基本信息中
    */
   getTypeList() {
-    return new Promise((resolve)=>{
+    return new Promise(resolve => {
       this.dictService.getByDictCode('base_archives_milestone_type').then(response => {
         this.essentialInformation.milestoneList = response.result;
         resolve();
       });
-    })
-    
+    });
   }
 
   /**
@@ -220,57 +222,58 @@ export class ProjectManageArchivesUpdateComponent implements OnInit {
    */
   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;
-      console.log(JSON.stringify(projectManageArchives))
-      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'), '');
-        }
-      });
+      if (this.essentialInformation.submitForm()) {
+        this.isLoadingSave = true;
+        //基本信息
+        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;
+        console.log(JSON.stringify(projectManageArchives));
+        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'), '');
+          }
+        });
+      }
     });
   }
 
@@ -332,39 +335,39 @@ export class ProjectManageArchivesUpdateComponent implements OnInit {
           ///////////////基本信息页签
           this.essentialInformation.projectManageArchivesa = projectManageArchives;
           //业务员多选数据
-          this.essentialInformation.saleManIds=this.getPeronnelIds(projectManageArchives.saleManId);
+          this.essentialInformation.saleManIds = this.getPeronnelIds(projectManageArchives.saleManId);
           //实施顾问多选数据
-          this.essentialInformation.impConsultantIds=this.getPeronnelIds(projectManageArchives.impConsultantId);
+          this.essentialInformation.impConsultantIds = this.getPeronnelIds(projectManageArchives.impConsultantId);
           //开发工程师多选数据
-          this.essentialInformation.deEngineerIds=this.getPeronnelIds(projectManageArchives.deEngineerId);
+          this.essentialInformation.deEngineerIds = this.getPeronnelIds(projectManageArchives.deEngineerId);
           //服务工程师多选数据
-          this.essentialInformation.seEngineerIds=this.getPeronnelIds(projectManageArchives.seEngineerId);
+          this.essentialInformation.seEngineerIds = this.getPeronnelIds(projectManageArchives.seEngineerId);
           ///////////////商务页签
           //主表数据
           // this.businessAffairs.projectManageArchives = projectManageArchives;
           //收款计划
-          if(projectManageArchives.bsInfo.coPlanList){
+          if (projectManageArchives.bsInfo.coPlanList) {
             this.businessAffairs.collectionPlanList = projectManageArchives.bsInfo.coPlanList;
-            this.businessAffairs.collectionPlanSort=projectManageArchives.bsInfo.coPlanList.length+1;
+            this.businessAffairs.collectionPlanSort = projectManageArchives.bsInfo.coPlanList.length + 1;
           }
           //回款情况
-          if(projectManageArchives.bsInfo.coSituationList){
+          if (projectManageArchives.bsInfo.coSituationList) {
             this.businessAffairs.paymentCollectionList = projectManageArchives.bsInfo.coSituationList;
-            this.businessAffairs.paymentCollectionSort=projectManageArchives.bsInfo.coSituationList.length+1;
+            this.businessAffairs.paymentCollectionSort = projectManageArchives.bsInfo.coSituationList.length + 1;
           }
           //付款计划
-          if(projectManageArchives.bsInfo.payPlanList){
+          if (projectManageArchives.bsInfo.payPlanList) {
             this.businessAffairs.paymentPlanList = projectManageArchives.bsInfo.payPlanList;
-            this.businessAffairs.paymentPlanSort=projectManageArchives.bsInfo.payPlanList.length+1;
+            this.businessAffairs.paymentPlanSort = projectManageArchives.bsInfo.payPlanList.length + 1;
           }
           //付款情况
-          if(projectManageArchives.bsInfo.paySituationList){
+          if (projectManageArchives.bsInfo.paySituationList) {
             this.businessAffairs.paymentStatusList = projectManageArchives.bsInfo.paySituationList;
-            this.businessAffairs.paymentStatusSort=projectManageArchives.bsInfo.paySituationList.length+1;
+            this.businessAffairs.paymentStatusSort = projectManageArchives.bsInfo.paySituationList.length + 1;
           }
           //对应的收款情况
           this.businessAffairs.paymentCollectionList.forEach(element => {
-            this.remittanceInformationChange(element)
+            this.remittanceInformationChange(element);
           });
           /////////////////实施
           //主表基本数据
@@ -388,15 +391,13 @@ export class ProjectManageArchivesUpdateComponent implements OnInit {
    * 获取多选下拉列表中绑定的id数组
    * @param personnels 多选人员id字符
    */
-  getPeronnelIds(personnels):any{
-    if(personnels){
+  getPeronnelIds(personnels): any {
+    if (personnels) {
       //截取为数组
-      let personnelIdList=personnels.split("、");
+      let personnelIdList = personnels.split('、');
       return personnelIdList;
-    }else{
+    } else {
       return [];
     }
   }
 }
-
-

+ 109 - 0
src/app/routes/project-work/implementation-log/add/add.component.html

@@ -0,0 +1,109 @@
+<nz-spin [nzSpinning]="isLoadingSave">
+  <form nz-form [formGroup]="validateForm" (ngSubmit)="submitForm()">
+    <div nz-row [nzGutter]="24">
+      <div nz-col [nzSpan]="8">
+        <nz-form-item>
+          <nz-form-label [nzSm]="6" [nzXs]="24" nzRequired nzFor="code">单据编码</nz-form-label>
+          <nz-form-control [nzSm]="14" [nzXs]="24">
+            <input placeholder="自动生成" nz-input formControlName="billcode" id="billcode"
+              [(ngModel)]="proWorkLogic.billcode" [disabled]="true" />
+          </nz-form-control>
+        </nz-form-item>
+      </div>
+      <div nz-col [nzSpan]="8">
+        <nz-form-item>
+          <nz-form-label [nzSm]="6" [nzXs]="24" nzRequired>项目</nz-form-label>
+          <nz-form-control [nzSm]="14" [nzXs]="24">
+            <nz-select style="widows: 100%;" nzShowSearch nzAllowClear formControlName="proId" id="proId"
+              [(ngModel)]="proWorkLogic.proId" nzPlaceHolder="请选择" (ngModelChange)="proChange($event)">
+              <nz-option *ngFor="let i of proList" [nzValue]="i.id" [nzLabel]="i.proName"></nz-option>
+            </nz-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]="8">
+        <nz-form-item>
+          <nz-form-label [nzSm]="6" [nzXs]="24" nzRequired>汇报人</nz-form-label>
+          <nz-form-control [nzSm]="14" [nzXs]="24">
+            <nz-tree-select style="width: 100%" [nzNodes]="personnelList" nzShowSearch [nzMultiple]="false"
+              formControlName="reporterId" id="reporterId" nzPlaceHolder="请选择" [(ngModel)]="proWorkLogic.reporterId"
+              [nzMaxTagCount]="3" [nzAllowClear]="true">
+            </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>
+    <div nz-row [nzGutter]="24">
+      <div nz-col [nzSpan]="8">
+        <nz-form-item>
+          <nz-form-label [nzSm]="6" [nzXs]="24" nzRequired>开始时间</nz-form-label>
+          <nz-form-control [nzSm]="14" [nzXs]="24">
+            <nz-range-picker [nzShowTime]="true" formControlName="date" id="date" [(ngModel)]="date"></nz-range-picker>
+          </nz-form-control>
+        </nz-form-item>
+      </div>
+    </div>
+  </form>
+  <nz-card>
+    <div nz-row [nzGutter]="24">
+      <div nz-col [nzSpan]="24">
+        <!-- 新增按钮 -->
+        <button (click)="addRow()" 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]="itemList"
+          [nzFrontPagination]="false" [nzShowPagination]="false">
+          <thead>
+            <tr>
+              <th nzAlign="center" style="width: 5%;">序号</th>
+              <th style="width: 30%;">里程碑</th>
+              <th style="width: 50%;">工作内容</th>
+              <th style="width: 5%;">工作用时</th>
+              <th style="width: 10%;">操作</th>
+            </tr>
+          </thead>
+          <tbody>
+            <tr *ngFor="let data of basicTable.data;let i =index">
+              <td nzAlign="center">{{i+1}}</td>
+              <td>
+                <nz-tree-select style="width: 100%" [nzNodes]="mieList" nzShowSearch [nzMultiple]="false"
+                  nzPlaceHolder="请选择" [(ngModel)]="data.proArchivesId" [nzMaxTagCount]="3" [nzAllowClear]="true" (ngModelChange)="proArchivesIdChange(data)">
+                </nz-tree-select >
+              </td>
+              <td>
+                <textarea rows="1" nz-input [(ngModel)]="data.content"></textarea>
+              </td>
+              <td style="width: 10%;">
+                <nz-input-number [(ngModel)]="data.duration" [nzMin]="0" [nzStep]="1"></nz-input-number>
+              </td>
+              <td>
+                <a nz-popconfirm nzTitle="是否删除?" (nzOnConfirm)="deleteRow(data.sort)">{{'table.delete'|translate}}</a>
+              </td>
+            </tr>
+          </tbody>
+        </nz-table>
+      </div>
+    </div>
+  </nz-card>
+</nz-spin>
+<!-- 按钮 -->
+<div class="base">
+  <strong>填写人:</strong>{{proWorkLogic.currentUser}} <strong>填写时间:</strong>{{proWorkLogic.createTime}}
+  <!-- 关闭按钮 -->
+  <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)="submitForm()"
+    [nzLoading]="isLoadingSave"><span>{{'pm.finish' | translate}}</span></button>
+</div>

+ 24 - 0
src/app/routes/project-work/implementation-log/add/add.component.spec.ts

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

+ 286 - 0
src/app/routes/project-work/implementation-log/add/add.component.ts

@@ -0,0 +1,286 @@
+import { Component, OnInit } from '@angular/core';
+import { NzModalRef, NzMessageService, NzNotificationService, NzDrawerRef } from 'ng-zorro-antd';
+import { _HttpClient, SettingsService } from '@delon/theme';
+import { FormBuilder, Validators, FormGroup } from '@angular/forms';
+import { ProWorkLogic } from 'app/entity/project-work/pro-work-logic';
+import { DatePipe } from '@angular/common';
+import { ProjectManageArchivesService } from 'app/services/project-manage-archives/project-manage-archives.service';
+import { ProjectManageArchives } from 'app/entity/project-manage-archives/project-manage-archives';
+import { PersonnelService } from 'app/services/basedata/personnel.service';
+import { recursiveQuery } from '@shared';
+import { ProWorkLogicService } from 'app/services/project-work/pro-work-logic.service';
+import { I18NService } from '@core';
+
+@Component({
+  selector: 'app-project-work-implementation-log-add',
+  templateUrl: './add.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 ProjectWorkImplementationLogAddComponent implements OnInit {
+  constructor(
+    private fb: FormBuilder,
+    private settingsService: SettingsService,
+    private datePipe: DatePipe,
+    private projectManageArchivesService: ProjectManageArchivesService,
+    private personnelService: PersonnelService,
+    private proWorkLogicService: ProWorkLogicService,
+    private nzNotificationService: NzNotificationService,
+    private i18NService: I18NService,
+    private drawerRef: NzDrawerRef,
+  ) {}
+
+  ngOnInit(): void {
+    //初始化表单
+    this.validateForm = this.fb.group({
+      billcode: [{ value: '', disabled: true }],
+      proId: [null, [Validators.required]],
+      date: [null, [Validators.required]],
+      reporterId: [null, [Validators.required]],
+    });
+    //项目下拉
+    this.isLoadingSave = true;
+    this.getProList()
+      .then(() => {
+        //人员下来数据
+        return this.getPersonnelList();
+      })
+      .then(() => {
+        this.isLoadingSave = false;
+      });
+  }
+
+  isLoadingSave = false;
+  validateForm!: FormGroup;
+  proWorkLogic: ProWorkLogic = {
+    currentUser: this.settingsService.user.realname,
+    createTime: this.datePipe.transform(new Date(), 'yyyy-MM-dd HH:mm:ss'),
+  }; //对象
+  proList = []; //项目下拉数据
+  personnelList = []; //汇报人下拉数据
+  itemList = []; //明细集合
+  mieList = []; //里程碑数据下拉
+  date = null;
+
+  /**
+   * 获取项目下拉数据
+   */
+  getProList() {
+    return new Promise(resolve => {
+      let projectManageArchives = new ProjectManageArchives();
+      projectManageArchives.pageSize = 20000;
+      projectManageArchives.pkOrg = sessionStorage.getItem('pkOrg');
+      this.projectManageArchivesService.getList(projectManageArchives).then(response => {
+        if (response.result.records) {
+          this.proList = response.result.records;
+        }
+        resolve();
+      });
+    });
+  }
+
+  /**
+   * 项目下拉选择事件
+   */
+  proChange(event) {
+    this.getMieList(event);
+  }
+
+  /**
+   * 获取汇报人下拉数据
+   */
+  getPersonnelList() {
+    return new Promise(resolve => {
+      this.personnelService.queryApprover(sessionStorage.getItem('pkOrg')).then(response => {
+        if (response.result) {
+          this.personnelList = JSON.parse(JSON.stringify(response.result));
+        }
+        recursiveQuery(this.personnelList);
+        resolve();
+      });
+    });
+  }
+
+  /**
+   * 里程碑数据下拉
+   */
+  getMieList(proArchivesId) {
+    return new Promise(resolve => {
+      let plan = { id: proArchivesId, planType: '2' };
+      this.projectManageArchivesService.getPlanListById(plan).then(response => {
+        if (response.result) {
+          this.mieList = response.result;
+        }
+        resolve();
+      });
+    });
+  }
+
+  /**
+   * 里程碑选择事件
+   */
+  proArchivesIdChange(data) {
+    console.log(data.proArchivesId);
+    //是否选择里程碑
+    if (data.proArchivesId) {
+      this.getChild(this.mieList, data);
+    } else {
+      data.proArchivesMilestone = '';
+      data.proArchivesId = '';
+    }
+  }
+
+  /**
+   * 递归查询名称
+   */
+  getChild(mieList, data) {
+    mieList.forEach(element => {
+      if (element.key === data.proArchivesId) {
+        data.proArchivesMilestone = element.title;
+        data.proArchivesId = element.id;
+      } else {
+        if (element.children) {
+          this.getChild(element.children, data);
+        }
+      }
+    });
+  }
+
+  /**
+   * 增行按钮
+   */
+  sort = 0;
+  addRow() {
+    this.itemList = [
+      ...this.itemList,
+      {
+        sort: this.sort,
+      },
+    ];
+    this.sort++;
+  }
+
+  /**
+   * 删除行
+   */
+  deleteRow(sort) {
+    this.itemList = this.itemList.filter(d => d.sort !== sort);
+  }
+
+  /**
+   * 保存按钮
+   */
+  submitForm(): any {
+    return new Promise(resolve => {
+      for (const i in this.validateForm.controls) {
+        this.validateForm.controls[i].markAsDirty();
+        this.validateForm.controls[i].updateValueAndValidity();
+      }
+      let valid = this.validateForm.valid;
+      if (valid) {
+        this.isLoadingSave = true;
+        this.proWorkLogic.type = '2'; //实施
+        this.proWorkLogic.pkOrg = sessionStorage.getItem('pkOrg');
+        //项目名称
+        if (this.proWorkLogic.proId) {
+          this.proList.forEach(element => {
+            if (element.id === this.proWorkLogic.proId) {
+              this.proWorkLogic.proName = element.proName;
+            }
+          });
+        } else {
+          this.proWorkLogic.proName = '';
+        }
+        //汇报人名称
+        if (this.proWorkLogic.reporterId) {
+          //循环集合数据获取名称
+          this.personnelList.forEach(pkOrg => {
+            pkOrg.children.forEach(depart => {
+              depart.children.forEach(personnel => {
+                if (personnel.key === this.proWorkLogic.reporterId) {
+                  this.proWorkLogic.reporter = personnel.name;
+                }
+              });
+            });
+          });
+        } else {
+          this.proWorkLogic.reporter = '';
+        }
+        //时间格式化
+        this.proWorkLogic.startDate = this.datePipe.transform(this.date[0], 'yyyy-MM-dd HH:mm:ss');
+        this.proWorkLogic.endDate = this.datePipe.transform(this.date[1], 'yyyy-MM-dd HH:mm:ss');
+        //判断两个时间差的工时是否大于明细总工时
+        if(!this.getHourBoole()){
+          this.nzNotificationService.warning("工作用时不得大于开始时间与结束时间之差","");
+          this.isLoadingSave=false;
+          return;
+        }
+        //子表\
+        //判断是否输入子表数据
+        if (this.itemList && this.itemList.length > 0) {
+          this.proWorkLogic.detailList = this.itemList;
+        } else {
+          this.nzNotificationService.warning('工作内容必填', '');
+          this.isLoadingSave=false;
+          return;
+        }
+        this.proWorkLogicService.add(this.proWorkLogic).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'), '');
+          }
+        });
+      }
+    });
+  }
+
+  /**
+   * 判断两个时间差的工时是否大于明细总工时
+   */
+  getHourBoole():boolean{
+    //明细总工时
+    let itemHour=0;
+    //两个时间差
+    let dateHour=this.getInervalHour(this.date[0], this.date[1]);
+    //循环获取明细的总工时
+    this.itemList.forEach(element => {
+      if(element.duration){
+        itemHour=itemHour+Number(element.duration);
+      }
+    });
+    return dateHour>=itemHour;
+  }
+
+  /**
+   * 获取两个时间差
+   */
+  getInervalHour(startDate, endDate) {
+    var ms = endDate.getTime() - startDate.getTime();
+    if (ms < 0) return 0;
+    return Math.floor(ms / 1000 / 60 / 60);
+  }
+
+  close() {
+    this.drawerRef.close();
+  }
+}

+ 30 - 2
src/app/routes/project-work/implementation-log/implementation-log.component.html

@@ -4,6 +4,34 @@
   </ng-template>
 </page-header>
 <nz-card>
-  <sf mode="search" [schema]="searchSchema" (formSubmit)="st.reset($event)" (formReset)="st.reset($event)"></sf>
-  <st #st [data]="url" [columns]="columns"></st>
+   <!-- 表格 -->
+   <div nz-row [nzGutter]="{ xs: 8, sm: 16, md: 24, lg: 32 }">
+    <div nz-col [nzSpan]="24">
+      <nz-table nzSize="small" #basicTable [nzData]="listOfData" [nzFrontPagination]="false" [nzTotal]="page.total"
+        [nzPageIndex]="page.current" (nzPageIndexChange)="pageIndexChange($event)" [nzLoading]="isSpinning">
+        <thead>
+          <tr>
+            <th>单据编码</th>
+            <th>项目</th>
+            <th>开始时间</th>
+            <th>结束时间</th>
+            <th>操作</th>
+          </tr>
+        </thead>
+        <tbody>
+          <tr *ngFor="let data of basicTable.data">
+            <td>{{ data.billcode }}</td>
+            <td>{{ data.proName }}</td>
+            <td>{{ data.startDate }}</td>
+            <td>{{ data.endDate }}</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>
+              <a (click)="delete(data.id)" acl [acl-ability]="'base-archives-cost:delete'">删除</a>
+            </td>
+          </tr>
+        </tbody>
+      </nz-table>
+    </div>
+  </div>
 </nz-card>

+ 111 - 30
src/app/routes/project-work/implementation-log/implementation-log.component.ts

@@ -2,44 +2,125 @@ 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 { ProWorkLogic } from 'app/entity/project-work/pro-work-logic';
+import { ProWorkLogicService } from 'app/services/project-work/pro-work-logic.service';
+import { ProjectWorkImplementationLogAddComponent } from './add/add.component';
+import { NzDrawerService, NzNotificationService } from 'ng-zorro-antd';
+import { I18NService } from '@core';
+import { ProjectWorkImplementationLogUpdateComponent } from './update/update.component';
 
 @Component({
   selector: 'app-project-work-implementation-log',
   templateUrl: './implementation-log.component.html',
 })
 export class ProjectWorkImplementationLogComponent implements OnInit {
-  url = `/user`;
-  searchSchema: SFSchema = {
-    properties: {
-      no: {
-        type: 'string',
-        title: '编号'
-      }
-    }
-  };
-  @ViewChild('st') st: STComponent;
-  columns: STColumn[] = [
-    { title: '编号', index: 'no' },
-    { title: '调用次数', type: 'number', index: 'callNo' },
-    { title: '头像', type: 'img', width: '50px', index: 'avatar' },
-    { title: '时间', type: 'date', index: 'updatedAt' },
-    {
-      title: '',
-      buttons: [
-        // { text: '查看', click: (item: any) => `/form/${item.id}` },
-        // { text: '编辑', type: 'static', component: FormEditComponent, click: 'reload' },
-      ]
-    }
-  ];
-
-  constructor(private http: _HttpClient, private modal: ModalHelper) { }
-
-  ngOnInit() { }
+  constructor(
+    private proWorkLogicService:ProWorkLogicService,
+    private nzDrawerService:NzDrawerService,
+    private i18NService:I18NService,
+    private nzNotificationService:NzNotificationService
+  ) {}
+
+  ngOnInit() {
+    this.getList();
+  }
+  listOfData = [];
+  proWorkLogic: ProWorkLogic = {}; //对象
+  page = {
+    total: 0,
+    current: 0,
+  }; //页码
+  isSpinning = false;
+
+  //按页码显示数据
+  pageIndexChange(event) {
+    this.proWorkLogic.pageNo = event; //当前页码
+    this.getList();
+  }
 
+  /**
+   * 查询数据表
+   */
+  getList() {
+    // this.isSpinning=true;
+    this.proWorkLogic.pkOrg = sessionStorage.getItem('pkOrg'); //组织
+    this.proWorkLogic.type="2";
+    this.proWorkLogicService.getList(this.proWorkLogic).then(response => {
+      this.listOfData = response.result.records;
+    });
+  }
+
+  /**
+   * 查询按钮
+   */
+  query() {
+    this.proWorkLogic.pageNo = 1;
+    this.getList();
+  }
+  
+  /**
+   * 新增按钮
+   */
   add() {
-    // this.modal
-    //   .createStatic(FormEditComponent, { i: { id: 0 } })
-    //   .subscribe(() => this.st.reload());
+    const drawerRef = this.nzDrawerService.create<ProjectWorkImplementationLogAddComponent, { quotationId: string }, string>({
+      nzTitle: this.i18NService.fanyi("button.add"),//新增标题
+      nzContent: ProjectWorkImplementationLogAddComponent,
+      nzWidth: window.innerWidth,
+      nzBodyStyle: { height: 'calc(100% - 55px)', overflow: 'auto', 'padding-bottom': '53px' }
+      // nzContentParams: {
+      //   //模板id
+      //   quotationId: item.id
+      // }
+    });
+
+    //关闭抽屉的回调
+    drawerRef.afterClose.subscribe((isRefresh) => {
+      if (isRefresh) {//刷新list列表
+        this.getList();
+      }
+    });
+  }
+
+  /**
+   * 修改
+   * @param data 修改对象
+   */
+  update(data){
+    const drawerRef = this.nzDrawerService.create<ProjectWorkImplementationLogUpdateComponent, { id: string }, string>({
+      nzTitle: this.i18NService.fanyi("table.update"),//新增标题
+      nzContent: ProjectWorkImplementationLogUpdateComponent,
+      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();
+      }
+    });
   }
 
+  /**
+   * 删除
+   * @param id 
+   */
+  delete(id){
+    let proWorkLogic=new ProWorkLogic();
+    proWorkLogic.id=id;
+    this.proWorkLogicService.delete(proWorkLogic).then((response)=>{
+      if (response.success) {
+        //删除成功
+        this.nzNotificationService.success(this.i18NService.fanyi('successful.deletion'), '');
+        this.getList();
+      } else {
+        //删除失败
+        this.nzNotificationService.error(this.i18NService.fanyi('delete.failed'), '');
+      }
+    })
+  }
 }

+ 110 - 0
src/app/routes/project-work/implementation-log/update/update.component.html

@@ -0,0 +1,110 @@
+<nz-spin [nzSpinning]="isLoadingSave">
+  <form nz-form [formGroup]="validateForm" (ngSubmit)="submitForm()">
+    <div nz-row [nzGutter]="24">
+      <div nz-col [nzSpan]="8">
+        <nz-form-item>
+          <nz-form-label [nzSm]="6" [nzXs]="24" nzRequired nzFor="code">单据编码</nz-form-label>
+          <nz-form-control [nzSm]="14" [nzXs]="24">
+            <input placeholder="自动生成" nz-input formControlName="billcode" id="billcode"
+              [(ngModel)]="proWorkLogic.billcode" [disabled]="true" />
+          </nz-form-control>
+        </nz-form-item>
+      </div>
+      <div nz-col [nzSpan]="8">
+        <nz-form-item>
+          <nz-form-label [nzSm]="6" [nzXs]="24" nzRequired>项目</nz-form-label>
+          <nz-form-control [nzSm]="14" [nzXs]="24">
+            <nz-select style="widows: 100%;" nzShowSearch nzAllowClear formControlName="proId" id="proId"
+              [(ngModel)]="proWorkLogic.proId" nzPlaceHolder="请选择" (ngModelChange)="proChange($event)">
+              <nz-option *ngFor="let i of proList" [nzValue]="i.id" [nzLabel]="i.proName"></nz-option>
+            </nz-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]="8">
+        <nz-form-item>
+          <nz-form-label [nzSm]="6" [nzXs]="24" nzRequired>汇报人</nz-form-label>
+          <nz-form-control [nzSm]="14" [nzXs]="24">
+            <nz-tree-select style="width: 100%" [nzNodes]="personnelList" nzShowSearch [nzMultiple]="false"
+              formControlName="reporterId" id="reporterId" nzPlaceHolder="请选择" [(ngModel)]="proWorkLogic.reporterId"
+              [nzMaxTagCount]="3" [nzAllowClear]="true">
+            </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>
+    <div nz-row [nzGutter]="24">
+      <div nz-col [nzSpan]="8">
+        <nz-form-item>
+          <nz-form-label [nzSm]="6" [nzXs]="24" nzRequired>开始时间</nz-form-label>
+          <nz-form-control [nzSm]="14" [nzXs]="24">
+            <nz-range-picker [nzShowTime]="true" formControlName="date" id="date" [(ngModel)]="date"></nz-range-picker>
+          </nz-form-control>
+        </nz-form-item>
+      </div>
+    </div>
+  </form>
+  <nz-card>
+    <div nz-row [nzGutter]="24">
+      <div nz-col [nzSpan]="24">
+        <!-- 新增按钮 -->
+        <button (click)="addRow()" 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]="itemList"
+          [nzFrontPagination]="false" [nzShowPagination]="false">
+          <thead>
+            <tr>
+              <th nzAlign="center" style="width: 5%;">序号</th>
+              <th style="width: 30%;">里程碑</th>
+              <th style="width: 50%;">工作内容</th>
+              <th style="width: 5%;">工作用时</th>
+              <th style="width: 10%;">操作</th>
+            </tr>
+          </thead>
+          <tbody>
+            <tr *ngFor="let data of basicTable.data;let i =index">
+              <td nzAlign="center">{{i+1}}</td>
+              <td>
+                <nz-tree-select style="width: 100%" [nzNodes]="mieList" nzShowSearch [nzMultiple]="false"
+                  nzPlaceHolder="请选择" [(ngModel)]="data.proArchivesId" [nzMaxTagCount]="3" [nzAllowClear]="true"
+                  (ngModelChange)="proArchivesIdChange(data)">
+                </nz-tree-select>
+              </td>
+              <td>
+                <textarea rows="1" nz-input [(ngModel)]="data.content"></textarea>
+              </td>
+              <td style="width: 10%;">
+                <nz-input-number [(ngModel)]="data.duration" [nzMin]="0" [nzStep]="1"></nz-input-number>
+              </td>
+              <td>
+                <a nz-popconfirm nzTitle="是否删除?" (nzOnConfirm)="deleteRow(data.sort)">{{'table.delete'|translate}}</a>
+              </td>
+            </tr>
+          </tbody>
+        </nz-table>
+      </div>
+    </div>
+  </nz-card>
+</nz-spin>
+<!-- 按钮 -->
+<div class="base">
+  <strong>填写人:</strong>{{proWorkLogic.currentUser}} <strong>填写时间:</strong>{{proWorkLogic.createTime}}
+  <!-- 关闭按钮 -->
+  <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)="submitForm()"
+    [nzLoading]="isLoadingSave"><span>{{'pm.finish' | translate}}</span></button>
+</div>

+ 24 - 0
src/app/routes/project-work/implementation-log/update/update.component.spec.ts

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

+ 309 - 0
src/app/routes/project-work/implementation-log/update/update.component.ts

@@ -0,0 +1,309 @@
+import { Component, OnInit } from '@angular/core';
+import { NzModalRef, NzMessageService, NzNotificationService, NzDrawerRef } from 'ng-zorro-antd';
+import { _HttpClient, SettingsService } from '@delon/theme';
+import { FormBuilder, Validators, FormGroup } from '@angular/forms';
+import { DatePipe } from '@angular/common';
+import { ProjectManageArchivesService } from 'app/services/project-manage-archives/project-manage-archives.service';
+import { PersonnelService } from 'app/services/basedata/personnel.service';
+import { ProWorkLogicService } from 'app/services/project-work/pro-work-logic.service';
+import { I18NService } from '@core';
+import { ProWorkLogic } from 'app/entity/project-work/pro-work-logic';
+import { ProjectManageArchives } from 'app/entity/project-manage-archives/project-manage-archives';
+import { recursiveQuery } from '@shared';
+
+@Component({
+  selector: 'app-project-work-implementation-log-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 ProjectWorkImplementationLogUpdateComponent implements OnInit {
+  constructor(
+    private fb: FormBuilder,
+    private settingsService: SettingsService,
+    private datePipe: DatePipe,
+    private projectManageArchivesService: ProjectManageArchivesService,
+    private personnelService: PersonnelService,
+    private proWorkLogicService: ProWorkLogicService,
+    private nzNotificationService: NzNotificationService,
+    private i18NService: I18NService,
+    private drawerRef: NzDrawerRef,
+  ) {}
+
+  ngOnInit(): void {
+    //初始化表单
+    this.validateForm = this.fb.group({
+      billcode: [{ value: '', disabled: true }],
+      proId: [null, [Validators.required]],
+      date: [null, [Validators.required]],
+      reporterId: [null, [Validators.required]],
+    });
+    //项目下拉
+    this.isLoadingSave = true;
+    this.getProList()
+      .then(() => {
+        //人员下来数据
+        return this.getPersonnelList();
+      }).then(()=>{
+        //根据id查询
+        return this.getById();
+      })
+      .then(() => {
+        this.isLoadingSave = false;
+      });
+  }
+
+  isLoadingSave = false;
+  validateForm!: FormGroup;
+  proWorkLogic: ProWorkLogic = {
+  }; //对象
+  proList = []; //项目下拉数据
+  personnelList = []; //汇报人下拉数据
+  itemList = []; //明细集合
+  mieList = []; //里程碑数据下拉
+  date = null;
+  id="";
+
+  /**
+   * 根据id查询
+   */
+  getById(){
+    return new Promise((resolve)=>{
+      this.proWorkLogicService.getListById(this.id).then((response)=>{
+        if(response.result){
+          this.proWorkLogic=response.result;//主表对象
+          this.itemList=response.result.detailList;//明细数组
+          //最大排序
+          if(this.itemList){
+            this.sort=this.itemList.length+1;
+          }
+          //开始时间-结束时间
+          this.date=[new Date(this.proWorkLogic.startDate),new Date(this.proWorkLogic.endDate)]
+        }
+        resolve();
+      })
+    })
+  }
+
+  /**
+   * 获取项目下拉数据
+   */
+  getProList() {
+    return new Promise(resolve => {
+      let projectManageArchives = new ProjectManageArchives();
+      projectManageArchives.pageSize = 20000;
+      projectManageArchives.pkOrg = sessionStorage.getItem('pkOrg');
+      this.projectManageArchivesService.getList(projectManageArchives).then(response => {
+        if (response.result.records) {
+          this.proList = response.result.records;
+        }
+        resolve();
+      });
+    });
+  }
+
+  /**
+   * 项目下拉选择事件
+   */
+  proChange(event) {
+    this.getMieList(event);
+  }
+
+  /**
+   * 获取汇报人下拉数据
+   */
+  getPersonnelList() {
+    return new Promise(resolve => {
+      this.personnelService.queryApprover(sessionStorage.getItem('pkOrg')).then(response => {
+        if (response.result) {
+          this.personnelList = JSON.parse(JSON.stringify(response.result));
+        }
+        recursiveQuery(this.personnelList);
+        resolve();
+      });
+    });
+  }
+
+  /**
+   * 里程碑数据下拉
+   */
+  getMieList(proArchivesId) {
+    return new Promise(resolve => {
+      let plan = { id: proArchivesId, planType: '2' };
+      this.projectManageArchivesService.getPlanListById(plan).then(response => {
+        if (response.result) {
+          this.mieList = response.result;
+        }
+        resolve();
+      });
+    });
+  }
+
+  /**
+   * 里程碑选择事件
+   */
+  proArchivesIdChange(data) {
+    console.log(data.proArchivesId);
+    //是否选择里程碑
+    if (data.proArchivesId) {
+      this.getChild(this.mieList, data);
+    } else {
+      data.proArchivesMilestone = '';
+      data.proArchivesId = '';
+    }
+  }
+
+  /**
+   * 递归查询名称
+   */
+  getChild(mieList, data) {
+    mieList.forEach(element => {
+      if (element.key === data.proArchivesId) {
+        data.proArchivesMilestone = element.title;
+        data.proArchivesId = element.id;
+      } else {
+        if (element.children) {
+          this.getChild(element.children, data);
+        }
+      }
+    });
+  }
+
+  /**
+   * 增行按钮
+   */
+  sort = 0;
+  addRow() {
+    this.itemList = [
+      ...this.itemList,
+      {
+        sort: this.sort,
+      },
+    ];
+    this.sort++;
+  }
+
+  /**
+   * 删除行
+   */
+  deleteRow(sort) {
+    this.itemList = this.itemList.filter(d => d.sort !== sort);
+  }
+
+  /**
+   * 保存按钮
+   */
+  submitForm(): any {
+    return new Promise(resolve => {
+      for (const i in this.validateForm.controls) {
+        this.validateForm.controls[i].markAsDirty();
+        this.validateForm.controls[i].updateValueAndValidity();
+      }
+      let valid = this.validateForm.valid;
+      if (valid) {
+        this.isLoadingSave = true;
+        this.proWorkLogic.type = '2'; //实施
+        this.proWorkLogic.pkOrg = sessionStorage.getItem('pkOrg');
+        //项目名称
+        if (this.proWorkLogic.proId) {
+          this.proList.forEach(element => {
+            if (element.id === this.proWorkLogic.proId) {
+              this.proWorkLogic.proName = element.proName;
+            }
+          });
+        } else {
+          this.proWorkLogic.proName = '';
+        }
+        //汇报人名称
+        if (this.proWorkLogic.reporterId) {
+          //循环集合数据获取名称
+          this.personnelList.forEach(pkOrg => {
+            pkOrg.children.forEach(depart => {
+              depart.children.forEach(personnel => {
+                if (personnel.key === this.proWorkLogic.reporterId) {
+                  this.proWorkLogic.reporter = personnel.name;
+                }
+              });
+            });
+          });
+        } else {
+          this.proWorkLogic.reporter = '';
+        }
+        //时间格式化
+        this.proWorkLogic.startDate = this.datePipe.transform(this.date[0], 'yyyy-MM-dd HH:mm:ss');
+        this.proWorkLogic.endDate = this.datePipe.transform(this.date[1], 'yyyy-MM-dd HH:mm:ss');
+        //判断两个时间差的工时是否大于明细总工时
+        if (!this.getHourBoole()) {
+          this.nzNotificationService.warning('工作用时不得大于开始时间与结束时间之差', '');
+          this.isLoadingSave = false;
+          return;
+        }
+        //子表\
+        //判断是否输入子表数据
+        if (this.itemList && this.itemList.length > 0) {
+          this.proWorkLogic.detailList = this.itemList;
+        } else {
+          this.nzNotificationService.warning('工作内容必填', '');
+          this.isLoadingSave = false;
+          return;
+        }
+        this.proWorkLogicService.update(this.proWorkLogic).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'), '');
+          }
+        });
+      }
+    });
+  }
+
+  /**
+   * 判断两个时间差的工时是否大于明细总工时
+   */
+  getHourBoole(): boolean {
+    //明细总工时
+    let itemHour = 0;
+    //两个时间差
+    let dateHour = this.getInervalHour(this.date[0], this.date[1]);
+    //循环获取明细的总工时
+    this.itemList.forEach(element => {
+      if (element.duration) {
+        itemHour = itemHour + Number(element.duration);
+      }
+    });
+    return dateHour >= itemHour;
+  }
+
+  /**
+   * 获取两个时间差
+   */
+  getInervalHour(startDate, endDate) {
+    var ms = endDate.getTime() - startDate.getTime();
+    if (ms < 0) return 0;
+    return Math.floor(ms / 1000 / 60 / 60);
+  }
+
+  close() {
+    this.drawerRef.close();
+  }
+}

+ 5 - 1
src/app/routes/project-work/project-work.module.ts

@@ -2,10 +2,14 @@ import { NgModule } from '@angular/core';
 import { SharedModule } from '@shared';
 import { ProjectWorkRoutingModule } from './project-work-routing.module';
 import { ProjectWorkImplementationLogComponent } from './implementation-log/implementation-log.component';
+import { ProjectWorkImplementationLogAddComponent } from './implementation-log/add/add.component';
+import { ProjectWorkImplementationLogUpdateComponent } from './implementation-log/update/update.component';
 
 const COMPONENTS = [
   ProjectWorkImplementationLogComponent];
-const COMPONENTS_NOROUNT = [];
+const COMPONENTS_NOROUNT = [
+  ProjectWorkImplementationLogAddComponent,
+  ProjectWorkImplementationLogUpdateComponent];
 
 @NgModule({
   imports: [

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

@@ -40,4 +40,10 @@ export class ProjectManageArchivesService {
   async delete(body:any):Promise<BaseResponse<any>>{
     return await this.http.post<BaseResponse<any>>('archives/projectManageArchives/delete',body).toPromise();
   }
+
+  //根据档案id、类型id查询计划里程碑明细
+  async getPlanListById(body: any): Promise<BaseResponse<any>> {
+    return await this.http.get<BaseResponse<any>>("archives/projectManageArchives/getPlanListById", { params: body }).toPromise();
+  }
+
 }

+ 33 - 0
src/app/services/project-work/pro-work-logic.service.ts

@@ -1,5 +1,8 @@
 import { Injectable } from '@angular/core';
 import { HttpClient } from '@angular/common/http';
+import { BaseResponse } from 'app/entity/baseResponse';
+import { Result } from 'app/entity/Result';
+import { ProWorkLogic } from 'app/entity/project-work/pro-work-logic';
 
 @Injectable({
   providedIn: 'root'
@@ -7,4 +10,34 @@ import { HttpClient } from '@angular/common/http';
 export class ProWorkLogicService {
 
   constructor(private http:HttpClient) { }
+
+   //分页查询
+   async getList(body: any): Promise<BaseResponse<Result<any>>> {
+    return await this.http
+      .get<BaseResponse<Result<any>>>('/prowork/proWorkLogic/list', { params: body })
+      .toPromise();
+  }
+
+  //新增
+  async add(body: ProWorkLogic): Promise<BaseResponse<any>> {
+    return await this.http.post<BaseResponse<any>>('/prowork/proWorkLogic/add', body).toPromise();
+  }
+
+  //根据id查询
+  async getListById(id: string): Promise<BaseResponse<any>> {
+    return await this.http.get<BaseResponse<any>>("prowork/proWorkLogic/queryById", { params: { id: id } }).toPromise();
+  }
+
+  //修改
+  async update(body: ProWorkLogic): Promise<BaseResponse<any>> {
+    return await this.http.put<BaseResponse<any>>('prowork/proWorkLogic/edit', body).toPromise();
+  }
+
+   //删除
+   async delete(body:any):Promise<BaseResponse<any>>{
+    return await this.http.delete<BaseResponse<any>>('prowork/proWorkLogic/delete',{params:body}).toPromise();
+  }
+
+  
+  
 }