You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
besure_web/src/views/mes/taskManagement/index.vue

470 lines
15 KiB
Vue

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<template>
<ContentWrap>
<el-form
class="-mb-15px"
:model="queryParams"
ref="queryFormRef"
:inline="true"
min-label-width="68px"
>
<el-form-item :label="t('EquipmentManagement.TaskManagement.name')" prop="name">
<el-input
v-model="queryParams.name"
:placeholder="t('EquipmentManagement.TaskManagement.placeholderName')"
clearable
@keyup.enter="handleQuery"
class="!w-240px"
/>
</el-form-item>
<el-form-item :label="t('EquipmentManagement.TaskManagement.taskType')" prop="taskType">
<el-select
v-model="queryParams.taskType"
:placeholder="t('EquipmentManagement.TaskManagement.placeholderTaskType')"
clearable
class="!w-240px"
>
<el-option v-for="opt in taskTypeOptions" :key="opt.value" :label="opt.label" :value="opt.value" />
</el-select>
</el-form-item>
<el-form-item :label="t('EquipmentManagement.TaskManagement.projectForm')" prop="projectForm">
<el-select
v-model="queryParams.projectForm"
multiple
filterable
clearable
:placeholder="t('EquipmentManagement.TaskManagement.placeholderProjectForm')"
class="!w-240px"
>
<el-option v-for="item in planOptions" :key="String(item.id)" :label="item.planName" :value="String(item.id)" />
</el-select>
</el-form-item>
<el-form-item :label="t('EquipmentManagement.TaskManagement.deviceList')" prop="deviceIds">
<el-select
v-model="queryParams.deviceIds"
multiple
filterable
clearable
collapse-tags
collapse-tags-tooltip
:placeholder="t('EquipmentManagement.TaskManagement.placeholderDeviceList')"
class="!w-240px"
>
<el-option
v-for="item in deviceOptions"
:key="item.id"
:label="item.label"
:value="item.id"
/>
</el-select>
</el-form-item>
<el-form-item>
<el-button @click="handleQuery">
<Icon icon="ep:search" class="mr-5px" />
{{ t('common.query') }}
</el-button>
<el-button @click="resetQuery">
<Icon icon="ep:refresh" class="mr-5px" />
{{ t('common.reset') }}
</el-button>
<el-button type="primary" plain @click="openForm('create')" v-hasPermi="['mes:task-management:create']">
<Icon icon="ep:plus" class="mr-5px" />
{{ t('action.add') }}
</el-button>
<el-button
type="success"
plain
@click="handleExport"
:loading="exportLoading"
v-hasPermi="['mes:task-management:export']"
>
<Icon icon="ep:download" class="mr-5px" />
{{ t('action.export') }}
</el-button>
</el-form-item>
</el-form>
</ContentWrap>
<ContentWrap>
<el-table
ref="tableRef"
v-loading="loading"
:data="list"
:stripe="true"
:show-overflow-tooltip="true"
:max-height="planTableMaxHeight"
@selection-change="handleSelectionChange"
>
<el-table-column type="selection" width="55" />
<el-table-column
type="index"
:label="t('EquipmentManagement.TaskManagement.index')"
align="center"
width="70"
/>
<el-table-column
:label="t('EquipmentManagement.TaskManagement.name')"
align="center"
prop="name"
min-width="200"
sortable />
<el-table-column
:label="t('EquipmentManagement.TaskManagement.deviceList')"
align="center"
prop="deviceList"
min-width="180"
>
<template #default="scope">
<span>{{ getDeviceNames(scope.row.deviceList) }}</span>
</template>
</el-table-column>
<el-table-column
:label="t('EquipmentManagement.TaskManagement.taskType')"
align="center"
prop="taskType"
width="90"
sortable>
<template #default="scope">
<el-tag v-if="scope.row.taskType === 1" type="primary">
{{ t('EquipmentManagement.TaskManagement.taskTypeInspect') }}
</el-tag>
<el-tag v-else-if="scope.row.taskType === 2" type="success">
{{ t('EquipmentManagement.TaskManagement.taskTypeMaintain') }}
</el-tag>
<span v-else>-</span>
</template>
</el-table-column>
<el-table-column
:label="t('EquipmentManagement.TaskManagement.projectForm')"
align="center"
prop="projectFormName"
min-width="300"
sortable />
<el-table-column
:label="t('EquipmentManagement.TaskManagement.startDate')"
align="center"
prop="startDate"
:formatter="dateFormatter2"
width="120"
sortable />
<el-table-column
:label="t('EquipmentManagement.TaskManagement.endDate')"
align="center"
prop="endDate"
:formatter="dateFormatter2"
width="120"
sortable />
<el-table-column
:label="t('EquipmentManagement.TaskManagement.cronExpression')"
align="center"
prop="cronExpression"
min-width="180"
/>
<el-table-column
:label="t('EquipmentManagement.TaskManagement.enabled')"
align="center"
prop="enabled"
width="110"
>
<template #default="scope">
<el-switch
:model-value="scope.row.enabled === true || scope.row.enabled === 'true'"
:before-change="() => handleBeforeEnabledChange(scope.row)"
@change="(val) => handleEnabledChange(scope.row, val)"
/>
</template>
</el-table-column>
<el-table-column
:label="t('EquipmentManagement.TaskManagement.creatorName')"
align="center"
prop="creatorName"
width="200"
sortable />
<el-table-column
:label="t('EquipmentManagement.TaskManagement.createTime')"
align="center"
prop="createTime"
:formatter="dateFormatter"
width="180"
sortable />
<el-table-column
:label="t('EquipmentManagement.TaskManagement.updateTime')"
align="center"
prop="updateTime"
:formatter="dateFormatter"
width="180"
sortable />
<el-table-column
:label="t('EquipmentManagement.TaskManagement.operate')"
fixed="right"
align="center"
min-width="230"
>
<template #default="scope">
<el-button
link
type="success"
:disabled="!isTaskEnabled(scope.row)"
@click="handleCreateTicket(scope.row)"
:loading="ticketLoadingId === scope.row.id"
>
{{ t('EquipmentManagement.TaskManagement.createWorkOrder') }}
</el-button>
<el-button
link
type="primary"
@click="openForm('update', scope.row)"
v-hasPermi="['mes:task-management:update']"
>
{{ t('action.update') }}
</el-button>
<el-button link type="danger" @click="handleDelete(scope.row.id)" v-hasPermi="['mes:task-management:delete']">
{{ t('action.delete') }}
</el-button>
</template>
</el-table-column>
</el-table>
<Pagination
:total="total"
v-model:page="queryParams.pageNo"
v-model:limit="queryParams.pageSize"
@pagination="getList"
/>
</ContentWrap>
<TaskManagementForm ref="formRef" @success="getList" />
</template>
<script setup lang="ts">
import { ElMessageBox } from 'element-plus'
import { DICT_TYPE } from '@/utils/dict'
import { dateFormatter, dateFormatter2 } from '@/utils/formatTime'
import download from '@/utils/download'
import { TaskManagementApi, TaskManagementVO } from '@/api/mes/taskManagement'
import { DeviceLedgerApi, DeviceLedgerVO } from '@/api/mes/deviceledger'
import { PlanMaintenanceApi } from '@/api/mes/planmaintenance'
import TaskManagementForm from './TaskManagementForm.vue'
defineOptions({ name: 'TaskManagement' })
const message = useMessage()
const { t } = useI18n()
const taskTypeOptions = [
{ label: t('EquipmentManagement.TaskManagement.taskTypeInspect'), value: 1 },
{ label: t('EquipmentManagement.TaskManagement.taskTypeMaintain'), value: 2 }
]
const loading = ref(true)
const list = ref<TaskManagementVO[]>([])
const total = ref(0)
const tableRef = ref()
const planTableMaxHeight = ref(520)
const planPaginationRef = ref<HTMLElement>()
const exportLoading = ref(false)
const selectedIds = ref<number[]>([])
const updatePlanTableMaxHeight = async () => {
await nextTick()
const tableTop = tableRef.value?.$el?.getBoundingClientRect().top ?? 0
const paginationHeight = planPaginationRef.value?.getBoundingClientRect().height ?? 72
const pageBottomGap = 56
const availableHeight = window.innerHeight - tableTop - paginationHeight - pageBottomGap
planTableMaxHeight.value = Math.min(window.innerHeight, Math.max(240, Math.floor(availableHeight)))
}
type PlanOption = {
id: number | string
planName: string
}
const planOptions = ref<PlanOption[]>([])
const deviceOptions = ref<{ id: number; label: string; raw?: DeviceLedgerVO }[]>([])
const queryParams = reactive({
pageNo: 1,
pageSize: 10,
name: undefined as string | undefined,
taskType: undefined as number | undefined,
projectForm: [] as string[],
deviceIds: [] as number[]
})
const queryFormRef = ref()
const parseIdsValue = (value: any): string[] => {
if (!value) return []
if (Array.isArray(value)) return value.map((v) => String(v).trim()).filter(Boolean)
return String(value)
.split(',')
.map((v) => v.trim())
.filter(Boolean)
}
const toCommaSeparatedIds = (value: any): string | undefined => {
const ids = parseIdsValue(value)
return ids.length ? ids.join(',') : undefined
}
const ensurePlanOptionsLoaded = async () => {
const planRes = await PlanMaintenanceApi.getPlanMaintenancePage({ pageNo: 1, pageSize: 100 })
planOptions.value = (planRes?.list ?? []) as PlanOption[]
}
const ensureDeviceOptionsLoaded = async () => {
const deviceRes = await DeviceLedgerApi.getDeviceLedgerList()
const rows = (Array.isArray(deviceRes) ? deviceRes : deviceRes?.list ?? deviceRes?.data ?? []) as DeviceLedgerVO[]
deviceOptions.value = rows
.filter((item) => typeof item?.id === 'number')
.map((item) => ({
id: item.id,
label: `${item.deviceCode ?? ''} ${item.deviceName ?? ''}`.trim() || String(item.id),
raw: item
}))
}
const getDeviceNames = (value: any) => {
const ids = parseIdsValue(value)
if (!ids.length) return '-'
const names = ids
.map((id) => {
const option = deviceOptions.value.find((item) => String(item.id) === id)
return option?.raw?.deviceName ?? option?.label?.split(' ').slice(1).join(' ') ?? id
})
.filter(Boolean)
return names.length ? names.join('') : '-'
}
const buildQueryParams = () => {
return {
...queryParams,
projectForm: toCommaSeparatedIds(queryParams.projectForm)
}
}
const getList = async () => {
loading.value = true
try {
const data = await TaskManagementApi.getTaskManagementPage(buildQueryParams())
list.value = data.list
total.value = data.total
} finally {
loading.value = false
updatePlanTableMaxHeight()
}
}
const handleQuery = () => {
queryParams.pageNo = 1
getList()
}
const resetQuery = () => {
queryFormRef.value.resetFields()
handleQuery()
}
const handleSelectionChange = (rows: TaskManagementVO[]) => {
selectedIds.value = rows
.map((r) => r.id)
.filter((id): id is number => typeof id === 'number')
}
const formRef = ref()
const openForm = (type: string, row?: TaskManagementVO) => {
formRef.value.open(type, row)
}
const isTaskEnabled = (row: TaskManagementVO) => row.enabled === true || (row.enabled as any) === 'true'
const handleDelete = async (id?: number) => {
if (!id) return
try {
await message.delConfirm()
await TaskManagementApi.deleteTaskManagement(String(id))
message.success(t('common.delSuccess'))
await getList()
} catch { }
}
const ticketLoadingId = ref<number | undefined>(undefined)
const handleCreateTicket = async (row?: TaskManagementVO) => {
if (!row?.id) return
if (!isTaskEnabled(row)) {
message.warning(t('EquipmentManagement.TaskManagement.createTicketDisabledTip'))
return
}
try {
await message.confirm(
t('EquipmentManagement.TaskManagement.createTicketConfirm'),
t('common.reminder')
)
} catch {
return
}
ticketLoadingId.value = row.id
try {
await TaskManagementApi.createTaskManagementTicket(row.id)
message.success(t('EquipmentManagement.TaskManagement.createTicketSuccess'))
} catch {
message.error(t('EquipmentManagement.TaskManagement.createTicketFail'))
} finally {
ticketLoadingId.value = undefined
}
}
const handleBeforeEnabledChange = async (row: TaskManagementVO) => {
const isEnabled = isTaskEnabled(row)
if (isEnabled) return true
const cronExpression = (row as any)?.cronExpression
if (typeof cronExpression === 'string' && cronExpression.trim()) return true
await ElMessageBox.alert(t('EquipmentManagement.TaskManagement.selectCronBeforeEnable'), t('EquipmentManagement.TaskManagement.cronAlertTitle'), {
type: 'warning',
confirmButtonText: t('EquipmentManagement.TaskManagement.cronAlertConfirm'),
closeOnClickModal: false,
closeOnPressEscape: false
})
return false
}
const handleEnabledChange = async (row: TaskManagementVO, value: boolean) => {
if (!row.id) return
const oldEnabled = row.enabled
row.enabled = value
try {
await TaskManagementApi.updateTaskManagementEnabled(String(row.id), value ? 'true' : 'false')
message.success(t('EquipmentManagement.TaskManagement.updateEnabledSuccess'))
} catch {
row.enabled = oldEnabled
message.error(t('EquipmentManagement.TaskManagement.updateEnabledFail'))
}
}
const handleExport = async () => {
try {
await message.exportConfirm()
exportLoading.value = true
const params: Record<string, any> = buildQueryParams()
if (selectedIds.value.length > 0) {
params.ids = selectedIds.value.join(',')
}
const data = await TaskManagementApi.exportTaskManagement(params)
download.excel(data, t('EquipmentManagement.TaskManagement.exportFilename'))
} catch {
} finally {
exportLoading.value = false
}
}
onMounted(async () => {
await Promise.all([ensurePlanOptionsLoaded(), ensureDeviceOptionsLoaded(), getList()])
updatePlanTableMaxHeight()
window.addEventListener('resize', updatePlanTableMaxHeight)
})
onBeforeUnmount(() => {
window.removeEventListener('resize', updatePlanTableMaxHeight)
})
</script>