fix: 设备保养:可以在app上面进行设备保养计划新增,可多选设备(不需要设备编号),计划新增后,需定时生成多条任务(根据选择的多个设备生成多个任务)
| | |
| | | <el-form ref="formRef" :model="form" :rules="rules" label-width="120px"> |
| | | <el-row> |
| | | <el-col :span="12"> |
| | | <el-form-item label="设备名称" prop="taskId"> |
| | | <el-select v-model="form.taskId" @change="setDeviceModel" filterable> |
| | | <el-form-item label="任务名称" prop="taskName"> |
| | | <el-input v-model="form.taskName" placeholder="请输入任务名称" clearable /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="设备名称" prop="deviceIds"> |
| | | <el-select |
| | | v-model="form.deviceIds" |
| | | multiple |
| | | filterable |
| | | placeholder="请选择设备" |
| | | @change="handleDeviceChange" |
| | | > |
| | | <el-option |
| | | v-for="(item, index) in deviceOptions" |
| | | :key="index" |
| | |
| | | </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 |
| | |
| | | const data = reactive({ |
| | | form: { |
| | | taskId: undefined, |
| | | taskName: undefined, |
| | | deviceIds: [], |
| | | taskName: "", |
| | | // 录入人:单选一个用户 id |
| | | inspector: undefined, |
| | | remarks: '', |
| | |
| | | registrationDate: '' |
| | | }, |
| | | rules: { |
| | | taskId: [{ required: true, message: "请选择设备", trigger: "change" },], |
| | | deviceIds: [{ required: true, message: "请选择设备", trigger: "change" }], |
| | | taskName: [{ required: true, message: "请输入任务名称", trigger: "blur" }], |
| | | inspector: [{ required: true, message: "请选择录入人", trigger: "blur" },], |
| | | registrationDate: [{ required: true, message: "请选择登记时间", trigger: "change" }] |
| | | } |
| | |
| | | deviceOptions.value = data; |
| | | }; |
| | | |
| | | // 选择设备时,回填设备名称(taskName)和规格型号(deviceModel) |
| | | const setDeviceModel = (id) => { |
| | | const option = deviceOptions.value.find((item) => item.id === id); |
| | | if (option) { |
| | | form.value.taskId = option.id; |
| | | form.value.taskName = option.deviceName; |
| | | form.value.deviceModel = option.deviceModel; |
| | | const normalizeIdList = (val) => { |
| | | if (!val) return [] |
| | | if (Array.isArray(val)) return val |
| | | if (typeof val === 'string') { |
| | | const s = val.trim() |
| | | // JSON 字符串:"[1,2,3]" |
| | | if (s.startsWith('[') && s.endsWith(']')) { |
| | | try { |
| | | const arr = JSON.parse(s) |
| | | return Array.isArray(arr) ? arr : [] |
| | | } catch { |
| | | return [] |
| | | } |
| | | } |
| | | // 逗号分隔:"1,2,3" |
| | | return s.split(',').map(v => v.trim()).filter(Boolean) |
| | | } |
| | | return [] |
| | | } |
| | | |
| | | // 选择设备时,顺带回填规格型号(多选时取第一个设备的规格型号) |
| | | const handleDeviceChange = () => { |
| | | const selectedIds = form.value.deviceIds || [] |
| | | const firstId = Array.isArray(selectedIds) ? selectedIds[0] : undefined |
| | | const firstDevice = deviceOptions.value.find(d => String(d.id) === String(firstId)) |
| | | form.value.deviceModel = firstDevice?.deviceModel || firstDevice?.model || form.value.deviceModel |
| | | } |
| | | |
| | | // 打开弹框 |
| | |
| | | await loadDeviceName(); |
| | | |
| | | if (type === 'edit' && row) { |
| | | form.value = { ...row } |
| | | form.value = { ...form.value, ...row } |
| | | // 编辑时用接口返回的 registrantId 回显录入人 |
| | | if (row.registrantId) { |
| | | form.value.inspector = row.registrantId |
| | | } |
| | | |
| | | // 如果有设备ID,自动设置设备信息 |
| | | if (form.value.taskId) { |
| | | setDeviceModel(form.value.taskId); |
| | | } |
| | | // 编辑回显:deviceIds 可能是 JSON 字符串 / 逗号分隔 / 数组 |
| | | const ids = normalizeIdList(row.deviceIds ?? row.taskIds) |
| | | form.value.deviceIds = ids.map(v => { |
| | | const n = Number(v) |
| | | return Number.isNaN(n) ? v : n |
| | | }) |
| | | handleDeviceChange() |
| | | } else if (type === 'add') { |
| | | // 新增时设置登记日期为当天 |
| | | form.value.registrationDate = getCurrentDate(); |
| | |
| | | // 重置表单数据确保设备信息正确重置 |
| | | form.value = { |
| | | taskId: undefined, |
| | | taskName: undefined, |
| | | inspector: undefined, |
| | | deviceIds: [], |
| | | taskName: "", |
| | | inspector: undefined, |
| | | remarks: '', |
| | | frequencyType: '', |
| | |
| | | if (valid) { |
| | | try { |
| | | const payload = { ...form.value } |
| | | // 后端要求:deviceIds 以 JSON.stringify([1,2,3]) 形式传参 |
| | | payload.deviceIds = JSON.stringify(form.value.deviceIds || []) |
| | | // 不再向后端传保养人字段,仅使用接口要求的 registrant / registrantId |
| | | // 根据选择的"录入人"设置 registrant / registrantId |
| | | if (payload.inspector) { |
| | |
| | | } |
| | | delete payload.inspector |
| | | delete payload.inspectorIds |
| | | delete payload.taskIds |
| | | |
| | | if (payload.frequencyType === 'WEEKLY') { |
| | | let frequencyDetail = '' |
| | |
| | | :prefix-icon="Search" |
| | | @change="getScheduledTableData" /> |
| | | </el-form-item> |
| | | <el-form-item label="任务状态"> |
| | | <!-- <el-form-item label="任务状态"> |
| | | <el-select v-model="scheduledFilters.status" |
| | | placeholder="请选择任务状态" |
| | | clearable |
| | |
| | | <el-option label="停用" |
| | | value="0" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-form-item> --> |
| | | <el-form-item> |
| | | <el-button type="primary" |
| | | @click="getScheduledTableData">搜索</el-button> |
| | |
| | | |
| | | // 定时任务管理表格列配置 |
| | | const scheduledColumns = ref([ |
| | | { prop: "taskName", label: "设备名称" }, |
| | | { prop: "taskName", label: "任务名称" }, |
| | | { |
| | | label: "规格型号", |
| | | prop: "deviceModel", |
| | | prop: "deviceName", |
| | | label: "设备", |
| | | minWidth: 180 |
| | | }, |
| | | { |
| | | prop: "frequencyType", |
| | |
| | | <el-table-column label="入库数量" |
| | | prop="stockInNum" |
| | | show-overflow-tooltip/> |
| | | <el-table-column label="车牌号" |
| | | prop="licensePlateNo" |
| | | v-if="type === '0'" |
| | | show-overflow-tooltip/> |
| | | <el-table-column label="毛重(吨)" |
| | | prop="grossWeight" |
| | | v-if="type === '0'" |
| | | show-overflow-tooltip/> |
| | | <el-table-column label="皮重(吨)" |
| | | prop="tareWeight" |
| | | v-if="type === '0'" |
| | | show-overflow-tooltip/> |
| | | <el-table-column label="净重(吨)" |
| | | prop="netWeight" |
| | | v-if="type === '0'" |
| | |
| | | prop="weighingDate" |
| | | v-if="type === '0'" |
| | | show-overflow-tooltip/> |
| | | <el-table-column label="过磅员" |
| | | prop="weighingOperator" |
| | | v-if="type === '0'" |
| | | show-overflow-tooltip/> |
| | | </el-table> |
| | | <pagination v-show="total > 0" |
| | | :total="total" |
| | |
| | | <el-input v-model="formState.unit" disabled /> |
| | | </el-form-item> |
| | | |
| | | <!-- productType === 0:原材料 --> |
| | | <el-form-item |
| | | label="库存数量" |
| | | prop="qualitity" |
| | | v-if="type === 'qualified' && formState.productType === 0" |
| | | label="车牌号" |
| | | prop="licensePlateNo" |
| | | > |
| | | <el-input-number v-model="formState.qualitity" :step="1" :min="1" style="width: 100%" /> |
| | | <el-input v-model="formState.licensePlateNo" /> |
| | | </el-form-item> |
| | | |
| | | <el-form-item |
| | | v-if="type === 'qualified'" |
| | | label="库存预警数量" |
| | | prop="warnNum" |
| | | v-if="type === 'qualified' && formState.productType === 0" |
| | | label="毛重(吨)" |
| | | prop="grossWeight" |
| | | > |
| | | <el-input-number v-model="formState.warnNum" :step="1" :min="0" :max="formState.qualitity" style="width: 100%" /> |
| | | <el-input-number |
| | | v-model="formState.grossWeight" |
| | | :step="0.01" |
| | | :min="0" |
| | | style="width: 100%" |
| | | @change="computeNetWeight" |
| | | /> |
| | | </el-form-item> |
| | | <!-- productType === 0:原材料 --> |
| | | |
| | | <el-form-item |
| | | v-if="type === 'qualified' && formState.productType === 0" |
| | | label="皮重(吨)" |
| | | prop="tareWeight" |
| | | > |
| | | <el-input-number |
| | | v-model="formState.tareWeight" |
| | | :step="0.01" |
| | | :min="0" |
| | | style="width: 100%" |
| | | @change="computeNetWeight" |
| | | /> |
| | | </el-form-item> |
| | | |
| | | <el-form-item |
| | | v-if="type === 'qualified' && formState.productType === 0" |
| | | label="净重(吨)" |
| | | prop="netWeight" |
| | | > |
| | | <el-input-number |
| | | v-model="formState.netWeight" |
| | | :step="0.01" |
| | | :min="0" |
| | | style="width: 100%" |
| | | disabled |
| | | /> |
| | | </el-form-item> |
| | | |
| | | <el-form-item |
| | | v-if="type === 'qualified' && formState.productType === 0" |
| | | label="过磅日期" |
| | |
| | | |
| | | <el-form-item |
| | | v-if="type === 'qualified' && formState.productType === 0" |
| | | label="净重(吨)" |
| | | prop="netWeight" |
| | | label="过磅员" |
| | | prop="weighingOperator" |
| | | > |
| | | <el-input-number v-model="formState.netWeight" :step="0.01" :min="0" style="width: 100%" /> |
| | | <el-input v-model="formState.weighingOperator" /> |
| | | </el-form-item> |
| | | |
| | | <el-form-item label="备注" prop="remark"> |
| | |
| | | productName: "", |
| | | productModelName: "", |
| | | unit: "", |
| | | weighingDate: undefined, |
| | | productType: undefined, |
| | | qualitity: 0, |
| | | warnNum: 0, |
| | | // 过磅相关字段(仅原材料合格品使用) |
| | | licensePlateNo: "", |
| | | grossWeight: undefined, |
| | | tareWeight: undefined, |
| | | netWeight: undefined, |
| | | weighingDate: undefined, |
| | | weighingOperator: "", |
| | | remark: '', |
| | | }); |
| | | |
| | |
| | | // 产品选择处理 |
| | | const handleProductSelect = async (products) => { |
| | | formState.value.weighingDate = undefined; |
| | | formState.value.grossWeight = undefined; |
| | | formState.value.tareWeight = undefined; |
| | | formState.value.netWeight = undefined; |
| | | if (products && products.length > 0) { |
| | | const product = products[0]; |
| | |
| | | } |
| | | }; |
| | | |
| | | // 净重 = 毛重 - 皮重 |
| | | const computeNetWeight = () => { |
| | | const { grossWeight, tareWeight } = formState.value; |
| | | if (grossWeight != null && tareWeight != null) { |
| | | const net = Number(grossWeight) - Number(tareWeight); |
| | | // 保留两位小数,且不为负 |
| | | const safeNet = Number(net.toFixed(2)); |
| | | formState.value.netWeight = safeNet > 0 ? safeNet : 0; |
| | | } else { |
| | | formState.value.netWeight = undefined; |
| | | } |
| | | }; |
| | | |
| | | const handleSubmit = () => { |
| | | proxy.$refs["formRef"].validate(valid => { |
| | | if (valid) { |
| | |
| | | <el-table-column label="单位" prop="unit" show-overflow-tooltip /> |
| | | <el-table-column label="库存数量" prop="qualitity" show-overflow-tooltip /> |
| | | <el-table-column label="冻结数量" prop="lockedQuantity" show-overflow-tooltip /> |
| | | <el-table-column label="库存预警数量" prop="warnNum" show-overflow-tooltip /> |
| | | <!-- <el-table-column label="库存预警数量" prop="warnNum" show-overflow-tooltip /> --> |
| | | <el-table-column label="净重(吨)" prop="netWeight" show-overflow-tooltip /> |
| | | <el-table-column label="备注" prop="remark" show-overflow-tooltip /> |
| | | <el-table-column label="最近更新时间" prop="updateTime" show-overflow-tooltip /> |
| | |
| | | </el-form-item> |
| | | |
| | | <el-form-item |
| | | label="数量" |
| | | prop="qualitity" |
| | | > |
| | | <el-input-number v-model="formState.qualitity" :step="1" :min="1" :max="maxQuality" style="width: 100%" /> |
| | | </el-form-item> |
| | | |
| | | <el-form-item |
| | | v-if="isRawMaterial" |
| | | label="净重" |
| | | prop="netWeight" |
| | | > |
| | | <el-input-number v-model="formState.netWeight" :precision="2" :step="0.01" :min="0" style="width: 100%" /> |
| | | </el-form-item> |
| | | |
| | | <el-form-item |
| | | label="车牌号" |
| | | prop="licensePlateNo" |
| | | > |
| | | <el-input v-model="formState.licensePlateNo" /> |
| | | </el-form-item> |
| | | |
| | | <el-form-item |
| | | label="毛重(吨)" |
| | | prop="grossWeight" |
| | | > |
| | | <el-input-number |
| | | v-model="formState.grossWeight" |
| | | :step="0.01" |
| | | :min="0" |
| | | style="width: 100%" |
| | | @change="computeNetWeight" |
| | | /> |
| | | </el-form-item> |
| | | |
| | | <el-form-item |
| | | label="皮重(吨)" |
| | | prop="tareWeight" |
| | | > |
| | | <el-input-number |
| | | v-model="formState.tareWeight" |
| | | :step="0.01" |
| | | :min="0" |
| | | style="width: 100%" |
| | | @change="computeNetWeight" |
| | | /> |
| | | </el-form-item> |
| | | |
| | | <el-form-item |
| | | label="净重(吨)" |
| | | prop="netWeight" |
| | | > |
| | | <el-input-number |
| | | v-model="formState.netWeight" |
| | | :step="0.01" |
| | | :min="0" |
| | | style="width: 100%" |
| | | disabled |
| | | /> |
| | | </el-form-item> |
| | | |
| | | <el-form-item |
| | | label="过磅日期" |
| | | prop="weighingDate" |
| | | > |
| | | <el-date-picker |
| | | style="width: 100%" |
| | | v-model="formState.weighingDate" |
| | | value-format="YYYY-MM-DD HH:mm:ss" |
| | | format="YYYY-MM-DD HH:mm:ss" |
| | | type="datetime" |
| | | placeholder="请选择过磅日期" |
| | | clearable |
| | | /> |
| | | </el-form-item> |
| | | |
| | | <el-form-item |
| | | label="过磅员" |
| | | prop="weighingOperator" |
| | | > |
| | | <el-input v-model="formState.weighingOperator" /> |
| | | </el-form-item> |
| | | |
| | | <el-form-item label="备注" prop="remark"> |
| | |
| | | </template> |
| | | |
| | | <script setup> |
| | | import {ref, computed, getCurrentInstance} from "vue"; |
| | | import {ref, computed, getCurrentInstance, onMounted} from "vue"; |
| | | import ProductSelectDialog from "@/views/basicData/product/ProductSelectDialog.vue"; |
| | | import {subtractStockInventory} from "@/api/inventoryManagement/stockInventory.js"; |
| | | import {subtractStockUnInventory} from "@/api/inventoryManagement/stockUninventory.js"; |
| | |
| | | initFormData() |
| | | }) |
| | | |
| | | const maxQuality = computed(() => { |
| | | return props.record.unLockedQuantity ? props.record.unLockedQuantity : 0; |
| | | }) |
| | | |
| | | const isRawMaterial = computed(() => { |
| | | return props.record.parentName === '原材料'; |
| | | }) |
| | |
| | | productName: "", |
| | | model: "", |
| | | unit: "", |
| | | qualitity: 0, |
| | | // 过磅相关字段 |
| | | licensePlateNo: "", |
| | | grossWeight: undefined, |
| | | tareWeight: undefined, |
| | | netWeight: undefined, |
| | | licensePlateNo: undefined, |
| | | weighingDate: undefined, |
| | | weighingOperator: "", |
| | | remark: '', |
| | | }); |
| | | |
| | |
| | | productName: "", |
| | | model: "", |
| | | unit: "", |
| | | qualitity: 0, |
| | | licensePlateNo: "", |
| | | grossWeight: undefined, |
| | | tareWeight: undefined, |
| | | netWeight: undefined, |
| | | weighingDate: undefined, |
| | | weighingOperator: "", |
| | | remark: '', |
| | | }; |
| | | isShow.value = false; |
| | | }; |
| | | |
| | | // 净重 = 毛重 - 皮重 |
| | | const computeNetWeight = () => { |
| | | const { grossWeight, tareWeight } = formState.value; |
| | | if (grossWeight != null && tareWeight != null) { |
| | | const net = Number(grossWeight) - Number(tareWeight); |
| | | const safeNet = Number(net.toFixed(2)); |
| | | formState.value.netWeight = safeNet > 0 ? safeNet : 0; |
| | | } else { |
| | | formState.value.netWeight = undefined; |
| | | } |
| | | }; |
| | | |
| | | // 产品选择处理 |
| | | const handleProductSelect = async (products) => { |
| | | if (products && products.length > 0) { |