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.

242 lines
8.1 KiB
Vue

<template>
<Dialog :title="dialogTitle" v-model="dialogVisible">
<el-form
ref="formRef"
:model="formData"
:rules="formRules"
label-width="110px"
v-loading="formLoading"
>
<el-form-item label="名称" prop="name">
<el-input v-model="formData.name" placeholder="请输入名称" />
</el-form-item>
<el-form-item label="类型" prop="taskType">
<el-radio-group v-model="formData.taskType">
<el-radio :label="1">点检</el-radio>
<el-radio :label="2">保养</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="设备列表" prop="deviceList">
<el-select
v-model="formData.deviceList"
multiple
filterable
clearable
placeholder="请选择设备列表"
class="!w-full"
>
<el-option v-for="item in deviceOptions" :key="String(item.id)" :label="item.deviceName" :value="String(item.id)" />
</el-select>
</el-form-item>
<el-form-item label="项目表单" prop="projectForm">
<el-select
v-model="formData.projectForm"
filterable
clearable
placeholder="请选择项目表单"
class="!w-full"
>
<el-option v-for="item in planOptions" :key="String(item.id)" :label="item.planName" :value="Number(item.id)" />
</el-select>
</el-form-item>
<el-form-item label="起止日期" prop="dateRange">
<el-date-picker
v-model="formData.dateRange"
value-format="YYYY-MM-DD"
type="daterange"
start-placeholder="开始日期"
end-placeholder="结束日期"
class="!w-320px"
/>
</el-form-item>
<el-form-item label="cron 表达式" prop="cronExpression">
<crontab v-model="formData.cronExpression" />
</el-form-item>
<el-form-item label="可操作人" prop="operableUsers">
<el-select
v-model="formData.operableUsers"
multiple
filterable
clearable
placeholder="请选择可操作人"
class="!w-full"
>
<el-option v-for="item in users" :key="String(item.id)" :label="item.nickname" :value="String(item.id)" />
</el-select>
</el-form-item>
</el-form>
<template #footer>
<el-button @click="submitForm" type="primary" :disabled="formLoading"> </el-button>
<el-button @click="dialogVisible = false"> </el-button>
</template>
</Dialog>
</template>
<script setup lang="ts">
import { DICT_TYPE, getBoolDictOptions } from '@/utils/dict'
import { TaskManagementApi, TaskManagementVO } from '@/api/mes/taskManagement'
import { DeviceLedgerApi } from '@/api/mes/deviceledger'
import { PlanMaintenanceApi } from '@/api/mes/planmaintenance'
import { getSimpleUserList, UserVO } from '@/api/system/user'
defineOptions({ name: 'TaskManagementForm' })
const { t } = useI18n()
const message = useMessage()
const dialogVisible = ref(false)
const dialogTitle = ref('')
const formLoading = ref(false)
const formType = ref('')
const formRef = ref()
type DeviceOption = {
id: number | string
deviceName: string
}
type PlanOption = {
id: number | string
planName: string
}
const deviceOptions = ref<DeviceOption[]>([])
const planOptions = ref<PlanOption[]>([])
const users = ref<UserVO[]>([])
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 ensureOptionsLoaded = async () => {
const [deviceRes, planRes, userRes] = await Promise.all([
DeviceLedgerApi.getDeviceLedgerList({}),
PlanMaintenanceApi.getPlanMaintenancePage({ pageNo: 1, pageSize: 100 }),
getSimpleUserList()
])
deviceOptions.value = (Array.isArray(deviceRes) ? deviceRes : deviceRes?.list ?? deviceRes?.data ?? []) as DeviceOption[]
planOptions.value = (planRes?.list ?? []) as PlanOption[]
users.value = userRes ?? []
}
const formData = ref({
id: undefined as number | undefined,
name: undefined as string | undefined,
taskType: undefined as number | undefined,
deviceList: [] as string[],
projectForm: undefined as number | undefined,
dateRange: [] as string[],
cronExpression: undefined as string | undefined,
operableUsers: [] as string[],
enabled: true as boolean
})
const formRules = reactive({
name: [{ required: true, message: '名称不能为空', trigger: 'blur' }],
taskType: [{ required: true, message: '类型不能为空', trigger: 'change' }],
enabled: [{ required: true, message: '是否启用不能为空', trigger: 'change' }],
deviceList: [{ required: true, message: '设备列表不能为空', trigger: 'change' }],
projectForm: [{ required: true, message: '项目表单不能为空', trigger: 'change' }],
dateRange: [{required: true, message: '起止日期不能为空', trigger: 'change' }]
})
const resetForm = () => {
formData.value = {
id: undefined,
name: undefined,
taskType: undefined,
deviceList: [],
projectForm: undefined,
dateRange: [],
cronExpression: undefined,
operableUsers: [],
enabled: true
}
formRef.value?.resetFields()
}
const open = async (type: string, row?: TaskManagementVO) => {
dialogVisible.value = true
dialogTitle.value = t('action.' + type)
formType.value = type
resetForm()
await ensureOptionsLoaded()
if (type === 'update' && row) {
formData.value.id = row.id
formData.value.name = row.name
formData.value.taskType = row.taskType
formData.value.deviceList = parseIdsValue((row as any).deviceList)
const projectFormIds = parseIdsValue((row as any).projectForm)
if (projectFormIds.length) {
const n = Number(projectFormIds[0])
formData.value.projectForm = Number.isFinite(n) ? n : undefined
} else {
const projectFormNames = parseIdsValue((row as any).projectFormName)
const mapped = projectFormNames
.map((name) => planOptions.value.find((p) => p.planName === name)?.id)
.filter((id) => id !== undefined && id !== null)
.map((id) => Number(id))
const firstId = mapped[0]
formData.value.projectForm = typeof firstId === 'number' && Number.isFinite(firstId) ? firstId : undefined
}
formData.value.dateRange = [row.startDate, row.endDate].filter(Boolean) as string[]
formData.value.cronExpression = row.cronExpression
formData.value.operableUsers = parseIdsValue((row as any).operableUsers)
if (typeof row.enabled === 'boolean') {
formData.value.enabled = row.enabled
} else if (row.enabled === 'true' || row.enabled === 'false') {
formData.value.enabled = row.enabled === 'true'
} else {
formData.value.enabled = true
}
}
}
defineExpose({ open })
const emit = defineEmits(['success'])
const submitForm = async () => {
await formRef.value.validate()
formLoading.value = true
try {
const [startDate, endDate] = Array.isArray(formData.value.dateRange) ? formData.value.dateRange : []
const payload: TaskManagementVO = {
id: formData.value.id,
name: formData.value.name,
taskType: formData.value.taskType,
deviceList: toCommaSeparatedIds((formData.value as any).deviceList),
projectForm: formData.value.projectForm,
startDate: startDate || undefined,
endDate: endDate || undefined,
cronExpression: formData.value.cronExpression,
operableUsers: toCommaSeparatedIds((formData.value as any).operableUsers),
enabled: formData.value.enabled
}
if (formType.value === 'create') {
await TaskManagementApi.createTaskManagement(payload)
message.success(t('common.createSuccess'))
} else {
await TaskManagementApi.updateTaskManagement(payload)
message.success(t('common.updateSuccess'))
}
dialogVisible.value = false
emit('success')
} finally {
formLoading.value = false
}
}
</script>