| | |
| | | <template> |
| | | <el-drawer v-model="visible" :title="modalOptions.title" direction="ltr"> |
| | | <MaintainForm ref="maintainFormRef" /> |
| | | <template #footer> |
| | | <el-button @click="closeModal">{{ modalOptions.cancelText }}</el-button> |
| | | <el-button type="primary" @click="sendForm" :loading="loading"> |
| | | {{ modalOptions.confirmText }} |
| | | </el-button> |
| | | </template> |
| | | </el-drawer> |
| | | <FormDialog |
| | | v-model="visible" |
| | | :title="'设备维修'" |
| | | width="500px" |
| | | @confirm="sendForm" |
| | | @cancel="handleCancel" |
| | | @close="handleClose" |
| | | > |
| | | <el-form :model="form" label-width="80px"> |
| | | <el-form-item label="维修人"> |
| | | <el-input v-model="form.maintenanceName" placeholder="请输入维修人" /> |
| | | </el-form-item> |
| | | <el-form-item label="维修结果"> |
| | | <el-input v-model="form.maintenanceResult" placeholder="请输入维修结果" /> |
| | | </el-form-item> |
| | | <el-form-item label="维修状态"> |
| | | <el-select v-model="form.status"> |
| | | <el-option label="待报修" :value="0"></el-option> |
| | | <el-option label="完结" :value="1"></el-option> |
| | | <el-option label="失败" :value="2"></el-option> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item label="维修日期"> |
| | | <el-date-picker |
| | | v-model="form.maintenanceTime" |
| | | placeholder="请选择维修日期" |
| | | format="YYYY-MM-DD HH:mm:ss" |
| | | value-format="YYYY-MM-DD HH:mm:ss" |
| | | type="datetime" |
| | | clearable |
| | | style="width: 100%" |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item label="设备备件"> |
| | | <el-select v-model="form.sparePartsIds" :loading="loadingSparePartOptions" placeholder="请选择设备备件" multiple filterable> |
| | | <el-option |
| | | v-for="item in sparePartOptions" |
| | | :key="item.id" |
| | | :label="item.name" |
| | | :value="item.id" |
| | | /> |
| | | </el-select> |
| | | </el-form-item> |
| | | |
| | | <el-form-item v-if="selectedSpareParts.length" label="领用数量"> |
| | | <div style="width: 100%"> |
| | | <div |
| | | v-for="item in selectedSpareParts" |
| | | :key="item.id" |
| | | style="display: flex; align-items: center; gap: 10px; margin-bottom: 10px;" |
| | | > |
| | | <div style="flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;"> |
| | | {{ item.name }} |
| | | <span v-if="item.quantity !== null && item.quantity !== undefined" style="color: #909399;"> |
| | | (库存:{{ item.quantity }}) |
| | | </span> |
| | | </div> |
| | | <el-input-number |
| | | v-model="sparePartQtyMap[item.id]" |
| | | :min="1" |
| | | :max="item.quantity !== null && item.quantity !== undefined ? Number(item.quantity) : undefined" |
| | | :step="1" |
| | | controls-position="right" |
| | | style="width: 180px" |
| | | /> |
| | | </div> |
| | | </div> |
| | | </el-form-item> |
| | | </el-form> |
| | | </FormDialog> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { useModal } from "@/hooks/useModal"; |
| | | import MaintainForm from "../Form/MaintainForm.vue"; |
| | | import { computed, getCurrentInstance, nextTick, ref } from "vue"; |
| | | import FormDialog from "@/components/Dialog/FormDialog.vue"; |
| | | import { addMaintain } from "@/api/equipmentManagement/repair"; |
| | | import useFormData from "@/hooks/useFormData"; |
| | | import useUserStore from "@/store/modules/user"; |
| | | import dayjs from "dayjs"; |
| | | import { ElMessage } from "element-plus"; |
| | | import { getSparePartsList } from "@/api/equipmentManagement/spareParts"; |
| | | |
| | | defineOptions({ |
| | | name: "维修模态框", |
| | | }); |
| | | |
| | | const maintainFormRef = ref(); |
| | | const emits = defineEmits(["ok"]); |
| | | const { proxy } = getCurrentInstance(); |
| | | |
| | | const { |
| | | id, |
| | | visible, |
| | | loading, |
| | | openModal, |
| | | modalOptions, |
| | | handleConfirm, |
| | | closeModal, |
| | | } = useModal({ title: "设备维修" }); |
| | | // 保存报修记录的id |
| | | const repairId = ref(); |
| | | const visible = ref(false); |
| | | const loading = ref(false); |
| | | |
| | | const userStore = useUserStore(); |
| | | const { form, resetForm } = useFormData({ |
| | | maintenanceName: undefined, // 维修名称 |
| | | maintenanceResult: undefined, // 维修结果 |
| | | maintenanceTime: undefined, // 维修日期 |
| | | status: 0, |
| | | sparePartsIds: [], |
| | | }); |
| | | const sparePartOptions = ref([]) |
| | | const loadingSparePartOptions = ref(true) |
| | | const sparePartQtyMap = ref({}) |
| | | |
| | | const selectedSpareParts = computed(() => { |
| | | const ids = Array.isArray(form.sparePartsIds) ? form.sparePartsIds : []; |
| | | const set = new Set(ids.map((i) => String(i))); |
| | | return (sparePartOptions.value || []).filter((p) => set.has(String(p.id))); |
| | | }); |
| | | |
| | | const setForm = (data) => { |
| | | form.maintenanceName = data.maintenanceName ?? userStore.nickName; |
| | | form.maintenanceResult = data.maintenanceResult; |
| | | form.maintenanceTime = |
| | | data.maintenanceTime |
| | | ? dayjs(data.maintenanceTime).format("YYYY-MM-DD HH:mm:ss") |
| | | : dayjs().format("YYYY-MM-DD HH:mm:ss"); |
| | | form.status = 1; // 默认状态为完结 |
| | | // multiple 选择器要求数组;后端常返回 "1,2,3" |
| | | if (Array.isArray(data?.sparePartsIds)) { |
| | | form.sparePartsIds = data.sparePartsIds.map((v) => Number(v)).filter((v) => Number.isFinite(v)); |
| | | } else if (typeof data?.sparePartsIds === "string") { |
| | | form.sparePartsIds = data.sparePartsIds |
| | | .split(",") |
| | | .map((s) => Number(String(s).trim())) |
| | | .filter((v) => Number.isFinite(v)); |
| | | } else if (typeof data?.sparePartsIds === "number") { |
| | | form.sparePartsIds = [data.sparePartsIds]; |
| | | } else { |
| | | form.sparePartsIds = []; |
| | | } |
| | | }; |
| | | |
| | | const sendForm = async () => { |
| | | loading.value = true; |
| | | const form = await maintainFormRef.value.getForm(); |
| | | const { code } = await addMaintain({ id: id.value, ...form }); |
| | | if (code == 200) { |
| | | emits("ok"); |
| | | maintainFormRef.value.resetForm(); |
| | | closeModal(); |
| | | try { |
| | | // 领用数量校验 |
| | | if (Array.isArray(form.sparePartsIds) && form.sparePartsIds.length > 0) { |
| | | for (const partId of form.sparePartsIds) { |
| | | const qty = Number(sparePartQtyMap.value?.[partId]); |
| | | if (!Number.isFinite(qty) || qty <= 0) { |
| | | proxy?.$modal?.msgError?.("请填写备件领用数量"); |
| | | return; |
| | | } |
| | | const part = sparePartOptions.value.find((p) => String(p.id) === String(partId)); |
| | | const stock = part?.quantity; |
| | | if (stock !== null && stock !== undefined && Number.isFinite(Number(stock))) { |
| | | if (qty > Number(stock)) { |
| | | proxy?.$modal?.msgError?.(`备件「${part?.name || ""}」领用数量不能超过库存(${stock})`); |
| | | return; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | const data = { |
| | | id: repairId.value, |
| | | ...form, |
| | | sparePartsIds: form.sparePartsIds ? form.sparePartsIds.join(",") : "", |
| | | sparePartsQty: form.sparePartsIds |
| | | ? form.sparePartsIds.map((id) => sparePartQtyMap.value?.[id] ?? 1).join(",") |
| | | : "", |
| | | sparePartsUseList: form.sparePartsIds |
| | | ? form.sparePartsIds.map((id) => ({ id, quantity: sparePartQtyMap.value?.[id] ?? 1 })) |
| | | : [], |
| | | } |
| | | const { code } = await addMaintain(data); |
| | | if (code == 200) { |
| | | ElMessage.success("维修成功"); |
| | | emits("ok"); |
| | | resetForm(); |
| | | sparePartQtyMap.value = {}; |
| | | visible.value = false; |
| | | } |
| | | } finally { |
| | | loading.value = false; |
| | | } |
| | | loading.value = false; |
| | | }; |
| | | |
| | | const fetchSparePartOptions = () => { |
| | | loadingSparePartOptions.value = true; |
| | | // 和备件管理页一致:/spareParts/listPage → res.data.records |
| | | getSparePartsList({ current: 1, size: 1000 }) |
| | | .then((res) => { |
| | | if (res.code === 200) { |
| | | sparePartOptions.value = res?.data?.records || []; |
| | | } else { |
| | | sparePartOptions.value = []; |
| | | } |
| | | }) |
| | | .catch(() => { |
| | | sparePartOptions.value = []; |
| | | }) |
| | | .finally(() => { |
| | | loadingSparePartOptions.value = false; |
| | | }); |
| | | } |
| | | |
| | | const handleCancel = () => { |
| | | resetForm(); |
| | | sparePartQtyMap.value = {}; |
| | | visible.value = false; |
| | | }; |
| | | |
| | | const handleClose = () => { |
| | | resetForm(); |
| | | sparePartQtyMap.value = {}; |
| | | visible.value = false; |
| | | }; |
| | | |
| | | const open = async (id, row) => { |
| | | openModal(id); |
| | | repairId.value = id; // 保存报修记录的id |
| | | visible.value = true; |
| | | await nextTick(); |
| | | maintainFormRef.value.setForm(row); |
| | | setForm(row); |
| | | fetchSparePartOptions() |
| | | }; |
| | | |
| | | defineExpose({ |