Sfoglia il codice sorgente

报工计时逻辑

hh 3 giorni fa
parent
commit
03283390fc

+ 101 - 25
entry/src/main/ets/pages/ProcessIndex.ets

@@ -21,13 +21,14 @@ import { CompleteReceiveDialog } from '../view/CompleteReceiveDialog';
 import { WorkInstructionsDialog } from '../view/WorkInstructionsDialog';
 import connection from '@ohos.net.connection';
 import { ReportWorkNumDialog } from '../view/ReportWorkNumDialog';
-import { ProcessReportingDialog } from '../view/ProcessReportingDialog';
+import { ReportPieceworkDialog } from '../view/ReportPieceworkDialog';
+import { ReportTimeBasedDialog } from '../view/ReportTimeBasedDialog';
 import { JoinPersonNameDialog } from '../view/JoinPersonNameDialog';
-import ReportInfo from '../viewmodel/ReportInfo';
-import { BindTaskSeqVO } from '../viewmodel/process/BindTaskSeqVO';
+import ReportInfo from '../viewmodel/process/ReporterInfo';
+import { BindTaskSeq } from '../viewmodel/process/BindTaskSeq';
 import { MqttClientOptions, MqttConnectOptions } from '@ohos/mqtt';
 import MqttManager from '../common/util/mqtt';
-import { DefectNumReportDialog } from '../view/DefectNumReportDialog';
+import { ReportDefectNumDialog } from '../view/ReportDefectNumDialog';
 import { SelfInspectView } from '../view/process/SelfInspectView';
 import { MultiMediaCollect } from '../view/process/MultiMediaCollect';
 import { BarcodeAssociationDialog } from '../view/BarcodeAssociationDialog';
@@ -44,6 +45,7 @@ import preferencesUtil from '../common/util/PerferencesUtil';
 import TimeUtil from '../common/util/TimeUtil';
 import ProcessDeviceDailyCheck from '../viewmodel/process/ProcessDeviceDailyCheck';
 import { DeviceCheckView } from '../view/process/DeviceCheckView';
