| | |
| | | ]"> |
| | | <el-input v-model="formState.name" /> |
| | | </el-form-item> |
| | | <el-form-item label="工序编号" prop="no"> |
| | | |
| | | <!-- <el-form-item label="工序编号" prop="no"> |
| | | <el-input v-model="formState.no" /> |
| | | </el-form-item> --> |
| | | <el-form-item |
| | | label="工序机台" |
| | | prop="deviceId" |
| | | :rules="[ |
| | | { |
| | | required: true, |
| | | message: '请选择工序类型', |
| | | } |
| | | ]" |
| | | > |
| | | <el-select |
| | | v-model="formState.deviceId" |
| | | placeholder="请选择工序机台" |
| | | filterable |
| | | remote |
| | | clearable |
| | | reserve-keyword |
| | | :remote-method="handleDeviceRemoteSearch" |
| | | :loading="deviceLoading" |
| | | @clear="handleDeviceClear" |
| | | @change="handleDeviceChange" |
| | | @visible-change="handleDeviceDropdownVisible" |
| | | popper-class="device-select-popper" |
| | | > |
| | | <el-option v-for="item in equipmentList" :key="item.id" :label="item.deviceName" :value="item.id" /> |
| | | <el-option |
| | | v-if="equipmentList.length > 0 && deviceHasMore" |
| | | :value="__deviceLoadMoreSentinel" |
| | | label="加载更多…" |
| | | disabled |
| | | /> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item |
| | | label="工序类型" |
| | |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { ref, computed, getCurrentInstance, watch } from "vue"; |
| | | import {update} from "@/api/productionManagement/productionProcess.js"; |
| | | import { ref, computed, getCurrentInstance, watch, reactive, nextTick, onBeforeUnmount } from "vue"; |
| | | import { update } from "@/api/productionManagement/productionProcess.js"; |
| | | import { getLedgerPage } from "@/api/equipmentManagement/ledger.js"; |
| | | |
| | | const props = defineProps({ |
| | | visible: { |
| | |
| | | name: props.record.name, |
| | | type: props.record.type, |
| | | no: props.record.no, |
| | | deviceId: props.record.deviceId, |
| | | deviceName: props.record.deviceName, |
| | | remark: props.record.remark, |
| | | salaryQuota: props.record.salaryQuota, |
| | | isQuality: props.record.isQuality, |
| | | }); |
| | | |
| | | const page = reactive({ |
| | | current: 1, |
| | | size: 10, |
| | | total: 0, |
| | | }); |
| | | |
| | | const equipmentList = ref([]); |
| | | const deviceLoading = ref(false); |
| | | const deviceQuery = ref(""); |
| | | const deviceScrollWrap = ref(null); |
| | | const __deviceLoadMoreSentinel = "__deviceLoadMoreSentinel"; |
| | | |
| | | const deviceHasMore = computed(() => { |
| | | const total = Number(page.total ?? 0); |
| | | if (!total) { |
| | | return false; |
| | | } |
| | | return equipmentList.value.length < total; |
| | | }); |
| | | |
| | | const handleDeviceChange = (val) => { |
| | | formState.value.deviceName = equipmentList.value.find(item => item.id === val)?.deviceName || ""; |
| | | }; |
| | | |
| | | const isShow = computed({ |
| | | get() { |
| | |
| | | }, |
| | | }); |
| | | |
| | | // 监听 record 变化,更新表单数据 |
| | | const ensureSelectedDeviceOption = () => { |
| | | const currentDeviceId = formState.value.deviceId; |
| | | if (!currentDeviceId || !props.record?.deviceName) { |
| | | return; |
| | | } |
| | | const exists = equipmentList.value.some(item => item.id === currentDeviceId); |
| | | if (!exists) { |
| | | equipmentList.value.unshift({ |
| | | id: currentDeviceId, |
| | | deviceName: props.record.deviceName, |
| | | }); |
| | | } |
| | | }; |
| | | |
| | | const getLedgerPageS = async ({ reset = false } = {}) => { |
| | | if (deviceLoading.value) return; |
| | | deviceLoading.value = true; |
| | | try { |
| | | const res = await getLedgerPage({ |
| | | current: page.current, |
| | | size: page.size, |
| | | deviceName: deviceQuery.value ? deviceQuery.value : undefined, |
| | | }); |
| | | const data = res?.data || {}; |
| | | const records = Array.isArray(data.records) ? data.records : []; |
| | | page.total = Number(data.total ?? page.total ?? 0); |
| | | page.current = Number(data.current ?? page.current); |
| | | page.size = Number(data.size ?? page.size); |
| | | equipmentList.value = reset ? records : [...equipmentList.value, ...records]; |
| | | ensureSelectedDeviceOption(); |
| | | } finally { |
| | | deviceLoading.value = false; |
| | | } |
| | | }; |
| | | |
| | | const resetDeviceOptions = async () => { |
| | | page.current = 1; |
| | | page.size = 10; |
| | | page.total = 0; |
| | | equipmentList.value = []; |
| | | await getLedgerPageS({ reset: true }); |
| | | }; |
| | | |
| | | const loadMoreDevices = async () => { |
| | | if (deviceLoading.value) return; |
| | | if (!deviceHasMore.value) return; |
| | | page.current += 1; |
| | | await getLedgerPageS(); |
| | | }; |
| | | |
| | | let remoteTimer = null; |
| | | const handleDeviceRemoteSearch = (query) => { |
| | | const nextQuery = (query ?? "").trim(); |
| | | deviceQuery.value = nextQuery; |
| | | if (remoteTimer) clearTimeout(remoteTimer); |
| | | remoteTimer = setTimeout(() => { |
| | | resetDeviceOptions(); |
| | | }, 300); |
| | | }; |
| | | |
| | | const handleDeviceClear = () => { |
| | | deviceQuery.value = ""; |
| | | resetDeviceOptions(); |
| | | }; |
| | | |
| | | const onDeviceDropdownScroll = (e) => { |
| | | const el = e.target; |
| | | if (!el) return; |
| | | if (el.scrollHeight - el.scrollTop - el.clientHeight <= 20) { |
| | | loadMoreDevices(); |
| | | } |
| | | }; |
| | | |
| | | const unbindDeviceDropdownScroll = () => { |
| | | if (deviceScrollWrap.value) { |
| | | deviceScrollWrap.value.removeEventListener("scroll", onDeviceDropdownScroll); |
| | | deviceScrollWrap.value = null; |
| | | } |
| | | }; |
| | | |
| | | const bindDeviceDropdownScroll = () => { |
| | | unbindDeviceDropdownScroll(); |
| | | const wrap = |
| | | document.querySelector(".device-select-popper .el-scrollbar__wrap") || |
| | | document.querySelector(".device-select-popper .el-select-dropdown__wrap"); |
| | | if (wrap) { |
| | | deviceScrollWrap.value = wrap; |
| | | wrap.addEventListener("scroll", onDeviceDropdownScroll); |
| | | } |
| | | }; |
| | | |
| | | const handleDeviceDropdownVisible = async (visible) => { |
| | | if (!visible) { |
| | | unbindDeviceDropdownScroll(); |
| | | return; |
| | | } |
| | | if (equipmentList.value.length === 0) { |
| | | await resetDeviceOptions(); |
| | | } |
| | | await nextTick(); |
| | | bindDeviceDropdownScroll(); |
| | | }; |
| | | |
| | | const applyRecordToForm = (record) => { |
| | | formState.value = { |
| | | id: record.id, |
| | | name: record.name || "", |
| | | no: record.no || "", |
| | | type: record.type, |
| | | deviceId: record.deviceId, |
| | | deviceName: record.deviceName || "", |
| | | remark: record.remark || "", |
| | | salaryQuota: record.salaryQuota || "", |
| | | isQuality: record.isQuality, |
| | | }; |
| | | ensureSelectedDeviceOption(); |
| | | }; |
| | | |
| | | watch(() => props.record, (newRecord) => { |
| | | if (newRecord && isShow.value) { |
| | | formState.value = { |
| | | id: newRecord.id, |
| | | name: newRecord.name || '', |
| | | no: newRecord.no || '', |
| | | type: newRecord.type, |
| | | remark: newRecord.remark || '', |
| | | salaryQuota: newRecord.salaryQuota || '', |
| | | isQuality: props.record.isQuality, |
| | | }; |
| | | applyRecordToForm(newRecord); |
| | | } |
| | | }, { immediate: true, deep: true }); |
| | | |
| | | // 监听弹窗打开,重新初始化表单数据 |
| | | watch(() => props.visible, (visible) => { |
| | | if (visible && props.record) { |
| | | formState.value = { |
| | | id: props.record.id, |
| | | name: props.record.name || '', |
| | | no: props.record.no || '', |
| | | type: props.record.type, |
| | | remark: props.record.remark || '', |
| | | salaryQuota: props.record.salaryQuota || '', |
| | | isQuality: props.record.isQuality, |
| | | }; |
| | | applyRecordToForm(props.record); |
| | | } |
| | | }); |
| | | |
| | |
| | | const handleSubmit = () => { |
| | | proxy.$refs["formRef"].validate(valid => { |
| | | if (valid) { |
| | | update(formState.value).then(res => { |
| | | update(formState.value).then(() => { |
| | | // 关闭模态框 |
| | | isShow.value = false; |
| | | // 告知父组件已完成 |
| | |
| | | handleSubmit, |
| | | isShow, |
| | | }); |
| | | |
| | | onBeforeUnmount(() => { |
| | | unbindDeviceDropdownScroll(); |
| | | if (remoteTimer) clearTimeout(remoteTimer); |
| | | }); |
| | | </script> |