charles
2024-04-29 b95cf940af8e01e4eca30b2599b029c2f645bd1e
src/views/dashboard/components/TaskControl.vue
@@ -21,29 +21,147 @@
        开始生产
      </BigButton>
      <template v-if="task?.Procedure.Status === 2 || task?.Procedure.Status === 3">
        <BigButton class="btn" bg-color="#ff9933">打印</BigButton>
        <BigButton class="btn" bg-color="#00cc33">报工</BigButton>
        <BigButton class="btn" bg-color="#ff0000">完成</BigButton>
        <BigButton class="btn" bg-color="#ff9933" :disabled="task?.Procedure.Status === 3">打印</BigButton>
        <BigButton
          v-if="task?.ShowCheck"
          class="btn"
          bg-color="#00cc33"
          :disabled="task?.Procedure.Status === 3"
          @click="openQualityModal"
          >质检</BigButton
        >
        <BigButton
          class="btn"
          :bg-color="task?.ShowCheck ? '#0066ff' : '#00cc33'"
          :disabled="task?.Procedure.Status === 3"
          @click="openReportModal"
        >
          报工
        </BigButton>
        <el-popconfirm
          width="340"
          confirm-button-text="确定"
          cancel-button-text="取消"
          :icon="CircleCloseFilled"
          icon-color="red"
          :hide-after="0"
          :teleported="false"
          :title="Number(processingPercent) < 100 ? '进度未完成,是否提前完成任务?' : '请确认是否已完成此生产任务?'"
          placement="top"
          @confirm="finishTaskProduce"
        >
          <template #reference>
            <BigButton class="btn" bg-color="#ff0000" :disabled="task?.Procedure.Status === 3">完成</BigButton>
          </template>
        </el-popconfirm>
      </template>
    </div>
  </div>
  <TaskControlModal v-model="showTaskControlModal" :task="task" @produce-start="onProduceStart"></TaskControlModal>
  <ReportProductionModal
    v-model="showReportModal"
    :model-title="modelTitle"
    :amount="plcInfo?.finishNumber ?? 0"
    @close="showReportModal = false"
    @submit="onReportProduction"
  ></ReportProductionModal>
  <ReportProductionModal1
    v-model="showReportModal1"
    :model-title="modelTitle"
    :amount="plcInfo?.finishNumber ?? 0"
    :pass-amount="passAmount"
    :rework-amount="reworkAmount"
    :scrapped-amount="scrappedAmount"
    @close="showReportModal1 = false"
    @submit="onReportCheck"
  ></ReportProductionModal1>
</template>
<script setup lang="ts">
import type { Task } from '@/api/task'
import { toRefs } from 'vue'
import type { Task, Worker } from '@/api/task'
import { ref, toRefs, computed } from 'vue'
import BigButton from '@/views/dashboard/components/BigButton.vue'
import { useDateFormat } from '@vueuse/core'
import TaskControlModal from '@/views/dashboard/components/TaskControlModal.vue'
import { CircleCloseFilled } from '@element-plus/icons-vue'
import { apiReportWork, procedureUpdate, bulletinReport, bulletinQualityInspection, getQualityInspection } from '@/api'
import { ElMessage } from 'element-plus'
import ReportProductionModal from '@/views/dashboard/components/ReportProductionModal.vue'
import ReportProductionModal1 from '@/views/dashboard/components/ReportProductionModal1.vue'
import { usePLCStore } from '@/stores/plc'
import { storeToRefs } from 'pinia'
const props = defineProps<{
  task?: Task
  workers: Worker[]
}>()
const { task } = toRefs(props)
const { task, workers } = toRefs(props)
const emit = defineEmits<{
  shouldReload: [task: Task]
}>()
const showTaskControlModal = ref(false)
const modelTitle = ref('')
const passAmount = ref(0)
const reworkAmount = ref(0)
const scrappedAmount = ref(0)
/**
 * 开始生产
 */
function startProduce() {
  // TODO:
  // console.log(1)
  showTaskControlModal.value = true
}
/**
 * 完成任务
 */