+import { ReportWorkHourRateDialog } from '../view/ReportWorkHourRateDialog';
 
 // 声明接受参数的类型
 interface Params {
@@ -65,7 +67,7 @@ struct ProcessIndex {
   // 当前流转卡号
   @State seqNo: string = ''
   //是否打开底部抽屉
-  @State isAuxiliaryViewOpen:boolean = false
+  @State isAuxiliaryViewOpen: boolean = false
   // 选中工序id
   @State selectOperationId: string = ''
   // 绩效模式(0:计时 1:计件)
@@ -117,13 +119,14 @@ struct ProcessIndex {
   @Provide('currentUserName') currentUserName: string =''
   @Provide('currentUserId') currentUserId: number = 0
   // 报工人、报工流水号和不良流水号
-  @Provide('bindTaskSeq') bindTaskSeq: BindTaskSeqVO[] = []
-  @State reportList: ReportInfo[] = []
+  @Provide('bindTaskSeq') bindTaskSeq: BindTaskSeq[] = []
+  @State reporterList: ReportInfo[] = []
   @State currentReporterIndex:number =0
   @State currentReportNumIndex:number =0
   @State currentDefectIndex:number =0
   // mqtt是否连接
   @State isConnected: boolean = false
+  startWorkTime: string = ''
   // 工位发生改变则可能需要重新选择工单
   async refreshWorkOrder() {
     if (!this.selectWorkOder || !this.selectWorkOder.workOrderCode) {
@@ -203,6 +206,9 @@ struct ProcessIndex {
     }
     seqNos.push(this.seqNo)
     preferencesUtil.put(CommonConstants.PREFERENCE_INSTANCE_NAME, this.selectWorkOder.workOrderCode!, seqNos)
+    if (!this.startWorkTime) {
+      this.startWorkTime = TimeUtil.getCurrentTime()
+    }
   }
   // 未开工查询工序组件(工步)
   async getComponentsForNotStartWork() {
@@ -235,6 +241,7 @@ struct ProcessIndex {
     this.process = {}
     this.opComponents = []
     this.taskSeqArray = []
+    preferencesUtil.clear(CommonConstants.PREFERENCE_INSTANCE_NAME)
     this.handleAllClick()
   }
 
@@ -299,7 +306,6 @@ struct ProcessIndex {
   }
 
   onPageShow() {
-    console.log('hhtest', '------------------------------')
     const params = router.getParams() as Params; // 获取传递过来的参数对象
     if (params && params.auxiliaryOperationFlag) {
       this.isAuxiliaryViewOpen = true
@@ -992,7 +998,7 @@ struct ProcessIndex {
                 this.scanState = 1
                 // this.scanCodeToStartWork()
               } else if (this.scanState === 1) {
-                this.processReportingController.open()
+                this.reportTimeBasedController.open()
               }
             })
           }
@@ -1142,14 +1148,14 @@ struct ProcessIndex {
   // 工序报工-报工数量弹窗
   ReportWorkNumController: CustomDialogController = new CustomDialogController({
     builder: ReportWorkNumDialog({
-      userName: this.reportList[this.currentReportNumIndex].userName,
+      userName: this.reporterList[this.currentReportNumIndex].userName,
       currentOperationId: this.selectOperationId,
       currentWorkOrderCode: this.selectWorkOder.workOrderCode!,
       onConfirm:(num:number)=>{
         const index = this.currentReportNumIndex;
-        if (this.reportList[index]) {
-          this.reportList[index].reportNum = String(num);
-          this.reportList = [...this.reportList];
+        if (this.reporterList[index]) {
+          this.reporterList[index].reportNum = String(num);
+          this.reporterList = [...this.reporterList];
         }
       }
     }),
@@ -1160,13 +1166,13 @@ struct ProcessIndex {
   })
   // 工序报工-不良品报工弹窗
   defectNumReportController: CustomDialogController = new CustomDialogController({
-    builder: DefectNumReportDialog({
-      userName: this.reportList[this.currentDefectIndex].userName,
+    builder: ReportDefectNumDialog({
+      userName: this.reporterList[this.currentDefectIndex].userName,
       onConfirm:(num:number)=>{
         const index = this.currentDefectIndex;
-        if (this.reportList[index]) {
-          this.reportList[index].defectNum = String(num);
-          this.reportList = [...this.reportList];
+        if (this.reporterList[index]) {
+          this.reporterList[index].defectNum = String(num);
+          this.reporterList = [...this.reporterList];
         }
       }
     }),
@@ -1175,10 +1181,26 @@ struct ProcessIndex {
     alignment:DialogAlignment.Center,
     maskColor: 'rgba(0,0,0,0.8)',
   })
+  // 工序报工-用户用时占比
+  reportWorkHourRateController: CustomDialogController = new CustomDialogController({
+    builder: ReportWorkHourRateDialog({
+      onConfirm:(rateNum: number)=>{
+        const index = this.currentDefectIndex;
+        if (this.reporterList[index]) {
+          this.reporterList[index].workingHoursRate = rateNum / 100;
+          this.reporterList = [...this.reporterList];
+        }
+      }
+    }),
+    autoCancel: true,
+    customStyle: true,
+    alignment: DialogAlignment.Center,
+    maskColor: 'rgba(0,0,0,0.8)',
+  })
   // 工序报工-添加参与人员
   JoinPersonNameController: CustomDialogController = new CustomDialogController({
     builder: JoinPersonNameDialog({
-      reportList:this.reportList,
+      reporterList:this.reporterList,
       currentReporterIndex:this.currentReporterIndex,
     }),
     autoCancel: true,
@@ -1186,15 +1208,15 @@ struct ProcessIndex {
     alignment:DialogAlignment.Center,
     maskColor: 'rgba(0,0,0,0.8)',
   })
-  // 工序报工弹窗
-  processReportingController: CustomDialogController = new CustomDialogController({
-    builder: ProcessReportingDialog({
+  // 工序报工(计件)弹窗
+  reportPieceworkController: CustomDialogController = new CustomDialogController({
+    builder: ReportPieceworkDialog({
       onSelectReporter:(index:number)=>{
         this.currentReporterIndex = index;
         this.JoinPersonNameController.open();
       },
       onSelectReportNum:(index:number)=>{
-        if (!this.reportList[index]?.userName?.trim()) {
+        if (!this.reporterList[index]?.userName?.trim()) {
           promptAction.showToast({
             message: '请先添加用户',
             duration: 2000
@@ -1205,7 +1227,7 @@ struct ProcessIndex {
         this.ReportWorkNumController.open()
       },
       onSelectDefectNum:(index:number)=>{
-        if (!this.reportList[index]?.userName?.trim()) {
+        if (!this.reporterList[index]?.userName?.trim()) {
           promptAction.showToast({
             message: '请先添加用户',
             duration: 2000
@@ -1218,7 +1240,7 @@ struct ProcessIndex {
       clearSelectData:()=>{
         this.clearSelectData()
       },
-      reportList:this.reportList,
+      reporterList:this.reporterList,
       selectWorkOder: this.selectWorkOder,
       selectOperationName: this.selectOperationName,
       selectOperationId: this.selectOperationId,
@@ -1230,6 +1252,60 @@ struct ProcessIndex {
     alignment:DialogAlignment.Center,
     maskColor: 'rgba(0,0,0,0.8)',
   })
+  // 工序报工(计时)弹窗
+  reportTimeBasedController: CustomDialogController = new CustomDialogController({
+    builder: ReportTimeBasedDialog({
+      onSelectReporter:(index: number)=>{
+        this.currentReporterIndex = index;
+        this.JoinPersonNameController.open();
+      },
+      onSelectReportNum:(index: number)=>{
+        if (!this.reporterList[index]?.userName?.trim()) {
+          promptAction.showToast({
+            message: '请先添加用户',
+            duration: 2000
+          });
+          return;
+        }
+        this.currentReportNumIndex = index
+        this.ReportWorkNumController.open()
+      },
+      onSelectDefectNum:(index: number)=>{
+        if (!this.reporterList[index]?.userName?.trim()) {
+          promptAction.showToast({
+            message: '请先添加用户',
+            duration: 2000
+          });
+          return;
+        }
+        this.currentDefectIndex = index
+        this.defectNumReportController.open()
+      },
+      onSelectWorkHourRate:(index: number)=>{
+        if (!this.reporterList[index]?.userName?.trim()) {
+          promptAction.showToast({
+            message: '请先添加用户',
+            duration: 2000
+          });
+          return;
+        }
+        this.currentDefectIndex = index
+        this.reportWorkHourRateController.open()
+      },
+      clearSelectData:()=>{
+        this.clearSelectData()
+      },
+      reporterList:this.reporterList,
+      selectWorkOder: this.selectWorkOder,
+      selectOperationName: this.selectOperationName,
+      selectOperationId: this.selectOperationId,
+      process: this.process,
+    }),
+    autoCancel: true,
+    customStyle: true,
+    alignment:DialogAlignment.Center,
+    maskColor: 'rgba(0,0,0,0.8)',
+  })
   // 切换产线弹窗控制器
   SwitchingProductLineController: CustomDialogController = new CustomDialogController({
     builder: SwitchingProductLineDialog({}),

+ 0 - 1
entry/src/main/ets/view/DefectRecordDialog.ets

@@ -117,7 +117,6 @@ export struct DefectRecordDialog {
           this.selectedDefectBug = i;
         }
       }
-      console.log('hhtest', JSON.stringify(this.defectBugs))
     }
   }
 

+ 0 - 1
entry/src/main/ets/view/DeviceInspectionDialog.ets

@@ -33,7 +33,6 @@ export struct DeviceInspectionDialog {
     let deviceDicts: DictValue[] = await ProcessRequest.get(`/api/v1/sys/dictData/queryByType/${this.deviceTypeDictCode}`)
     if (deviceDicts) {
       for (const dict of deviceDicts) {
-        console.log('hhtest', JSON.stringify(dict))
         this.deviceTypes.set(dict.dictValue!, dict.dictLabel!);
       }
     }

+ 9 - 9
entry/src/main/ets/view/JoinPersonNameDialog.ets

@@ -1,9 +1,8 @@
 //参与人员
 import { pinyin } from "pinyin-pro";
 import ProcessRequest from '../common/util/request/ProcessRequest';
-import { BindTaskSeqVO } from '../viewmodel/process/BindTaskSeqVO';
-import PageInfo from '../viewmodel/PageInfo';
-import ReportInfo from '../viewmodel/ReportInfo';
+import { BindTaskSeq } from '../viewmodel/process/BindTaskSeq';
+import ReportInfo from '../viewmodel/process/ReporterInfo';
 import RequestParamModel from '../viewmodel/RequestParamModel';
 import { UserInfo } from '../viewmodel/UserInfo';
 import promptAction from '@ohos.promptAction';
@@ -18,8 +17,8 @@ export struct JoinPersonNameDialog{
   @State selectNameIndex:number=-1
   @State selectName:string = ''
   @State queryName:string = ''
-  @Link reportList: ReportInfo[]
-  @Consume ('bindTaskSeq') bindTaskSeq: BindTaskSeqVO[]
+  @Link reporterList: ReportInfo[]
+  @Consume ('bindTaskSeq') bindTaskSeq: BindTaskSeq[]
 
   private value: string[] = ['A', 'B', 'C', 'D', 'E', 'F', 'G',
     'H', 'I', 'J', 'K', 'L', 'M', 'N',
@@ -38,7 +37,7 @@ export struct JoinPersonNameDialog{
   private onSelectName(index: number) {
     this.selectNameIndex = index
     this.selectName = this.nameList[index].userName ?? ""
-    const nameExists = this.reportList.some(item =>
+    const nameExists = this.reporterList.some(item =>
     item.userName && this.selectName &&
       item.userName.toString().toLowerCase() === this.selectName.toString().toLowerCase().trim()
     );
@@ -49,9 +48,10 @@ export struct JoinPersonNameDialog{
       });
       return;
     }
-    if (this.reportList[this.currentReporterIndex]) {
-      this.reportList[this.currentReporterIndex].userName = this.selectName;
-      this.reportList = [...this.reportList];
+    if (this.reporterList[this.currentReporterIndex]) {
+      this.reporterList[this.currentReporterIndex].userName = this.selectName;
+      this.reporterList[this.currentReporterIndex].userId = this.nameList[index].id! as string;
+      this.reporterList = [...this.reporterList];
     }
     if (this.bindTaskSeq[this.currentReporterIndex]) {
       this.bindTaskSeq[this.currentReporterIndex].userName = this.selectName;

+ 36 - 8
entry/src/main/ets/view/DefectNumReportDialog.ets

@@ -1,18 +1,21 @@
 import ProcessRequest from '../common/util/request/ProcessRequest';
-import { BindTaskSeqVO } from '../viewmodel/process/BindTaskSeqVO';
+import { BindTaskSeq } from '../viewmodel/process/BindTaskSeq';
 import TaskSeqVO from '../viewmodel/process/TaskSeqInfo';
 import RequestParamModel from '../viewmodel/RequestParamModel';
 import promptAction from '@ohos.promptAction';
+import preferencesUtil from '../common/util/PerferencesUtil';
+import CommonConstants from '../common/constants/CommonConstants';
+import ProcessDefectRecord from '../viewmodel/process/ProcessDefectRecord';
 
 //报工-不良品数量
 @CustomDialog
-export struct DefectNumReportDialog {
+export struct ReportDefectNumDialog {
   controller: CustomDialogController
   onConfirm: (num:number)=> void = () => {}
   scroller: Scroller = new Scroller()
 
   //是否全选
-  @State isAllSelected:boolean = false
+  @State isAllSelected: boolean = false
   //选择的数量
   @State selectNum:number= 0
   //当前工单
@@ -22,17 +25,42 @@ export struct DefectNumReportDialog {
   //当前工位
   @State currentStationId:string = ''
   //总数量
-  @State totalNum:number= 0
+  @State totalNum: number= 0
   //查询报工
   @State queryTaskSeq: TaskSeqVO[] = []
-  @Consume ('bindTaskSeq') bindTaskSeq: BindTaskSeqVO[]
+  @Consume ('bindTaskSeq') bindTaskSeq: BindTaskSeq[]
   @Prop userName:string= ''
   @State selectedIndexes:number[] =[]
 
   onQueryTask=async ()=>{
-    this.queryTaskSeq = await ProcessRequest.post('/api/v1/process/check/items/list', {
-      checkType: "self_check",
+    let result: TaskSeqVO[] = await ProcessRequest.post('/api/v1/plan/task/list', {
+      stationId:this.currentStationId,
+      workOrderCode:this.currentWorkOrderCode,
+      operationId:this.currentOperationId,
+      stateList:[-1,0,1]
     } as RequestParamModel) as TaskSeqVO[];
+    let seqNos: string[] = []
+    seqNos = await preferencesUtil.get(CommonConstants.PREFERENCE_INSTANCE_NAME, this.currentWorkOrderCode, seqNos)
+    if (!seqNos || seqNos.length <= 0) {
+      this.queryTaskSeq = []
+      this.totalNum = 0
+      return
+    }
+    // 根据流水号查询不良记录
+    let defectRecords = await ProcessRequest.post('/api/v1/process/defectRecord/list', {
+      seqNos: seqNos
+    } as RequestParamModel) as ProcessDefectRecord[];
+    let defectSeqNos: string[] = []
+    if (defectRecords && defectRecords.length > 0) {
+      for (const element of defectRecords) {
+        defectSeqNos.push(element.seqNo!);
+      }
+    }
+    for (const element of result) {
+      if (seqNos.includes(element.seqNo!) && defectSeqNos.includes(element.seqNo!)) {
+        this.queryTaskSeq.push(element)
+      }
+    }
     this.totalNum = this.queryTaskSeq.length
   }
 
@@ -268,7 +296,7 @@ export struct DefectNumReportDialog {
             for (const element of selectTasks) {
               seqNos.push(element.seqNo)
             }
-            const currentUserSelection: BindTaskSeqVO = {
+            const currentUserSelection: BindTaskSeq = {
               userName: this.userName,
               defectSeqNos: seqNos
             };

+ 26 - 24
entry/src/main/ets/view/ProcessReportingDialog.ets

@@ -1,18 +1,18 @@
 import ProcessRequest from '../common/util/request/ProcessRequest'
-import { BindTaskSeqVO } from '../viewmodel/process/BindTaskSeqVO'
+import { BindTaskSeq } from '../viewmodel/process/BindTaskSeq'
 import TaskSeqVO from '../viewmodel/process/TaskSeqInfo'
-import ReportInfo from '../viewmodel/ReportInfo'
+import ReportInfo from '../viewmodel/process/ReporterInfo'
 import RequestParamModel from '../viewmodel/RequestParamModel'
 import WorkOrderInfo from '../viewmodel/WorkOrderInfo'
 import promptAction from '@ohos.promptAction'
 import ProcessInfo from '../viewmodel/process/ProcessInfo'
 
-//工序报工
+//工序(计件)报工
 @CustomDialog
-export struct ProcessReportingDialog {
+export struct ReportPieceworkDialog {
   private scrollerList: Scroller = new Scroller()
   //查询报工
-  @Link reportList: ReportInfo[]
+  @Link reporterList: ReportInfo[]
   //选中的工序id
   @Link selectOperationId: string
   // 绩效模式(0:计时 1:计件)
@@ -30,11 +30,11 @@ export struct ProcessReportingDialog {
   @State reportedNum:number = 0
   //计划报工数量
   @State planReportNum:number = 0
-  //扫描的流水号/序列/铭牌号
-  @State scanSeqValue: string = ''
+  // 当前登录用户名称
   @Consume('currentUserName') userName: string
-  @State currentReporterIndex: number = 0; // 记录当前点击的报工人索引
-  @Consume ('bindTaskSeq') bindTaskSeq: BindTaskSeqVO[]
+  // 记录当前点击的报工人索引
+  @State currentReporterIndex: number = 0;
+  @Consume ('bindTaskSeq') bindTaskSeq: BindTaskSeq[]
 
   controller: CustomDialogController
   onConfirm: () => void = () => {}
@@ -48,21 +48,21 @@ export struct ProcessReportingDialog {
   clearSelectData: () => void = () => {}
 
   updateReporterName(index: number, name: string) {
-    if (this.reportList[index]) {
-      this.reportList[index].userName = name;
+    if (this.reporterList[index]) {
+      this.reporterList[index].userName = name;
       // 强制刷新界面
-      this.reportList = [...this.reportList];
+      this.reporterList = [...this.reporterList];
     }
   }
 
   //加载第一个报工人(无法删除)
   loadFirstReport=async ()=>{
-    if (this.reportList.length > 0) {
+    if (this.reporterList.length > 0) {
       return
     }
-    const firstReporter:ReportInfo= {}
+    const firstReporter:ReportInfo = {}
     firstReporter.userName = this.userName
-    this.reportList.push(firstReporter)
+    this.reporterList.push(firstReporter)
   }
 
   onQueryTask = async (currentStateList: Array<number>): Promise<number> => {
@@ -156,6 +156,12 @@ export struct ProcessReportingDialog {
             .width('30%')
             .justifyContent(FlexAlign.End)
             .alignItems(HorizontalAlign.End)
+
+            Divider()
+              .vertical(true)
+              .width('100%')
+              .strokeWidth(1)
+              .color($r('app.color.15FFFFFF'))
           }
           .height('10%')
           .width('96%')
@@ -186,12 +192,12 @@ export struct ProcessReportingDialog {
             setTimeout(() => {
               this.addReportingClick = 1;
               const newReporter:ReportInfo= {}
-              this.reportList.push(newReporter)
+              this.reporterList.push(newReporter)
             }, 200);
           })
           Column(){
             List({space: 8, scroller: this.scrollerList}) {
-              ForEach(this.reportList, (item:ReportInfo,index) => {
+              ForEach(this.reporterList, (item: ReportInfo, index: number) => {
                 ListItem() {
                   Row(){
                     Column(){
@@ -298,7 +304,7 @@ export struct ProcessReportingDialog {
                           .fillColor($r('app.color.FF453A'))
                           .margin({top:'35%'})
                           .onClick(()=>{
-                            this.reportList.splice(index,1)
+                            this.reporterList.splice(index,1)
                             this.bindTaskSeq = this.bindTaskSeq.filter(i => i.userName !== item.userName);
                           })
                       }
@@ -364,10 +370,8 @@ export struct ProcessReportingDialog {
               });
               return;
             }
-            // if (this.operationPerformance === '1') {
-              this.bindTaskSeq[0].processId = this.process.id!
-              await ProcessRequest.post('/api/v1/process/info/reportByPiecework', this.bindTaskSeq)
-            // }
+            this.bindTaskSeq[0].processId = this.process.id!
+            await ProcessRequest.post('/api/v1/process/info/reportByPiecework', this.bindTaskSeq)
             this.clearSelectData()
             this.controller.close();
           })
@@ -382,8 +386,6 @@ export struct ProcessReportingDialog {
     .backgroundColor($r('app.color.2A2A2A'))
     .justifyContent(FlexAlign.End)
     .alignItems(HorizontalAlign.Start)
-    .borderColor($r('app.color.000000'))
-    .borderWidth(1)
     .borderRadius($r('app.float.virtualSize_16'))
   }
 }

+ 470 - 0
entry/src/main/ets/view/ReportTimeBasedDialog.ets

@@ -0,0 +1,470 @@
+//工序(计时)报工
+import ProcessRequest from '../common/util/request/ProcessRequest'
+import ProcessInfo from '../viewmodel/process/ProcessInfo'
+import ReporterInfo from '../viewmodel/process/ReporterInfo'
+import ReportInfo from '../viewmodel/process/ReporterInfo'
+import TaskSeqVO from '../viewmodel/process/TaskSeqInfo'
+import RequestParamModel from '../viewmodel/RequestParamModel'
+import WorkOrderInfo from '../viewmodel/WorkOrderInfo'
+import promptAction from '@ohos.promptAction'
+import ProcessReportTimeBased from '../viewmodel/process/ProcessReportTimeBased'
+import { BindTaskSeq } from '../viewmodel/process/BindTaskSeq'
+
+@CustomDialog
+export struct ReportTimeBasedDialog {
+
+  controller: CustomDialogController
+  private scrollerList: Scroller = new Scroller()
+
+  //选中的工序id
+  @Link selectOperationId: string
+  //从首页传来的工单
+  @Link selectWorkOder: WorkOrderInfo
+  // 当前生产过程
+  @Link process: ProcessInfo
+  //查询报工
+  @Link reporterList: ReportInfo[]
+  //工序名字
+  selectOperationName: string = ''
+  //当前工序已报工数量
+  @State reportedNum: number = 0
+  //计划报工数量
+  @State planReportNum: number = 0
+  // 记录当前点击的报工人索引
+  @State currentReporterIndex: number = 0;
+  //当前工位
+  @Consume('currentStationId') currentStationId: string
+  // 当前登录用户名称
+  @Consume('currentUserName') userName: string
+  // 当前登录用户名称
+  @Consume('currentUserId') currentUserId: number
+  @Consume ('bindTaskSeq') bindTaskSeq: BindTaskSeq[]
+  // 开工时间
+  startWorkTime: string = ''
+
+  //选择报工数量
+  onSelectReportNum: (index:number) => void = () => {}
+  //选择不良品数量
+  onSelectDefectNum: (index:number) => void = () => {}
+  //选择用户用时占比
+  onSelectWorkHourRate: (index:number) => void = () => {}
+  //选择报工人
+  onSelectReporter: (index:number) => void = () => {}
+  // 报工后清除相关数据
+  clearSelectData: () => void = () => {}
+  //加载第一个报工人(无法删除)
+  loadFirstReporter=async ()=>{
+    if (this.reporterList.length > 0) {
+      return
+    }
+    const firstReporter: ReporterInfo = {}
+    firstReporter.userName = this.userName
+    firstReporter.userId = this.currentUserId.toString()
+    firstReporter.workingHoursRate = 1
+    this.reporterList.push(firstReporter)
+  }
+
+  async aboutToAppear() {
+    this.loadFirstReporter()
+    // 查询所有流转卡号
+    let res = await ProcessRequest.post('/api/v1/plan/task/list', {
+      stationId: this.currentStationId,
+      workOrderCode: this.selectWorkOder.workOrderCode!,
+      operationId: this.selectOperationId
+    } as RequestParamModel) as TaskSeqVO[];
+    if (!res || res.length <= 0) {
+      return
+    }
+    this.planReportNum = res.length
+    // 计算已报工数量
+    let num: number = 0
+    for (const element of res) {
+      if (element.state! === '2') {
+        num++
+      }
+    }
+    this.reportedNum = num
+  }
+
+  build() {
+    Column() {
+      Column() {
+        Text('工序报工')
+          .fontColor($r('app.color.FFFFFF'))
+          .fontSize($r('app.float.fontSize_30'))
+      }
+      .height('10%')
+      .width('100%')
+      .justifyContent(FlexAlign.Center)
+
+      Column(){
+        Row(){
+          Column({space:3}){
+            Text(this.selectWorkOder.materialName)
+              .fontSize($r('app.float.fontSize_24'))
+              .fontColor($r('app.color.FFFFFF'))
+            Text(this.selectWorkOder.materialCode)
+              .fontSize($r('app.float.fontSize_12'))
+              .fontColor($r('app.color.FFFFFF'))
+              .fontWeight(FontWeight.Lighter)
+            Row(){
+              Text('工单 ')
+                .fontSize($r('app.float.fontSize_16'))
+                .fontColor($r('app.color.FFFFFF'))
+                .fontWeight(FontWeight.Lighter)
+              Text(this.selectWorkOder.workOrderCode)
+                .fontSize($r('app.float.fontSize_16'))
+                .fontColor($r('app.color.FFFFFF'))
+                .fontWeight(FontWeight.Bold)
+            }
+          }
+          .height('100%')
+          .width('30%')
+          .justifyContent(FlexAlign.End)
+          .alignItems(HorizontalAlign.Start)
+          Row(){
+            Text('工序 ')
+              .fontSize($r('app.float.fontSize_16'))
+              .fontColor($r('app.color.FFFFFF'))
+              .fontWeight(FontWeight.Lighter)
+            Text(this.selectOperationName)
+              .fontSize($r('app.float.fontSize_16'))
+              .fontColor($r('app.color.FFFFFF'))
+              .fontWeight(FontWeight.Bold)
+          }
+          .height('100%')
+          .width('40%')
+          .justifyContent(FlexAlign.Center)
+          .alignItems(VerticalAlign.Bottom)
+          Column(){
+            Row(){
+              Text(`${this.reportedNum}/`)
+                .fontSize($r('app.float.fontSize_38'))
+                .fontColor($r('app.color.FFFFFF'))
+              Text(`${this.planReportNum}`)
+                .fontSize($r('app.float.fontSize_38'))
+                .fontColor($r('app.color.60FFFFFF'))
+            }
+            Text('当前工序已报工/计划')
+              .fontSize($r('app.float.fontSize_12'))
+              .fontColor($r('app.color.FFFFFF'))
+              .fontWeight(FontWeight.Lighter)
+          }
+          .height('100%')
+          .width('30%')
+          .justifyContent(FlexAlign.End)
+          .alignItems(HorizontalAlign.End)
+        }
+        .height('14.4%')
+        .width('100%')
+        .alignItems(VerticalAlign.Bottom)
+
+        Divider()
+          .vertical(false)
+          .width('100%')
+          .strokeWidth(1)
+          .color($r('app.color.15FFFFFF'))
+          .height('3.1%')
+        // 报工流水号、不良流水号选择
+        Row({space: 5}) {
+          Column() {
+            Text(`报工数量`)
+              .fontColor($r('app.color.FFFFFF'))
+              .fontSize($r('app.float.fontSize_16'))
+              .fontWeight(FontWeight.Regular)
+              .height('27%')
+              .margin({left:'2%'})
+            Row(){
+              Text(this.reporterList && this.reporterList[0].reportNum ? this.reporterList[0].reportNum! : '0')
+                .fontColor($r('app.color.FFFFFF'))
+                .fontSize($r('app.float.fontSize_24'))
+                .margin({left:'8%'})
+                .width('82%')
+                .textAlign(TextAlign.Start)
+              Text('>')
+                .fontColor($r('app.color.FFFFFF'))
+                .fontSize($r('app.float.fontSize_24'))
+                .textAlign(TextAlign.Start)
+                .width('10%')
+            }
+            .justifyContent(FlexAlign.Start)
+            .borderRadius($r('app.float.virtualSize_16'))
+            .height('73%')
+            .backgroundColor($r('app.color.20FFFFFF'))
+            .onClick(()=>{
+              this.onSelectReportNum(0)
+            })
+          }
+          .width('30%')
+          .height('100%')
+          .alignItems(HorizontalAlign.Start)
+          Column(){
+            Text(`不良品数量`)
+              .fontColor($r('app.color.FFFFFF'))
+              .fontSize($r('app.float.fontSize_16'))
+              .fontWeight(FontWeight.Regular)
+              .height('27%')
+              .margin({left:'2%'})
+            Row(){
+              Text(this.reporterList && this.reporterList[0].defectNum ? this.reporterList[0].defectNum! : '0')
+                .fontColor($r('app.color.FFFFFF'))
+                .fontSize($r('app.float.fontSize_24'))
+                .margin({left:'8%'})
+                .width('82%')
+                .textAlign(TextAlign.Start)
+              Text('>')
+                .fontColor($r('app.color.FFFFFF'))
+                .fontSize($r('app.float.fontSize_24'))
+                .textAlign(TextAlign.Start)
+                .width('10%')
+            }
+            .justifyContent(FlexAlign.Start)
+            .borderRadius($r('app.float.virtualSize_16'))
+            .backgroundColor($r('app.color.20FFFFFF'))
+            .height('73%')
+            .onClick(()=>{
+              this.onSelectDefectNum(0)
+            })
+          }
+          .width('30%')
+          .alignItems(HorizontalAlign.Start)
+          .height('100%')
+          Blank()
+          Text('开工时间:' +this.startWorkTime)
+            .fontColor($r('app.color.FFFFFF'))
+            .fontSize($r('app.float.fontSize_12'))
+            .fontWeight(FontWeight.Lighter)
+        }
+        .width('100%')
+        .height('17.2%')
+        Row().height('7.9%')
+        // 添加报工人
+        Row(){
+          Image($r('app.media.general_create'))
+            .width($r('app.float.virtualSize_24'))
+            .height($r('app.float.virtualSize_24'))
+            .fillColor($r('app.color.0A84FF'))
+          Text('添加报工人')
+            .fontColor($r('app.color.0A84FF'))
+            .fontSize($r('app.float.fontSize_24'))
+            .margin({left:'4%'})
+        }
+        .height('8.8%')
+        .width('14%')
+        .justifyContent(FlexAlign.Center)
+        .backgroundColor($r('app.color.20FFFFFF'))
+        .borderRadius($r('app.float.virtualSize_16'))
+        .onClick(() => {
+          const newReporter: ReportInfo = {}
+          // 默认占比为剩余占比
+          if (this.reporterList && this.reporterList.length > 0) {
+            let rateTotal: number = 1
+            for (const element of this.reporterList) {
+              if (element.workingHoursRate && element.workingHoursRate > 0) {
+                rateTotal -= element.workingHoursRate
+              }
+            }
+            newReporter.workingHoursRate = rateTotal
+          }
+          this.reporterList.push(newReporter)
+        })
+
+        Column(){
+          List({space: 8, scroller: this.scrollerList}) {
+            ForEach(this.reporterList, (item: ReporterInfo, index: number) => {
+              ListItem() {
+                Row(){
+                  Column(){
+                    Text(`报工人${index+1}`)
+                      .fontColor($r('app.color.FFFFFF'))
+                      .fontSize($r('app.float.fontSize_16'))
+                      .fontWeight(FontWeight.Regular)
+                      .height('30%')
+                      .margin({left:'2%'})
+                    Row(){
+                      Text(item.userName)
+                        .fontColor($r('app.color.FFFFFF'))
+                        .fontSize($r('app.float.fontSize_24'))
+                        .margin({left:'8%'})
+                        .width('82%')
+                        .textAlign(TextAlign.Start)
+                      Text('>')
+                        .fontColor($r('app.color.FFFFFF'))
+                        .fontSize($r('app.float.fontSize_24'))
+                        .textAlign(TextAlign.Start)
+                        .width('10%')
+                    }
+                    .justifyContent(FlexAlign.Start)
+                    .borderRadius($r('app.float.virtualSize_16'))
+                    .height('70%')
+                    .enabled(index!=0)
+                    .backgroundColor($r('app.color.20FFFFFF'))
+                    .onClick(()=>{
+                      this.onSelectReporter(index)
+                      this.currentReporterIndex = index;
+                    })
+                  }
+                  .width('29%')
+                  .height('100%')
+                  .alignItems(HorizontalAlign.Start)
+                  Column(){
+                    Text(`用时占比`)
+                      .fontColor($r('app.color.FFFFFF'))
+                      .fontSize($r('app.float.fontSize_16'))
+                      .fontWeight(FontWeight.Regular)
+                      .height('30%')
+                      .margin({left:'2%'})
+                    Row(){
+                      Text(item.workingHoursRate ? item.workingHoursRate * 100 + '%' : '0%')
+                        .fontColor($r('app.color.FFFFFF'))
+                        .fontSize($r('app.float.fontSize_24'))
+                        .margin({left:'8%'})
+                        .width('82%')
+                        .textAlign(TextAlign.Start)
+                      Text('>')
+                        .fontColor($r('app.color.FFFFFF'))
+                        .fontSize($r('app.float.fontSize_24'))
+                        .textAlign(TextAlign.Start)
+                        .width('10%')
+                    }
+                    .justifyContent(FlexAlign.Start)
+                    .borderRadius($r('app.float.virtualSize_16'))
+                    .height('70%')
+                    .backgroundColor($r('app.color.20FFFFFF'))
+                    .onClick(()=>{
+                      this.onSelectWorkHourRate(index)
+                    })
+                  }
+                  .width('29%')
+                  .height('100%')
+                  .alignItems(HorizontalAlign.Start)
+                  .margin({left:'2%',right:'2%'})
+                  Blank()
+                  if(index > 0) {
+                    Column(){
+                      Image($r('app.media.process_delete_seq'))
+                        .width($r('app.float.virtualSize_48'))
+                        .height($r('app.float.virtualSize_48'))
+                        .fillColor($r('app.color.FF453A'))
+                        .margin({top:'35%'})
+                        .onClick(()=>{
+                          this.reporterList.splice(index,1)
+                        })
+                    }
+                    .width('9%')
+                    .alignItems(HorizontalAlign.Center)
+                    .height('100%')
+                  }
+                }
+                .height('100%')
+                .width('100%')
+              }
+              .height('40.7%')
+              .width('100%')
+            })
+          }
+          .width('100%')
+          .height('87%')
+        }
+        .height('48.6%')
+        .width('100%')
+        .justifyContent(FlexAlign.Center)
+      }
+      .justifyContent(FlexAlign.Start)
+      .alignItems(HorizontalAlign.Start)
+      .width('96%')
+      .height('82.7%')
+
+      Column() {
+        Divider()
+          .vertical(false)
+          .strokeWidth(1)
+          .color($r('app.color.15FFFFFF'))
+        Row() {
+          Row() {
+            Text('取消')
+              .fontColor($r('app.color.60FFFFFF'))
+              .fontSize($r('app.float.fontSize_30'))
+          }
+          .justifyContent(FlexAlign.Center)
+          .width('50%')
+          .onClick(() => this.controller.close())
+          Divider()
+            .vertical(true)
+            .strokeWidth(1)
+            .color($r('app.color.15FFFFFF'))
+          Row() {
+            Text('确认报工')
+              .fontColor($r('app.color.007AFF'))
+              .fontSize($r('app.float.fontSize_30'))
+          }
+          .justifyContent(FlexAlign.Center)
+          .width('50%')
+          .onClick(async () => {
+            if (!this.process || !this.process.id) {
+              promptAction.showToast({
+                message: '请先工序开工',
+                duration: 2000
+              });
+              return;
+            }
+            let rateTotal = 0
+            for (const reporter of this.reporterList) {
+              if (!reporter.workingHoursRate) {
+                promptAction.showToast({
+                  message: `请给${reporter.userName!}选择用时占比`,
+                  duration: 2000
+                });
+                return;
+              }
+              rateTotal += reporter.workingHoursRate
+            }
+            if (rateTotal > 1) {
+              promptAction.showToast({
+                message: `用时占比超过100%,请修改`,
+                duration: 2000
+              });
+              return;
+            } else if (rateTotal < 1) {
+              promptAction.showToast({
+                message: `用时占比少于100%,请修改`,
+                duration: 2000
+              });
+              return;
+            }
+            // 报工
+            let seqNos: string [] = []
+            if (this.bindTaskSeq[0].reportSeqNos) {
+              seqNos = seqNos.concat(this.bindTaskSeq[0].reportSeqNos)
+            }
+            if (this.bindTaskSeq[0].defectSeqNos) {
+              seqNos = seqNos.concat(this.bindTaskSeq[0].defectSeqNos)
+            }
+            if (seqNos.length <= 0) {
+              promptAction.showToast({
+                message: `请选择报工流水号或者不良流水号`,
+                duration: 2000
+              });
+              return;
+            }
+            await ProcessRequest.post('/api/v1/process/info/reporting', {
+              processId: this.process.id!,
+              processUserReportList: this.reporterList,
+              seqList: seqNos
+            } as ProcessReportTimeBased)
+            this.clearSelectData()
+            this.controller.close();
+          })
+        }
+      }
+      .width('100%')
+      .height('7.3%')
+    }
+    .height('71%')
+    .width('62%')
+    .backgroundColor($r('app.color.2A2A2A'))
+    .justifyContent(FlexAlign.End)
+    .alignItems(HorizontalAlign.Center)
+    .borderRadius($r('app.float.virtualSize_16'))
+  }
+}

+ 87 - 0
entry/src/main/ets/view/ReportWorkHourRateDialog.ets

@@ -0,0 +1,87 @@
+//报工用户用时占比
+import { Font } from '@ohos.arkui.UIContext'
+
+@CustomDialog
+export struct ReportWorkHourRateDialog {
+
+  controller: CustomDialogController
+
+  onConfirm: (rate: number)=> void = () => {}
+
+  //选择的占比
+  @State selectIndex: number = 4
+  // 占比数字(eg: 50%的50)
+  rateNum: number = 50
+  private rateList: string[] = ['10%', '20%', '30%', '40%', '50%', '60%', '70%', '80%', '90%', '100%']
+
+  build() {
+    Column(){
+      Column() {
+        Text('用时占比')
+          .fontColor($r('app.color.FFFFFF'))
+          .fontSize($r('app.float.fontSize_30'))
+          .fontWeight(FontWeight.Medium)
+      }
+      .height('20%')
+      .width('100%')
+      .justifyContent(FlexAlign.End)
+
+      TextPicker({ range: this.rateList, selected: this.selectIndex })
+        .onChange((value: string | string[], index: number| number[]) => {
+          this.rateNum = Number.parseFloat(value.slice(0, -1) as string)
+          this.selectIndex = index as number
+        })
+        .selectedTextStyle({color: $r('app.color.FFFFFF'), font: {size: $r('app.float.fontSize_30'), weight: FontWeight.Medium }})
+        .textStyle({color: $r('app.color.FFFFFF'), font: {size: $r('app.float.fontSize_24'), weight: FontWeight.Medium }})
+        .disappearTextStyle({color: $r('app.color.FFFFFF'), font: {size: $r('app.float.fontSize_16'), weight: FontWeight.Lighter}})
+        .backgroundColor($r('app.color.2A2A2A'))
+        .width('85%')
+        .height('65%')
+
+      // 确认/取消栏
+      Column() {
+        Divider()
+          .vertical(false)
+          .strokeWidth(1)
+          .color($r('app.color.15FFFFFF'))
+        Row() {
+          Row() {
+            Text('取消')
+              .fontColor($r('app.color.60FFFFFF'))
+              .fontSize($r('app.float.fontSize_30'))
+          }
+          .justifyContent(FlexAlign.Center)
+          .width('50%')
+          .onClick(() => this.controller.close())
+          Divider()
+            .vertical(true)
+            .strokeWidth(1)
+            .color($r('app.color.15FFFFFF'))
+          Row() {
+            Text('确定')
+              .fontColor($r('app.color.007AFF'))
+              .fontSize($r('app.float.fontSize_30'))
+          }
+          .justifyContent(FlexAlign.Center)
+          .width('50%')
+          .onClick(() => {
+            this.onConfirm(this.rateNum);
+            this.controller.close()
+          })
+        }
+      }
+      .width('100%')
+      .height('15%')
+    }
+    .height('34%')
+    .width('28%')
+    .backgroundColor($r('app.color.2A2A2A'))
+    .justifyContent(FlexAlign.End)
+    .alignItems(HorizontalAlign.Center)
+    .borderRadius($r('app.float.virtualSize_16'))
+  }
+}
+
+
+
+

+ 15 - 4
entry/src/main/ets/view/ReportWorkNumDialog.ets

@@ -1,10 +1,11 @@
 import ProcessRequest from '../common/util/request/ProcessRequest';
-import { BindTaskSeqVO } from '../viewmodel/process/BindTaskSeqVO';
+import { BindTaskSeq } from '../viewmodel/process/BindTaskSeq';
 import TaskSeqVO from '../viewmodel/process/TaskSeqInfo';
 import RequestParamModel from '../viewmodel/RequestParamModel';
 import preferencesUtil from '../common/util/PerferencesUtil';
 import CommonConstants from '../common/constants/CommonConstants';
 import promptAction from '@ohos.promptAction';
+import ProcessDefectRecord from '../viewmodel/process/ProcessDefectRecord';
 
 //报工数量
 @CustomDialog
@@ -27,7 +28,7 @@ export struct ReportWorkNumDialog{
   @State totalNum:number= 0
   //查询报工
   @State queryTaskSeq: TaskSeqVO[] = []
-  @Consume ('bindTaskSeq') bindTaskSeq: BindTaskSeqVO[]
+  @Consume ('bindTaskSeq') bindTaskSeq: BindTaskSeq[]
   @Prop userName:string= ''
   @State selectedIndexes:number[] =[]
 
@@ -45,8 +46,18 @@ export struct ReportWorkNumDialog{
       this.totalNum = 0
       return
     }
+    // 根据流水号查询不良记录
+    let defectRecords = await ProcessRequest.post('/api/v1/process/defectRecord/list', {
+      seqNos: seqNos
+    } as RequestParamModel) as ProcessDefectRecord[];
+    let defectSeqNos: string[] = []
+    if (defectRecords && defectRecords.length > 0) {
+      for (const element of defectRecords) {
+        defectSeqNos.push(element.seqNo!);
+      }
+    }
     for (const element of result) {
-      if (seqNos.includes(element.seqNo!)) {
+      if (seqNos.includes(element.seqNo!) && !defectSeqNos.includes(element.seqNo!)) {
         this.queryTaskSeq.push(element)
       }
     }
@@ -285,7 +296,7 @@ export struct ReportWorkNumDialog{
             for (const element of selectTasks) {
               seqNos.push(element.seqNo)
             }
-            const currentUserSelection: BindTaskSeqVO = {
+            const currentUserSelection: BindTaskSeq = {
               userName: this.userName,
               reportSeqNos: seqNos
             };

+ 1 - 1
entry/src/main/ets/view/SpecialInspectionDialog.ets

@@ -1,6 +1,6 @@
 //专检
 import ProcessRequest from '../common/util/request/ProcessRequest';
-import { BindTaskSeqVO } from '../viewmodel/process/BindTaskSeqVO';
+import { BindTaskSeqVO } from '../viewmodel/process/BindTaskSeq';
 import TaskSeqVO from '../viewmodel/process/TaskSeqInfo';
 import RequestParamModel from '../viewmodel/RequestParamModel';
 import { Font } from '@ohos.arkui.UIContext';

+ 2 - 0
entry/src/main/ets/view/SwitchingProductDialog.ets

@@ -262,6 +262,8 @@ export struct SwitchingProductDialog{
                  this.scanSeqValue = ''
                  return
                }
+               // this.seqNo = this.scanSeqValue
+               // this.controller.close();
              })
              .onChange((value: string) => {
                this.scanSeqValue = value;

+ 19 - 12
entry/src/main/ets/view/process/SelfInspectView.ets

@@ -41,6 +41,7 @@ export struct SelfInspectView {
         processId: this.process.id!,
         seqNo: this.seqNo
       } as RequestParamModel)
+      this.queryDefectRecord()
     } else {
       let result = await ProcessRequest.post('/api/v1/op/operationCheck/page', {
         operationId: this.selectOperationId,
@@ -51,24 +52,30 @@ export struct SelfInspectView {
     }
   }
 
-  async aboutToAppear() {
-    this.queryByScanState()
-    this.defectTypes = await ProcessRequest.get(`/api/v1/sys/dictData/queryByType/${this.defectTypeDictCode}`)
-    this.defectRecords = await ProcessRequest.post('/api/v1/process/defectRecord/list', {
-      seqNo: this.seqNo
-    } as RequestParamModel)
-    if (this.defectRecords && this.defectTypes) {
-      for (const element of this.defectRecords) {
-        for (const dict of this.defectTypes) {
-          if (element.defectType === dict.dictValue) {
-            element.defectTypeLabel = dict.dictLabel
-            break
+  async queryDefectRecord() {
+    if (this.seqNo) {
+      this.defectRecords = await ProcessRequest.post('/api/v1/process/defectRecord/list', {
+        seqNo: this.seqNo
+      } as RequestParamModel)
+      if (this.defectRecords && this.defectTypes) {
+        for (const element of this.defectRecords) {
+          for (const dict of this.defectTypes) {
+            if (element.defectType === dict.dictValue) {
+              element.defectTypeLabel = dict.dictLabel
+              break
+            }
           }
         }
       }
     }
   }
 
+  async aboutToAppear() {
+    this.queryByScanState()
+    this.defectTypes = await ProcessRequest.get(`/api/v1/sys/dictData/queryByType/${this.defectTypeDictCode}`)
+    this.queryDefectRecord()
+  }
+
   build() {
     Row() {
       // 点检

+ 2 - 0
entry/src/main/ets/viewmodel/RequestParamModel.ets

@@ -106,4 +106,6 @@ export default class RequestParamModel {
   stationIp?:string
   //创建日期
   createDate?:string
+  //流转卡号/序列号集合
+  seqNos?:string[]
 }

+ 1 - 3
entry/src/main/ets/viewmodel/process/BindTaskSeqVO.ets

@@ -1,6 +1,4 @@
-import TaskSeqVO from './TaskSeqInfo'
-
-export interface BindTaskSeqVO
+export interface BindTaskSeq
 {
   userName?:string,
   userId?:string,

+ 11 - 0
entry/src/main/ets/viewmodel/process/ProcessReportTimeBased.ets

@@ -0,0 +1,11 @@
+// 报工(计时)参数
+import ReporterInfo from './ReporterInfo';
+
+export default interface ProcessReportTimeBased {
+  // 生产过程id
+  processId?: string,
+  // 报工卡号
+  seqList?: string[]
+  // 用户报工占比
+  processUserReportList?: ReporterInfo[],
+}

+ 5 - 0
entry/src/main/ets/viewmodel/ReportInfo.ets

@@ -1,8 +1,13 @@
+// 报工人信息
 export default class ReportInfo {
   // 报工人
   userName?: string
+  // 报工人id
+  userId?: string
   // 报工数量
   reportNum?: string
   //不良数量
   defectNum?: string
+  // 用户占用工时比列
+  workingHoursRate?: number
 }