<template>
|
<div class="task-control-modal">
|
<BaseModal v-model="modelData" :wider="false">
|
<template #title>新任务</template>
|
<div class="modal-content">
|
<div v-if="!messageError" class="content-title">
|
<div class="content-title-item">当前任务:{{ task?.Procedure.procedure.procedureName || '' }}</div>
|
<div class="content-title-item">
|
生产数量:
|
<div class="leaf-shape box">
|
{{ task?.Order?.amount || 0 }}
|
</div>
|
</div>
|
</div>
|
|
<div v-if="!!messageError" class="content-tips">
|
<div class="error-t">
|
<span v-if="messageError === '下发成功!'" class="el-icon-success color_success"></span>
|
<span v-else class="el-icon-error color_error"></span>
|
</div>
|
<div class="error-m">
|
{{ messageError }}
|
</div>
|
<div class="font_size_20 color_fff" style="text-align: center; width: 100%; margin: 10px 0">
|
<span v-if="messageError === '下发成功!'" style="font-size: 30px"></span>
|
<span v-else>请重试</span>
|
</div>
|
</div>
|
|
<div v-else class="content-scroll">
|
<div class="scroll-container">
|
<el-scrollbar always class="scroller">
|
<template v-if="task">
|
<div class="info">
|
<div class="info-item">订单编号:{{ task.Order.orderId || '' }}</div>
|
<div class="info-item">工单编号:{{ task.Order.workOrderId || '' }}</div>
|
<div class="info-item">产品名称:{{ task.Order.productName || '' }}</div>
|
<div class="info-item">数量:{{ task.Order.amount || 0 }}{{ task.Order.unit }}</div>
|
<div class="info-item">交货日期:{{ task.Order.deliverDate || '' }}</div>
|
<div class="info-item">工时: {{ task.Procedure.procedure.workHours || '' }}</div>
|
<div class="info-item">
|
计划时间: {{ formatDate(task.Procedure.startTime) || '' }}
|
-
|
{{ formatDate(task.Procedure.endTime) }}
|
</div>
|
|
<div class="info-item">客户名称:{{ task.Order.customer || '' }}</div>
|
<div class="info-item info-item-two">通道: {{ CHANNEL_NAME_MAP[task.Channel] || '' }}</div>
|
|
<div class="info-item info-item-two">参数要求:{{ task.Order.parameter || '' }}</div>
|
|
<div class="info-item-two">
|
<div style="color: #4efefa; font-size: 18px; margin-bottom: 10px; margin-top: 20px">工艺参数</div>
|
<div v-for="(item, index) in craftParams" :key="index" class="info-item info-item-two">
|
{{ item.Key }}:{{ item.Value || '' }}
|
</div>
|
</div>
|
</div>
|
|
<div class="title-auto-box"></div>
|
<div v-if="getCraftParamsErrMsg" class="process-err-tip">
|
<div class="tip-icon">
|
<span class="el-icon-error color_error"></span>
|
</div>
|
<div class="tip-content">提示: {{ getCraftParamsErrMsg }}</div>
|
</div>
|
|
<div v-if="countdown30s.countdownStatus.value === 'running'" class="countdown">
|
{{ countdown30s.formattedTime.value }}
|
</div>
|
|
<!-- <div v-if="showBtn === 2 || showBtn === 3" class="process-box">-->
|
<!-- <div-->
|
<!-- style="-->
|
<!-- color: red;-->
|
<!-- font-size: 26px;-->
|
<!-- width: 100%;-->
|
<!-- text-align: center;-->
|
<!-- margin-bottom: 15px;-->
|
<!-- line-height: 35px;-->
|
<!-- "-->
|
<!-- :class="showBtn === 3 && isLoading ? 'margin-top-10px' : 'margin-top-40px'"-->
|
<!-- >-->
|
<!-- <div v-if="showBtn === 2 || (showBtn === 3 && !isLoading)" class="gif-box">-->
|
<!-- <template v-if="showBtn === 2">-->
|
<!-- <div class="gif">-->
|
<!-- <img src="../../public/shan.gif" />-->
|
<!-- </div>-->
|
<!-- </template>-->
|
<!-- <template v-if="showBtn === 3 && !isLoading">-->
|
<!-- <div class="gif">-->
|
<!-- <span class="yuandian"></span>-->
|
<!-- </div>-->
|
<!-- </template>-->
|
<!-- <div class="gif-right">-->
|
<!-- <div>----- 剩余时间 -----</div>-->
|
<!-- <div>-->
|
<!-- <span>00:{{ countdown30s.formattedTime }}</span>-->
|
<!-- </div>-->
|
<!-- </div>-->
|
<!-- </div>-->
|
<!-- {{ message }}-->
|
<!-- </div>-->
|
<!-- <template v-if="showBtn === 3 && isLoading">-->
|
<!-- <div class="progress-item">-->
|
<!-- <span>{{ (+num / 30) * 100 }}%</span>-->
|
<!-- <el-progress-->
|
<!-- style="width: calc(100% - 50px); float: right"-->
|
<!-- define-back-color="#CDC6C6"-->
|
<!-- color="#00cc66"-->
|
<!-- text-color="#fff"-->
|
<!-- :text-inside="true"-->
|
<!-- :stroke-width="20"-->
|
<!-- :percentage="(+num / 30) * 100"-->
|
<!-- ></el-progress>-->
|
<!-- </div>-->
|
<!-- </template>-->
|
<!-- </div>-->
|
</template>
|
</el-scrollbar>
|
</div>
|
</div>
|
</div>
|
<template #footer>
|
<div class="btn">
|
<BigButton bg-color="#4765c0" @click="closeModal">暂缓生产</BigButton>
|
<BigButton
|
v-if="countdown30s.countdownStatus.value !== 'complete'"
|
color="#0d0d0d"
|
:disabled="countdown30s.countdownStatus.value === 'running'"
|
@click="startCountdown30s"
|
>
|
生产准备
|
</BigButton>
|
<BigButton v-if="countdown30s.countdownStatus.value === 'complete'" bg-color="#4efefa" @click="startProduce">
|
开始生产
|
</BigButton>
|
</div>
|
</template>
|
</BaseModal>
|
</div>
|
</template>
|
<script setup lang="ts">
|
import type { CraftParam, Task } from '@/api/task'
|
import { useDateFormat, useVModel } from '@vueuse/core'
|
import { computed, ref, toRefs, watch } from 'vue'
|
import BigButton from '@/views/dashboard/components/BigButton.vue'
|
import { CHANNEL_NAME_MAP } from '@/common/constants'
|
import { getCraftParams, sendProcessParams } from '@/api'
|
import { useCountDown } from '@/common/composable'
|
import { storeToRefs } from 'pinia'
|
import { useTasksStore } from '@/stores/tasks'
|
|
export interface TaskControlModalProps {
|
task?: Task
|
/** 是否展示模态框 */
|
modelValue: boolean
|
}
|
const props = withDefaults(defineProps<TaskControlModalProps>(), {
|
task: undefined,
|
modelValue: false
|
})
|
const emit = defineEmits<{
|
'update:modelValue': [show: boolean]
|
}>()
|
|
const modelData = useVModel(props, 'modelValue', emit)
|
function closeModal() {
|
modelData.value = false
|
}
|
const { task } = toRefs(props)
|
|
const messageError = ref('')
|
|
/**
|
* 格式化时间戳
|
* @param timestamp 后端返的10位时间戳
|
*/
|
function formatDate(timestamp?: number) {
|
if (!timestamp) {
|
return '--'
|
}
|
const time = useDateFormat(timestamp * 1000, 'YYYY-MM-DD', { locales: 'zh-cn' })
|
return time.value
|
}
|
|
// 工艺参数
|
const craftParams = ref<CraftParam[]>()
|
// 获取工艺参数失败信息
|
const getCraftParamsErrMsg = ref('')
|
|
/**
|
* 获取当前展示的任务的工艺参数
|
*/
|
function getTaskProduceParams(taskId?: number) {
|
if (taskId) {
|
craftParams.value = []
|
getCraftParamsErrMsg.value = ''
|
getCraftParams({ id: taskId }).then(
|
(res) => {
|
craftParams.value = res.data.Params ?? []
|
getCraftParamsErrMsg.value = ''
|
// TODO: 处理各个按钮显隐
|
// this.getInfo()
|
console.log('processParams', craftParams.value)
|
},
|
(err) => {
|
console.error(err)
|
craftParams.value = []
|
getCraftParamsErrMsg.value = '获取工艺参数失败!'
|
}
|
)
|
}
|
}
|
|
watch(modelData, () => {
|
// 弹窗显示时获取工艺参数
|
if (modelData.value) {
|
getTaskProduceParams(task?.value?.Procedure?.ID)
|
}
|
})
|
|
const countdown30s = useCountDown(3)
|
|
function startCountdown30s() {
|
countdown30s.startCountdown()
|
}
|
|
/**
|
* 下发工艺参数
|
*/
|
function startProduce() {
|
if (task.value?.Procedure?.ID) {
|
message.value = '工艺参数下发中...'
|
|
isLoading.value = true
|
sendProcessParams({
|
procedureId: task.value.Procedure.ID
|
})
|
.then(
|
(res) => {
|
console.log(res)
|
messageError.value = '下发成功'
|
},
|
(err) => {
|
console.error(err)
|
messageError.value = err.msg ? err.msg : '抱歉,工序下发失败!'
|
}
|
)
|
.finally(() => {
|
isLoading.value = false
|
})
|
}
|
}
|
|
const { channels } = storeToRefs(useTasksStore())
|
const safeProduce = computed(() => {
|
if (task?.value?.Channel) {
|
return channels?.value?.[task.value.Channel]?.Prompt?.safeProduce
|
}
|
return ''
|
})
|
const message = ref(safeProduce.value)
|
const isLoading = ref(false)
|
</script>
|
<style scoped lang="scss">
|
.modal-content {
|
height: 550px;
|
}
|
.content-scroll {
|
height: 400px;
|
overflow: hidden;
|
}
|
:deep(.el-dialog__body) {
|
padding: 0 20px;
|
}
|
.btn {
|
display: flex;
|
align-items: center;
|
justify-content: space-around;
|
}
|
.content-title {
|
display: flex;
|
align-items: center;
|
justify-content: space-between;
|
padding: 10px 40px;
|
}
|
.content-title-item {
|
width: 50%;
|
font-size: 20px;
|
color: #4efefa;
|
}
|
|
.leaf-shape {
|
position: relative;
|
display: inline-block;
|
width: 140px;
|
height: 46px;
|
border-radius: 23px 0 23px 0;
|
text-align: center;
|
line-height: 46px;
|
color: #fff;
|
background: url('/leaf-shape.png') no-repeat center center / cover;
|
}
|
.scroll-container {
|
margin: 0 auto;
|
padding: 10px 20px;
|
width: calc(100% - 40px);
|
height: 400px;
|
}
|
.info {
|
display: flex;
|
align-items: center;
|
flex-wrap: wrap;
|
background-color: #0e246a;
|
padding: 10px 20px;
|
}
|
.info-item {
|
width: 50%;
|
height: 35px;
|
line-height: 35px;
|
font-size: 16px;
|
color: #fff;
|
}
|
.info-item-two {
|
width: 100%;
|
}
|
</style>
|