function finishTaskProduce() {
  if (task?.value && task.value?.Procedure?.ID) {
    //点击的时候不能比实际开始时间大于1分钟
    let realStartTime = task.value?.Procedure?.realStartTime
    if (realStartTime) {
      realStartTime = realStartTime * 1000
      let time = Date.now()
      let differ = Math.abs(time - realStartTime) / 1000
      if (differ < 60) {
        ElMessage({
          message: '工序制造时间太短,请检查!',
          type: 'warning'
        })
        return true
      }
    }
    procedureUpdate({
      isFinish: true,
      isProcessing: false,
      workOrderProcedureID: Number(task!.value.Procedure.ID)
    }).then(
      (res: any) => {
        ElMessage({
          message: '操作成功!',
          type: 'success'
        })
        emit('shouldReload', task.value as Task)
      },
      (err) => {
        console.error(err)
        ElMessage({
          message: '操作失败!',
          type: 'warning'
        })
      }
    )
  } else {
    ElMessage({
      message: '当前设备没有工序!',
      type: 'warning'
    })
  }
}
function onProduceStart() {
  emit('shouldReload', task!.value as Task)
}
/**
@@ -54,9 +172,198 @@
  if (!timestamp) {
    return '--'
  }
  const time = useDateFormat(timestamp * 1000, 'YYYY-MM-DD', { locales: 'zh-cn' })
  const time = useDateFormat(timestamp * 1000, 'YYYY-MM-DD HH:mm:ss', { locales: 'zh-cn' })
  return time.value
}
const plcStore = usePLCStore()
const { plcInfo } = storeToRefs(plcStore)
// 报工
const showReportModal = ref(false)
// 报工
const showReportModal1 = ref(false)
const reprotIds = ref([])
const passCount = ref(0)
function openReportModal() {
  // 有人员才可以报工
  if (!workers.value || workers.value.length == 0) {
    ElMessage({
      message: '没有人员信息不允许手动报工!',
      type: 'error',
      duration: 3000
    })
    return true
  }
  // 从开始生产到报工的点击时间不能小于1分钟
  if (task?.value && task.value?.Procedure?.realStartTime) {
    let realStartTime = task.value?.Procedure?.realStartTime
    if (realStartTime) {
      realStartTime = realStartTime * 1000
      let time = Date.now()
      let differ = Math.abs(time - realStartTime) / 1000
      if (differ < 60) {
        ElMessage({
          message: '工序制造时间太短,请检查!',
          type: 'warning'
        })
        return true
      }
    }
  }
  if (workers.value[0].workerId) {
    modelTitle.value = '生产报工'
    if (task?.value?.ShowCheck) {
      getQualityInspection({
        procedureId: task.value?.Procedure?.procedure.procedureId,
        workOrderId: task.value?.Order.workOrderId
      }).then((res: any) => {
        console.log(res, '999999')
        passAmount.value = res.data.passAmount
        passCount.value = res.data.passAmount
        reworkAmount.value = res.data.reworkAmount
        scrappedAmount.value = res.data.scrappedAmount
        reprotIds.value = res.data.ids || []
        showReportModal1.value = true
      })
    } else {
      showReportModal.value = true
    }
  }
}
// 质检
function openQualityModal() {
  // 有人员才可以报工
  if (!workers.value || workers.value.length == 0) {
    ElMessage({
      message: '没有人员信息不允许质检!',
      type: 'error',
      duration: 3000
    })
    return true
  }
  if (workers.value[0].workerId) {
    modelTitle.value = '提交质检'
    showReportModal.value = true
  }
}
/**
 * 上报加工数
 * @param amount 加工数
 */
