<template>
|
<FormDialog
|
v-model="dialogVisitable"
|
:title="operationType === 'add' ? '新增保养任务' : '编辑保养任务'"
|
width="800px"
|
:operation-type="operationType"
|
@confirm="submitForm"
|
@cancel="cancel"
|
@close="cancel"
|
>
|
<el-form ref="formRef" :model="form" :rules="rules" label-width="120px">
|
<el-row>
|
<el-col :span="12">
|
<el-form-item label="所属区域" prop="areaId">
|
<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="设备名称" prop="deviceLedgerIds">
|
<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-row>
|
<el-row>
|
<el-col :span="12">
|
<el-form-item label="录入人" prop="inspector">
|
<el-select
|
v-model="form.inspector"
|
filterable
|
default-first-option
|
:reserve-keyword="false"
|
placeholder="请选择"
|
clearable
|
>
|
<el-option
|
v-for="item in userList"
|
:key="item.userId"
|
:label="item.nickName"
|
:value="item.userId"
|
/>
|
</el-select>
|
</el-form-item>
|
</el-col>
|
<el-col :span="12">
|
<el-form-item label="登记时间" prop="registrationDate">
|
<el-date-picker
|
v-model="form.registrationDate"
|
type="date"
|
placeholder="选择登记日期"
|
format="YYYY-MM-DD"
|
value-format="YYYY-MM-DD"
|
style="width: 100%"
|
/>
|
</el-form-item>
|
</el-col>
|
</el-row>
|
<el-row>
|
<el-col :span="12">
|
<el-form-item label="任务频率" prop="frequencyType">
|
<el-select v-model="form.frequencyType" placeholder="请选择" clearable>
|
<el-option label="每日" value="DAILY" />
|
<el-option label="每周" value="WEEKLY" />
|
<el-option label="每月" value="MONTHLY" />
|
<el-option label="季度" value="QUARTERLY" />
|
<el-option label="每年" value="YEARLY" />
|
</el-select>
|
</el-form-item>
|
</el-col>
|
<el-col :span="12" v-if="form.frequencyType === 'DAILY'">
|
<el-form-item label="日期" prop="frequencyDetail">
|
<el-time-picker
|
v-model="form.frequencyDetail"
|
placeholder="选择时间"
|
format="HH:mm"
|
value-format="HH:mm"
|
/>
|
</el-form-item>
|
</el-col>
|
<el-col :span="12" v-if="form.frequencyType === 'WEEKLY'">
|
<el-form-item label="日期" prop="frequencyDetail">
|
<el-select v-model="form.week" placeholder="请选择" clearable style="width: 50%">
|
<el-option label="周一" value="MON" />
|
<el-option label="周二" value="TUE" />
|
<el-option label="周三" value="WED" />
|
<el-option label="周四" value="THU" />
|
<el-option label="周五" value="FRI" />
|
<el-option label="周六" value="SAT" />
|
<el-option label="周日" value="SUN" />
|
</el-select>
|
<el-time-picker
|
v-model="form.time"
|
placeholder="选择时间"
|
format="HH:mm"
|
value-format="HH:mm"
|
style="width: 50%"
|
/>
|
</el-form-item>
|
</el-col>
|
<el-col :span="12" v-if="form.frequencyType === 'MONTHLY'">
|
<el-form-item label="日期" prop="frequencyDetail">
|
<el-date-picker
|
v-model="form.frequencyDetail"
|
type="datetime"
|
clearable
|
placeholder="选择开始日期"
|
format="DD,HH:mm"
|
value-format="DD,HH:mm"
|
/>
|
</el-form-item>
|
</el-col>
|
<el-col :span="12" v-if="form.frequencyType === 'QUARTERLY'">
|
<el-form-item label="日期" prop="frequencyDetail">
|
<el-date-picker
|
v-model="form.frequencyDetail"
|
type="datetime"
|
clearable
|
placeholder="选择开始日期"
|
format="MM,DD,HH:mm"
|
value-format="MM,DD,HH:mm"
|
/>
|
</el-form-item>
|
</el-col>
|
<el-col :span="12" v-if="form.frequencyType === 'YEARLY'">
|
<el-form-item label="日期" prop="frequencyDetail">
|
<el-date-picker
|
v-model="form.frequencyDetail"
|
type="datetime"
|
clearable
|
placeholder="选择开始日期"
|
format="MM,DD,HH:mm"
|
value-format="MM,DD,HH:mm"
|
/>
|
</el-form-item>
|
</el-col>
|
</el-row>
|
<el-row>
|
<el-col :span="12">
|
<el-form-item label="备注" prop="remarks">
|
<el-input v-model="form.remarks" placeholder="请输入备注" type="textarea" />
|
</el-form-item>
|
</el-col>
|
</el-row>
|
</el-form>
|
</FormDialog>
|
</template>
|
|
<script setup>
|
import { getCurrentInstance, reactive, ref, toRefs } from "vue";
|
import FormDialog from "@/components/Dialog/FormDialog.vue";
|
import { userListNoPageByTenantId } from "@/api/system/user.js";
|
import {
|
getDeviceAreaTree,
|
getDeviceAreaTreeWithDevices,
|
} from "@/api/equipmentManagement/deviceArea";
|
import {
|
deviceMaintenanceTaskAdd,
|
deviceMaintenanceTaskEdit,
|
} from "@/api/equipmentManagement/upkeep";
|
import { getCurrentDate } from "@/utils/index.js";
|
import useUserStore from "@/store/modules/user.js";
|
|
const { proxy } = getCurrentInstance();
|
const emit = defineEmits(["closeDia"]);
|
const dialogVisitable = ref(false);
|
const operationType = ref("add");
|
const areaOptions = ref([]);
|
const deviceOptions = ref([]);
|
const userList = ref([]);
|
const areaTreeProps = {
|
label: "areaName",
|
children: "children",
|
};
|
const userStore = useUserStore();
|
|
const data = reactive({
|
form: {
|
areaId: undefined,
|
taskId: undefined,
|
taskIds: [],
|
taskIdsStr: undefined,
|
deviceLedgerIds: [],
|
deviceLedgerIdsStr: undefined,
|
taskName: undefined,
|
inspector: undefined,
|
remarks: "",
|
frequencyType: "",
|
frequencyDetail: "",
|
week: "",
|
time: "",
|
deviceModel: undefined,
|
registrationDate: "",
|
},
|
rules: {
|
areaId: [{ required: true, message: "请选择所属区域", trigger: "change" }],
|
deviceLedgerIds: [{ required: true, message: "请选择设备", trigger: "change" }],
|
inspector: [{ required: true, message: "请选择录入人", trigger: "change" }],
|
registrationDate: [{ required: true, message: "请选择登记时间", trigger: "change" }],
|
},
|
});
|
|
const { form, rules } = toRefs(data);
|
|
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.value.deviceLedgerIds = selectedIds;
|
form.value.deviceLedgerIdsStr = selectedIds.join(",");
|
form.value.taskIds = [...selectedIds];
|
form.value.taskIdsStr = selectedIds.join(",");
|
form.value.taskId = selectedIds[0];
|
form.value.taskName = selectedDevices
|
.map((item) => item.deviceName)
|
.filter(Boolean)
|
.join(",");
|
form.value.deviceModel = selectedDevices
|
.map((item) => item.deviceModel || "-")
|
.join(",");
|
};
|
|
const setDeviceModels = (deviceIds) => {
|
syncDeviceFields(deviceIds);
|
};
|
|
const handleAreaChange = async (areaId) => {
|
form.value.taskId = undefined;
|
form.value.taskIds = [];
|
form.value.taskIdsStr = undefined;
|
form.value.deviceLedgerIds = [];
|
form.value.deviceLedgerIdsStr = undefined;
|
form.value.taskName = undefined;
|
form.value.deviceModel = undefined;
|
await loadDevicesByArea(areaId);
|
};
|
|
const resetForm = () => {
|
if (proxy.$refs.formRef) {
|
proxy.$refs.formRef.resetFields();
|
}
|
form.value = {
|
areaId: undefined,
|
taskId: undefined,
|
taskIds: [],
|
taskIdsStr: undefined,
|
deviceLedgerIds: [],
|
deviceLedgerIdsStr: undefined,
|
taskName: undefined,
|
inspector: undefined,
|
remarks: "",
|
frequencyType: "",
|
frequencyDetail: "",
|
week: "",
|
time: "",
|
deviceModel: undefined,
|
registrationDate: "",
|
};
|
};
|
|
const openDialog = async (type, row) => {
|
dialogVisitable.value = true;
|
operationType.value = type;
|
resetForm();
|
|
userListNoPageByTenantId().then((res) => {
|
userList.value = res.data;
|
});
|
|
await loadAreaTree();
|
|
if (type === "edit" && row) {
|
form.value = {
|
...form.value,
|
...row,
|
inspector: row.registrantId || row.inspector,
|
};
|
form.value.deviceLedgerIds = normalizeIdList(
|
row.deviceLedgerIds ??
|
row.deviceLedgerIdsStr ??
|
row.taskIds ??
|
row.taskIdsStr ??
|
row.taskId
|
);
|
form.value.deviceLedgerIdsStr = form.value.deviceLedgerIds.join(",");
|
form.value.taskIds = [...form.value.deviceLedgerIds];
|
form.value.taskIdsStr = form.value.deviceLedgerIds.join(",");
|
form.value.taskId = form.value.deviceLedgerIds[0];
|
|
if (form.value.areaId) {
|
await loadDevicesByArea(form.value.areaId);
|
syncDeviceFields(form.value.deviceLedgerIds);
|
}
|
} else {
|
form.value.registrationDate = getCurrentDate();
|
form.value.inspector = userStore.id;
|
deviceOptions.value = [];
|
}
|
};
|
|
const cancel = () => {
|
resetForm();
|
dialogVisitable.value = false;
|
emit("closeDia");
|
};
|
|
const submitForm = () => {
|
proxy.$refs.formRef.validate(async (valid) => {
|
if (!valid) {
|
return;
|
}
|
try {
|
syncDeviceFields(form.value.deviceLedgerIds);
|
const payload = { ...form.value };
|
|
if (payload.inspector) {
|
const selectedUser = userList.value.find(
|
(item) => String(item.userId) === String(payload.inspector)
|
);
|
if (selectedUser) {
|
payload.registrantId = selectedUser.userId;
|
payload.registrant = selectedUser.nickName;
|
}
|
}
|
|
delete payload.inspector;
|
delete payload.inspectorIds;
|
|
if (payload.frequencyType === "WEEKLY") {
|
payload.frequencyDetail = `${payload.week},${payload.time}`;
|
}
|
|
if (
|
payload.status === undefined ||
|
payload.status === null ||
|
payload.status === ""
|
) {
|
payload.status = "0";
|
}
|
|
payload.deviceLedgerIds = [...form.value.deviceLedgerIds];
|
payload.deviceLedgerIdsStr = form.value.deviceLedgerIds.join(",");
|
payload.taskIds = [...form.value.deviceLedgerIds];
|
payload.taskIdsStr = form.value.deviceLedgerIds.join(",");
|
payload.taskId = form.value.deviceLedgerIds[0];
|
payload.taskName = form.value.taskName;
|
payload.deviceModel = form.value.deviceModel || "-";
|
payload.active = true;
|
payload.deleted = 0;
|
|
if (operationType.value === "edit") {
|
await deviceMaintenanceTaskEdit(payload);
|
} else {
|
await deviceMaintenanceTaskAdd(payload);
|
}
|
|
cancel();
|
proxy.$modal.msgSuccess("提交成功");
|
} catch (error) {
|
proxy.$modal.msgError("提交失败,请重试");
|
}
|
});
|
};
|
|
defineExpose({ openDialog });
|
</script>
|
|
<style scoped></style>
|