This commit is contained in:
xhf 2025-02-14 11:44:55 +08:00
parent 168c463451
commit 18d5b74d17
6 changed files with 572 additions and 122 deletions

View File

@ -4,7 +4,7 @@ NODE_ENV=development
VITE_DEV=true
# 请求路径
VITE_BASE_URL='http://192.168.0.66:48080'
VITE_BASE_URL='http://192.168.0.74:48080'
# VITE_BASE_URL='http://192.168.0.189:48080'
# 文件上传类型server - 后端上传, client - 前端直连上传,仅支持 S3 服务

View File

@ -87,3 +87,7 @@ export const createOrEditOrDelHouseArea = async (data) => {
export const createOrEditOrDelHouseLane = async (data) => {
return await request.post({ url: `/system/ware/house-lane/createOrEditOrDel`, data })
}
//根据点位获取库位信息列表
export const houseLocationGetByMapItemId = async (params) => {
return await request.get({ url: `/system/ware/house-location/getByMapItemId`, params })
}

View File

@ -1,45 +1,40 @@
<template>
<ContentWrap>
<div>
<div class="new-top-box">
<div class="new-top-box-left">
<div class="new-top-box-left-title"> 车辆看板 </div>
<div class="new-top-box-left-statistics"> 总数 {{ carStatistics.total || 0 }} </div>
<div class="new-top-box-left-statistics" @click="changeRobotStatisticsType(undefined)" :style="{ background: queryParams.robotStatisticsType== undefined ? '#ebf1ff' : 'none' }"> 总数 {{ carStatistics.total || 0 }} </div>
<div class="grey-line"> </div>
<!-- <el-divider direction="vertical" /> -->
<div style="display: flex; align-items: center" v-if="carStatistics" >
<div class="new-top-box-left-item" style="color: #00329f">
<div style="display: flex; align-items: center" v-if="carStatistics">
<div class="new-top-box-left-item" @click="changeRobotStatisticsType('inTask')" style="color: #00329f" :style="{background:queryParams.robotStatisticsType== 'inTask' ? '#ebf1ff' : '' }">
<div class="new-top-box-left-item-name">工作</div>
<div class="new-top-box-left-item-value">{{ carStatistics.inTask || 0 }}</div>
</div>
<div class="grey-line"> </div>
<div class="new-top-box-left-item" style="color: #e07300;background: #EBF1FF;">
<div class="new-top-box-left-item" @click="changeRobotStatisticsType('charge')" style="color: #e07300; " :style="{background:queryParams.robotStatisticsType== 'charge' ? '#ebf1ff' : '' }">
<!-- background: #ebf1ff -->
<div class="new-top-box-left-item-name">充电</div>
<div class="new-top-box-left-item-value">{{ carStatistics.charge || 0 }}</div>
</div>
<div class="grey-line" > </div>
<div class="new-top-box-left-item" style="color: #c60606">
<div class="new-top-box-left-item-name">异常</div>
<div class="new-top-box-left-item-value">{{ carStatistics.fault || 0 }}</div>
</div>
<div class="grey-line" > </div>
<div class="new-top-box-left-item" style="color: #f1cd0b">
<div class="new-top-box-left-item-name">锁定</div>
<div class="new-top-box-left-item-value">{{ carStatistics.doLock || 0 }}</div>
</div>
<div class="grey-line" > </div>
<div class="new-top-box-left-item" style="color: #4dc606">
<div class="new-top-box-left-item-name">待命</div>
<div class="new-top-box-left-item-value">{{ carStatistics.standby || 0 }}</div>
</div>
<div class="grey-line"> </div>
<div class="new-top-box-left-item" style="color: #7a7a7a">
<div class="new-top-box-left-item" @click="changeRobotStatisticsType('fault')" style="color: #c60606" :style="{background:queryParams.robotStatisticsType== 'fault' ? '#ebf1ff' : '' }">
<div class="new-top-box-left-item-name">异常</div>
<div class="new-top-box-left-item-value">{{ carStatistics.fault || 0 }}</div>
</div>
<div class="grey-line"> </div>
<div class="new-top-box-left-item" @click="changeRobotStatisticsType('doLock')" style="color: #e07300" :style="{background:queryParams.robotStatisticsType== 'doLock' ? '#ebf1ff' : '' }" >
<div class="new-top-box-left-item-name">锁定</div>
<div class="new-top-box-left-item-value">{{ carStatistics.doLock || 0 }}</div>
</div>
<div class="grey-line"> </div>
<div class="new-top-box-left-item" @click="changeRobotStatisticsType('standby')" style="color: #4dc606" :style="{background:queryParams.robotStatisticsType== 'standby' ? '#ebf1ff' : '' }">
<div class="new-top-box-left-item-name">待命</div>
<div class="new-top-box-left-item-value">{{ carStatistics.standby || 0 }}</div>
</div>
<div class="grey-line"> </div>
<div class="new-top-box-left-item" @click="changeRobotStatisticsType('offline')" style="color: #cccccc" :style="{background:queryParams.robotStatisticsType== 'offline' ? '#ebf1ff' : '' }">
<div class="new-top-box-left-item-name">离线</div>
<div class="new-top-box-left-item-value">{{ carStatistics.offline || 0 }}</div>
</div>
@ -81,70 +76,137 @@
</ContentWrap>
<div class="new-list-box-all">
<div class="new-list-box">
<div class="item" v-for="(item, index) in list" :key="index">
<div
class="item"
v-for="(item, index) in list"
:key="index"
:style="{ background: item.robotEssenceStatus == 2 ? '#FFDFDF' : '#ffffff' }"
>
<div class="item-top">
<div class="item-inner-left-name">
<div class="item-inner-left-name-inner">
{{ item.robotNo }}
<div
class="item-inner-left-status"
:style="{ backgroundColor: item.onlineStatus == 0 ? '#CCCCCC' : '#52C41A' }"
>
</div>
<div class="item-inner-left-name">
<div
class="item-inner-left-name-inner"
:style="{ color: item.onlineStatus == 0 ? '#CCCCCC' : '#0D162A' }"
>
{{ item.robotNo }}
</div>
</div>
</div>
<div class="item-inner-right-top">
<div class="swiper-item-box-top-msg">
<el-dropdown>
<div style="flex-shrink: 0">
<el-icon size="20px"><MoreFilled /></el-icon>
</div>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item @click="openForm('update', item.id)">编辑</el-dropdown-item>
<el-dropdown-item @click="clockCar(item)">{{
item.status == 0 ? '解锁' : '锁定'
}}</el-dropdown-item>
<el-dropdown-item @click="deleteCar(item.id)">删除</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</div>
<div class="swiper-item-box-top-msg">
<el-dropdown>
<div style="flex-shrink: 0">
<el-icon size="20px"><MoreFilled /></el-icon>
</div>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item @click="openForm('update', item.id)">编辑</el-dropdown-item>
<el-dropdown-item @click="clockCar(item)">{{
item.status == 0 ? '解锁' : '锁定'
}}</el-dropdown-item>
<el-dropdown-item @click="deleteCar(item.id)">删除</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</div>
</div>
</div>
<div class="item-inner">
<div class="item-inner-left">
<div class="item-inner-left-img-box">
<el-image style="width: 100%; height: 100%" :src="item.url" :fit="'fill'" />
</div>
<div class="item-inner-left-bottom">
<div class="item-inner-left-bottom-btn" @click="goMap(item)"> 地图定位 </div>
<div class="item-inner-left-bottom-btn"> 日志查看 </div>
<div
class="item-inner-left-bottom-btn"
@click="goMap(item)"
:style="{ color: item.onlineStatus == 0 ? '#CCCCCC' : '#0D162A' }"
>
地图定位
</div>
<div
class="item-inner-left-bottom-btn"
:style="{ color: item.onlineStatus == 0 ? '#CCCCCC' : '#0D162A' }"
>
日志查看
</div>
</div>
</div>
<div class="item-inner-right-msg">
<div class="item-inner-right-msg" v-if="item.onlineStatus != 0">
<div class="item-inner-right-msg-item m-b-10">
<div class="item-inner-right-msg-item-name">电量</div>
<div class="item-inner-right-msg-item-value" :style="{color:item.electricity>20?'#4DC606':'#C60606'}" v-if="item.electricity">{{ item.electricity || '' }} %</div>
<div
class="item-inner-right-msg-item-value"
:style="{ color: item.electricity > 20 ? '#4DC606' : '#C60606' }"
v-if="item.electricity"
>{{ item.electricity || '' }} %</div
>
</div>
<div class="item-inner-right-msg-item m-b-10">
<div class="item-inner-right-msg-item-name">状态</div>
<div class="item-inner-right-msg-item-value" >
<span v-if="item.robotStatus == 0" style="color: #C60606;">待命</span>
<span v-if="item.robotStatus == 1" style="color: #F1CD0B;">暂停</span>
<span v-if="item.robotStatus == 2" style="color: #01D3D8;">工作中</span>
<span v-if="item.robotStatus == 3" style="color: #4DC606;">待命中</span>
<div class="item-inner-right-msg-item-name">车辆状态</div>
<div class="item-inner-right-msg-item-value">
<span v-if="item.robotEssenceStatus == 2" style="color: #c60606">异常</span>
<span v-if="item.robotEssenceStatus == 1" style="color: #f1cd0b">锁定</span>
<span v-if="item.robotEssenceStatus == 0" style="color: #4dc606">空闲</span>
</div>
</div>
<div class="item-inner-right-msg-item m-b-10">
<div class="item-inner-right-msg-item-name">任务状态</div>
<div class="item-inner-right-msg-item-value">
<span v-if="item.robotTaskStatus == 1" style="color: #f1cd0b">工作中</span>
<span v-if="item.robotTaskStatus == 0" style="color: #01d3d8">待命中</span>
<span v-if="item.robotTaskStatus == 2" style="color: #4dc606">充电中</span>
</div>
</div>
<div class="item-inner-right-msg-item m-b-10">
<div class="item-inner-right-msg-item-name">楼层</div>
<div class="item-inner-right-msg-item-value" v-if="item.floor!==null">{{ item.floor || '' }} </div>
<div class="item-inner-right-msg-item-value" v-if="item.floor !== null"
>{{ item.floor || '' }}
</div>
</div>
<div class="item-inner-right-msg-item m-b-10">
<div class="item-inner-right-msg-item-name">区域</div>
<div class="item-inner-right-msg-item-value" v-if="item.area!==null">{{ item.area || '' }} </div>
<div class="item-inner-right-msg-item-value" v-if="item.area !== null"
>{{ item.area || '' }}
</div>
</div>
<div class="item-inner-right-msg-item m-b-10">
<div class="item-inner-right-msg-item-name">信息</div>
<div class="item-inner-right-msg-item-value" v-if="item.msg!==null">{{ item.msg || '' }} </div>
<div class="item-inner-right-msg-item-value" v-if="item.msg !== null"
>{{ item.msg || '' }}
</div>
</div>
</div>
</div>
<div class="item-inner-right-msg" v-if="item.onlineStatus == 0">
<div class="item-inner-right-msg-item m-b-10" style="align-items: center">
<div class="item-inner-right-msg-item-name">电量</div>
<div style="width: 14px; height: 2px; background-color: #4dc606;margin-left: 10px;"> </div>
</div>
<div class="item-inner-right-msg-item m-b-10" style="align-items: center">
<div class="item-inner-right-msg-item-name">车辆状态</div>
<div style="width: 14px; height: 2px; background-color: #C60606;margin-left: 10px;"> </div>
</div>
<div class="item-inner-right-msg-item m-b-10" style="align-items: center">
<div class="item-inner-right-msg-item-name">任务状态</div>
<div style="width: 14px; height: 2px; background-color: #4dc606;margin-left: 10px;"> </div>
</div>
<div class="item-inner-right-msg-item m-b-10" style="align-items: center">
<div class="item-inner-right-msg-item-name">楼层</div>
<div style="width: 14px; height: 2px; background-color: #0D162A;margin-left: 10px;"> </div>
</div>
<div class="item-inner-right-msg-item m-b-10" style="align-items: center">
<div class="item-inner-right-msg-item-name">区域</div>
<div style="width: 14px; height: 2px; background-color: #0D162A;margin-left: 10px;"> </div>
</div>
<div class="item-inner-right-msg-item m-b-10" style="align-items: center">
<div class="item-inner-right-msg-item-name">信息</div>
<div style="width: 14px; height: 2px; background-color: #0D162A;margin-left: 10px;"> </div>
</div>
</div>
</div>
</div>
</div>
@ -156,45 +218,46 @@
import { ref, reactive, onMounted, onBeforeUnmount } from 'vue'
defineOptions({ name: 'BoardCarBoard' })
import * as CarApi from '@/api/car/index'
import { Swiper, SwiperSlide } from 'swiper/vue'
// import { Swiper, SwiperSlide } from 'swiper/vue'
// API
import { onBeforeRouteLeave, onBeforeRouteUpdate } from 'vue-router'
const message = useMessage() //
// swiper
import 'swiper/css/pagination' //
import 'swiper/css/navigation' //
// import 'swiper/css/pagination' //
// import 'swiper/css/navigation' //
// import 'swiper/css/scrollbar' // 使import
// swiper
import { Autoplay, Pagination, Navigation, Scrollbar } from 'swiper'
// import { Autoplay, Pagination, Navigation, Scrollbar } from 'swiper'
import createEditDialog from './createEditDialog.vue'
import 'swiper/css'
// import 'swiper/css'
const router = useRouter() //
const createEditDialogRef = ref(null)
const list = ref([])
const queryParams = reactive({
// pageNo: 1,
// pageSize: 100,
robotNo: undefined
robotNo: undefined,
robotStatisticsType:undefined, //(:standby, :inTask, :doLock, 线:offline, :charge, :fault)
})
const spaceBetween = ref(20)
const navigation = ref({
nextEl: '.swiper-button-next-custome',
prevEl: '.swiper-button-prev-custome'
})
// modules使
const modules = [Autoplay, Navigation, Scrollbar]
// Pagination
const prevEl = (item, index) => {
// console.log('' + index + item)
}
const nextEl = () => {
// console.log('')
}
// swiper
const onSlideChange = (swiper) => {
// swiperswiperactiveIndex
console.log(swiper.activeIndex)
}
// const spaceBetween = ref(20)
// const navigation = ref({
// nextEl: '.swiper-button-next-custome',
// prevEl: '.swiper-button-prev-custome'
// })
// // modules使
// const modules = [Autoplay, Navigation, Scrollbar]
// // Pagination
// const prevEl = (item, index) => {
// // console.log('' + index + item)
// }
// const nextEl = () => {
// // console.log('')
// }
// // swiper
// const onSlideChange = (swiper) => {
// // swiperswiperactiveIndex
// console.log(swiper.activeIndex)
// }
const timerRef = ref(null)
//
const getCarList = async () => {
@ -225,13 +288,13 @@ const getRobotInformationStatistics = async () => {
console.log('车辆统计', res)
if (res) {
carStatistics.value = res
carStatistics.value.total =
Number(carStatistics.value.standby) +
Number(carStatistics.value.inTask) +
Number(carStatistics.value.doLock) +
Number(carStatistics.value.offline) +
Number(carStatistics.value.fault) +
Number(carStatistics.value.charge)
// carStatistics.value.total =
// Number(carStatistics.value.standby) +
// Number(carStatistics.value.inTask) +
// Number(carStatistics.value.doLock) +
// Number(carStatistics.value.offline) +
// Number(carStatistics.value.fault) +
// Number(carStatistics.value.charge)
} else {
carStatistics.value = {
standby: 0,
@ -244,6 +307,12 @@ const getRobotInformationStatistics = async () => {
}
}
}
const changeRobotStatisticsType = (type) => {
queryParams.robotStatisticsType = type
getCarList()
}
//
const openForm = (type, id) => {
createEditDialogRef.value.open(type, id ? id : null)
@ -338,7 +407,7 @@ onBeforeRouteLeave((to, from, next) => {
}
.swiperBox {
width: 100%;
/* background: rgba(0, 0, 0, 0.3); */
}
.swiper-item-box {
@ -468,6 +537,7 @@ onBeforeRouteLeave((to, from, next) => {
color: #0d162a;
flex-shrink: 0;
background: #ebf1ff;
cursor: pointer;
}
.grey-line {
width: 1px;
@ -483,7 +553,7 @@ onBeforeRouteLeave((to, from, next) => {
PingFang SC;
font-weight: 600;
font-size: 16px;
padding: 5px 10px;
cursor: pointer;
}
@ -545,7 +615,7 @@ input::-webkit-input-placeholder {
/* background: red; */
padding: 20px 22px 26px 22px;
margin-bottom: 12px;
height: 222px;
height: 230px;
background: #ffffff;
}
.item-inner {
@ -567,9 +637,9 @@ input::-webkit-input-placeholder {
PingFang SC;
font-weight: 600;
font-size: 14px;
width: 0;
width: 0;
}
.item-inner-left-name-inner{
.item-inner-left-name-inner {
white-space: nowrap; /* 防止文本换行 */
overflow: hidden; /* 隐藏超出容器的部分 */
text-overflow: ellipsis; /* 显示省略号来表示被截断的文本 */
@ -578,6 +648,7 @@ input::-webkit-input-placeholder {
width: 124px;
height: 124px;
background: #eeeeee;
position: relative;
}
.item-inner-left-bottom {
display: flex;
@ -602,7 +673,7 @@ input::-webkit-input-placeholder {
flex: 1;
height: 100%;
}
.item-top{
.item-top {
display: flex;
align-items: center;
justify-content: space-between;
@ -613,28 +684,43 @@ input::-webkit-input-placeholder {
display: flex;
justify-content: flex-end;
}
.item-inner-right-msg{
.item-inner-right-msg {
margin-left: 35px;
flex: 1;
}
.item-inner-right-msg-item{
.item-inner-right-msg-item {
width: 100%;
display: flex;
flex-shrink: 0;
}
.item-inner-right-msg-item-name{
font-family: PingFangSC, PingFang SC;
.item-inner-right-msg-item-name {
font-family:
PingFangSC,
PingFang SC;
font-weight: 400;
font-size: 14px;
width: 60px;
text-align: end;
}
.item-inner-right-msg-item-value{
.item-inner-right-msg-item-value {
flex: 1;
margin-left: 8px;
font-size: 14px;
color: #0D162A;
color: #0d162a;
overflow: hidden;
text-overflow: ellipsis; /* 超出宽度200px后显示省略号 */
white-space: nowrap; /* 限制不允许换行 */
width: 0;
}
.m-b-10{
.m-b-10 {
margin-bottom: 10px;
}
.item-inner-left-status {
width: 12px;
height: 12px;
flex-shrink: 0;
border-radius: 50%;
margin-right: 4px;
}
</style>

View File

@ -105,18 +105,18 @@
import { ref, reactive, onMounted, onBeforeUnmount } from 'vue'
defineOptions({ name: 'BoardDevice' })
import * as DeviceApi from '@/api/device/index'
import { Swiper, SwiperSlide } from 'swiper/vue'
// import { Swiper, SwiperSlide } from 'swiper/vue'
// API
import { onBeforeRouteLeave, onBeforeRouteUpdate } from 'vue-router'
const message = useMessage() //
// swiper
import 'swiper/css/pagination' //
import 'swiper/css/navigation' //
// import 'swiper/css/pagination' //
// import 'swiper/css/navigation' //
// import 'swiper/css/scrollbar' // 使import
// swiper
import { Autoplay, Pagination, Navigation, Scrollbar } from 'swiper'
// import { Autoplay, Pagination, Navigation, Scrollbar } from 'swiper'
import createEditDialog from './createEditDialog.vue'
import 'swiper/css'
// import 'swiper/css'
import { formatter } from 'element-plus'
import { DICT_TYPE, getDictOptions } from '@/utils/dict'
@ -130,11 +130,11 @@ const queryParams = reactive({
deviceNo: undefined,
deviceType: undefined
})
const spaceBetween = ref(20)
const navigation = ref({
nextEl: '.swiper-button-next-custome',
prevEl: '.swiper-button-prev-custome'
})
// const spaceBetween = ref(20)
// const navigation = ref({
// nextEl: '.swiper-button-next-custome',
// prevEl: '.swiper-button-prev-custome'
// })
const activeName = ref('-1')
const handleClick = (tab, event) => {
console.log(tab, event)

View File

@ -108,6 +108,7 @@
import { ref, defineComponent, reactive, nextTick, onMounted, onBeforeUnmount } from 'vue'
import * as MapApi from '@/api/map/map'
import WebSocketClient from '../webSocket.js'
import storeDialog from './storeDialog.vue'
const imgUrl = ref('')
const socketClient = ref(null)
@ -133,8 +134,14 @@ const getList = async () => {
getMapData(data[1][0])
}
}
const storeClick = (item) => {
//
const storeClick = async (item) => {
console.log(item)
let storeData = await MapApi.houseLocationGetByMapItemId({
mapId: item.positionMapId,
mapItemId: item.id
})
console.log(storeData)
}
const pointList = ref([])
const getPositionMapListFun = async (positionMapId) => {
@ -174,6 +181,7 @@ const formatteTypeImg = (type) => {
const replaceHttpWithWs = (str) => {
return str.replace(/^http/, 'ws')
}
// websocket
const linkWebSocket = (url) => {
socketClient.value = new WebSocketClient(url)
if (socketClient.value) {
@ -183,11 +191,11 @@ const linkWebSocket = (url) => {
})
}
}
// websocket
const sendMessage = () => {
socketClient.value.send('Hello, WebSocket!')
}
//
const disconnect = () => {
socketClient.value.disconnect()
}

View File

@ -0,0 +1,352 @@
<template>
<Dialog v-model="dialogVisible" title="新建任务" width="600" class="task-dialog">
<el-form :model="formData" label-width="auto" ref="formRef" :rules="formRules">
<el-form-item required label="任务号" prop="taskNo">
<el-input v-model="formData.taskNo" :disabled="true" />
</el-form-item>
<el-form-item label="取货类型" prop="taskDetailList[0].takeType" required>
<el-select
v-model="formData.taskDetailList[0].takeType"
placeholder="请选择取货类型"
required
>
<el-option label="库位" :value="1" />
<el-option label="线库" :value="2" />
<el-option label="区域" :value="3" />
</el-select>
</el-form-item>
<el-form-item required label="取货位置" prop="taskDetailList[0].takeId">
<el-select
:disabled="!formData.taskDetailList[0].takeType"
v-model="formData.taskDetailList[0].takeId"
filterable
remote
reserve-keyword
placeholder="请输入取货位置"
:remote-method="
(query) => {
takeRemoteMethod(query, formData.taskDetailList[0])
}
"
:loading="loading"
>
<el-option
v-for="item in formData.taskDetailList[0].takeList"
:key="item.id"
:label="item.locationNo"
:value="item.id"
/>
<template #loading>
<svg class="circular" viewBox="0 0 50 50">
<circle class="path" cx="25" cy="25" r="20" fill="none" />
</svg>
</template>
</el-select>
</el-form-item>
<el-form-item label="放货类型" prop="taskDetailList[0].releaseType" required>
<el-select v-model="formData.taskDetailList[0].releaseType" placeholder="请选择放货类型">
<el-option label="库位" :value="1" />
<el-option label="线库" :value="2" />
<el-option label="区域" :value="3" />
</el-select>
</el-form-item>
<el-form-item required label="放货位置" prop="taskDetailList[0].releaseId">
<el-select
:disabled="!formData.taskDetailList[0].releaseType"
v-model="formData.taskDetailList[0].releaseId"
filterable
remote
reserve-keyword
placeholder="请输入放货位置"
:remote-method="
(query) => {
releaseRemoteMethod(query, formData.taskDetailList[0])
}
"
:loading="loading"
>
<el-option
v-for="item in formData.taskDetailList[0].releaseList"
:key="item.id"
:label="item.locationNo"
:value="item.id"
/>
<template #loading>
<svg class="circular" viewBox="0 0 50 50">
<circle class="path" cx="25" cy="25" r="20" fill="none" />
</svg>
</template>
</el-select>
</el-form-item>
<el-form-item label="物料信息" prop="skuInfo">
<el-input v-model="formData.skuInfo" placeholder="请输入物料信息" />
</el-form-item>
<el-form-item label="指定车辆" prop="robotNo">
<el-select v-model="formData.robotNo" placeholder="请选择车辆">
<el-option
v-for="car in robotList"
:key="car.id"
:label="car.robotNo"
:value="car.robotNo"
/>
</el-select>
</el-form-item>
<el-form-item label="优先级" prop="priority">
<el-input-number
placeholder="优先级范围为1-100"
v-model="formData.priority"
:min="1"
:max="100"
class="!w-220px"
/>
</el-form-item>
<el-form-item label="其他信息" prop="otherMsg">
<el-input
v-model="formData.otherMsg"
rows="3"
type="textarea"
placeholder="请输入其他信息"
/>
</el-form-item>
<div class="task-tips">
<el-text class="mx-1">若需要发起拼接任务请点击前往</el-text>
<el-link type="primary" @click="taskManagement()">任务管理</el-link>
</div>
</el-form>
<template #footer>
<el-button :disabled="formLoading" type="primary" @click="submitForm"> </el-button>
<el-button @click="dialogVisible = false"> </el-button>
</template>
</Dialog>
</template>
<script lang="ts" setup>
const { t } = useI18n() //
const message = useMessage() //
import * as MapTaskAPi from '@/api/map/mapTask'
const dialogVisible = ref(false) //
const formLoading = ref(false) // 12
const formData = ref({
montageTask: 0, //01
montageNumber: 1, //
taskDetailList: [
{
taskType: 1, //12 345678
releaseType: 1, // 12线 3
takeType: 1, //12线 3
releaseId: undefined, //id
releaseList: [], //
takeId: undefined, //id
takeList: [], //
robotNo: undefined, //AGV
needLock: 0, //(0:1:)
electricity: undefined //()
}
], //
skuInfo: undefined, //
skuBatch: undefined, //
skuNumber: undefined, //
priority: undefined, //
otherMsg: undefined, //
doCycle: 0, //(0:1)
doMoveAll: 0, //线/(0:1)
cycleNumber: 0, //
remainingCycleNumber: 1, //1
taskNo: undefined, //
taskStatus: 0, //(0:123)
taskStage: 0, //(0:12345)
startTime: 0, //
endTime: 0 //
})
const formRules = reactive({
taskNo: [{ required: true, message: '任务号不能为空', trigger: 'change' }],
'taskDetailList[0].takeType': [
{ required: true, message: '取货类型不能为空', trigger: 'change' }
],
'taskDetailList[0].takeId': [{ required: true, message: '取货位置不能为空', trigger: 'change' }],
'taskDetailList[0].releaseType': [
{ required: true, message: '放货类型不能为空', trigger: 'change' }
],
'taskDetailList[0].releaseId': [
{ required: true, message: '放货位置不能为空', trigger: 'change' }
]
})
const formRef = ref() // Ref
/** 打开弹窗 */
const open = async () => {
dialogVisible.value = true
resetForm()
getCanUseRobotList()
getTaskNo()
}
defineExpose({ open }) // open
/** 提交表单 */
const emit = defineEmits(['success']) // success
const submitForm = async () => {
//
if (!formRef) return
const valid = await formRef.value.validate()
if (!valid) return
//
formLoading.value = true
try {
await MapTaskAPi.createTask(formData.value)
message.success(t('common.createSuccess'))
dialogVisible.value = false
push({ name: 'taskManagementTaskList' })
} finally {
formLoading.value = false
}
}
//
const { push } = useRouter()
const taskManagement = () => {
push({ name: 'taskManagementCreateTask' })
}
//
const robotList = ref([])
const getCanUseRobotList = async () => {
robotList.value = await MapTaskAPi.getCanUseRobot()
}
//
const getTaskNo = async () => {
formData.value.taskNo = await MapTaskAPi.getTaskNo()
}
//
const getLocationList = async (type, locationNo) => {
return await MapTaskAPi.getLocationByName({
type, // 12线 3
locationNo
})
}
//
const loading = ref(false)
const releaseRemoteMethod = async (query, item) => {
if (query) {
loading.value = true
item.releaseList = await getLocationList(item.releaseType, query)
loading.value = false
} else {
item.releaseList = []
}
}
//
const takeRemoteMethod = async (query, item) => {
if (query) {
item.takeList = await getLocationList(item.takeType, query)
} else {
item.takeList = []
}
}
/** 重置表单 */
const resetForm = () => {
formData.value = {
montageTask: 0, //01
montageNumber: 0, //
taskDetailList: [
{
taskType: 1, //12 345678
releaseType: 1, // 12线 3
takeType: 1, //12线 3
releaseId: undefined, //id
releaseList: [], //
takeId: undefined, //id
takeList: [], //
robotNo: undefined, //AGV
needLock: 0, //(0:1:)
electricity: undefined //()
}
], //
skuInfo: undefined, //
skuBatch: undefined, //
skuNumber: undefined, //
priority: undefined, //
otherMsg: undefined, //
doCycle: 0, //(0:1)
doMoveAll: 0, //线/(0:1)
cycleNumber: 0, //
remainingCycleNumber: 1, //1
taskNo: undefined, //
taskStatus: 0, //(0:123)
taskStage: 0, //(0:12345)
startTime: 0, //
endTime: 0 //
}
formRef.value?.resetFields()
}
</script>
<style lang="scss">
.task-dialog {
.el-dialog__header {
border-bottom: none;
}
.el-dialog__footer {
border-top: none !important;
}
}
.task-tips {
display: flex;
align-items: center;
justify-content: flex-end;
}
.el-select-dropdown__loading {
display: flex;
justify-content: center;
align-items: center;
height: 100px;
font-size: 20px;
}
.circular {
display: inline;
height: 30px;
width: 30px;
animation: loading-rotate 2s linear infinite;
}
.path {
animation: loading-dash 1.5s ease-in-out infinite;
stroke-dasharray: 90, 150;
stroke-dashoffset: 0;
stroke-width: 2;
stroke: var(--el-color-primary);
stroke-linecap: round;
}
@keyframes loading-rotate {
to {
transform: rotate(360deg);
}
}
@keyframes loading-dash {
0% {
stroke-dasharray: 1, 200;
stroke-dashoffset: 0;
}
50% {
stroke-dasharray: 90, 150;
stroke-dashoffset: -40px;
}
100% {
stroke-dasharray: 90, 150;
stroke-dashoffset: -120px;
}
}
@keyframes custom-spin-move {
to {
opacity: 1;
}
}
</style>