function onReportProduction(amount: number) {
  if (!task?.value) {
    return
  }
  // 有人员才可以报工
  if (workers.value[0].workerId) {
    let requestUrl = task?.value.ShowCheck ? bulletinQualityInspection : apiReportWork
    let tipStr = task?.value.ShowCheck ? '质检' : '报工'
    requestUrl({
      workOrderProcedureID: Number(task.value?.Procedure.ID),
      reportAmount: amount,
      workerID: workers.value[0].workerId,
      workerName: workers.value[0].workerName
    })
      .then((res: any) => {
        if (res.code === 200) {
          ElMessage({
            message: `${tipStr}成功`,
            type: 'success',
            duration: 2000
          })
          showReportModal.value = false
        } else {
          ElMessage({
            message: `${tipStr}失败`,
            type: 'error',
            duration: 3000
          })
        }
      })
      .catch((err) => {
        console.error(err)
      })
  }
}
/**
 * 质检后的上报加工数
 * @param amount 加工数
 */
function onReportCheck(amount: number) {
  if (!task?.value) {
    return
  }
  // 有人员才可以报工
  if (workers.value[0].workerId) {
    bulletinReport({
      workOrderProcedureID: Number(task.value?.Procedure.ID),
      reportAmount: passCount.value,
      workerID: workers.value[0].workerId,
      workerName: workers.value[0].workerName,
      ids: reprotIds.value
    })
      .then((res: any) => {
        if (res.code === 200) {
          ElMessage({
            message: '报工成功',
            type: 'success',
            duration: 2000
          })
          showReportModal1.value = false
        } else {
          ElMessage({
            message: '报工失败',
            type: 'error',
            duration: 3000
          })
        }
      })
      .catch((err) => {
        console.error(err)
      })
  }
}
export interface Statistics {
  totalNumber: number
  finishNumber: number
}
/**
 * 计算生产进度
 * @param statistics
 * @return 进度,0~100
 */
function calculateProgress(statistics: Statistics): number {
  if (!statistics) {
    return 0
  }
  if (statistics.finishNumber === 0) {
    return 0
  }
  if (statistics.finishNumber === statistics.totalNumber) {
    return 100
  }
  const result = Math.floor((statistics.finishNumber / statistics.totalNumber) * 100)
  return result > 100 ? 100 : result
}
const processingPercent = computed(() => {
  // if (task?.value?.Procedure?.Status === 1) {
  //   return 0
  // }
  if (task?.value?.Procedure?.Status === 3) {
    return 100
  }
  // if (task?.value?.Procedure?.Status === 2 || task?.value?.Procedure?.Status === 1) {
  //   return calculateProgress(plcStore.plcInfo as Statistics)
  // }
  return calculateProgress(plcStore.plcInfo as Statistics)
})
</script>
<style scoped lang="scss">
$title-text-color: #9599af;
@@ -67,10 +374,12 @@
  align-items: start;
  width: 100%;
}
.task-info,
.produce-btn {
  width: 50%;
.task-info {
  flex: 1;
  height: 100%;
}
.produce-btn {
  flex-shrink: 0;
  height: 100%;
}
.produce-btn {
@@ -85,7 +394,6 @@
.task-info-item {
  padding: 10px 20px;
  margin-bottom: 6px;
}
.task-info-title {
  font-size: 18px;
@@ -95,7 +403,7 @@
  font-size: 19px;
  color: $content-text-color;
  font-weight: 600;
  margin-top: 12px;
  margin-top: 4px;
}
.produce-btn {
  display: flex;
@@ -115,4 +423,41 @@
.finish-btn {
  background-color: #ff0000;
}
:deep(.el-popper) {
  background-color: #133f97;
  color: #fff;
}
:deep(.el-popconfirm__main) {
  font-size: 25px;
}
:deep(.el-popconfirm__icon) {
  font-size: 38px;
}
:deep(.el-popconfirm__main) {
  margin-bottom: 20px;
}
:deep(.el-popconfirm__action) {
  display: flex;
  align-items: center;
  justify-content: space-around;
}
:deep(.el-popconfirm__action .el-button) {
  font-size: 22px;
  height: 54px;
  width: 140px;
  color: #fff;
  background-color: #0ae5ec;
  &:hover {
    background-color: #0ae5ec;
  }
  &.is-text {
    color: #92a1c0;
    background-color: #133f97;
    border: 1px solid #0ae5ec;
    &:hover {
      background-color: #133f97;
    }
  }
}
</style>