<template>
|
<el-dialog
|
class="gd-dialog"
|
v-model="visible"
|
:title="titleEnum[dialogMode]"
|
@closed="visible = false"
|
destroy-on-close
|
width="75%"
|
:close-on-click-modal="false"
|
>
|
<div class="gd-dialog-form">
|
<!-- 关联工单选择 -->
|
<div class="work-order-section">
|
<div class="detail-title" :style="{ marginBottom: 0, marginRight: pxToRem(10) }">选择工单</div>
|
<el-select
|
class="gd-select"
|
style="width: 150px"
|
popper-class="gd-select-popper"
|
v-model="selectedWorkOrderId"
|
placeholder="请选择"
|
clearable
|
filterable
|
:disabled="dialogMode !== 'add'"
|
@change="handleWorkOrderChange"
|
>
|
<el-option v-for="item in workOrderList" :key="item.id" :label="item.workOrderName" :value="item.id" />
|
</el-select>
|
</div>
|
|
<!-- 工单信息展示 -->
|
<div class="work-order-info">
|
<el-row class="detail-row-view">
|
<el-col :span="12">
|
<div class="info-item">
|
<span class="label">工单类型</span>
|
<span class="val" v-if="selectedWorkOrder">
|
{{ getDictLabel(selectedWorkOrder.workOrderType, dictObj.workOrderType) }}
|
</span>
|
<span class="val grayText" v-else>选择工单后自动带出</span>
|
</div>
|
</el-col>
|
<el-col :span="12">
|
<div class="info-item">
|
<span class="label">执行时间范围</span>
|
<span class="val" v-if="selectedWorkOrder">
|
{{ selectedWorkOrder.executeStartTime }} ~ {{ selectedWorkOrder.executeEndTime }}
|
</span>
|
<span class="val grayText" v-else>选择工单后自动带出</span>
|
</div>
|
</el-col>
|
<el-col :span="12">
|
<div class="info-item">
|
<span class="label">设备需求</span>
|
<span class="val" v-if="selectedWorkOrder">
|
{{ getDictLabel(selectedWorkOrder.deviceLoadDemand, dictObj.deviceLoadDemand) }}
|
</span>
|
<span class="val grayText" v-else>选择工单后自动带出</span>
|
</div>
|
</el-col>
|
<el-col :span="12">
|
<div class="info-item">
|
<span class="label">工单备注</span>
|
<span class="val" v-if="selectedWorkOrder">{{ selectedWorkOrder.remark }}</span>
|
<span class="val grayText" v-else>选择工单后自动带出</span>
|
</div>
|
</el-col>
|
</el-row>
|
</div>
|
|
<!-- 子任务表格表单 -->
|
<div
|
class="task-table-section"
|
:class="{ 'disabled-section': !selectedWorkOrderId }"
|
@click="handleTaskSectionClick"
|
>
|
<div class="detail-title" :style="{ marginTop: pxToRem(10) }">添加子任务</div>
|
<div class="task-table-container">
|
<el-table :data="taskList">
|
<el-table-column width="50" label="">
|
<template v-slot="{ $index }">{{ $index + 1 }}</template>
|
</el-table-column>
|
<el-table-column prop="patrolTaskName" min-width="120">
|
<template #header>
|
<span class="required-star">*</span>
|
巡查任务名称
|
</template>
|
<template v-slot="{ row }">
|
<el-input
|
class="gd-input"
|
v-model="row.patrolTaskName"
|
placeholder="请输入"
|
:disabled="dialogReadonly"
|
/>
|
</template>
|
</el-table-column>
|
<el-table-column prop="patrolTaskType" min-width="140">
|
<template #header>
|
<span class="required-star">*</span>
|
巡查任务类型
|
</template>
|
<template v-slot="{ row, $index }">
|
<el-select
|
class="gd-select"
|
popper-class="gd-select-popper"
|
v-model="row.patrolTaskType"
|
placeholder="请选择"
|
@change="handlePatrolTaskTypeChange($index, $event)"
|
>
|
<el-option
|
v-for="item in dictObj.workOrderType"
|
:key="item.dictKey"
|
:label="item.dictValue"
|
:value="item.dictKey"
|
/>
|
</el-select>
|
</template>
|
</el-table-column>
|
<el-table-column prop="executeTime" min-width="180">
|
<template #header>
|
<span class="required-star">*</span>
|
任务执行时间
|
</template>
|
<template v-slot="{ row }">
|
<!-- gd-date-picker-popper-->
|
<el-date-picker
|
class="gd-date-picker"
|
popper-class=""
|
v-model="row.executeTime"
|
type="datetime"
|
placeholder="请选择"
|
value-format="YYYY-MM-DD HH:mm:ss"
|
:disabled="dialogReadonly"
|
/>
|
</template>
|
</el-table-column>
|
<el-table-column prop="patrolRouteUrl" min-width="120">
|
<template #header>
|
<span class="required-star">*</span>
|
巡查任务航线
|
</template>
|
<template v-slot="{ row }">
|
<el-select
|
class="gd-select"
|
popper-class="gd-select-popper"
|
v-model="row.patrolRouteUrl"
|
placeholder="请选择"
|
:disabled="dialogReadonly"
|
>
|
<el-option v-for="item in routeOptions" :key="item.id" :label="item.name" :value="item.id" />
|
</el-select>
|
</template>
|
</el-table-column>
|
<el-table-column prop="recommendFlyerName" min-width="120">
|
<template #header>
|
<span class="required-star">*</span>
|
推荐飞手
|
</template>
|
<template v-slot="{ row, $index }">
|
<el-select
|
no-data-text="暂无推荐飞手"
|
class="gd-select"
|
popper-class="gd-select-popper"
|
v-model="row.recommendFlyerName"
|
placeholder="请选择"
|
filterable
|
:disabled="dialogReadonly || !taskList[$index].patrolTaskType"
|
>
|
<el-option
|
v-for="item in flyerListMap[$index] || []"
|
:key="item.id"
|
:label="item.flyerName"
|
:value="item.flyerName"
|
/>
|
</el-select>
|
</template>
|
</el-table-column>
|
<el-table-column prop="deviceId" min-width="120">
|
<template #header>
|
<span class="required-star">*</span>
|
选择设备
|
</template>
|
<template v-slot="{ row }">
|
<el-select
|
class="gd-select"
|
popper-class="gd-select-popper"
|
v-model="row.deviceId"
|
placeholder="请选择"
|
filterable
|
:disabled="dialogReadonly"
|
>
|
<el-option v-for="item in deviceList" :key="item.id" :label="item.nickname" :value="item.id" />
|
</el-select>
|
</template>
|
</el-table-column>
|
<el-table-column prop="taskDesc" label="巡查任务描述" min-width="120">
|
<template v-slot="{ row }">
|
<el-input class="gd-input" v-model="row.taskDesc" placeholder="请输入" :disabled="dialogReadonly" />
|
</template>
|
</el-table-column>
|
<el-table-column label="操作" width="90" fixed="right" v-if="dialogMode === 'add'">
|
<template v-slot="{ $index }">
|
<el-button type="primary" :icon="Plus" circle size="small" @click="addTaskRow" />
|
<el-button
|
type="danger"
|
:icon="Delete"
|
circle
|
size="small"
|
@click="removeTaskRow($index)"
|
:disabled="taskList.length <= 1"
|
/>
|
</template>
|
</el-table-column>
|
</el-table>
|
</div>
|
</div>
|
</div>
|
|
<template #footer>
|
<el-button color="#F2F3F5" @click="visible = false">{{ dialogReadonly ? '关闭' : '取消' }}</el-button>
|
<el-button
|
class=""
|
color="#4C34FF"
|
v-if="!dialogReadonly"
|
:loading="submitting"
|
:disabled="submitting"
|
@click="handleSubmit"
|
>
|
确认
|
</el-button>
|
</template>
|
</el-dialog>
|
</template>
|
|
<script setup>
|
import { computed, ref, onMounted } from 'vue'
|
import { ElMessage } from 'element-plus'
|
import { Plus, Delete } from '@element-plus/icons-vue'
|
import { getDictLabel } from '@ztzf/utils'
|
import { gdPatrolTaskSaveApi, gdFlyerPageApi, gdPatrolTaskAuditApi } from './inspectionRequestApi'
|
import { gdWorkOrderPageApi } from '../orderManage/orderManageApi'
|
import { gdManageDeviceListApi } from '../orderManage/gdManageDeviceApi'
|
import { pxToRem } from '@/utils/rem'
|
import { airlineListApi } from '@/api/zkxt'
|
|
// 初始化任务行
|
const initTaskRow = () => ({
|
patrolTaskName: '',
|
patrolTaskType: '',
|
executeTime: '',
|
patrolRouteUrl: '',
|
recommendFlyerName: '',
|
deviceId: null,
|
taskDesc: '',
|
})
|
const dictObj = inject('dictObj')
|
const emit = defineEmits(['success'])
|
const visible = defineModel() // 弹框显隐
|
const dialogMode = ref('add') // 弹框模式
|
const submitting = ref(false) // 提交中
|
const dialogReadonly = computed(() => dialogMode.value === 'view')
|
const titleEnum = ref({ edit: '新增', view: '查看', add: '新增' })
|
|
// 工单相关
|
const workOrderList = ref([]) // 工单列表
|
const selectedWorkOrderId = ref(null) // 选中的工单ID
|
const selectedWorkOrder = ref(null) // 选中的工单信息
|
|
// 下拉选项
|
const flyerListMap = ref({}) // 飞手列表,按行索引存储
|
const deviceList = ref([]) // 设备列表
|
const routeOptions = inject('routeOptions')
|
|
// 子任务列表
|
const taskList = ref([initTaskRow(), initTaskRow(), initTaskRow(), initTaskRow(), initTaskRow()])
|
|
// 处理工单选择变化
|
function handleWorkOrderChange(val) {
|
if (val) {
|
selectedWorkOrder.value = workOrderList.value.find(item => item.id === val)
|
// 将工单类型赋值给所有子任务行
|
const workOrderType = selectedWorkOrder.value?.workOrderType
|
if (workOrderType) {
|
taskList.value.forEach((task, index) => {
|
task.patrolTaskType = workOrderType
|
// 获取对应的飞手列表
|
getFlyerList(index, workOrderType)
|
})
|
}
|
} else {
|
selectedWorkOrder.value = null
|
}
|
}
|
|
// 添加任务行
|
function addTaskRow() {
|
const newTask = initTaskRow()
|
// 如果已选择工单,自动填充工单类型
|
if (selectedWorkOrder.value?.workOrderType) {
|
newTask.patrolTaskType = selectedWorkOrder.value.workOrderType
|
}
|
const newIndex = taskList.value.length
|
taskList.value.push(newTask)
|
// 获取对应的飞手列表
|
if (newTask.patrolTaskType) {
|
getFlyerList(newIndex, newTask.patrolTaskType)
|
}
|
}
|
|
// 删除任务行
|
function removeTaskRow(index) {
|
if (taskList.value.length > 1) {
|
taskList.value.splice(index, 1)
|
// 重新整理 flyerListMap 的索引
|
const newFlyerListMap = {}
|
Object.keys(flyerListMap.value).forEach(key => {
|
const keyIndex = parseInt(key)
|
if (keyIndex < index) {
|
newFlyerListMap[keyIndex] = flyerListMap.value[keyIndex]
|
} else if (keyIndex > index) {
|
newFlyerListMap[keyIndex - 1] = flyerListMap.value[keyIndex]
|
}
|
})
|
flyerListMap.value = newFlyerListMap
|
}
|
}
|
|
// 处理任务区域点击事件(未选择工单时提示)
|
function handleTaskSectionClick() {
|
if (!selectedWorkOrderId.value) {
|
ElMessage.warning('请先选择工单')
|
}
|
}
|
|
// 获取工单列表
|
async function getWorkOrderList() {
|
const res = await gdWorkOrderPageApi({ size: 999, workOrderStatus: dialogMode.value === 'add' ? '20' : '' })
|
workOrderList.value = res?.data?.data?.records ?? []
|
}
|
|
// 处理巡查任务类型变化
|
async function handlePatrolTaskTypeChange(index, skilledTaskType) {
|
// 清空该行已选择的飞手
|
taskList.value[index].recommendFlyerName = ''
|
// 获取对应的飞手列表
|
await getFlyerList(index, skilledTaskType)
|
}
|
|
// 获取飞手列表
|
async function getFlyerList(index, skilledTaskType) {
|
const res = await gdFlyerPageApi({
|
size: 999,
|
current: 1,
|
skilledTaskType,
|
})
|
flyerListMap.value[index] = res?.data?.data?.records ?? []
|
}
|
|
// 获取设备列表
|
async function getDeviceList() {
|
const res = await gdManageDeviceListApi({
|
deviceIds: selectedWorkOrder.value?.recommendDeviceIds,
|
})
|
deviceList.value = res?.data?.data ?? []
|
}
|
|
watch(
|
() => selectedWorkOrderId.value,
|
() => {
|
handleWorkOrderChange(selectedWorkOrderId.value)
|
getDeviceList()
|
}
|
)
|
|
// 判断一行是否已填写(至少填写了任务名称)
|
function isTaskRowFilled(task) {
|
return !!(task.patrolTaskName || task.executeTime || task.patrolRouteUrl || task.recommendFlyerName || task.deviceId)
|
}
|
|
// 提交新增
|
async function handleSubmit() {
|
if (!selectedWorkOrderId.value) {
|
ElMessage.warning('请选择关联工单')
|
return
|
}
|
// 过滤出已填写的任务行
|
const filledTasks = taskList.value.filter(task => isTaskRowFilled(task))
|
if (!filledTasks.length) {
|
ElMessage.warning('请至少填写一个子任务')
|
return
|
}
|
// 只校验已填写的子任务
|
for (let i = 0; i < taskList.value.length; i++) {
|
const task = taskList.value[i]
|
// 跳过未填写的行
|
if (!isTaskRowFilled(task)) continue
|
// 已填写的行需要校验完整性
|
if (!task.patrolTaskName) {
|
ElMessage.warning(`第${i + 1}行: 请输入巡查任务名称`)
|
return
|
}
|
if (!task.patrolTaskType) {
|
ElMessage.warning(`第${i + 1}行: 请选择巡查任务类型`)
|
return
|
}
|
if (!task.executeTime) {
|
ElMessage.warning(`第${i + 1}行: 请选择任务执行时间`)
|
return
|
}
|
if (!task.patrolRouteUrl) {
|
ElMessage.warning(`第${i + 1}行: 请选择巡查任务航线`)
|
return
|
}
|
if (!task.recommendFlyerName) {
|
ElMessage.warning(`第${i + 1}行: 请选择推荐飞手`)
|
return
|
}
|
if (!task.deviceId) {
|
ElMessage.warning(`第${i + 1}行: 请选择设备`)
|
return
|
}
|
}
|
submitting.value = true
|
try {
|
const preID = filledTasks[0]?.id
|
// 只提交已填写的任务行
|
const dataList = filledTasks.map(item => ({
|
...item,
|
workOrderId: selectedWorkOrderId.value,
|
id: undefined,
|
}))
|
await gdPatrolTaskSaveApi(dataList)
|
dialogMode.value === 'add' ? ElMessage.success('新增成功') : ElMessage.success('修改成功')
|
dialogMode.value === 'edit' && (await gdPatrolTaskAuditApi({ auditStatus: 7, id: preID }))
|
visible.value = false
|
emit('success')
|
} finally {
|
submitting.value = false
|
}
|
}
|
|
// 打开弹框
|
async function open({ mode = 'add', row } = {}) {
|
dialogMode.value = mode
|
await getWorkOrderList()
|
if (dialogMode.value === 'add') {
|
selectedWorkOrderId.value = null
|
selectedWorkOrder.value = null
|
taskList.value = [initTaskRow(), initTaskRow(), initTaskRow(), initTaskRow(), initTaskRow()]
|
flyerListMap.value = {}
|
} else {
|
// 编辑/查看模式 - 加载已有数据
|
selectedWorkOrderId.value = row?.workOrderId
|
handleWorkOrderChange(row?.workOrderId)
|
taskList.value = [{ ...row }]
|
flyerListMap.value = {}
|
// 如果有巡查类型,加载对应的飞手列表
|
if (row?.patrolTaskType) {
|
getFlyerList(0, row.patrolTaskType)
|
}
|
}
|
}
|
|
onMounted(() => {})
|
|
defineExpose({ open })
|
</script>
|
|
<style scoped lang="scss">
|
.detail-row-view {
|
margin-top: 10px;
|
}
|
.work-order-section {
|
display: flex;
|
align-items: center;
|
}
|
.required-star {
|
color: #f56c6c;
|
margin-right: 4px;
|
}
|
:deep(.el-table__header th) {
|
font-weight: normal !important;
|
}
|
|
.grayText {
|
color: #9f9f9f !important;
|
}
|
|
// 禁用区域样式 - 使用 pointer-events: none 禁用所有子元素的点击
|
.disabled-section {
|
.task-table-container {
|
* {
|
pointer-events: none;
|
}
|
}
|
opacity: 0.6;
|
cursor: not-allowed;
|
}
|
</style>
|