<template>
|
<FormDialog
|
v-model="visible"
|
:title="id ? '编辑设备报修' : '新增设备报修'"
|
width="800px"
|
@confirm="sendForm"
|
@cancel="handleCancel"
|
@close="handleClose"
|
>
|
<el-form :model="form" label-width="100px">
|
<el-row>
|
<el-col :span="12">
|
<el-form-item label="所属区域">
|
<el-tree-select
|
v-model="form.areaId"
|
:data="areaOptions"
|
:props="areaTreeProps"
|
node-key="id"
|
value-key="id"
|
check-strictly
|
clearable
|
filterable
|
placeholder="请选择所属区域"
|
style="width: 100%"
|
@change="handleAreaChange"
|
/>
|
</el-form-item>
|
</el-col>
|
<el-col :span="12">
|
<el-form-item label="设备名称">
|
<el-select
|
v-model="form.deviceLedgerIds"
|
filterable
|
clearable
|
multiple
|
collapse-tags
|
collapse-tags-tooltip
|
placeholder="请先选择区域,再选择设备"
|
style="width: 100%"
|
@change="setDeviceModels"
|
>
|
<el-option
|
v-for="item in deviceOptions"
|
:key="item.id"
|
:label="item.deviceName"
|
:value="item.id"
|
/>
|
</el-select>
|
</el-form-item>
|
</el-col>
|
<el-col :span="12">
|
<el-form-item label="规格型号">
|
<el-input
|
v-model="form.deviceModel"
|
placeholder="自动带出规格型号"
|
disabled
|
/>
|
</el-form-item>
|
</el-col>
|
<el-col :span="12">
|
<el-form-item label="报修日期">
|
<el-date-picker
|
v-model="form.repairTime"
|
placeholder="请选择报修日期"
|
format="YYYY-MM-DD"
|
value-format="YYYY-MM-DD"
|
type="date"
|
clearable
|
style="width: 100%"
|
/>
|
</el-form-item>
|
</el-col>
|
<el-col :span="12">
|
<el-form-item label="报修人">
|
<el-input v-model="form.repairName" placeholder="请输入报修人" />
|
</el-form-item>
|
</el-col>
|
</el-row>
|
<el-row v-if="id">
|
<el-col :span="12">
|
<el-form-item label="报修状态">
|
<el-select v-model="form.status">
|
<el-option label="待维修" :value="0" />
|
<el-option label="完结" :value="1" />
|
<el-option label="失败" :value="2" />
|
</el-select>
|
</el-form-item>
|
</el-col>
|
</el-row>
|
<el-row>
|
<el-col :span="24">
|
<el-form-item label="故障现象">
|
<el-input
|
v-model="form.remark"
|
:rows="2"
|
type="textarea"
|
placeholder="请输入故障现象"
|
/>
|
</el-form-item>
|
</el-col>
|
</el-row>
|
</el-form>
|
</FormDialog>
|
</template>
|
|
<script setup>
|
import { nextTick, ref, unref } from "vue";
|
import dayjs from "dayjs";
|
import { ElMessage } from "element-plus";
|
import FormDialog from "@/components/Dialog/FormDialog.vue";
|
import useFormData from "@/hooks/useFormData";
|
import useUserStore from "@/store/modules/user";
|
import {
|
addRepair,
|
editRepair,
|
getRepairById,
|
} from "@/api/equipmentManagement/repair";
|
import {
|
getDeviceAreaTree,
|
getDeviceAreaTreeWithDevices,
|
} from "@/api/equipmentManagement/deviceArea";
|
|
defineOptions({
|
name: "设备报修弹窗",
|
});
|
|
const emits = defineEmits(["ok"]);
|
|
const id = ref();
|
const visible = ref(false);
|
const loading = ref(false);
|
const userStore = useUserStore();
|
const areaOptions = ref([]);
|
const deviceOptions = ref([]);
|
const areaTreeProps = {
|
label: "areaName",
|
children: "children",
|
};
|
|
const { form, resetForm } = useFormData({
|
areaId: undefined,
|
deviceLedgerId: undefined,
|
deviceLedgerIds: [],
|
deviceLedgerIdsStr: undefined,
|
deviceName: undefined,
|
deviceModel: undefined,
|
repairTime: dayjs().format("YYYY-MM-DD"),
|
repairName: userStore.nickName,
|
remark: undefined,
|
status: 0,
|
});
|
|
const loadAreaTree = async () => {
|
const { data } = await getDeviceAreaTree();
|
areaOptions.value = Array.isArray(data) ? data : [];
|
};
|
|
const normalizeIdList = (value) => {
|
if (Array.isArray(value)) {
|
return value
|
.map((item) => Number(item))
|
.filter((item) => Number.isFinite(item));
|
}
|
if (typeof value === "string") {
|
return value
|
.split(",")
|
.map((item) => Number(item.trim()))
|
.filter((item) => Number.isFinite(item));
|
}
|
if (value !== undefined && value !== null && value !== "") {
|
const numericValue = Number(value);
|
return Number.isFinite(numericValue) ? [numericValue] : [];
|
}
|
return [];
|
};
|
|
const getNodeDevices = (node) => {
|
const candidates = [
|
node?.deviceList,
|
node?.devices,
|
node?.deviceLedgerList,
|
node?.deviceLedgers,
|
node?.ledgerList,
|
node?.ledgers,
|
];
|
return candidates.find((item) => Array.isArray(item)) || [];
|
};
|
|
const normalizeDevice = (item) => ({
|
...item,
|
id: item.id ?? item.deviceLedgerId,
|
deviceName: item.deviceName ?? item.name,
|
deviceModel: item.deviceModel ?? item.model,
|
});
|
|
const collectDevices = (node) => {
|
const currentDevices = getNodeDevices(node).map(normalizeDevice);
|
const childDevices = (node?.children || []).flatMap((child) =>
|
collectDevices(child)
|
);
|
const deviceMap = new Map();
|
[...currentDevices, ...childDevices].forEach((item) => {
|
if (item?.id !== undefined && item?.id !== null) {
|
deviceMap.set(Number(item.id), item);
|
}
|
});
|
return Array.from(deviceMap.values());
|
};
|
|
const findAreaNode = (nodes, areaId) => {
|
for (const node of nodes || []) {
|
if (Number(node.id) === Number(areaId)) {
|
return node;
|
}
|
const target = findAreaNode(node.children, areaId);
|
if (target) {
|
return target;
|
}
|
}
|
return null;
|
};
|
|
const loadDevicesByArea = async (areaId) => {
|
if (!areaId) {
|
deviceOptions.value = [];
|
return;
|
}
|
const { data } = await getDeviceAreaTreeWithDevices();
|
const treeData = Array.isArray(data) ? data : [];
|
const currentNode = findAreaNode(treeData, areaId);
|
deviceOptions.value = currentNode ? collectDevices(currentNode) : [];
|
};
|
|
const syncDeviceFields = (deviceIds) => {
|
const selectedIds = normalizeIdList(deviceIds);
|
const selectedDevices = selectedIds
|
.map((deviceId) =>
|
deviceOptions.value.find((item) => Number(item.id) === Number(deviceId))
|
)
|
.filter(Boolean);
|
|
form.deviceLedgerIds = selectedIds;
|
form.deviceLedgerId = selectedIds[0];
|
form.deviceLedgerIdsStr = selectedIds.join(",");
|
form.deviceName = selectedDevices
|
.map((item) => item.deviceName)
|
.filter(Boolean)
|
.join(",");
|
form.deviceModel = selectedDevices
|
.map((item) => item.deviceModel || "-")
|
.join(",");
|
};
|
|
const setDeviceModels = (deviceIds) => {
|
syncDeviceFields(deviceIds);
|
};
|
|
const setForm = (data) => {
|
form.areaId = data.areaId;
|
form.deviceLedgerIds = normalizeIdList(
|
data.deviceLedgerIds ?? data.deviceLedgerIdsStr ?? data.deviceLedgerId
|
);
|
form.deviceLedgerId = form.deviceLedgerIds[0];
|
form.deviceLedgerIdsStr =
|
data.deviceLedgerIdsStr ?? form.deviceLedgerIds.join(",");
|
form.deviceName = data.deviceName;
|
form.deviceModel = data.deviceModel;
|
form.repairTime = data.repairTime;
|
form.repairName = data.repairName;
|
form.remark = data.remark;
|
form.status = data.status;
|
};
|
|
const handleAreaChange = async (areaId) => {
|
form.deviceLedgerId = undefined;
|
form.deviceLedgerIds = [];
|
form.deviceLedgerIdsStr = undefined;
|
form.deviceName = undefined;
|
form.deviceModel = undefined;
|
await loadDevicesByArea(areaId);
|
};
|
|
const sendForm = async () => {
|
loading.value = true;
|
try {
|
syncDeviceFields(form.deviceLedgerIds);
|
const payload = {
|
...form,
|
deviceLedgerId: form.deviceLedgerIds[0],
|
deviceLedgerIds: [...form.deviceLedgerIds],
|
deviceLedgerIdsStr: form.deviceLedgerIds.join(","),
|
deviceModel: form.deviceModel || "-",
|
};
|
const { code } = id.value
|
? await editRepair({ id: unref(id), ...payload })
|
: await addRepair(payload);
|
if (code === 200) {
|
ElMessage.success(`${id.value ? "编辑" : "新增"}报修成功`);
|
visible.value = false;
|
emits("ok");
|
}
|
} finally {
|
loading.value = false;
|
}
|
};
|
|
const handleCancel = () => {
|
resetForm();
|
visible.value = false;
|
};
|
|
const handleClose = () => {
|
resetForm();
|
visible.value = false;
|
};
|
|
const openAdd = async () => {
|
id.value = undefined;
|
visible.value = true;
|
await nextTick();
|
await loadAreaTree();
|
deviceOptions.value = [];
|
};
|
|
const openEdit = async (editId) => {
|
const { data } = await getRepairById(editId);
|
id.value = editId;
|
visible.value = true;
|
await nextTick();
|
await loadAreaTree();
|
setForm(data);
|
await loadDevicesByArea(form.areaId);
|
syncDeviceFields(form.deviceLedgerIds);
|
};
|
|
defineExpose({
|
openAdd,
|
openEdit,
|
});
|
</script>
|
|
<style lang="scss" scoped></style>
|