jingshuyong пре 1 година
родитељ
комит
a8c5bda4de

+ 134 - 0
src/api/mainData/index.js

@@ -45,3 +45,137 @@ export async function factoryworkstation (params) {
   }
   return Promise.reject(new Error(res.data.message));
 }
+
+// 根据首工序id拿工位
+export async function listByFirstTaskId(firstTaskId) {
+  const res = await request.get(
+    `/main/factoryworkstation/listByFirstTaskId/${firstTaskId}`
+  );
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
+
+// 查询产线
+export async function lineByCurrentUser(workCenterId) {
+  const res = await request.get(
+    `/main/factoryarea/listFactoryLineByWorkCenterId/${workCenterId}`
+  );
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
+
+// 分批任务类型
+export async function listAssigneeType() {
+  const res = await request.get(`/aps/assign/listAssigneeType`);
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
+
+// 派单任务保存
+export async function taskSave(data) {
+  const res = await request.post('/aps/assign/assign/save', data);
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
+
+// 派单任务撤销
+export async function taskRevoked(data) {
+  const res = await request.post('/aps/assign/assign/revoked', data);
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
+
+// 重置派单任务
+export async function resetAssignee(assigneeId) {
+  const res = await request.put('/aps/assign/resetAssignee/' + assigneeId);
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
+// 派单任务
+export async function taskAssignment(data) {
+  const res = await request.post('/aps/assign/assign', data);
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
+
+// 获取派单任务列表
+export async function listAssign(params) {
+  const res = await request.get(`/aps/assign/listAssign`, { params });
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
+
+// 检查派单确认
+export async function checkAssignConfirm(params) {
+  const res = await request.get(`/aps/assign/checkAssignConfirm`, { params });
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
+
+// 获取工序的工作中心和班组列表
+export async function listByRoutingIds(data) {
+  const res = await request.post(`/main/producerouting/taskinstance/listByRoutingIds`, data);
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
+
+export async function listUserByIds(data) {
+  const res = await request.post('/main/team/listUserByIds', data);
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
+
+// 根据当前用户查工作中心跟班组
+export async function listWorkCenter(firstProduceTaskId) {
+  const res = await request.get(
+    `/aps/assign/listWorkCenterTeamsByProduceTaskId/${firstProduceTaskId}`
+  );
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
+
+// 查询工序列表 已派单
+export async function listByMesWorkOrder(params) {
+  const res = await request.get(
+    `/aps/assign/listByMesWorkOrder`,{params}
+  );
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
+
+// 下达
+export async function releaseWorkOrder(data) {
+  const res = await request.post(
+    `/aps/workorder/releaseWorkOrder`, data
+  );
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}

+ 10 - 1
src/api/produceOrder/index.js

@@ -182,4 +182,13 @@ export async function updatePriority(data) {
     return res.data.data;
   }
   return Promise.reject(new Error(res.data.message));
-}
+}
+
+// 根据任务实例id查询工序id
+export async function getTaskIdByInstanceId(taskInstanceId) {
+  const res = await request.get(`/main/producetask/getTaskIdByInstanceId/${taskInstanceId}`);
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}

+ 65 - 0
src/api/workOrderList/index.js

@@ -85,3 +85,68 @@ export async function pickorderList(params) {
 // 	}
 // 	return Promise.reject(data.message);
 // }
+
+// 任务列表 pageByCurrentUser 我的任务
+export async function pageByCurrentUser (data) {
+  const res = await request.get('/aps/assign/pageByCurrentUser/v2', {
+    params: data
+  });
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
+
+// 任务列表 pageByCurrentUserLeader 全部任务
+export async function pageByCurrentUserLeader (data) {
+  const res = await request.get('/aps/assign/pageByCurrentUserLeader/v2', {
+    params: data
+  });
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
+
+// 根据当前用户查工作中心跟班组
+export async function listWorkCenter(firstProduceTaskId) {
+  const res = await request.get(
+    `/aps/assign/listWorkCenterTeamsByProduceTaskId/${firstProduceTaskId}`
+  );
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
+
+// 更新派单任务实际时间
+export async function batchUpdateRealTime(data) {
+  const res = await request.put(
+    `/aps/assign/batchUpdateRealTime`,data
+  );
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
+// 获取派单任务项更新实际时间记录
+export async function listUpdateRealTimeRecord(assigneeId) {
+  const res = await request.get(
+    `/aps/assign/listUpdateRealTimeRecord/${assigneeId}`
+  );
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
+// 根据任务ID获取派单任务项分页列表
+export async function pageAssigneeByTask(params) {
+  const res = await request.get(
+    `/aps/assign/pageAssigneeByTask`,{params}
+  );
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
+

+ 3 - 3
src/components/bpmnProcessDesigner/package/designer/plugins/content-pad/contentPadProvider.js

@@ -242,7 +242,7 @@ ContextPadProvider.prototype.getContextPadEntries = function(element) {
   if (is(businessObject, "bpmn:FlowNode")) {
     if (is(businessObject, "bpmn:EventBasedGateway")) {
       assign(actions, {
-        "append.receive-task": appendAction("bpmn:ReceiveTask", "bpmn-icon-receive-task", translate("Append ReceiveTask")),
+        "append.receive-task": appendAction("bpmn:ReceiveTask", "bpmn-icon-receive-taskDialog", translate("Append ReceiveTask")),
         "append.message-intermediate-event": appendAction(
           "bpmn:IntermediateCatchEvent",
           "bpmn-icon-intermediate-event-catch-message",
@@ -270,7 +270,7 @@ ContextPadProvider.prototype.getContextPadEntries = function(element) {
       });
     } else if (isEventType(businessObject, "bpmn:BoundaryEvent", "bpmn:CompensateEventDefinition")) {
       assign(actions, {
-        "append.compensation-activity": appendAction("bpmn:Task", "bpmn-icon-task", translate("Append compensation activity"), {
+        "append.compensation-activity": appendAction("bpmn:Task", "bpmn-icon-taskDialog", translate("Append compensation activity"), {
           isForCompensation: true
         })
       });
@@ -283,7 +283,7 @@ ContextPadProvider.prototype.getContextPadEntries = function(element) {
       assign(actions, {
         "append.end-event": appendAction("bpmn:EndEvent", "bpmn-icon-end-event-none", translate("Append EndEvent")),
         "append.gateway": appendAction("bpmn:ExclusiveGateway", "bpmn-icon-gateway-none", translate("Append Gateway")),
-        "append.append-task": appendAction("bpmn:UserTask", "bpmn-icon-user-task", translate("Append Task")),
+        "append.append-task": appendAction("bpmn:UserTask", "bpmn-icon-user-taskDialog", translate("Append Task")),
         "append.intermediate-event": appendAction(
           "bpmn:IntermediateThrowEvent",
           "bpmn-icon-intermediate-event-none",

+ 1 - 1
src/components/bpmnProcessDesigner/package/designer/plugins/palette/CustomPalette.js

@@ -123,7 +123,7 @@ F.prototype.getPaletteEntries = function() {
     ),
     "create.end-event": createAction("bpmn:EndEvent", "event", "bpmn-icon-end-event-none", translate("Create EndEvent")),
     "create.exclusive-gateway": createAction("bpmn:ExclusiveGateway", "gateway", "bpmn-icon-gateway-none", translate("Create Gateway")),
-    "create.user-task": createAction("bpmn:UserTask", "activity", "bpmn-icon-user-task", translate("Create User Task")),
+    "create.user-task": createAction("bpmn:UserTask", "activity", "bpmn-icon-user-taskDialog", translate("Create User Task")),
     "create.data-object": createAction("bpmn:DataObjectReference", "data-object", "bpmn-icon-data-object", translate("Create DataObjectReference")),
     "create.data-store": createAction("bpmn:DataStoreReference", "data-store", "bpmn-icon-data-store", translate("Create DataStoreReference")),
     "create.subprocess-expanded": {

+ 1 - 1
src/components/bpmnProcessDesigner/package/designer/plugins/palette/paletteProvider.js

@@ -132,7 +132,7 @@ PaletteProvider.prototype.getPaletteEntries = function() {
     ),
     "create.end-event": createAction("bpmn:EndEvent", "event", "bpmn-icon-end-event-none", translate("Create EndEvent")),
     "create.exclusive-gateway": createAction("bpmn:ExclusiveGateway", "gateway", "bpmn-icon-gateway-none", translate("Create Gateway")),
-    "create.user-task": createAction("bpmn:UserTask", "activity", "bpmn-icon-user-task", translate("Create User Task")),
+    "create.user-task": createAction("bpmn:UserTask", "activity", "bpmn-icon-user-taskDialog", translate("Create User Task")),
     "create.data-object": createAction("bpmn:DataObjectReference", "data-object", "bpmn-icon-data-object", translate("Create DataObjectReference")),
     "create.data-store": createAction("bpmn:DataStoreReference", "data-store", "bpmn-icon-data-store", translate("Create DataStoreReference")),
     "create.subprocess-expanded": {

+ 25 - 6
src/views/produce/components/footBtn.vue

@@ -57,6 +57,11 @@
             name: '工步',
             type: 'workStep',
             bjColor: '#409EFF'
+          },
+          {
+            name: '任务',
+            type: 'task',
+            bjColor: '#67c23a'
           }
         ],
         btnList2: [
@@ -85,6 +90,16 @@
             name: '工艺文件',
             type: 'work',
             bjColor: '#2B56C2'
+          },
+          {
+            name: '工步',
+            type: 'workStep',
+            bjColor: '#409EFF'
+          },
+          {
+            name: '任务',
+            type: 'task',
+            bjColor: '#67c23a'
           }
         ],
         btnList3: [
@@ -130,6 +145,16 @@
             name: '工艺文件',
             type: 'work',
             bjColor: '#2B56C2'
+          },
+          {
+            name: '工步',
+            type: 'workStep',
+            bjColor: '#409EFF'
+          },
+          {
+            name: '任务',
+            type: 'task',
+            bjColor: '#67c23a'
           }
         ],
         btnList: []
@@ -173,10 +198,7 @@
       },
       type: {
         handler(v) {
-          console.log('899789', v);
-          console.log(this.clientEnvironmentId, 'clientEnvironmentId');
           if (v == '2' || v == '3' || v == '6') {
-            console.log(111);
             let btnList2 = this.btnList2.filter((item) => {
               if (v != 6) {
               }
@@ -188,15 +210,12 @@
           } else {
             this.$set(this, 'btnList', this.btnList1);
           }
-
-          console.log(this.btnList, 'btnList');
         },
         immediate: true,
         deep: true
       },
       singleReportInspection: {
         handler(v) {
-          console.log('15655', v);
           if (v == 1 || v == null) {
             let index = this.btnList2.findIndex(
               (obj) => obj.name == '取样质检'

+ 394 - 0
src/views/produce/components/taskDialog/index.vue

@@ -0,0 +1,394 @@
+<template>
+  <ele-modal
+    :centered="true"
+    :close-on-click-modal="false"
+    :maxable="true"
+    :visible.sync="visible"
+    append-to-body
+    custom-class="ele-dialog-form long-dialog-form"
+    title="任务列表"
+    width="85%"
+    @close="handleClose"
+  >
+    <ele-pro-table
+      ref="fileTable"
+      :columns="columns"
+      :datasource="workList"
+      :loading="loading"
+      style="min-height: 400px"
+    >
+      <template v-slot:realStartTime="{ row }">
+        <el-date-picker
+          v-model="row.realStartTime"
+          :picker-options="{
+            disabledDate: (time) => {
+              return (
+                row.realEndTime && time.getTime() > new Date(row.realEndTime)
+              );
+            }
+          }"
+          placeholder="选择实际开始时间"
+          type="datetime"
+          value-format="yyyy-MM-dd HH:mm:ss"
+        >
+        </el-date-picker>
+      </template>
+      <template v-slot:realEndTime="{ row }">
+        <el-date-picker
+          v-model="row.realEndTime"
+          :picker-options="{
+            disabledDate: (time) => {
+              return (
+                row.realStartTime &&
+                time.getTime() < new Date(row.realStartTime)
+              );
+            }
+          }"
+          placeholder="选择结束日期"
+          type="datetime"
+          value-format="yyyy-MM-dd HH:mm:ss"
+        >
+        </el-date-picker>
+      </template>
+      <template v-slot:qualifiedQuantity="{ row }">
+        <el-input
+          v-model="row.qualifiedQuantity"
+          placeholder="请输入"
+          type="number"
+          @input="(e) => handleQuantityInput(e, 'qualifiedQuantity', row)"
+        ></el-input>
+      </template>
+      <template v-slot:qualifiedWeight="{ row }">
+        <el-input
+          v-model="row.qualifiedWeight"
+          placeholder="请输入"
+          type="number"
+          @input="(e) => handleWeightInput(e, 'qualifiedWeight', row)"
+        ></el-input>
+      </template>
+      <template v-slot:unqualifiedQuantity="{ row }">
+        <el-input
+          v-model="row.unqualifiedQuantity"
+          placeholder="请输入"
+          type="number"
+          @input="(e) => handleQuantityInput(e, 'unqualifiedQuantity', row)"
+        ></el-input>
+      </template>
+      <template v-slot:unqualifiedWeight="{ row }">
+        <el-input
+          v-model="row.unqualifiedWeight"
+          placeholder="请输入"
+          type="number"
+          @input="(e) => handleWeightInput(e, 'unqualifiedWeight', row)"
+        ></el-input>
+      </template>
+      <template v-slot:assigneeRemark="{ row }">
+        <el-input
+          v-model="row.assigneeRemark"
+          placeholder="请输入"
+          type="textarea"
+        ></el-input>
+      </template>
+      <template v-slot:action="{ row }">
+        <el-popconfirm title="确认本次报工?" @confirm="saveData(row)">
+          <template v-slot:reference>
+            <el-link :underline="false" type="primary">报工 </el-link>
+          </template>
+        </el-popconfirm>
+
+        <el-link
+          style="margin-left: 10px"
+          :underline="false"
+          type="primary"
+          @click="viewRecords(row.id)"
+          >修改记录</el-link
+        >
+      </template>
+    </ele-pro-table>
+    <modifyDialog ref="modifyRef" />
+  </ele-modal>
+</template>
+
+<script>
+  import {
+    batchUpdateRealTime,
+    listUpdateRealTimeRecord,
+    pageAssigneeByTask
+  } from '@/api/workOrderList';
+  import modifyDialog from '@/views/taskList/components/modifyDialog.vue';
+
+  export default {
+    // components: { WorkTimeHistory, Details },
+    components: { modifyDialog },
+    data() {
+      return {
+        visible: false,
+        workList: [],
+        columns: [
+          {
+            title: '序号',
+            type: 'index',
+            width: 60,
+            align: 'center',
+            fixed: 'left'
+          },
+          {
+            label: '执行对象名称',
+            prop: 'assigneeName',
+            width: 180,
+            align: 'center',
+            showOverflowTooltip: true,
+          },
+          {
+            label: '执行类型',
+            prop: 'assigneeType',
+            width: 100,
+            align: 'center',
+            showOverflowTooltip: true,
+            formatter: (row) => {
+              if (!row.assigneeType) return '';
+              return row.assigneeType.desc;
+            }
+          },
+          {
+            label: '工时',
+            prop: 'durationText',
+            width: 140,
+            align: 'center',
+            showOverflowTooltip: true
+          },
+          {
+            label: '任务开始时间',
+            prop: 'startTime',
+            width: 170,
+            align: 'center',
+            showOverflowTooltip: true
+          },
+          {
+            label: '任务结束时间',
+            prop: 'endTime',
+            width: 170,
+            align: 'center',
+            showOverflowTooltip: true
+          },
+          {
+            label: '任务数量',
+            prop: 'quantity',
+            width: 120,
+            align: 'center',
+            showOverflowTooltip: true
+          },
+          {
+            label: '任务重量(kg)',
+            prop: 'weight',
+            width: 120,
+            align: 'center',
+            showOverflowTooltip: true
+          },
+          {
+            slot: 'realStartTime',
+            label: '实际开始时间',
+            prop: 'realStartTime',
+            width: 250,
+            align: 'center',
+            showOverflowTooltip: true
+          },
+          {
+            slot: 'realEndTime',
+            label: '实际结束时间',
+            prop: 'realEndTime',
+            width: 250,
+            align: 'center',
+            showOverflowTooltip: true
+          },
+          {
+            slot: 'qualifiedQuantity',
+            label: '合格数量',
+            prop: 'qualifiedQuantity',
+            width: 160,
+            align: 'center',
+            showOverflowTooltip: true
+          },
+          {
+            slot: 'qualifiedWeight',
+            label: '合格重量',
+            prop: 'qualifiedWeight',
+            width: 160,
+            align: 'center',
+            showOverflowTooltip: true
+          },
+          {
+            slot: 'unqualifiedQuantity',
+            label: '不合格数量',
+            prop: 'unqualifiedQuantity',
+            width: 160,
+            align: 'center',
+            showOverflowTooltip: true
+          },
+          {
+            slot: 'unqualifiedWeight',
+            label: '不合格重量',
+            prop: 'unqualifiedWeight',
+            width: 160,
+            align: 'center',
+            showOverflowTooltip: true
+          },
+          {
+            slot: 'assigneeRemark',
+            label: '备注',
+            prop: 'assigneeRemark',
+            width: 230,
+            align: 'center',
+            showOverflowTooltip: true
+          },
+          {
+            columnKey: 'action',
+            slot: 'action',
+            label: '操作',
+            align: 'center',
+            width: 140,
+            resizable: false,
+            showOverflowTooltip: true,
+            fixed: 'right'
+          }
+        ],
+        loading: false
+      };
+    },
+    computed: {},
+    methods: {
+      open(queryParam, workData) {
+        this.visible = true;
+        this.params = {
+          produceRoutingId: workData.produceRoutingId,
+          taskId: this.$store.state.user.taskObj.id,
+          mesWorkOrderId: workData.id,
+          categoryId: workData.categoryId,
+          apsWorkOrderId: workData.apsWorkOrderId
+        };
+        this.getData();
+      },
+      getData() {
+        this.workList = [];
+        this.loading = true;
+        pageAssigneeByTask(this.params)
+          .then((res) => {
+            this.loading = false;
+            this.workList = res.list;
+          })
+          .catch((err) => {
+            this.loading = false;
+            this.workList = [];
+            this.$message.error(err.message);
+          });
+      },
+      //   保存
+      saveData(row) {
+        if (!row.realStartTime) {
+          return this.$message.warning('请选择开始时间');
+        }
+        if (!row.realEndTime) {
+          return this.$message.warning('请选择结束时间');
+        }
+        if (!row.qualifiedQuantity) {
+          return this.$message.warning('请输入合格数量');
+        }
+        if (!row.qualifiedWeight) {
+          return this.$message.warning('请输入合格重量');
+        }
+        if (!row.unqualifiedQuantity) {
+          return this.$message.warning('请输入不合格数量');
+        }
+        if (!row.unqualifiedWeight) {
+          return this.$message.warning('请输入不合格重量');
+        }
+        let params = {
+          realStartTime: row.realStartTime,
+          realEndTime: row.realEndTime,
+          qualifiedQuantity: row.qualifiedQuantity,
+          qualifiedWeight: row.qualifiedWeight,
+          unqualifiedQuantity: row.unqualifiedQuantity,
+          unqualifiedWeight: row.unqualifiedWeight,
+          remark: row.assigneeRemark,
+          apsAssigneeId: row.id
+        };
+        // getData
+        batchUpdateRealTime([params])
+          .then((res) => {
+            if (res) {
+              this.$message.success('操作成功');
+              this.getData();
+            }
+          })
+          .catch((err) => {
+            this.$message.error(err.message);
+          });
+      },
+      // 重量正则判断
+      handleWeightInput(e, type, row) {
+        // 过滤非数字和非小数点字符(包括负号)
+        let value = e.replace(/[^\d.]/g, '');
+        // 限制只能有一个小数点
+        const dotCount = (value.match(/\./g) || []).length;
+        if (dotCount > 1) {
+          value = value.slice(0, value.lastIndexOf('.'));
+        }
+        // 限制不能以小数点开头
+        if (value.startsWith('.')) {
+          value = '0' + value;
+        }
+        // 更新绑定值
+        row[type] = value;
+        this.calculateWeight(row, type);
+      },
+      // 数量正则 quantity
+      handleQuantityInput(e, type, row) {
+        // 过滤非数字字符(包括负号)
+        let value = e.replace(/[^\d]/g, '');
+        // 限制不能以 0 开头(除非是 0 本身)
+        if (value.startsWith('0') && value.length > 1) {
+          value = value.slice(1);
+        }
+        // 更新绑定值
+        row[type] = value;
+        this.calculateQuantity(row, type);
+      },
+      //计算重量
+      calculateWeight(row, type) {
+        let total = row.qualifiedWeight - 0 + (row.unqualifiedWeight - 0);
+        if (total > row.weight) {
+          row[type] = 0;
+          this.$message.warning('合格重量加不合格重量不能大于任务重量');
+        }
+      },
+      // 计算数量
+      calculateQuantity(row, type) {
+        let total = row.qualifiedQuantity - 0 + (row.unqualifiedQuantity - 0);
+        if (total > row.quantity) {
+          row[type] = 0;
+          this.$message.warning('合格数量加不合格数量不能大于任务数量');
+        }
+      },
+      // 查看修改记录
+      viewRecords(apsAssigneeId) {
+        listUpdateRealTimeRecord(apsAssigneeId)
+          .then((res) => {
+            if (res && res.length > 0) {
+              this.$refs.modifyRef.open(res);
+            } else {
+              this.$message.warning('暂无修改历史记录数据');
+            }
+          })
+          .catch((err) => {
+            this.$message.error(err.message);
+          });
+      },
+      handleClose() {
+        this.visible = false;
+      },
+      close() {
+        this.detailsVisible = false;
+      }
+    }
+  };
+</script>

+ 1 - 1
src/views/produce/components/workStep/index.vue

@@ -46,7 +46,7 @@
       </template>
       <template v-slot:action="{ row }">
         <el-link type="primary" @click="saveData(row)" :underline="false"
-          >保存</el-link
+          >确定</el-link
         >
         <el-link
           v-if="row.hasStepWorkTimeRecord"

+ 13 - 12
src/views/produce/index.vue

@@ -238,10 +238,13 @@
     <!-- :workListIds="workListIds" :taskId="taskObj.id" -->
     <!-- 工步 -->
     <workStep ref="workStepRef" />
+    <!--  任务  -->
+    <TaskDialog ref="taskDialogRef" />
   </div>
 </template>
 
 <script>
+import TaskDialog from '@/views/produce/components/taskDialog/index.vue';
   import Search from './components/search.vue';
   import footBtn from './components/footBtn.vue';
   // import produceOrder from './components/produceOrder.vue';
@@ -290,7 +293,8 @@
       inspection,
       warehousing,
       workStep,
-      workPlan
+      workPlan,
+      TaskDialog
     },
     data() {
       return {
@@ -407,7 +411,6 @@
       },
 
       handleNodeClickNew(info) {
-        console.log(info, '999');
         // this.current = info;
 
         let current = { id: info.id };
@@ -463,7 +466,6 @@
       // 获取工位
       getFactoryworkstationPageList() {
         factoryworkstationPage({ pageNum: 1, size: 99999999 }).then((res) => {
-          console.log(res, 'res');
           this.factoryworkstationList = res.list;
 
           this.arrTow = JSON.parse(JSON.stringify(this.factoryworkstationList));
@@ -497,7 +499,6 @@
       },
 
       workSelect(data) {
-        console.log(11112222, data);
         this.workTaskId = data.list.length > 0 ? data.list[0].taskId : null;
         this.workStepQueryParam.taskId =
           data.list.length > 0 ? data.list[0].taskId : null;
@@ -528,7 +529,7 @@
       footBtn(t) {
         // this.operationType = t;
         // 新增判断 *** 出现弹窗的时候不然右边数据消失
-        if (t == 'work' || t == 'workStep') {
+        if ((t == 'work' || t == 'workStep', t === 'task')) {
           this.popupType = t;
         } else {
           this.operationType = t;
@@ -540,7 +541,7 @@
           this.$message.warning('请选择工序');
           return true;
         }
-        if (['pick', 'feed', 'job', 'work', 'workStep'].includes(t)) {
+        if (['pick', 'feed', 'job', 'work', 'workStep', 'task'].includes(t)) {
           if (this.workListIds.length == 0) {
             this.$message.warning('请选择工单列表');
             return false;
@@ -579,6 +580,12 @@
 
           // this.$refs.wokePopupRef.open(req);
         }
+        if (t === 'task') {
+          if (this.workListIds.length > 1) {
+            return this.$message.warning('任务只能选择一个工单!');
+          }
+          this.$refs.taskDialogRef.open(this.workStepQueryParam, this.workData);
+        }
         // 工艺路线 *** 修改 判断只能选择一个
         // if (t === 'work') {
         //   let req = {
@@ -616,7 +623,6 @@
       },
 
       handOutsource(workOrderId) {
-        console.log(this.taskObj, workOrderId);
         // return
         let param = {
           taskId: this.taskObj.id,
@@ -628,7 +634,6 @@
           };
           this.outsourceForm.name = this.taskObj.name + '委外';
 
-          console.log(res, 'res');
           if (res.data.outsource) {
             this.isType = '3';
             this.getTaskInstanceByIdFn(workOrderId);
@@ -641,18 +646,15 @@
       //获取工单列表
       getTaskInstanceByIdFn(workOrderId) {
         getTaskInstanceById(workOrderId).then((res) => {
-          console.log(res, 'res');
           let { data } = res;
           if (data.length) {
             data = data.filter((item) => item.type == 1 || item.type == 4);
             let arr = data.findIndex(
               (item) => item.sourceTaskId == this.taskObj.id
             );
-            console.log(arr);
             if (arr != -1) {
               data.splice(0, arr + 1);
             }
-            console.log(data, '吃饭吃饭吃饭吃饭');
             this.$set(this.outsourceForm, 'newStepsList', data);
           }
         });
@@ -674,7 +676,6 @@
       },
 
       rowClick(row, taskId) {
-        console.log(row, taskId, 'row');
         if (taskId) {
           let params = {
             categoryId: row.categoryId,

+ 1131 - 0
src/views/produceOrder/components/releaseDialog/index.vue

@@ -0,0 +1,1131 @@
+<template>
+  <ele-modal
+    :before-close="cancel"
+    :close-on-click-modal="false"
+    :maxable="true"
+    :title="'派单'"
+    :visible.sync="dispatchVisible"
+    :width="modelWidth"
+    append-to-body
+    custom-class="ele-dialog-form"
+  >
+    <div class="form-wrapper">
+      <el-form
+        ref="form"
+        :inline="true"
+        :model="form"
+        label-position="right"
+        label-width="100px"
+      >
+        <el-row :gutter="10" class="basic" style="flex-wrap: wrap" type="flex">
+          <el-col
+            v-for="item in fieldList"
+            :key="item.prop"
+            :lg="8"
+            :md="12"
+            :sm="12"
+            :xl="6"
+            :xs="12"
+          >
+            <el-form-item :label="item.label">
+              <!-- <div class="item_label">{{ current[item.prop] }}</div> -->
+              <el-input v-model="current[item.prop]" disabled />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="10">
+          <el-col :lg="8" :md="12" :sm="12" :xl="6" :xs="12">
+            <el-form-item label="所属工厂:">
+              <el-input v-model="form.factoryName" :disabled="true"></el-input>
+            </el-form-item>
+          </el-col>
+          <el-col :lg="8" :md="12" :sm="12" :xl="6" :xs="12">
+            <el-form-item label="所属工作中心:">
+              <el-select
+                v-model="form.workCenterId"
+                placeholder="请选择"
+                style="width: 100%"
+                @change="changeWork"
+              >
+                <el-option
+                  v-for="item in workCenterList"
+                  :key="item.id"
+                  :label="item.name"
+                  :value="item.id"
+                >
+                </el-option>
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :lg="8" :md="12" :sm="12" :xl="6" :xs="12">
+            <el-form-item label="所属班组:" required>
+              <el-select
+                v-model="form.teamId"
+                placeholder="请选择"
+                style="width: 100%"
+                @change="changeGroups"
+              >
+                <el-option
+                  v-for="item in teamList"
+                  :key="item.id"
+                  :label="item.name"
+                  :value="item.id"
+                >
+                </el-option>
+              </el-select>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <!--        <el-row>-->
+        <!--          <el-form-item label="报工类型:" required>-->
+        <!--            <el-radio-group v-model="form.singleReport">-->
+        <!--              &lt;!&ndash; v-if="clientEnvironmentId != 2" &ndash;&gt;-->
+        <!--              <el-radio :label="1">单件报工</el-radio>-->
+        <!--              <el-radio :label="0">批量报工</el-radio>-->
+        <!--            </el-radio-group>-->
+        <!--          </el-form-item>-->
+        <!--        </el-row>-->
+        <!--        <el-row>-->
+        <!--          <el-form-item label="派单方式:" prop="taskAss">-->
+        <!--            <el-radio-group v-model="form.taskAss">-->
+        <!--              <el-radio :label="1">生产订单派单</el-radio>-->
+        <!--              <el-radio :disabled="procTaskDis" :label="0"-->
+        <!--              >工序任务派单-->
+        <!--              </el-radio-->
+        <!--              >-->
+        <!--            </el-radio-group>-->
+        <!--          </el-form-item>-->
+        <!--        </el-row>-->
+        <!--        <el-row v-if="form.taskAss == 1">-->
+        <!--          <el-col :span="24">-->
+        <!--            <el-form-item label="指派:" prop="assignType">-->
+        <!--              <el-radio-group-->
+        <!--                v-model="form.assignType"-->
+        <!--                size="mini"-->
+        <!--                @change="assignRadio"-->
+        <!--              >-->
+        <!--                <el-radio-button :label="1">工位</el-radio-button>-->
+        <!--                <el-radio-button :label="2">人员</el-radio-button>-->
+        <!--                &lt;!&ndash; <el-radio-button :label="3">产线</el-radio-button> &ndash;&gt;-->
+        <!--              </el-radio-group>-->
+        <!--            </el-form-item>-->
+        <!--          </el-col>-->
+        <!--          <el-form-item v-if="form.assignType == 1" label="工位:" required>-->
+        <!--            <el-select-->
+        <!--              v-model="form.workstationIds"-->
+        <!--              class="ele-block"-->
+        <!--              filterable-->
+        <!--              multiple-->
+        <!--              placeholder="请选择工位"-->
+        <!--              size="mini"-->
+        <!--            >-->
+        <!--              <el-option-->
+        <!--                v-for="item in stationList"-->
+        <!--                :key="item.id"-->
+        <!--                :label="item.name + '(' + item.code + ')'"-->
+        <!--                :value="item.id"-->
+        <!--              >-->
+        <!--              </el-option>-->
+        <!--            </el-select>-->
+        <!--          </el-form-item>-->
+
+        <!--          <el-form-item-->
+        <!--            v-if="form.assignType == 2"-->
+        <!--            label="人员:"-->
+        <!--            prop="crewIds"-->
+        <!--          >-->
+        <!--            <el-select-->
+        <!--              v-model="form.crewIds"-->
+        <!--              class="ele-block"-->
+        <!--              filterable-->
+        <!--              multiple-->
+        <!--              placeholder="请选择人员"-->
+        <!--              size="mini"-->
+        <!--            >-->
+        <!--              <el-option-->
+        <!--                v-for="item in crewList"-->
+        <!--                :key="item.id"-->
+        <!--                :label="item.name"-->
+        <!--                :value="item.id"-->
+        <!--              >-->
+        <!--              </el-option>-->
+        <!--            </el-select>-->
+        <!--          </el-form-item>-->
+        <!--        </el-row>-->
+        <!-- v-show="form.taskAss == 0" -->
+        <el-tabs
+          v-model="processId"
+          v-loading="tabsLoading"
+          class="process_list"
+          style="margin-bottom: 20px"
+          type="border-card"
+          @tab-click="handleClick"
+        >
+          <el-tab-pane
+            v-for="(item, index) in processList"
+            :key="item.id"
+            :label="item.name"
+            :name="item.id"
+          >
+            <ele-pro-table
+              ref="tableRef"
+              v-loading="tabLoading"
+              :columns="columns"
+              :datasource="item.list"
+              :pageSize="20"
+              :selection.sync="item.selection"
+              cache-key="systemRoleTable"
+              class="table"
+            >
+              <template v-slot:toolbar>
+                <el-button
+                  :loading="toolbarLoading"
+                  type="primary"
+                  @click="dispatch(item, 1)"
+                >
+                  派单
+                </el-button>
+                <el-button
+                  :loading="toolbarLoading"
+                  type="primary"
+                  @click="dispatch(item, 2)"
+                >
+                  撤回
+                </el-button>
+                <el-button
+                  :loading="toolbarLoading"
+                  type="primary"
+                  @click="dispatch(item, 3)"
+                >
+                  保存
+                </el-button>
+
+                <div style="margin-left: 50px; display: inline-block">
+                  <span
+                    class="text"
+                    style="
+                      font-weight: bold;
+                      font-size: 14px;
+                      margin-right: 8px;
+                    "
+                    >指派:</span
+                  >
+                  <el-radio-group
+                    v-model="item.assignType"
+                    size="mini"
+                    @change="(e) => changeRadio(e, index)"
+                  >
+                    <el-radio-button
+                      :disabled="radioBun(item, 'stationDis')"
+                      :label="1"
+                      >工位
+                    </el-radio-button>
+                    <el-radio-button
+                      :disabled="radioBun(item, 'staffDis')"
+                      :label="2"
+                      >人员
+                    </el-radio-button>
+                    <el-radio-button
+                      :disabled="radioBun(item, 'lineDis')"
+                      :label="3"
+                      >产线
+                    </el-radio-button>
+                  </el-radio-group>
+                </div>
+              </template>
+              <template v-slot:quantity="{ row }">
+                <el-input
+                  v-model="row.quantity"
+                  :disabled="permissions(row)"
+                  placeholder="请输入数量"
+                  type="number"
+                  @input="(e) => handleQuantityInput(e, row, item)"
+                ></el-input>
+              </template>
+              <template v-slot:weight="{ row }">
+                <el-input
+                  v-model="row.weight"
+                  :disabled="permissions(row)"
+                  placeholder="请输入重量"
+                  type="number"
+                  @input="(e) => handleWeightInput(e, row, item)"
+                ></el-input>
+              </template>
+              <template v-slot:startTime="{ row }">
+                <el-date-picker
+                  v-model="row.startTime"
+                  :disabled="permissions(row)"
+                  :picker-options="{
+                    disabledDate: (time) => {
+                      return (
+                        row.endTime && time.getTime() > new Date(row.endTime)
+                      );
+                    }
+                  }"
+                  class="w100"
+                  placeholder="开始时间"
+                  type="datetime"
+                  value-format="yyyy-MM-dd HH:mm:ss"
+                ></el-date-picker>
+              </template>
+              <template v-slot:endTime="{ row }">
+                <el-date-picker
+                  v-model="row.endTime"
+                  :disabled="permissions(row)"
+                  :picker-options="{
+                    disabledDate: (time) => {
+                      return (
+                        row.startTime &&
+                        time.getTime() < new Date(row.startTime)
+                      );
+                    }
+                  }"
+                  class="w100"
+                  placeholder="完成时间"
+                  type="datetime"
+                  value-format="yyyy-MM-dd HH:mm:ss"
+                ></el-date-picker>
+              </template>
+
+              <template v-slot:action="{ row }">
+                <!--  :disabled="resetBtnDis(row)" -->
+                <el-popconfirm
+                  v-if="resetBtnDis(row)"
+                  title="确定要重置该条数据吗?"
+                  @confirm="resetData(row, item)"
+                >
+                  <template v-slot:reference>
+                    <el-link :underline="false" type="primary"> 重置</el-link>
+                  </template>
+                </el-popconfirm>
+              </template>
+            </ele-pro-table>
+          </el-tab-pane>
+        </el-tabs>
+      </el-form>
+    </div>
+
+    <!--    <div slot="footer">-->
+    <!--      <el-button plain @click="cancel">取消</el-button>-->
+    <!--      <el-button :loading="toolbarLoading" type="primary" @click="confirm"-->
+    <!--      >确定-->
+    <!--      </el-button-->
+    <!--      >-->
+    <!--    </div>-->
+  </ele-modal>
+</template>
+
+<script>
+  import {
+    lineByCurrentUser,
+    listAssign,
+    listByFirstTaskId,
+    listByMesWorkOrder,
+    listByRoutingIds,
+    listUserByIds,
+    listWorkCenter,
+    resetAssignee,
+    taskAssignment,
+    taskRevoked,
+    taskSave
+  } from '@/api/mainData/index.js';
+
+  export default {
+    components: {},
+    props: {
+      current: {
+        type: Object,
+        default: () => {}
+      },
+      dispatchVisible: {
+        type: Boolean,
+        default: false
+      }
+    },
+    data() {
+      return {
+        processId: '',
+        tabLoading: false,
+        dynamicName: '工位名称',
+        form: {
+          assignType: 1,
+          crewIds: '',
+          workstationIds: '',
+          teamId: '',
+          singleReport: '',
+          workCenterId: '',
+          taskAss: 1,
+          factoryName: ''
+        },
+        toolbarLoading: false,
+        processList: [],
+        workCenterList: [],
+        teamList: [],
+        tabsLoading: false,
+        stationList: [], // 工位的数据
+        productionList: [], // 产线的数据
+        crewList: [], // 人员的数据
+        // procTaskDis: false, // 工序任务派单选择
+        // firstTaskindex: '', // 首工序id 对应的工序列表数据下标
+        fieldList: [
+          { label: '生产订单号:', prop: 'code' },
+          { label: '计划编号:', prop: 'productionPlanCode' },
+          { label: '工艺路线:', prop: 'produceRoutingName' },
+          // { label: '编码', prop: 'productCode' },
+          { label: '名称:', prop: 'productName' },
+          { label: '生产编号:', prop: 'productionCodes' },
+          { label: '牌号:', prop: 'brandNo' },
+          { label: '批次号:', prop: 'batchNo' },
+          { label: '型号:', prop: 'model' },
+          { label: '要求生产数量:', prop: 'formingNum' },
+          { label: '要求生产重量:', prop: 'initialWeight' },
+          { label: '计划开始时间:', prop: 'planStartTime' },
+          { label: '计划结束时间:', prop: 'planCompleteTime' }
+        ]
+      };
+    },
+    computed: {
+      clientEnvironmentId() {
+        return this.$store.state.user.info.clientEnvironmentId;
+      },
+      userInfo() {
+        return this.$store.state.user.info;
+      },
+      modelWidth() {
+        // if(this.form.taskAss == 1){
+        //   return '1000px'
+        // }
+        return '75vw';
+      },
+      // 重置按钮 的置灰权限 没有进行操作跟派单的数据 置灰
+      resetBtnDis() {
+        return (row) => {
+          if (!row.status) return false;
+          let flag = row.status.code != 1;
+          return flag;
+        };
+      },
+      // 指派单选框操作 已派单的 其它两个按钮不能操作
+      radioBun() {
+        return (row, type) => {
+          if (!row.radioBun) return false;
+          let flag = row.radioBun[type];
+          return flag;
+        };
+      },
+      // 列表输入框操作 已派单的不能操作
+      permissions() {
+        return (row) => {
+          if (!row.status) return false;
+          if (row.status.code == 1) return true;
+        };
+      },
+      columns() {
+        return [
+          {
+            columnKey: 'index',
+            label: '序号',
+            type: 'index',
+            width: 55,
+            align: 'center',
+            showOverflowTooltip: true,
+            fixed: 'left'
+          },
+          {
+            width: 45,
+            type: 'selection',
+            columnKey: 'selection',
+            align: 'center',
+            fixed: 'left'
+          },
+          {
+            prop: 'name',
+            label: this.dynamicName,
+            align: 'center',
+            showOverflowTooltip: true,
+            width: 200
+          },
+          {
+            prop: 'code',
+            label: '编码',
+            align: 'center',
+            showOverflowTooltip: true,
+            width: 200
+          },
+          {
+            prop: 'status',
+            label: '状态',
+            align: 'center',
+            showOverflowTooltip: true,
+            width: 150,
+            formatter: (row) => {
+              if (!row.status) return '';
+              return row.status.desc || '';
+            }
+          },
+          // {
+          //   prop: 'name',
+          //   label: '名称',
+          //   align: 'center',
+          //   showOverflowTooltip: true,
+          //   width: 180
+          // },
+          // {
+          //   prop: 'model',
+          //   label: '型号',
+          //   align: 'center',
+          //   showOverflowTooltip: true,
+          //   width: 180
+          // },
+          // {
+          //   prop: 'specifications',
+          //   label: '规格',
+          //   align: 'center',
+          //   showOverflowTooltip: true,
+          //   width: 180
+          // },
+          // {
+          //   prop: 'brandNumber',
+          //   label: '牌号',
+          //   align: 'center',
+          //   showOverflowTooltip: true,
+          //   width: 180
+          // },
+          {
+            slot: 'quantity',
+            prop: 'quantity',
+            label: '数量',
+            align: 'center',
+            showOverflowTooltip: true,
+            width: 140
+          },
+          {
+            slot: 'weight',
+            prop: 'weight',
+            label: `重量(${this.current.weightUnit})`,
+            align: 'center',
+            showOverflowTooltip: true,
+            width: 140
+          },
+          {
+            slot: 'startTime',
+            prop: 'startTime',
+            label: '计划开始时间',
+            align: 'center',
+            showOverflowTooltip: true,
+            minWidth: 240
+          },
+          {
+            slot: 'endTime',
+            prop: 'endTime',
+            label: '计划完成时间',
+            align: 'center',
+            showOverflowTooltip: true,
+            minWidth: 240
+          },
+          {
+            columnKey: 'action',
+            label: '操作',
+            width: 120,
+            align: 'center',
+            resizable: false,
+            fixed: 'right',
+            slot: 'action'
+          }
+        ];
+      }
+    },
+    watch: {},
+    created() {
+      this.workCenterData();
+      this.FirstTaskIdFn();
+      this.form.singleReport = this.clientEnvironmentId == 2 ? 0 : 1;
+    },
+    methods: {
+      async workCenterData() {
+        const res = await listWorkCenter(this.current.taskInstanceId);
+        this.workCenterList = res;
+        if (res.length > 0) {
+          this.form.factoryName = res[0].factoryName;
+          this.form.workCenterId = res[0].id;
+          // 查首工序
+          this.changeWork(res[0].id); // 选择工作中心
+          this.getProductionData(res[0].id); // 查询产线
+        }
+      },
+      // 查询工序列表数据
+      async changeDispatch(e) {
+        this.tabsLoading = true;
+        try {
+          // /aps/assign/listByMesWorkOrder
+          let allRes = await listByRoutingIds([this.current.produceRoutingId]); // 查询全部工序数据
+          let params = {
+            apsWorkOrderId: this.current.apsWorkOrderId,
+            categoryId: this.current.categoryId,
+            mesWorkOrderId: this.current.id,
+            produceRoutingId: this.current.produceRoutingId
+          };
+          let existRes = await listByMesWorkOrder(params); // 存在的工序数据
+          let res = [];
+          if (!existRes || existRes.length === 0) {
+            res = allRes;
+          } else {
+            // 先将 存在的工序数据 数组的 id 存入 Set
+            const existIds = new Set(existRes.map((item) => item.taskId));
+            // 过滤 全部工序数据 数组
+            res = allRes.filter((aItem) => !existIds.has(aItem.sourceTaskId));
+          }
+          // 如果没有首工序的数据 就不能选择工序任务派单
+          if (!res || res.length === 0) {
+            this.processList = [];
+            // this.form.taskAss = 1;
+            // this.procTaskDis = true;
+            this.$message.warning('当前工单没有工序数据');
+            return;
+          }
+          // this.procTaskDis = false;
+          let list = [];
+          res.forEach((item, index) => {
+            let obj = {
+              id: item.sourceTaskId, //工序 id
+              name: item.name, //工序 名称
+              assignType: 1, // 默认的指派数据
+              assignName: '工位', // 默认指派数据名称
+              list: [], // 当前工序下面的指派 绑定的表格
+              selection: [], // 当前工序下面的指派 选中的数据
+              code: item.code, // 工序 编码
+              index: index, // 当前工序数据的下标
+              radioBun: {
+                // 指派按钮的操作状态 绑定 默认false(可操作)
+                stationDis: false,
+                staffDis: false,
+                lineDis: false
+              }
+            };
+            list.push(obj);
+          });
+          this.processList = list;
+          this.handleClick({ name: res[0].sourceTaskId });
+        } catch (err) {
+          this.processList = [];
+          this.$message.error(err.message);
+        } finally {
+          this.tabsLoading = false;
+        }
+      },
+      // 选择工作中心
+      changeWork(e) {
+        this.form.workCenterId = e;
+        // this.changeDispatch(); // 查询工序列表
+        let data = this.workCenterList.find((item) => item.id == e);
+        this.form.workCenterName = data.name;
+        this.teamList = data.teamList || [];
+        if (this.teamList.length > 0) {
+          this.form.teamId = this.teamList[0].id;
+          this.changeGroups(this.teamList[0].id);
+        }
+      },
+      // 选择班组 查询人员的数据
+      async changeGroups(e) {
+        let data = this.teamList.find((item) => item.id == e);
+        this.form.teamName = data.name;
+        try {
+          const res = await listUserByIds([e]);
+          this.crewList = res || [];
+          // 查看当前的工序数据是不是 选择的人员 是的话同步更改
+          if (this.form.taskAss == 1) {
+            return;
+          }
+          let data = this.processList.find(
+            (item) => item.id === this.processId
+          );
+          if (data.assignType == 2) {
+            this.$set(data, 'list', res);
+          }
+        } catch {
+          this.crewList = [];
+        }
+      },
+      // 获取产线数据
+      async getProductionData() {
+        const res = await lineByCurrentUser(this.form.workCenterId);
+        this.productionList = res || [];
+      },
+      // 查询工位数据
+      FirstTaskIdFn() {
+        listByFirstTaskId(this.current.taskInstanceId)
+          .then((res) => {
+            this.stationList = res;
+            this.changeDispatch();
+          })
+          .catch((err) => {
+            this.stationList = [];
+            this.$message.error(err.message);
+          });
+      },
+      // 重置(单个)
+      resetData(row, item) {
+        if (!row.changeId) {
+          return this.$message.warning('只能对已撤回跟已保存的数据进行重置');
+        }
+        this.toolbarLoading = true;
+        resetAssignee(row.changeId)
+          .then((res) => {
+            this.toolbarLoading = false;
+            if (res) {
+              this.$message.success('操作成功');
+              // 更改当前表格数据
+              this.setCurrentTab(item);
+            }
+          })
+          .catch((err) => {
+            this.toolbarLoading = false;
+            this.$message.warning(err.message);
+          });
+      },
+      // 撤回的逻辑
+      getWithdrawT(row, type) {
+        if (type != 2) {
+          return true;
+        }
+        let isFlag = true;
+        row.selection.forEach((item) => {
+          if (!item.status) {
+            isFlag = false;
+            return;
+          }
+          if (!item.status.code) {
+            isFlag = false;
+          }
+        });
+        return isFlag;
+      },
+      // 派单
+      dispatch(row, type) {
+        if (row.selection.length == 0) {
+          return this.$message.warning('请最少选择一条数据');
+        }
+        let isWithdraw = this.getWithdrawT(row, type);
+        if (!isWithdraw) {
+          this.$message.warning('只有状态为派单的数据才能进行撤回');
+          return;
+        }
+        let assignees = [];
+        let changeIds = [];
+        let flag = true;
+        row.selection.forEach((item) => {
+          if (
+            !item.quantity ||
+            !item.weight ||
+            !item.startTime ||
+            !item.endTime
+          ) {
+            flag = false;
+            return;
+          }
+          assignees.push({
+            assigneeId: item.id,
+            quantity: item.quantity,
+            weight: item.weight,
+            startTime: item.startTime,
+            endTime: item.endTime,
+            assigneeType: row.assignType,
+            assigneeName: item.name
+          });
+          changeIds.push(item.changeId);
+        });
+        if (!flag) {
+          this.$message.warning(
+            '请将所选数据的 数量,重量,开始时间,完成时间 填写完毕'
+          );
+          return;
+        }
+        let data = null;
+        this.toolbarLoading = true;
+        if (type == 2) {
+          data = changeIds;
+        } else {
+          data = {
+            taskId: this.processId,
+            taskName: row.name,
+            taskCode: row.code,
+            teamName: this.form.teamName,
+            teamId: this.form.teamId,
+            workCenterId: this.form.workCenterId,
+            workCenterName: this.form.workCenterName,
+            workOrderId: this.current.apsWorkOrderId,
+            sourceType: 2,
+            assignees
+          };
+        }
+        const api =
+          type == 1 ? taskAssignment : type == 2 ? taskRevoked : taskSave;
+        api(data)
+          .then((res) => {
+            this.toolbarLoading = false;
+            if (res) {
+              this.$message.success('操作成功');
+              // 更改当前表格数据
+              this.setCurrentTab(row);
+            }
+          })
+          .catch((err) => {
+            this.toolbarLoading = false;
+            this.$message.warning(err.message);
+          });
+      },
+      cancel() {
+        this.$emit('update:dispatchVisible', false);
+      },
+      // 按钮操作成功后 更改当前的表格数据
+      setCurrentTab(row) {
+        let arr = [];
+        if (row.assignType == 1) {
+          arr = this.stationList;
+        } else if (row.assignType == 2) {
+          arr = this.crewList;
+        } else {
+          arr = this.productionList;
+        }
+        this.getAssignData(row.index, arr);
+      },
+      // 最后提交
+      // async confirm() {
+      //   if (!this.form.singleReport) {
+      //     this.$message.warning('请先选择报工类型');
+      //     return;
+      //   }
+      //   if (!this.form.teamId) {
+      //     this.$message.warning('请先选择班组');
+      //     return;
+      //   }
+      //   if (this.form.taskAss == 1) {
+      //     this.issue();
+      //     // 按原来的逻辑
+      //     return;
+      //   }
+      //   let params = {
+      //     teamId: this.form.teamId,
+      //     workCenterId: this.form.workCenterId,
+      //     workOrderId: this.current.id
+      //   };
+      //   this.toolbarLoading = true;
+      //   try {
+      //     const res = await checkAssignConfirm(params);
+      //     if (!res) {
+      //       this.toolbarLoading = false;
+      //       return;
+      //     }
+      //     let paramsD = {
+      //       assignType: data.assignType,
+      //       singleReport: this.form.singleReport,
+      //       teamId: this.form.teamId,
+      //       crewIds: data.assignType == 2 ? dispatchArr : [], // 人员 2
+      //       workstationIds: data.assignType == 1 ? dispatchArr : [], // 工位 1
+      //       id: this.current.id
+      //     };
+      //     const response = await releaseWorkOrder(paramsD);
+      //     this.toolbarLoading = false;
+      //     if (response) {
+      //       this.$message.success('操作成功');
+      //       this.cancel();
+      //       this.$emit('createSuccess');
+      //     }
+      //   } catch (err) {
+      //     this.toolbarLoading = false;
+      //     this.$message.warning(err.message);
+      //   }
+      // },
+      // 下达
+      // issue() {
+      //   if (this.form.assignType == 1) {
+      //     if (
+      //       !this.form.workstationIds ||
+      //       this.form.workstationIds.length == 0
+      //     ) {
+      //       this.$message.warning('请选择工位');
+      //       return;
+      //     }
+      //   }
+      //   let data = {
+      //     assignType: this.form.assignType,
+      //     singleReport: this.form.singleReport,
+      //     teamId: this.form.teamId,
+      //     crewIds: [],
+      //     workstationIds: [],
+      //     id: this.current.id
+      //   };
+      //   if (this.form.assignType == 1) {
+      //     data.workstationIds = this.form.workstationIds || [];
+      //   } else {
+      //     data.crewIds = this.form.crewIds || [];
+      //   }
+      //   this.toolbarLoading = true;
+      //   releaseWorkOrder(data)
+      //     .then((res) => {
+      //       this.toolbarLoading = false;
+      //       if (res) {
+      //         this.$message.success('操作成功');
+      //         this.cancel();
+      //         this.$emit('createSuccess');
+      //       }
+      //     })
+      //     .catch((err) => {
+      //       this.toolbarLoading = false;
+      //       this.$message.warning(err.message);
+      //     });
+      // },
+      // 工序选择
+      handleClick(tab) {
+        let id = tab.name;
+        this.processId = id;
+        let data = this.processList.find((item) => item.id == this.processId);
+        if (data.list.length == 0) {
+          this.changeRadio(1, data.index);
+        }
+      },
+      // 指派选择
+      changeRadio(e, index) {
+        let data = this.processList[index];
+        if (e == 1) {
+          this.dynamicName = '工位名称';
+          data.assignName = '工位';
+          this.getAssignData(index, this.stationList);
+        } else if (e == 2) {
+          this.dynamicName = '人员名称';
+          data.assignName = '人员';
+          this.getAssignData(index, this.crewList);
+        } else {
+          this.dynamicName = '产线名称';
+          data.assignName = '产线';
+          this.getAssignData(index, this.productionList);
+        }
+      },
+      // 指派数据处理
+      async getAssignData(index, arr) {
+        let list = JSON.parse(JSON.stringify(arr));
+        let dataRow = this.processList[index];
+        let params = {
+          workOrderId: this.current.apsWorkOrderId,
+          workCenterId: this.form.workCenterId,
+          teamId: this.form.teamId,
+          taskId: this.processId
+        };
+        this.tabLoading = true;
+        try {
+          const res = await listAssign(params);
+          this.tabLoading = false;
+          // 如果 res 没有数据 说明未对数据进行操作 直接赋值
+          if (res.length == 0) {
+            this.$set(dataRow, 'list', list);
+            return;
+          }
+          // 对有操作过的数据进行赋值
+          this.operationalData(index, res, list);
+        } catch (err) {
+          this.tabLoading = false;
+          this.$message.warning(err.message);
+        }
+      },
+      // 操作过的数据 赋值
+      operationalData(index, res, list) {
+        const dataRow = this.processList[index];
+        // 键值对存储 当前工序 操作的数据  指派的code(键) 数据(list:值)
+        let arrMap = {};
+        // 要先判断有没有操作的数据 如果有的话 其它的指派操作置灰
+        let codeT = null; // 表示有已操作的数据(对应的 code)
+        res[0].assignees.map((el) => {
+          let code = el.assigneeType.code;
+          if (arrMap[code]) {
+            arrMap[code].arr.push(el);
+            arrMap[code].bunDis = arrMap[code].bunDis
+              ? arrMap[code].bunDis
+              : el.status.desc
+              ? true
+              : false;
+          } else {
+            arrMap[code] = {
+              arr: [el],
+              bunDis: el.status.desc ? true : false
+            };
+          }
+          codeT = codeT ? codeT : el.status.desc ? code : '';
+        });
+        let radioBun = {
+          lineDis: false, // 产线 3
+          staffDis: false, // 人员 2
+          stationDis: false // 工位 1
+        };
+        // 默认是传递下来的 list 数据 但是如果 codeT有值 说明 工位 人员 产线 有派单数据
+        // 需要自动切换过去
+        let listArr = list;
+        if (codeT) {
+          if (codeT == 1) {
+            radioBun.staffDis = true;
+            radioBun.lineDis = true;
+            radioBun.stationDis = false;
+            listArr = JSON.parse(JSON.stringify(this.stationList));
+            dataRow.assignType = 1;
+            dataRow.assignName = '工位';
+          } else if (codeT == 2) {
+            radioBun.stationDis = true;
+            radioBun.lineDis = true;
+            radioBun.staffDis = false;
+            listArr = JSON.parse(JSON.stringify(this.crewList));
+            dataRow.assignType = 2;
+            dataRow.assignName = '人员';
+          } else {
+            radioBun.stationDis = true;
+            radioBun.staffDis = true;
+            radioBun.lineDis = false;
+            listArr = JSON.parse(JSON.stringify(this.productionList));
+            dataRow.assignType = 3;
+            dataRow.assignName = '产线';
+          }
+        }
+        // 切换完后 对 指派的数组数据进行赋值
+        let listMap = {};
+        listArr.map((el, index) => (listMap[el.id] = index));
+        let arrList = codeT ? arrMap[codeT].arr : res[0].assignees;
+        arrList.map((item) => {
+          if (item.assigneeType.code == dataRow.assignType) {
+            let idx = listMap[item.assigneeId];
+            listArr[idx].status = item.status;
+            listArr[idx].startTime = item.startTime;
+            listArr[idx].endTime = item.endTime;
+            listArr[idx].quantity = item.quantity;
+            listArr[idx].weight = item.weight;
+            listArr[idx].changeId = item.id;
+          }
+        });
+        this.$set(dataRow, 'list', listArr);
+        this.$set(dataRow, 'radioBun', radioBun);
+      },
+      assignRadio(e) {},
+      // 数量正则 quantity
+      handleQuantityInput(e, row, item) {
+        // 过滤非数字字符(包括负号)
+        let value = e.replace(/[^\d]/g, '');
+        // 限制不能以 0 开头(除非是 0 本身)
+        if (value.startsWith('0') && value.length > 1) {
+          value = value.slice(1);
+        }
+        // 更新绑定值
+        row.quantity = value;
+        this.calculateQuantity(row, item);
+      },
+      calculateQuantity(row, item) {
+        // 如果没有该字段 就不做判断
+        if (!this.current.formingNum) {
+          return;
+        }
+        let total = 0;
+        item.list.forEach((el) => {
+          if (el.quantity) {
+            total = total + (el.quantity - 0);
+          }
+        });
+        if (total > this.current.formingNum - 0) {
+          this.$message.warning('列表数量相加不能大于目标要求生产数量');
+          row.quantity = 0;
+        }
+      },
+      // 计算重量
+      calculateWeight(row, item) {
+        // 如果没有该字段 就不做判断
+        if (!this.current.formingWeight) {
+          return;
+        }
+        let total = 0;
+        item.list.forEach((el) => {
+          if (el.weight) {
+            total = total + (el.weight - 0);
+          }
+        });
+        if (total > this.current.formingWeight - 0) {
+          this.$message.warning('列表数量相加不能大于目标要求生产数量');
+          row.weight = 0;
+        }
+      },
+      // 重量正则 weight
+      handleWeightInput(e, row, item) {
+        // 过滤非数字和非小数点字符(包括负号)
+        let value = e.replace(/[^\d.]/g, '');
+        // 限制只能有一个小数点
+        const dotCount = (value.match(/\./g) || []).length;
+        if (dotCount > 1) {
+          value = value.slice(0, value.lastIndexOf('.'));
+        }
+
+        // 限制不能以小数点开头
+        if (value.startsWith('.')) {
+          value = '0' + value;
+        }
+        // 更新绑定值
+        row.weight = value;
+        this.calculateWeight(row, item);
+      }
+    }
+  };
+</script>
+
+<style lang="scss" scoped>
+  .top-box {
+    display: flex;
+    margin-bottom: 10px;
+
+    .item-box {
+      flex: 1;
+    }
+  }
+
+  .radio-box {
+    margin: 10px 0;
+  }
+
+  .table {
+    margin-top: 20px;
+  }
+
+  ::v-deep .el-radio-button__orig-radio:checked + .el-radio-button__inner {
+    background-color: #10d070;
+    border-color: #10d070;
+  }
+
+  ::v-deep .el-radio-button__orig-radio:checked + .el-radio-button__inner {
+    box-shadow: none;
+  }
+
+  // ::v-deep .ele-block{
+  //   width: 240px;
+  // }
+
+  // ::v-deep .basic {
+  //   .el-form-item {
+  //     width: 100%;
+  //   }
+
+  //   .form80 {
+  //     .el-form-item__content {
+  //       width: calc(100% - 80px);
+  //     }
+  //   }
+
+  //   .form65 {
+  //     .el-form-item__content {
+  //       width: calc(100% - 65px);
+  //     }
+  //   }
+
+  //   .el-form-item__label {
+  //     padding: 0 4px 0 0;
+  //   }
+
+  //   .item_label {
+  //     white-space: nowrap;
+  //     overflow: hidden;
+  //     text-overflow: ellipsis;
+  //     width: 100%;
+  //   }
+  // }
+</style>

+ 36 - 5
src/views/produceOrder/index.vue

@@ -101,6 +101,9 @@
             <el-link v-if="row.status == 4 && row.isSplit == 0" type="primary" :underline="false" @click="toEnd(row)">
               完结
             </el-link>
+            <el-link v-if="dispatchBtn(row)"  type="primary" :underline="false"  @click="toReleaseOpen(row)">
+              派单
+            </el-link>
           </template>
         </template>
       </ele-pro-table>
@@ -118,17 +121,25 @@
     <EquipmentDialog ref="equipmentRef" @choose="choose"></EquipmentDialog>
 
     <xlhView ref="xlhRef"></xlhView>
-
+    <releaseDialog
+      ref="releaseRef"
+      :current="dispatchRow"
+      :dispatchVisible.sync="dispatchVisible"
+      @createSuccess="createSuccess"
+      v-if="dispatchVisible"
+    />
   </div>
 </template>
 
 <script>
+import releaseDialog from './components/releaseDialog'
 import {
   getPage,
   batchCompletion,
   cancelCompletion,
   updatePriority,
-  update
+  update,
+  getTaskIdByInstanceId
 } from '@/api/produceOrder/index.js';
 import xlhView from './components/xlhView.vue';
 import { fieldModel } from '@/api/produceWord/index.js';
@@ -149,6 +160,7 @@ import tableColumnsMixin from '@/mixins/tableColumnsMixin';
 export default {
   mixins: [tableColumnsMixin],
   components: {
+    releaseDialog,
     produceOrderSearch,
     pickingDialog,
     createDialog,
@@ -191,7 +203,9 @@ export default {
       selection: [],
       newColumns: [],
       cacheKeyUrl:'7cc8e5d2-mes-produceOrder',
-      columnsVersion:0
+      columnsVersion:0,
+      dispatchVisible:false,
+      dispatchRow:{}
     };
   },
   computed: {
@@ -519,7 +533,11 @@ export default {
         }
       ];
     },
-
+    dispatchBtn(){
+      return (row)=>{
+        return !!row.taskId
+      }
+    },
     clientEnvironmentId() {
       return this.$store.state.user.info.clientEnvironmentId;
     }
@@ -545,7 +563,21 @@ export default {
   },
 
   methods: {
+    //派单
+    toReleaseOpen(row) {
+      getTaskIdByInstanceId(row.taskId).then((res)=>{
+        if (res){
+          this.dispatchRow = {...row};
+          this.dispatchRow.initialWeight = row.formingWeight + row.weightUnit;
+          this.dispatchRow.taskInstanceId = res
+          this.dispatchVisible = true;
+        }
+      }).catch((err)=>{
+        this.$message.error(err.message);
+      })
 
+
+    },
     search(e){
       if(Array.isArray(e.createTime)&&e.createTime.length){
         e.createTimeStart=e.createTime[0];
@@ -765,7 +797,6 @@ export default {
 
     /* 刷新表格 */
     reload(where = {}) {
-      console.log(where,'wwwwwwwwwww');
       this.$nextTick(() => {
         where.statusList = (
           where.status || this.statusOpt[this.activeName][0].value

+ 399 - 0
src/views/taskList/components/Ddtails.vue

@@ -0,0 +1,399 @@
+<template>
+  <ele-modal
+    :before-close="cancel"
+    :close-on-click-modal="false"
+    :maxable="true"
+    :title="title"
+    :visible.sync="detailsVisible"
+    append-to-body
+    custom-class="ele-dialog-form"
+    width="75vw"
+  >
+    <el-form
+      ref="form"
+      :model="form"
+      :rules="rules"
+      label-position="right"
+      label-width="110px"
+    >
+      <el-row>
+        <headerTitle style="margin-top: 15px" title="报工信息"></headerTitle>
+        <el-col :lg="8" :md="12" :sm="12" :xl="8" :xs="12">
+          <el-form-item
+            :rules="{
+              required: true,
+              message: '请选择实际开始时间',
+              trigger: 'change'
+            }"
+            label="实际开始时间"
+            prop="realStartTime"
+          >
+            <el-date-picker
+              v-model="form.realStartTime"
+              :disabled="inputDis"
+              class="time_select"
+              placeholder="选择实际开始时间"
+              type="datetime"
+              value-format="yyyy-MM-dd HH:mm:ss"
+              @change="handleTimeChange"
+            ></el-date-picker>
+          </el-form-item>
+        </el-col>
+        <el-col :lg="8" :md="12" :sm="12" :xl="8" :xs="12">
+          <el-form-item
+            :rules="{
+              required: true,
+              message: '请选择实际结束时间',
+              trigger: 'change'
+            }"
+            label="实际结束时间"
+            prop="realEndTime"
+          >
+            <el-date-picker
+              v-model="form.realEndTime"
+              :disabled="inputDis"
+              class="time_select"
+              placeholder="选择实际结束时间"
+              type="datetime"
+              value-format="yyyy-MM-dd HH:mm:ss"
+              @change="handleTimeChange"
+            ></el-date-picker>
+          </el-form-item>
+        </el-col>
+        <el-col :lg="8" :md="12" :sm="12" :xl="8" :xs="12">
+          <el-form-item label="合格数量" prop="qualifiedQuantity">
+            <el-input
+              v-model.number="form.qualifiedQuantity"
+              :disabled="inputDis"
+              placeholder="请输入"
+              type="number"
+              @input="(e) => handleQuantityInput(e, 'qualifiedQuantity')"
+            ></el-input>
+          </el-form-item>
+        </el-col>
+        <el-col :lg="8" :md="12" :sm="12" :xl="8" :xs="12">
+          <el-form-item label="不合格数量" prop="unqualifiedQuantity">
+            <el-input
+              v-model.number="form.unqualifiedQuantity"
+              :disabled="inputDis"
+              placeholder="请输入"
+              type="number"
+              @input="(e) => handleQuantityInput(e, 'unqualifiedQuantity')"
+            ></el-input>
+          </el-form-item>
+        </el-col>
+        <el-col :lg="8" :md="12" :sm="12" :xl="8" :xs="12">
+          <el-form-item label="合格重量" prop="qualifiedWeight">
+            <el-input
+              v-model.number="form.qualifiedWeight"
+              :disabled="inputDis"
+              placeholder="请输入"
+              type="number"
+              @input="(e) => handleWeightInput(e, 'qualifiedWeight')"
+            ></el-input>
+          </el-form-item>
+        </el-col>
+        <el-col :lg="8" :md="12" :sm="12" :xl="8" :xs="12">
+          <el-form-item label="不合格重量" prop="unqualifiedWeight">
+            <el-input
+              v-model.number="form.unqualifiedWeight"
+              :disabled="inputDis"
+              placeholder="请输入"
+              type="number"
+              @input="(e) => handleWeightInput(e, 'unqualifiedWeight')"
+            ></el-input>
+          </el-form-item>
+        </el-col>
+        <el-col :span="24">
+          <el-form-item label="备注信息">
+            <el-input
+              v-model="form.remark"
+              :disabled="inputDis"
+              :rows="2"
+              placeholder="请输入"
+              type="textarea"
+            ></el-input>
+          </el-form-item>
+        </el-col>
+      </el-row>
+      <headerTitle style="margin-top: 15px" title="工单信息"></headerTitle>
+      <el-row :gutter="10" class="basic">
+        <el-col
+          v-for="item in fieldMap.orderList"
+          :key="item.prop"
+          :lg="8"
+          :md="12"
+          :sm="12"
+          :xl="8"
+          :xs="12"
+        >
+          <el-form-item :label="item.label" class="form80">
+            <el-input v-model="current[item.prop]" disabled></el-input>
+          </el-form-item>
+        </el-col>
+      </el-row>
+      <headerTitle style="margin-top: 15px" title="任务信息"></headerTitle>
+      <el-row :gutter="10" class="basic">
+        <el-col
+          v-for="item in fieldMap.taskList"
+          :key="item.prop"
+          :lg="8"
+          :md="12"
+          :sm="12"
+          :xl="8"
+          :xs="12"
+        >
+          <el-form-item :label="item.label" class="form80">
+            <el-input v-model="current[item.prop]" disabled></el-input>
+          </el-form-item>
+        </el-col>
+      </el-row>
+      <el-row v-if="title === '详情'">
+        <headerTitle style="margin-top: 15px" title="修改记录"></headerTitle>
+        <ModifyRecord ref="ModifyRecordRef" :list="list" />
+      </el-row>
+    </el-form>
+    <div slot="footer" class="footer">
+      <el-button @click="cancel">返回</el-button>
+      <el-button type="primary" @click="submitAdd" :loading="loadingBtn">报工</el-button>
+    </div>
+  </ele-modal>
+</template>
+
+<script>
+  import { listWorkCenter,batchUpdateRealTime,listUpdateRealTimeRecord } from '@/api/workOrderList';
+  import ModifyRecord from '@/views/taskList/components/ModifyRecord.vue';
+  export default {
+    components: {
+      ModifyRecord
+    },
+    props: {
+      currentRow: {
+        type: Object,
+        default: () => ({})
+      }
+    },
+    data() {
+      return {
+        title: '详情',
+        form: {
+          realEndTime: '',
+          realStartTime: '',
+          unqualifiedWeight: '',
+          unqualifiedQuantity: '',
+          qualifiedWeight: '',
+          qualifiedQuantity: '',
+          remark: ''
+        },
+        rules: {
+          qualifiedQuantity: [
+            {
+              required: true,
+              message: '请输入合格数量',
+              trigger: 'blur'
+            }
+          ],
+          qualifiedWeight: [
+            {
+              required: true,
+              message: '请输入合格重量',
+              trigger: 'blur'
+            }
+          ],
+          unqualifiedQuantity: [
+            {
+              required: true,
+              message: '请输入不合格数量',
+              trigger: 'blur'
+            }
+          ],
+          unqualifiedWeight: [
+            {
+              required: true,
+              message: '请输入不合格重量',
+              trigger: 'blur'
+            }
+          ]
+        },
+        current: {},
+        detailsVisible: false,
+        fieldMap: {
+          orderList: [
+            { label: '生产订单编码:', prop: 'workOrderCode' },
+            { label: '计划编号:', prop: 'productionPlanCode' },
+            { label: '工艺路线:', prop: 'produceRoutingName' },
+            { label: '要求生产数量:', prop: 'formingNum' },
+            { label: '要求生产重量:', prop: 'formingWeight' },
+            { label: '所属工厂:', prop: 'factoryName' },
+            { label: '所属班组:', prop: 'assignTeamName' },
+            { label: '计划开始时间:', prop: 'planStartTime' },
+            { label: '计划结束时间:', prop: 'planCompleteTime' }
+          ],
+          taskList: [
+            { label: '任务编码:', prop: 'assignCode' },
+            { label: '工序名称:', prop: 'taskName' },
+            { label: '执行类型:', prop: 'assigneeType' },
+            { label: '执行对象名称:', prop: 'assigneeName' },
+            { label: '工时:', prop: 'durationText' },
+            { label: '任务开始时间:', prop: 'startTime' },
+            { label: '任务结束时间:', prop: 'endTime' },
+            { label: '任务数量:', prop: 'quantity' },
+            { label: '任务重量(kg):', prop: 'weight' }
+          ]
+        },
+        loadingBtn: false,
+        list:[]
+      };
+    },
+    computed: {
+      inputDis() {
+        return this.title === '详情';
+      }
+    },
+    methods: {
+      open(type, row,form) {
+        this.title = type === 'report' ? '报工' : '详情';
+        this.detailsVisible = true;
+        this.current = { ...row };
+        if (form.realEndTime){
+          this.$nextTick(()=>{
+            this.form = {...form};
+          })
+          if (type !== 'report'){
+            listUpdateRealTimeRecord(row.apsAssigneeId).then(res => {
+              if (res){
+                this.list = res;
+              }
+            }).catch((err)=> {
+              this.$message.error(err.message);
+            })
+          }
+        }
+        this.getData();
+      },
+      cancel() {
+        this.form = {
+          realEndTime: '',
+          realStartTime: '',
+          unqualifiedWeight: '',
+          unqualifiedQuantity: '',
+          qualifiedWeight: '',
+          qualifiedQuantity: '',
+          remark: ''
+        };
+        this.$refs.form.resetFields();
+        this.detailsVisible = false;
+      },
+      async getData() {
+        try {
+          const res = await listWorkCenter(this.current.firstTaskId);
+          this.$set(this.current, 'factoryName', res[0].factoryName);
+        } catch (err) {
+          this.$message.warning(err.message);
+        }
+      },
+      // 时间选择
+      handleTimeChange() {
+        // 如果结束时间早于开始时间,清空结束时间
+        if (this.form.realStartTime && this.form.realEndTime) {
+          const realStartTime = new Date(this.form.realStartTime).getTime();
+          const realEndTime = new Date(this.form.realEndTime).getTime();
+          if (realStartTime > realEndTime) {
+            this.form.realEndTime = '';
+            this.$message.warning('结束时间不能早于开始时间');
+          }
+        }
+      },
+      // 重量正则判断
+      handleWeightInput(e, type) {
+        // 过滤非数字和非小数点字符(包括负号)
+        let value = e.replace(/[^\d.]/g, '');
+        // 限制只能有一个小数点
+        const dotCount = (value.match(/\./g) || []).length;
+        if (dotCount > 1) {
+          value = value.slice(0, value.lastIndexOf('.'));
+        }
+        // 限制不能以小数点开头
+        if (value.startsWith('.')) {
+          value = '0' + value;
+        }
+        // 更新绑定值
+        this.form[type] = value;
+        this.calculateWeight(type);
+      },
+      //计算重量
+      calculateWeight(type) {
+        let total =
+          this.form.qualifiedWeight - 0 + (this.form.unqualifiedWeight - 0);
+        if (total > this.current.weight) {
+          this.form[type] = 0;
+          this.$message.warning('合格重量加不合格重量不能大于任务重量');
+        }
+      },
+      // 计算数量
+      calculateQuantity(type) {
+        let total =
+          this.form.qualifiedQuantity - 0 + (this.form.unqualifiedQuantity - 0);
+        if (total > this.current.quantity) {
+          this.form[type] = 0;
+          this.$message.warning('合格数量加不合格数量不能大于任务数量');
+        }
+      },
+      // 数量正则 quantity
+      handleQuantityInput(e, type) {
+        // 过滤非数字字符(包括负号)
+        let value = e.replace(/[^\d]/g, '');
+        // 限制不能以 0 开头(除非是 0 本身)
+        if (value.startsWith('0') && value.length > 1) {
+          value = value.slice(1);
+        }
+        // 更新绑定值
+        this.form[type] = value;
+        this.calculateQuantity(type);
+      },
+      submitAdd() {
+        this.$refs.form.validate((valid) => {
+          if (!valid) return;
+          if (
+            this.form.qualifiedQuantity -
+              0 +
+              (this.form.unqualifiedQuantity - 0) !==
+            this.current.quantity
+          ) {
+            return this.$message.warning('合格数量加不合格数量要等于任务数量');
+          }
+          if (
+            this.form.qualifiedWeight -
+              0 +
+              (this.form.unqualifiedWeight - 0) !==
+            this.current.weight
+          ) {
+            return this.$message.warning('合格重量加不合格重量要等于任务重量');
+          }
+          let data = {
+            ...this.form,
+            apsAssigneeId:this.current.apsAssigneeId
+          }
+          this.loadingBtn = true;
+          batchUpdateRealTime([data]).then((res)=>{
+            this.loadingBtn = false;
+            if (res){
+              this.$message.success('操作成功');
+              this.cancel();
+              this.$emit('success');
+            }
+          }).catch((err)=>{
+            this.loadingBtn = false;
+            this.$message.error(err.message);
+          })
+        });
+      }
+    }
+  };
+</script>
+
+<style scoped lang="scss">
+  ::v-deep .time_select {
+    width: 100%;
+  }
+</style>

+ 95 - 0
src/views/taskList/components/ModifyRecord.vue

@@ -0,0 +1,95 @@
+<template>
+  <ele-pro-table ref="fileTable" :columns="columns1" :datasource="list">
+  </ele-pro-table>
+</template>
+
+<script>
+  export default {
+    props: {
+      list: {
+        type: Array,
+        default: () => []
+      }
+    },
+    watch: {
+      list: {
+        handler(newVal) {
+          this.list = newVal;
+        },
+        immediated: true,
+        deep: true
+      }
+    },
+    data() {
+      return {
+        columns1: [
+          {
+            label: '序号',
+            type: 'index',
+            width: 60,
+            align: 'center'
+          },
+          {
+            label: '实际开始时间',
+            prop: 'realStartTime',
+            minWidth: 150,
+            align: 'center',
+            showOverflowTooltip: true
+          },
+          {
+            label: '实际开始时间',
+            prop: 'realStartTime',
+            minWidth: 150,
+            align: 'center',
+            showOverflowTooltip: true
+          },
+          {
+            label: '合格数量',
+            prop: 'qualifiedQuantity',
+            minWidth: 100,
+            align: 'center',
+            showOverflowTooltip: true
+          },
+          {
+            label: '不合格数量',
+            prop: 'unqualifiedQuantity',
+            minWidth: 100,
+            align: 'center',
+            showOverflowTooltip: true
+          },
+          {
+            label: '合格重量(kg)',
+            prop: 'qualifiedWeight',
+            minWidth: 100,
+            align: 'center',
+            showOverflowTooltip: true
+          },
+          {
+            label: '不合格重量(kg)',
+            prop: 'unqualifiedWeight',
+            minWidth: 100,
+            align: 'center',
+            showOverflowTooltip: true
+          },
+          {
+            label: '备注信息',
+            prop: 'remark',
+            minWidth: 220,
+            align: 'center',
+            showOverflowTooltip: true
+          },
+          {
+            label: '工时',
+            prop: 'durationText',
+            width: 150,
+            align: 'center',
+            showOverflowTooltip: true
+          }
+        ]
+      };
+    },
+    computed: {},
+    methods: {}
+  };
+</script>
+<style scoped lang="scss"></style>

+ 50 - 0
src/views/taskList/components/modifyDialog.vue

@@ -0,0 +1,50 @@
+<template>
+  <ele-modal
+    :centered="true"
+    :close-on-click-modal="false"
+    :maxable="true"
+    :title="title"
+    :visible.sync="detailsVisible"
+    append-to-body
+    custom-class="ele-dialog-form long-dialog-form"
+    width="55%"
+    @close="handleClose"
+  >
+    <ModifyRecord :list="list" />
+    <div slot="footer" class="footer">
+      <el-button @click="handleClose">返回</el-button>
+    </div>
+  </ele-modal>
+</template>
+<script>
+  import ModifyRecord from './ModifyRecord.vue';
+
+  export default {
+    components: {
+      ModifyRecord
+    },
+    data() {
+      return {
+        list: [],
+        detailsVisible: false
+      };
+    },
+    methods: {
+      handleClose() {
+        this.detailsVisible = false;
+        this.list = [];
+      },
+      open(list = []){
+        this.detailsVisible = true;
+        this.list = list;
+      }
+    },
+    watch: {},
+    props: {
+      title: {
+        type: String,
+        default: '修改记录'
+      },
+    }
+  };
+</script>

+ 62 - 0
src/views/taskList/components/task-search.vue

@@ -0,0 +1,62 @@
+<!-- 搜索表单 -->
+<template>
+  <seekPage :seekList="seekList" :formLength="3" @search="search"></seekPage>
+</template>
+<script>
+  export default {
+    data() {
+      return {};
+    },
+    props: {
+      levelList: {
+        type: Array,
+        default: () => []
+      }
+    },
+    computed: {
+      // 表格列配置
+      seekList() {
+        return [
+          {
+            label: '工作中心名称:',
+            value: 'workCenterName',
+            type: 'input',
+            placeholder: ''
+          },
+          {
+            label: '班组名称:',
+            value: 'teamName',
+            type: 'input',
+            placeholder: ''
+          },
+          {
+            label: '产品名称:',
+            value: 'productName',
+            type: 'input',
+            placeholder: ''
+          },
+          {
+            label: '工序名称:',
+            value: 'workTaskName',
+            type: 'input',
+            placeholder: ''
+          },
+          {
+            label: '工单编码:',
+            value: 'workOrderCode',
+            type: 'input',
+            placeholder: ''
+          }
+        ];
+      }
+    },
+    methods: {
+      /* 搜索 */
+      search(e) {
+        this.$emit('search', {
+          ...e
+        });
+      }
+    }
+  };
+</script>

+ 396 - 0
src/views/taskList/index.vue

@@ -0,0 +1,396 @@
+<template>
+  <div class="ele-body">
+    <el-card v-loading="loading" shadow="never">
+      <task-search @search="reload"></task-search>
+      <!-- <taskDialog-search></taskDialog-search> -->
+      <el-tabs v-model="tabValue" type="card" @tab-click="handleTabClick">
+        <el-tab-pane label="我的任务" name="1"></el-tab-pane>
+        <el-tab-pane label="全部任务" name="2"></el-tab-pane>
+      </el-tabs>
+    </el-card>
+    <ele-pro-table
+      ref="table"
+      :columns="columns"
+      :datasource="datasource"
+      :pageSize="20"
+      cache-key="workOrderTable"
+      class="my_pro_table"
+      row-key="id"
+    >
+      <template v-slot:assignCode="{ row }">
+        <el-link
+          :underline="false"
+          type="primary"
+          @click="details('assign', row)"
+          >{{ row.assignCode }}
+        </el-link>
+      </template>
+      <template v-slot:workOrderCode="{ row }">
+        <el-link
+          :underline="false"
+          type="primary"
+          @click="details('assign', row)"
+          >{{ row.workOrderCode }}
+        </el-link>
+      </template>
+      <template v-slot:action="{ row }">
+        <el-link
+          :underline="false"
+          type="primary"
+          @click="details('report', row)"
+          >报工
+        </el-link>
+        <el-link
+          :underline="false"
+          type="primary"
+          @click="viewRecords(row.id)"
+        >修改记录
+        </el-link>
+      </template>
+    </ele-pro-table>
+    <modifyDialog ref="modifyRef" />
+    <Ddtails ref="detailsRef" @success="reload" />
+  </div>
+</template>
+
+<script>
+  import TaskSearch from './components/task-search.vue';
+  import Ddtails from './components/Ddtails.vue';
+  import modifyDialog from '@/views/taskList/components/modifyDialog.vue';
+  import {
+    pageByCurrentUser,
+    pageByCurrentUserLeader,
+    listUpdateRealTimeRecord
+  } from '@/api/workOrderList';
+
+  export default {
+    components: { TaskSearch, Ddtails,modifyDialog },
+    data() {
+      return {
+        loading: false,
+        tabValue: '1',
+        statusOpt: [
+          { label: '待生产', value: 4 },
+          { label: '生产中', value: 5 },
+          { label: '待下达', value: 8 }
+        ]
+      };
+    },
+    computed: {
+      // 表格列配置
+      columns() {
+        return [
+          {
+            columnKey: 'index',
+            label: '序号',
+            type: 'index',
+            width: 55,
+            align: 'center',
+            showOverflowTooltip: true,
+            fixed: 'left'
+          },
+          {
+            slot: 'assignCode',
+            prop: 'assignCode',
+            label: '任务编码',
+            align: 'center',
+            showOverflowTooltip: true,
+            width: 210
+          },
+          {
+            slot: 'workOrderCode',
+            prop: 'workOrderCode',
+            label: '生产订单编码',
+            align: 'center',
+            showOverflowTooltip: true,
+            width: 210
+          },
+          {
+            prop: 'mesWorkOrderCode',
+            label: '生产工单编码',
+            align: 'center',
+            showOverflowTooltip: true,
+            width: 210
+          },
+          {
+            prop: 'productionPlanCode',
+            label: '计划编号',
+            align: 'center',
+            showOverflowTooltip: true,
+            width: 170
+          },
+          {
+            prop: 'assigneeType',
+            label: '执行类型',
+            align: 'center',
+            showOverflowTooltip: true,
+            width: 120,
+            formatter: (row) => {
+              if (!row.assigneeType) return '';
+              return row.assigneeType.desc;
+            }
+          },
+          {
+            prop: 'assigneeName',
+            label: '执行对象名称',
+            align: 'center',
+            showOverflowTooltip: true,
+            width: 180
+          },
+          {
+            prop: 'workCenterName',
+            label: '工作中心',
+            align: 'center',
+            width: 180,
+            showOverflowTooltip: true
+          },
+          {
+            prop: 'assignTeamName',
+            label: '班组名称',
+            align: 'center',
+            showOverflowTooltip: true,
+            width: 180
+          },
+          {
+            prop: 'taskName',
+            label: '工序名称',
+            align: 'center',
+            showOverflowTooltip: true,
+            width: 150
+          },
+          {
+            prop: 'produceRoutingName',
+            label: '工艺路线',
+            align: 'center',
+            showOverflowTooltip: true,
+            width: 170
+          },
+          {
+            prop: 'productCode',
+            label: '产品编码',
+            align: 'center',
+            showOverflowTooltip: true,
+            width: 170
+          },
+          {
+            prop: 'productName',
+            label: '产品名称',
+            align: 'center',
+            showOverflowTooltip: true,
+            width: 200
+          },
+          {
+            prop: 'productionCodes',
+            label: '生产编号',
+            align: 'center',
+            showOverflowTooltip: true,
+            width: 170
+          },
+          {
+            prop: 'brandNo',
+            label: '牌号',
+            align: 'center',
+            showOverflowTooltip: true,
+            width: 170
+          },
+          {
+            prop: 'batchNo',
+            label: '批次号',
+            align: 'center',
+            width: 100,
+            showOverflowTooltip: true
+          },
+          {
+            prop: 'model',
+            label: '型号',
+            align: 'center',
+            width: 200,
+            showOverflowTooltip: true
+          },
+          {
+            prop: 'formingNum',
+            label: '要求生产数量',
+            align: 'center',
+            showOverflowTooltip: true,
+            width: 110
+          },
+          {
+            prop: 'formingWeight',
+            label: '要求生产重量',
+            align: 'center',
+            showOverflowTooltip: true,
+            width: 110,
+            slot: 'formingWeight'
+          },
+          {
+            prop: 'planStartTime',
+            label: '计划开始时间',
+            align: 'center',
+            showOverflowTooltip: true,
+            width: 180
+          },
+
+          {
+            prop: 'planCompleteTime',
+            label: '计划结束时间',
+            align: 'center',
+            showOverflowTooltip: true,
+            width: 180
+          },
+          {
+            prop: 'startTime',
+            label: '任务开始时间',
+            align: 'center',
+            showOverflowTooltip: true,
+            width: 180
+          },
+
+          {
+            prop: 'endTime',
+            label: '任务结束时间',
+            align: 'center',
+            showOverflowTooltip: true,
+            width: 180
+          },
+          {
+            prop: 'firstTaskName',
+            label: '首工序',
+            align: 'center',
+            width: 180,
+            showOverflowTooltip: true
+          },
+          {
+            prop: 'createTime',
+            label: '创建时间',
+            align: 'center',
+            showOverflowTooltip: true,
+            width: 180
+          },
+          {
+            slot: 'status',
+            label: '状态',
+            align: 'center'
+            // formatter: (row) => {
+            //   const obj = this.statusOpt.find((i) => i.value == row.status);
+            //   return obj && obj.label;
+            // },
+            // width: 120
+          },
+          {
+            prop: 'customerName',
+            label: '客户名称',
+            align: 'center',
+            showOverflowTooltip: true,
+            width: 180
+          },
+          {
+            prop: 'serialNo',
+            label: '客户代号',
+            align: 'center',
+            showOverflowTooltip: true,
+            width: 180
+          },
+
+          {
+            prop: 'simpleName',
+            label: '客户简称',
+            align: 'center',
+            showOverflowTooltip: true,
+            width: 180
+          },
+          {
+            columnKey: 'action',
+            label: '操作',
+            width: 150,
+            align: 'center',
+            resizable: false,
+            fixed: 'right',
+            slot: 'action'
+          }
+        ];
+      }
+    },
+    created() {},
+    mounted() {
+
+    },
+    methods: {
+      handleTabClick(e) {
+        this.tabValue = e.name;
+        this.reload();
+      },
+      /* 表格数据源 */
+      datasource({ page, limit, where }) {
+        let api =
+          this.tabValue === '1' ? pageByCurrentUser : pageByCurrentUserLeader;
+        return api({
+          ...where,
+          pageNum: page,
+          size: limit
+        });
+      },
+      reload(where) {
+        this.$refs.table.reload({ page: 1, where });
+      },
+      details(type, row) {
+        let currentRow = {
+          assignCode: row.assignCode,
+          workOrderCode: row.workOrderCode,
+          productionPlanCode: row.productionPlanCode,
+          produceRoutingName: row.produceRoutingName,
+          formingNum: row.formingNum,
+          assignTeamName: row.assignTeamName,
+          formingWeight: row.formingWeight,
+          planStartTime: row.planStartTime,
+          planCompleteTime: row.planCompleteTime,
+          startTime: row.startTime,
+          firstTaskId: row.firstTaskId,
+          endTime: row.endTime,
+          taskName: row.taskName,
+          firstTaskName: row.firstTaskName,
+          assigneeType: row.assigneeType ? row.assigneeType.desc : '',
+          assigneeName: row.assigneeName,
+          weight: row.weight,
+          quantity: row.quantity,
+          durationText:row.durationText,
+          apsAssigneeId: row.id
+        };
+        let form = {
+          realEndTime: row.realEndTime,
+          realStartTime: row.realStartTime,
+          unqualifiedWeight: row.unqualifiedWeight,
+          unqualifiedQuantity: row.unqualifiedQuantity,
+          qualifiedWeight: row.qualifiedWeight,
+          remark: row.assigneeRemark,
+          qualifiedQuantity: row.qualifiedQuantity,
+        }
+        this.$refs.detailsRef.open(type, currentRow,form);
+      },
+      viewRecords(apsAssigneeId){
+        listUpdateRealTimeRecord(apsAssigneeId).then(res => {
+          if (res && res.length > 0){
+            this.$refs.modifyRef.open(res)
+          }else{
+            this.$message.warning('暂无修改历史记录数据')
+          }
+        }).catch((err)=>{
+          this.$message.error(err.message)
+        })
+      }
+    }
+  };
+</script>
+
+<style lang="scss" scoped>
+  .ele-body {
+    height: 100%;
+
+    .my_pro_table {
+      height: calc(100% - 136px);
+    }
+  }
+
+  ::v-deep .el-table {
+    height: calc(100% - 96px);
+  }
+</style>