| | |
| | | <el-dialog |
| | | v-model="isShow" |
| | | title="新增生产订单" |
| | | width="800" |
| | | width="1500" |
| | | :close-on-click-modal="false" |
| | | @close="closeModal" |
| | | class="production-order-dialog" |
| | | > |
| | | <el-form label-width="140px" :model="formState" label-position="top" ref="formRef"> |
| | | <el-form-item |
| | | label="产品名称" |
| | | prop="productModelId" |
| | | :rules="[ |
| | | { |
| | | required: true, |
| | | message: '请选择产品', |
| | | trigger: 'change', |
| | | } |
| | | ]" |
| | | > |
| | | <el-button type="primary" @click="showProductSelectDialog = true"> |
| | | {{ formState.productName ? formState.productName : '选择产品' }} |
| | | </el-button> |
| | | </el-form-item> |
| | | |
| | | <el-form-item |
| | | label="图纸编号" |
| | | prop="drawingNumber" |
| | | > |
| | | <el-input v-model="formState.drawingNumber" disabled /> |
| | | </el-form-item> |
| | | |
| | | <el-form-item |
| | | label="规格" |
| | | prop="productModelName" |
| | | > |
| | | <el-input v-model="formState.productModelName" disabled /> |
| | | </el-form-item> |
| | | |
| | | <el-form-item |
| | | label="单位" |
| | | prop="unit" |
| | | > |
| | | <el-input v-model="formState.unit" disabled /> |
| | | </el-form-item> |
| | | |
| | | <el-form-item label="工艺路线"> |
| | | <el-select v-model="formState.routeId" |
| | | placeholder="请选择工艺路线" |
| | | style="width: 100%;" |
| | | :loading="bindRouteLoading"> |
| | | <el-option v-for="item in routeOptions" |
| | | :key="item.id" |
| | | :label="`${item.processRouteCode || ''}`" |
| | | :value="item.id" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | |
| | | <el-form-item |
| | | label="需求数量" |
| | | prop="quantity" |
| | | > |
| | | <el-input-number v-model="formState.quantity" :step="1" :min="1" style="width: 100%" /> |
| | | </el-form-item> |
| | | </el-form> |
| | | <!-- 基本信息 --> |
| | | <div class="section-card"> |
| | | <div class="section-header"> |
| | | <span class="section-icon">📋</span> |
| | | <span class="section-title-text">基本信息</span> |
| | | </div> |
| | | <el-form label-width="100px" :model="formState" label-position="right" ref="formRef" class="compact-form"> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="12"> |
| | | <el-form-item |
| | | label="产品名称" |
| | | prop="productModelId" |
| | | :rules="[{ required: true, message: '请选择产品', trigger: 'change' }]" |
| | | > |
| | | <el-button type="primary" @click="showProductSelectDialog = true" class="select-btn"> |
| | | {{ formState.productName ? formState.productName : '选择产品' }} |
| | | </el-button> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="图纸编号" prop="productModelName"> |
| | | <el-input v-model="formState.productModelName" disabled /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="单位" prop="unit"> |
| | | <el-input v-model="formState.unit" disabled /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="销售合同号" prop="salesContractNo"> |
| | | <el-input v-model="formState.salesContractNo" placeholder="请输入销售合同号" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="客户名称" prop="customerName"> |
| | | <el-input v-model="formState.customerName" placeholder="请输入客户名称" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="需求数量" prop="quantity"> |
| | | <el-input-number v-model="formState.quantity" :step="1" :min="1" style="width: 100%" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="交付日期" prop="deliveryDate"> |
| | | <el-date-picker |
| | | v-model="formState.deliveryDate" |
| | | type="date" |
| | | placeholder="选择交付日期" |
| | | style="width: 100%" |
| | | format="YYYY-MM-DD" |
| | | value-format="YYYY-MM-DD" |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="图纸上传"> |
| | | <el-upload |
| | | action="#" |
| | | :auto-upload="false" |
| | | :on-change="handleFileChange" |
| | | :file-list="fileList" |
| | | :limit="5" |
| | | class="upload-inline" |
| | | > |
| | | <el-button type="primary" plain size="small"> |
| | | <el-icon><Upload /></el-icon> 选择文件 |
| | | </el-button> |
| | | <template #tip> |
| | | <div class="el-upload__tip">支持jpg/png/pdf,单个不超过10MB</div> |
| | | </template> |
| | | </el-upload> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | </el-form> |
| | | </div> |
| | | |
| | | <!-- 产品选择弹窗 --> |
| | | <ProductSelectDialog |
| | |
| | | @confirm="handleProductSelect" |
| | | single |
| | | /> |
| | | |
| | | <!-- 生产任务 --> |
| | | <div class="section-card"> |
| | | <div class="section-header"> |
| | | <span class="section-icon">🔧</span> |
| | | <span class="section-title-text">生产任务</span> |
| | | <el-button type="primary" size="small" @click="addProductionTask" class="add-btn"> |
| | | <el-icon><Plus /></el-icon> 添加任务 |
| | | </el-button> |
| | | </div> |
| | | <div class="table-container"> |
| | | <el-table :data="productionTaskList" border size="small" class="compact-table"> |
| | | <el-table-column type="index" label="序号" width="60" /> |
| | | <el-table-column label="工序名称" min-width="150"> |
| | | <template #default="{ row }"> |
| | | <el-input v-model="row.processName" placeholder="请输入工序名称" /> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="计划数" min-width="120"> |
| | | <template #default="{ row }"> |
| | | <el-input-number v-model="row.planQuantity" :min="0" style="width: 100%" /> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="报工权限" min-width="150"> |
| | | <template #default="{ row }"> |
| | | <el-input v-model="row.reportPermission" placeholder="请输入报工权限" /> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="计划开始时间" min-width="180"> |
| | | <template #default="{ row }"> |
| | | <el-date-picker |
| | | v-model="row.planStartTime" |
| | | type="datetime" |
| | | placeholder="选择开始时间" |
| | | style="width: 100%" |
| | | format="YYYY-MM-DD HH:mm" |
| | | value-format="YYYY-MM-DD HH:mm:ss" |
| | | /> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="计划结束时间" min-width="180"> |
| | | <template #default="{ row }"> |
| | | <el-date-picker |
| | | v-model="row.planEndTime" |
| | | type="datetime" |
| | | placeholder="选择结束时间" |
| | | style="width: 100%" |
| | | format="YYYY-MM-DD HH:mm" |
| | | value-format="YYYY-MM-DD HH:mm:ss" |
| | | /> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="操作" width="80" fixed="right" align="center"> |
| | | <template #default="{ $index }"> |
| | | <el-button type="danger" link size="small" @click="removeProductionTask($index)"> |
| | | <el-icon><Delete /></el-icon> |
| | | </el-button> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | <div v-if="productionTaskList.length === 0" class="empty-tip"> |
| | | <el-empty description="暂无生产任务,点击上方按钮添加" :image-size="60" /> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | |
| | | <!-- 用料清单 --> |
| | | <div class="section-card"> |
| | | <div class="section-header"> |
| | | <span class="section-icon">📦</span> |
| | | <span class="section-title-text">用料清单</span> |
| | | <el-button type="primary" size="small" @click="addMaterialItem" class="add-btn"> |
| | | <el-icon><Plus /></el-icon> 添加用料 |
| | | </el-button> |
| | | </div> |
| | | <div class="table-container"> |
| | | <el-table :data="materialList" border size="small" class="compact-table"> |
| | | <el-table-column type="index" label="序号" width="50" align="center" /> |
| | | <el-table-column label="图纸编号" min-width="140"> |
| | | <template #default="{ row }"> |
| | | <el-input v-model="row.drawingNumber" placeholder="请输入图纸编号" size="small" /> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="产品名称" min-width="140"> |
| | | <template #default="{ row }"> |
| | | <el-input v-model="row.productName" placeholder="请输入产品名称" size="small" /> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="单位用量" min-width="100"> |
| | | <template #default="{ row }"> |
| | | <el-input-number v-model="row.unitQuantity" :min="0" :precision="2" size="small" style="width: 100%" /> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="库存数量" min-width="100"> |
| | | <template #default="{ row }"> |
| | | <el-input-number v-model="row.inventoryQuantity" :min="0" size="small" style="width: 100%" /> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="操作" width="80" fixed="right" align="center"> |
| | | <template #default="{ $index }"> |
| | | <el-button type="danger" link size="small" @click="removeMaterialItem($index)"> |
| | | <el-icon><Delete /></el-icon> |
| | | </el-button> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | <div v-if="materialList.length === 0" class="empty-tip"> |
| | | <el-empty description="暂无用料清单,点击上方按钮添加" :image-size="60" /> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | |
| | | <template #footer> |
| | | <div class="dialog-footer"> |
| | | <el-button type="primary" @click="handleSubmit">确认</el-button> |
| | |
| | | |
| | | <script setup> |
| | | import {ref, computed, getCurrentInstance} from "vue"; |
| | | import { Plus, Delete, Upload } from '@element-plus/icons-vue'; |
| | | import ProductSelectDialog from "@/views/basicData/product/ProductSelectDialog.vue"; |
| | | import {addProductOrder, listProcessRoute} from "@/api/productionManagement/productionOrder.js"; |
| | | |
| | |
| | | unit: "", |
| | | drawingNumber: "", |
| | | quantity: 0, |
| | | salesContractNo: "", |
| | | customerName: "", |
| | | deliveryDate: "", |
| | | }); |
| | | |
| | | // 生产任务列表 |
| | | const productionTaskList = ref([]); |
| | | |
| | | // 用料清单列表 |
| | | const materialList = ref([]); |
| | | |
| | | // 文件列表 |
| | | const fileList = ref([]); |
| | | |
| | | const isShow = computed({ |
| | | get() { |
| | |
| | | productName: "", |
| | | drawingNumber: "", |
| | | productModelName: "", |
| | | quantity: '', |
| | | unit: "", |
| | | quantity: 0, |
| | | salesContractNo: "", |
| | | customerName: "", |
| | | deliveryDate: "", |
| | | }; |
| | | // 重置生产任务和用料清单 |
| | | productionTaskList.value = []; |
| | | materialList.value = []; |
| | | fileList.value = []; |
| | | isShow.value = false; |
| | | }; |
| | | |
| | |
| | | }) |
| | | } |
| | | |
| | | // 添加生产任务 |
| | | const addProductionTask = () => { |
| | | productionTaskList.value.push({ |
| | | processName: "", |
| | | planQuantity: 0, |
| | | reportPermission: "", |
| | | planStartTime: "", |
| | | planEndTime: "", |
| | | }); |
| | | }; |
| | | |
| | | // 删除生产任务 |
| | | const removeProductionTask = (index) => { |
| | | productionTaskList.value.splice(index, 1); |
| | | }; |
| | | |
| | | // 添加用料 |
| | | const addMaterialItem = () => { |
| | | materialList.value.push({ |
| | | drawingNumber: "", |
| | | productName: "", |
| | | unitQuantity: 0, |
| | | inventoryQuantity: 0, |
| | | }); |
| | | }; |
| | | |
| | | // 删除用料 |
| | | const removeMaterialItem = (index) => { |
| | | materialList.value.splice(index, 1); |
| | | }; |
| | | |
| | | // 文件上传变更 |
| | | const handleFileChange = (file, files) => { |
| | | fileList.value = files; |
| | | }; |
| | | |
| | | const handleSubmit = () => { |
| | | proxy.$refs["formRef"].validate(valid => { |
| | | if (valid) { |
| | |
| | | return; |
| | | } |
| | | |
| | | addProductOrder(formState.value).then(res => { |
| | | // 组装提交数据 |
| | | const submitData = { |
| | | ...formState.value, |
| | | productionTasks: productionTaskList.value, |
| | | materials: materialList.value, |
| | | files: fileList.value, |
| | | }; |
| | | |
| | | addProductOrder(submitData).then(res => { |
| | | // 关闭模态框 |
| | | isShow.value = false; |
| | | // 告知父组件已完成 |
| | |
| | | isShow, |
| | | }); |
| | | </script> |
| | | |
| | | <style scoped> |
| | | .production-order-dialog :deep(.el-dialog__body) { |
| | | padding: 15px 20px; |
| | | max-height: 70vh; |
| | | overflow-y: auto; |
| | | } |
| | | |
| | | .section-card { |
| | | background: #f8f9fa; |
| | | border-radius: 8px; |
| | | padding: 15px; |
| | | margin-bottom: 15px; |
| | | } |
| | | |
| | | .section-header { |
| | | display: flex; |
| | | align-items: center; |
| | | margin-bottom: 15px; |
| | | padding-bottom: 10px; |
| | | border-bottom: 1px solid #e4e7ed; |
| | | } |
| | | |
| | | .section-icon { |
| | | font-size: 18px; |
| | | margin-right: 8px; |
| | | } |
| | | |
| | | .section-title-text { |
| | | font-size: 15px; |
| | | font-weight: 600; |
| | | color: #303133; |
| | | flex: 1; |
| | | } |
| | | |
| | | .add-btn { |
| | | margin-left: auto; |
| | | } |
| | | |
| | | .compact-form :deep(.el-form-item) { |
| | | margin-bottom: 12px; |
| | | } |
| | | |
| | | .compact-form :deep(.el-form-item__label) { |
| | | font-size: 13px; |
| | | color: #606266; |
| | | } |
| | | |
| | | .select-btn { |
| | | width: 100%; |
| | | justify-content: flex-start; |
| | | } |
| | | |
| | | .table-container { |
| | | background: #fff; |
| | | border-radius: 4px; |
| | | padding: 10px; |
| | | } |
| | | |
| | | .compact-table :deep(.el-table__cell) { |
| | | padding: 4px 0; |
| | | } |
| | | |
| | | .compact-table :deep(.el-input__wrapper), |
| | | .compact-table :deep(.el-input-number) { |
| | | width: 100%; |
| | | } |
| | | |
| | | .empty-tip { |
| | | padding: 20px 0; |
| | | } |
| | | |
| | | .upload-inline :deep(.el-upload) { |
| | | display: inline-flex; |
| | | } |
| | | |
| | | .upload-inline :deep(.el-upload__tip) { |
| | | margin-top: 4px; |
| | | font-size: 12px; |
| | | } |
| | | |
| | | .dialog-footer { |
| | | display: flex; |
| | | justify-content: center; |
| | | gap: 10px; |
| | | } |
| | | </style> |