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/planMaintenance/PlanMaintenanceForm.vue

405 lines
13 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>
<Dialog :title="dialogTitle" v-model="dialogVisible" width="720px">
<el-form ref="formRef" :model="formData" :rules="formRules" label-width="100px" v-loading="formLoading">
<el-form-item :label="t('EquipmentManagement.PlanMaintenance.planName')" prop="planName" required>
<el-input
v-model="formData.planName"
:placeholder="t('EquipmentManagement.PlanMaintenance.placeholderPlanName')"
/>
</el-form-item>
<el-form-item :label="t('EquipmentManagement.PlanMaintenance.planType')" prop="planType" required>
<el-select
v-model="formData.planType"
:placeholder="t('EquipmentManagement.PlanMaintenance.placeholderPlanType')"
class="!w-full"
>
<el-option :value="1" :label="t('EquipmentManagement.PlanMaintenance.planTypeMaintain')" />
<el-option :value="2" :label="t('EquipmentManagement.PlanMaintenance.planTypeInspect')" />
</el-select>
</el-form-item>
<el-form-item :label="t('EquipmentManagement.PlanMaintenance.description')" prop="description">
<el-input
v-model="formData.description"
:placeholder="t('EquipmentManagement.PlanMaintenance.placeholderDescription')"
type="textarea"
/>
</el-form-item>
<el-form-item :label="t('EquipmentManagement.PlanMaintenance.subjectName')" prop="subjectIds">
<!-- <el-select
v-model="formData.subjectIds"
multiple
filterable
clearable
:placeholder="t('EquipmentManagement.PlanMaintenance.placeholderSubjectSelect')"
class="!w-full"
>
<el-option v-for="item in subjectOptions" :key="item.id" :label="item.subjectName" :value="item.id" />
</el-select>-->
<el-input
:model-value="subjectNameDisplay"
readonly
clearable
class="device-ledger-selection-input"
:placeholder="t('EquipmentManagement.PlanMaintenance.placeholderSubjectSelect')"
@clear="clearSubjectComponent"
@click="openSubjectComponentDialog"
/>
</el-form-item>
</el-form>
<template #footer>
<el-button type="primary" @click="submitForm" :disabled="formLoading">{{ t('common.ok') }}</el-button>
<el-button @click="dialogVisible = false">{{ t('common.cancel') }}</el-button>
</template>
</Dialog>
<!--点检名称-->
<el-dialog
v-model="subjectComponentDialogVisible"
title="选择点检项"
width="1200px"
class="device-ledger-transfer-dialog"
append-to-body
>
<el-form class="-mb-15px" :model="queryParams" ref="queryFormRef" :inline="true" min-label-width="68px" style="margin-bottom: 10px">
<el-form-item :label="t('EquipmentManagement.DvSubject.code')" prop="subjectCode">
<el-input
v-model="queryParams.subjectCode" :placeholder="t('EquipmentManagement.DvSubject.placeholderCode')"
clearable @keyup.enter="handleQuery" class="!w-240px" />
</el-form-item>
<el-form-item :label="t('EquipmentManagement.DvSubject.name')" prop="subjectName">
<el-input
v-model="queryParams.subjectName" :placeholder="t('EquipmentManagement.DvSubject.placeholderName')"
clearable @keyup.enter="handleQuery" class="!w-240px" />
</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-form-item>
</el-form>
<ContentWrap>
<el-table
ref="multipleTableRef"
v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true"
@selection-change="handleSelectionChange" @select="handleSelect" @select-all="handleSelectAll" row-key="id">
<el-table-column type="selection" width="55" :reserve-selection="true" />
<el-table-column :label="t('EquipmentManagement.DvSubject.code')" align="center" prop="subjectCode" sortable />
<el-table-column :label="t('EquipmentManagement.DvSubject.name')" align="center" prop="subjectName" sortable />
<el-table-column :label="t('EquipmentManagement.DvSubject.judgmentCriteria')" align="center" width="480px" prop="judgmentCriteria" />
</el-table>
<Pagination
:total="total" v-model:page="queryParams.pageNo" v-model:limit="queryParams.pageSize"
@pagination="getList" />
</ContentWrap>
<template #footer>
<el-button @click="subjectComponentDialogVisible = false">{{ t('common.cancel') }}</el-button>
<el-button type="primary" @click="confirmSubjectComponentDialog">{{ t('common.ok') }}</el-button>
</template>
</el-dialog>
</template>
<script setup lang="ts">
import type { FormRules } from 'element-plus'
import { DvSubjectApi, DvSubjectVO } from '@/api/mes/dvsubject'
import { PlanMaintenanceApi, PlanMaintenanceVO } from '@/api/mes/planmaintenance'
import {ref} from "vue";
import {ElTable} from "element-plus";
defineOptions({ name: 'PlanMaintenanceForm' })
const { t } = useI18n()
const message = useMessage()
const dialogVisible = ref(false)
const dialogTitle = ref('')
const formLoading = ref(false)
const formType = ref<'create' | 'update'>('create')
const queryFormRef = ref() // 搜索的表单
const subjectComponentDialogVisible = ref(false)
const loading = ref(true) // 列表的加载中
const list = ref<DvSubjectVO[]>([]) // 列表的数据
const total = ref(0) // 列表的总页数
const tableRef = ref()
const selectedIds = ref<number[]>([])
const selectedRows = ref<any[]>([]) // 存储所有选中的行
const queryParams = reactive({
pageNo: 1,
pageSize: 10,
subjectCode: undefined as string | undefined,
subjectName: undefined as string | undefined,
})
const multipleTableRef = ref<InstanceType<typeof ElTable>>()
const beijianOptions = ref<{ label: string; value: number }[]>([])
const formatSelectedSummary = (ids: number[], options: { label: string; value: number }[]) => {
const optionMap = new Map<number, string>(options.map((item) => [item.value, item.label]))
const labels = ids.map((id) => optionMap.get(id)).filter((v): v is string => Boolean(v))
if (!labels.length) return ''
if (labels.length <= 3) return labels.join('、')
return `${labels.slice(0, 3).join('、')}…等${labels.length}`
}
const subjectNameDisplay = computed(() =>
formatSelectedSummary(formData.value.subjectIds ?? [], beijianOptions.value)
)
const subjectOptions = ref<DvSubjectVO[]>([])
const ensureSubjectOptionsLoaded = async () => {
const res = await DvSubjectApi.getDvSubjectList()
beijianOptions.value = (res ?? []).map((item: any) => {
const code = item.subjectCode ? String(item.subjectCode) : ''
const name = item.subjectName ? String(item.subjectName) : ''
const label = code && name ? `${code}-${name}` : name || code || String(item.id)
return { label, value: Number(item.id) }
})
}
const parseIds = (value: any): Array<number | string> => {
if (!value) return []
const raw = Array.isArray(value)
? value
: String(value)
.split(',')
.map((v) => v.trim())
.filter((v) => v !== '')
return raw
.map((v) => {
if (typeof v === 'number') return v
const s = String(v).trim()
if (!s) return undefined
const n = Number(s)
if (Number.isFinite(n) && String(n) === s) return n
return s
})
.filter((v): v is number | string => v !== undefined)
}
const initFormData = () => ({
id: undefined as PlanMaintenanceVO['id'],
planName: '' as string,
planType: undefined as any,
description: '' as string,
subjectIds: [] as Array<number | string>
})
const formData = ref(initFormData())
const formRules = reactive<FormRules>({
planName: [
{ required: true, message: t('EquipmentManagement.PlanMaintenance.placeholderPlanName'), trigger: 'blur' }
],
planType: [
{ required: true, message: t('EquipmentManagement.PlanMaintenance.placeholderPlanType'), trigger: 'change' }
]
})
const formRef = ref()
const open = async (type: 'create' | 'update', row?: Partial<PlanMaintenanceVO>) => {
dialogVisible.value = true
dialogTitle.value = t('action.' + type)
formType.value = type
resetForm()
await ensureSubjectOptionsLoaded()
if (type === 'update' && row) {
formData.value = {
...initFormData(),
id: row.id,
planName: (row.planName as any) ?? '',
planType: (row.planType as any) ?? undefined,
description: (row.description as any) ?? '',
subjectIds: parseIds((row as any).subjectIds ?? (row as any).subjectIdS)
}
}
getList()
}
defineExpose({ open })
const emit = defineEmits(['success'])
const submitForm = async () => {
await formRef.value.validate()
formLoading.value = true
try {
const data = {
id: formData.value.id,
planName: formData.value.planName,
planType: formData.value.planType,
description: formData.value.description,
subjectIdS: formData.value.subjectIds?.length ? formData.value.subjectIds.join(',') : undefined
}
if (formType.value === 'create') {
await PlanMaintenanceApi.createPlanMaintenance(data)
message.success(t('common.createSuccess'))
} else {
await PlanMaintenanceApi.updatePlanMaintenance(data)
message.success(t('common.updateSuccess'))
}
dialogVisible.value = false
emit('success')
} finally {
formLoading.value = false
}
}
const resetForm = () => {
formData.value = initFormData()
formRef.value?.resetFields()
}
const clearSubjectComponent = () => {
formData.value.subjectIds = []
}
const ids = ref([])
const openSubjectComponentDialog = () => {
if (formType.value === 'create') {
selectedIds.value = []
selectedRows.value =[]
//formData.value.subjectIds = []
// multipleTableRef.value.clearSelection()
}else{
selectedIds.value = []
selectedRows.value =[]
//formData.value.subjectIds = []
// multipleTableRef.value.clearSelection()
}
// criticalComponentDraft.value = [...(formData.value.componentIds ?? [])]
subjectComponentDialogVisible.value = true
ids.value =formData.value.subjectIds
setDefaultSelections()
}
/** 搜索按钮操作 */
const handleQuery = () => {
queryParams.pageNo = 1
getList()
}
/** 重置按钮操作 */
const resetQuery = () => {
queryFormRef.value.resetFields()
handleQuery()
}
const handleSelectionChange = (rows: any[]) => {
selectedIds.value = rows?.map((row) => row.id).filter((id) => id !== undefined) ?? []
// 获取当前页所有行的 id
const currentPageIds = rows.map(item => item.id)
// 从已选中的数组中移除当前页的数据
selectedRows.value = selectedRows.value.filter(
item => item.id !== undefined
)
selectedRows.value = selectedRows.value.filter(
item => !currentPageIds.includes(item.id)
)
// 添加当前页新选中的数据
selectedRows.value.push(...rows)
}
// 存储当前已选中的行
const currentSelectedRows = ref([])
// select 事件row 是当前操作的行selected 是操作后的状态
const handleSelect = (selection, row) => {
// 判断是选中还是取消选中
const isSelected = selection.includes(row)
if (isSelected) {
// console.log(`✅ 行被选中: ID=${row.id}, Name=${row.name}`)
ids.value.push(row.id)
} else {
ids.value= ids.value.filter(
item => item !== row.id
)
// console.log(`❌ 行被取消选中: ID=${row.id}, Name=${row.name}`)
}
// 更新当前选中状态
currentSelectedRows.value = selection
}
const handleSelectAll = (selection) => {
ids.value = selection?.map((row) => row.id).filter((id) => id !== undefined) ?? []
}
/** 查询列表 */
const getList = async () => {
loading.value = true
try {
const data = await DvSubjectApi.getDvSubjectPage(queryParams)
list.value = data.list
total.value = data.total
} finally {
loading.value = false
}
}
const confirmSubjectComponentDialog = () => {
//let ids = selectedRows.value.map(item => item.id);
//const validMap = new Set(criticalComponentOptions.value.map((item) => item.value))
//const selected = Array.from(new Set(criticalComponentDraft.value.map((v) => Number(v)).filter((v) => validMap.has(v))))
formData.value.subjectIds = ids.value
subjectComponentDialogVisible.value = false
multipleTableRef.value.clearSelection()
}
const cancelHandle = () => {
multipleTableRef.value.clearSelection()
}
// 方法1直接监听 data
watch(list, (newData, oldData) => {
// 可以在这里执行相关操作
if (newData.length > 0) {
// 数据加载完成后的操作
setDefaultSelections()
}
}, { deep: true })
//const defaultSelectedIds = [144, 143,141]
// 设置默认选中的行
const setDefaultSelections = () => {
// 等待DOM更新完成
nextTick(() => {
if (!multipleTableRef.value) return
multipleTableRef.value.clearSelection()
const rawSubjectIds = toRaw(formData.value.subjectIds)
if(rawSubjectIds.length != 0){
let row={
id: undefined
}
multipleTableRef.value.toggleRowSelection(row, true)
}
// 遍历数据,找到需要选中的行
list.value.forEach(row => {
let id = row.id;
if (rawSubjectIds.includes(row.id)) {
multipleTableRef.value.toggleRowSelection(row, true)
}
})
})
}
</script>
<style lang="scss" scoped>
:deep(.device-ledger-transfer-dialog){
height: 200px;
}
</style>