| | |
| | | :model="searchForm" |
| | | class="search-form"> |
| | | <el-form-item label="申请单编号"> |
| | | <el-input v-model="searchForm.applyNo" |
| | | placeholder="请输入申请单编号" |
| | | style="width: 400px;"></el-input> |
| | | </el-form-item> |
| | | <el-form-item> |
| | | <el-button type="primary" |
| | | @click="handleSearch">搜索</el-button> |
| | | <el-select v-model="selectedApplyNo" |
| | | filterable |
| | | remote |
| | | reserve-keyword |
| | | placeholder="请输入申请单编号" |
| | | :loading="applyNoLoading" |
| | | :remote-method="handleApplyNoSearch" |
| | | @change="handleSearch" |
| | | style="width: 400px;"> |
| | | <el-option v-for="option in applyNoOptions" |
| | | :key="option.id" |
| | | :label="option.applyNo+'-'+option.productName+'-'+option.model" |
| | | :value="option.id" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-form> |
| | | </div> |
| | | </template> |
| | | <!-- 基础信息 --> |
| | | <div class="detail-section"> |
| | | <div v-if="rowData.productionPlanDto" |
| | | class="detail-section"> |
| | | <h3 class="section-title">基础信息</h3> |
| | | <el-descriptions :column="3" |
| | | border> |
| | | <el-descriptions-item label="申请单编号">{{ rowData.applyNo || '-' }}</el-descriptions-item> |
| | | <el-descriptions-item label="产品名称">{{ rowData.productName || '-' }}</el-descriptions-item> |
| | | <el-descriptions-item label="产品规格">{{ rowData.model || '-' }}</el-descriptions-item> |
| | | <el-descriptions-item label="物料编码">{{ rowData.materialCode || '-' }}</el-descriptions-item> |
| | | <el-descriptions-item label="下发数量">{{ rowData.assignedQuantity || 0 }} <span class="unit">方</span></el-descriptions-item> |
| | | <el-descriptions-item label="当前状态"> |
| | | <el-tag :type="getStatusType(rowData.status)"> |
| | | {{ getStatusText(rowData.status) }} |
| | | </el-tag> |
| | | </el-descriptions-item> |
| | | </el-descriptions> |
| | | <el-skeleton :loading="loading" |
| | | animated> |
| | | <template #template> |
| | | <el-skeleton-item variant="p" |
| | | style="width: 80%" /> |
| | | <el-skeleton-item variant="p" |
| | | style="width: 60%" /> |
| | | <el-skeleton-item variant="p" |
| | | style="width: 40%" /> |
| | | </template> |
| | | <el-descriptions :column="3" |
| | | border> |
| | | <el-descriptions-item label="申请单编号">{{ rowData.productionPlanDto?.applyNo || '-' }}</el-descriptions-item> |
| | | <el-descriptions-item label="产品名称">{{ rowData.productionPlanDto?.productName || '-' }}</el-descriptions-item> |
| | | <el-descriptions-item label="产品规格">{{ rowData.productionPlanDto?.model || '-' }}</el-descriptions-item> |
| | | <el-descriptions-item label="物料编码">{{ rowData.productionPlanDto?.materialCode || '-' }}</el-descriptions-item> |
| | | <el-descriptions-item label="下发数量">{{ rowData.productionPlanDto?.assignedQuantity || 0 }} <span class="unit">方</span></el-descriptions-item> |
| | | <el-descriptions-item label="当前状态"> |
| | | <el-tag :type="getStatusType(rowData.productionPlanDto?.status)"> |
| | | {{ getStatusText(rowData.productionPlanDto?.status) }} |
| | | </el-tag> |
| | | </el-descriptions-item> |
| | | </el-descriptions> |
| | | </el-skeleton> |
| | | </div> |
| | | <div class="progress-container"> |
| | | <el-empty v-else |
| | | description="暂无数据" /> |
| | | <div v-if="rowData.orderDtoList" |
| | | class="progress-container"> |
| | | <div class="progress-section"> |
| | | <h3 class="section-title">订单信息</h3> |
| | | <div v-for="item in rowData.orderList" |
| | | :key="item.orderNo" |
| | | class="order-item"> |
| | | <el-descriptions :column="3" |
| | | border> |
| | | <el-descriptions-item label="订单编号">{{ item.orderNo || '-' }}</el-descriptions-item> |
| | | <!-- <el-descriptions-item label="订单状态"> |
| | | <el-tag :type="getStatusType(item.status)">{{ getStatusText(item.status) }}</el-tag> |
| | | </el-descriptions-item> --> |
| | | <el-descriptions-item label="开始日期">{{ item.startTime || '-' }}</el-descriptions-item> |
| | | <el-descriptions-item label="完成进度"> |
| | | <el-progress :percentage="item.completionRate" |
| | | :color="customColors(item.completionRate)" |
| | | :status="item.completionRate === 100 ? 'success' : ''" |
| | | style="width: 120px;" /> |
| | | </el-descriptions-item> |
| | | <el-descriptions-item label="需求数量">{{ item.quantity || 0 }} <span class="unit">方</span></el-descriptions-item> |
| | | <el-descriptions-item label="完成数量">{{ item.completeQuantity || 0 }} <span class="unit">方</span></el-descriptions-item> |
| | | <el-descriptions-item label="剩余数量">{{ item.remainingQuantity || 0 }} <span class="unit">方</span></el-descriptions-item> |
| | | </el-descriptions> |
| | | <el-table :data="trackProgressForm.progressDetails" |
| | | border |
| | | style="width: auto; height: 200px"> |
| | | <el-table-column prop="step" |
| | | label="步骤(点击查看详情)" |
| | | align="center"> |
| | | <template #default="{ row, $index }"> |
| | | <el-link v-if="$index!=0" |
| | | @click="handleClickStep(row)" |
| | | type="primary">{{ row.step }}</el-link> |
| | | <span v-else>{{ row.step }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | <!-- <el-table-column prop="status" |
| | | label="状态" |
| | | align="center"> |
| | | <template #default="scope"> |
| | | <el-tag :type="scope.row.status === 'completed' ? 'success' : scope.row.status === 'processing' ? 'warning' : 'info'"> |
| | | {{ scope.row.status === 'completed' ? '已完成' : scope.row.status === 'processing' ? '进行中' : '待开始' }} |
| | | </el-tag> |
| | | </template> |
| | | </el-table-column> --> |
| | | <el-table-column prop="quantity" |
| | | label="数量" |
| | | align="center" /> |
| | | <el-table-column prop="startTime" |
| | | label="时间" |
| | | align="center" /> |
| | | <el-table-column prop="startTime1" |
| | | label="岗位人员" |
| | | align="center" /> |
| | | </el-table> |
| | | </div> |
| | | <el-skeleton :loading="loading" |
| | | animated> |
| | | <template #template> |
| | | <el-skeleton-item variant="p" |
| | | style="width: 80%" /> |
| | | <el-skeleton-item variant="p" |
| | | style="width: 60%" /> |
| | | <el-skeleton-item variant="p" |
| | | style="width: 40%" /> |
| | | <el-skeleton-item variant="p" |
| | | style="width: 100%" /> |
| | | </template> |
| | | <div v-for="(item, index) in rowData.orderDtoList" |
| | | :key="item.productOrderDto?.npsNo || index" |
| | | class="order-item"> |
| | | <el-descriptions :column="3" |
| | | border> |
| | | <el-descriptions-item label="订单编号">{{ item.productOrderDto?.npsNo || '-' }}</el-descriptions-item> |
| | | <el-descriptions-item label="开始日期">{{ item.productOrderDto?.startTime || '-' }}</el-descriptions-item> |
| | | <el-descriptions-item label="完成进度"> |
| | | <el-progress :percentage="item.productOrderDto?.completionStatus" |
| | | :color="customColors(item.productOrderDto?.completionStatus)" |
| | | :status="item.productOrderDto?.completionStatus === 100 ? 'success' : ''" |
| | | style="width: 120px;" /> |
| | | </el-descriptions-item> |
| | | <el-descriptions-item label="需求数量">{{ item.productOrderDto?.quantity || 0 }} <span class="unit">方</span></el-descriptions-item> |
| | | <el-descriptions-item label="完成数量">{{ item.productOrderDto?.completeQuantity || 0 }} <span class="unit">方</span></el-descriptions-item> |
| | | <el-descriptions-item label="剩余数量">{{ (item.productOrderDto?.quantity - item.productOrderDto?.completeQuantity) || 0 }} <span class="unit">方</span></el-descriptions-item> |
| | | </el-descriptions> |
| | | <el-table :data="item.productionProductMainDtos" |
| | | border |
| | | style="width: auto; max-height: 200px"> |
| | | <el-table-column prop="step" |
| | | label="报工(点击查看详情)" |
| | | align="center"> |
| | | <template #default="{ row }"> |
| | | <el-link @click="handleClickStep(row)" |
| | | type="primary">{{ row.productNo }}</el-link> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="quantity" |
| | | label="数量(方)" |
| | | align="center" /> |
| | | <el-table-column prop="reportingTime" |
| | | label="时间" |
| | | align="center" /> |
| | | <el-table-column prop="schedule" |
| | | label="班次" |
| | | align="center" /> |
| | | <el-table-column prop="postName" |
| | | label="岗位人员" |
| | | align="center" /> |
| | | </el-table> |
| | | </div> |
| | | </el-skeleton> |
| | | </div> |
| | | </div> |
| | | <el-empty v-else-if="rowData.productionPlanDto" |
| | | description="暂无进度" /> |
| | | </el-card> |
| | | <!-- 生产报工详情弹窗 --> |
| | | <el-dialog v-model="detailDialogVisible" |
| | |
| | | :close-on-click-modal="false" |
| | | custom-class="custom-dialog"> |
| | | <div class="detail-container"> |
| | | <!-- 基础信息 --> |
| | | <div class="detail-section"> |
| | | <h3 class="section-title">基础信息</h3> |
| | | <el-descriptions :column="3" |
| | | border> |
| | | <el-descriptions-item label="生产订单号">{{ detailData.npsNo || '-' }}</el-descriptions-item> |
| | | <el-descriptions-item label="班组"><el-tag :type="detailData.schedule == '白班' ? 'primary' : 'warning'">{{ detailData.schedule || '-' }}</el-tag></el-descriptions-item> |
| | | <el-descriptions-item label="岗位人员">{{ detailData.postName || '-' }}</el-descriptions-item> |
| | | <el-descriptions-item label="产品编码">{{ detailData.materialCode || '-' }}</el-descriptions-item> |
| | | <el-descriptions-item label="产品名称">{{ detailData.productName || '-' }}</el-descriptions-item> |
| | | <el-descriptions-item label="规格">{{ detailData.model || '-' }}</el-descriptions-item> |
| | | <el-descriptions-item label="合格数量"><span class="num2">{{ detailData.qualifiedQuantity || 0 }}</span> <span class="unit">方</span></el-descriptions-item> |
| | | <el-descriptions-item label="不合格数量"><span class="num3">{{ detailData.unqualifiedQuantity || 0 }}</span> <span class="unit">方</span></el-descriptions-item> |
| | | <el-descriptions-item label="总数量"><span class="num1">{{ detailData.quantity || 0 }}</span> <span class="unit">方</span></el-descriptions-item> |
| | | <el-descriptions-item label="报工时间">{{ formatTime(detailData.reportingTime) }}</el-descriptions-item> |
| | | <el-descriptions-item label="创建时间">{{ formatTime(detailData.createTime) }}</el-descriptions-item> |
| | | <el-descriptions-item label="更新时间">{{ formatTime(detailData.updateTime) }}</el-descriptions-item> |
| | | </el-descriptions> |
| | | </div> |
| | | <!-- 工序信息 --> |
| | | <div class="detail-section" |
| | | v-if="detailData.productionProductRouteItemDtoList && detailData.productionProductRouteItemDtoList.length > 0"> |
| | | <h3 class="section-title">工序信息</h3> |
| | | <div v-for="(process) in detailData.productionProductRouteItemDtoList" |
| | | :key="process.id" |
| | | class="process-item"> |
| | | <div class="process-header"> |
| | | <h4 class="process-title">{{ process.processName || '-' }}</h4> |
| | | <div class="process-info"> |
| | | <span class="process-label">岗位人员:{{ process.postName || '-' }}</span> |
| | | <span class="process-label">工序ID:{{ process.processNo || '-' }}</span> |
| | | <el-skeleton :loading="dialogLoading" |
| | | animated> |
| | | <template #template> |
| | | <el-skeleton-item variant="p" |
| | | style="width: 80%" /> |
| | | <el-skeleton-item variant="p" |
| | | style="width: 60%" /> |
| | | <el-skeleton-item variant="p" |
| | | style="width: 40%" /> |
| | | <el-skeleton-item variant="h3" |
| | | style="width: 50%" /> |
| | | <el-skeleton-item variant="p" |
| | | style="width: 100%" /> |
| | | <el-skeleton-item variant="p" |
| | | style="width: 100%" /> |
| | | </template> |
| | | <!-- 基础信息 --> |
| | | <div class="detail-section"> |
| | | <h3 class="section-title">基础信息</h3> |
| | | <el-descriptions :column="3" |
| | | border> |
| | | <el-descriptions-item label="生产订单号">{{ detailData.npsNo || '-' }}</el-descriptions-item> |
| | | <el-descriptions-item label="班组"><el-tag :type="detailData.schedule == '白班' ? 'primary' : 'warning'">{{ detailData.schedule || '-' }}</el-tag></el-descriptions-item> |
| | | <el-descriptions-item label="岗位人员">{{ detailData.postName || '-' }}</el-descriptions-item> |
| | | <el-descriptions-item label="产品编码">{{ detailData.materialCode || '-' }}</el-descriptions-item> |
| | | <el-descriptions-item label="产品名称">{{ detailData.productName || '-' }}</el-descriptions-item> |
| | | <el-descriptions-item label="规格">{{ detailData.model || '-' }}</el-descriptions-item> |
| | | <el-descriptions-item label="合格数量"><span class="num2">{{ detailData.qualifiedQuantity || 0 }}</span> <span class="unit">方</span></el-descriptions-item> |
| | | <el-descriptions-item label="不合格数量"><span class="num3">{{ detailData.unqualifiedQuantity || 0 }}</span> <span class="unit">方</span></el-descriptions-item> |
| | | <el-descriptions-item label="总数量"><span class="num1">{{ detailData.quantity || 0 }}</span> <span class="unit">方</span></el-descriptions-item> |
| | | <el-descriptions-item label="报工时间">{{ formatTime(detailData.reportingTime) }}</el-descriptions-item> |
| | | <el-descriptions-item label="创建时间">{{ formatTime(detailData.createTime) }}</el-descriptions-item> |
| | | <el-descriptions-item label="更新时间">{{ formatTime(detailData.updateTime) }}</el-descriptions-item> |
| | | </el-descriptions> |
| | | </div> |
| | | <!-- 工序信息 --> |
| | | <div class="detail-section" |
| | | v-if="detailData.productionProductRouteItemDtoList && detailData.productionProductRouteItemDtoList.length > 0"> |
| | | <h3 class="section-title">工序信息</h3> |
| | | <div v-for="(process) in detailData.productionProductRouteItemDtoList" |
| | | :key="process.id" |
| | | class="process-item"> |
| | | <div class="process-header"> |
| | | <h4 class="process-title">{{ process.processName || '-' }}</h4> |
| | | <div class="process-info"> |
| | | <span class="process-label">岗位人员:{{ process.postName || '-' }}</span> |
| | | <span class="process-label">工序ID:{{ process.processNo || '-' }}</span> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <!-- 工序基本信息 --> |
| | | <div class="process-details"> |
| | | <el-descriptions :column="2" |
| | | border> |
| | | <el-descriptions-item label="设备异常情况">{{ process.equipmentMalfunction || '-' }}</el-descriptions-item> |
| | | <el-descriptions-item label="当班设备处置">{{ process.equipmentDisposal || '-' }}</el-descriptions-item> |
| | | <el-descriptions-item label="工艺人员交待" |
| | | :span="2">{{ process.processExplained || '-' }}</el-descriptions-item> |
| | | </el-descriptions> |
| | | </div> |
| | | <!-- 工序参数 --> |
| | | <div v-if="process.productionProductRouteItemParamDtoList && process.productionProductRouteItemParamDtoList.length > 0"> |
| | | <!-- BOM信息 --> |
| | | <div class="param-section" |
| | | v-if="getBomList(process.productionProductRouteItemParamDtoList).length > 0"> |
| | | <h5 class="param-title">投入品信息</h5> |
| | | <el-table :data="getBomList(process.productionProductRouteItemParamDtoList)" |
| | | style="width: 100%" |
| | | size="small"> |
| | | <el-table-column prop="paramName" |
| | | label="产品名称" |
| | | min-width="120"></el-table-column> |
| | | <el-table-column prop="model" |
| | | label="规格型号" |
| | | min-width="120"></el-table-column> |
| | | <el-table-column prop="productValue" |
| | | label="投入量" |
| | | min-width="100"></el-table-column> |
| | | <el-table-column prop="unit" |
| | | label="单位" |
| | | width="80"></el-table-column> |
| | | </el-table> |
| | | <!-- 工序基本信息 --> |
| | | <div class="process-details"> |
| | | <el-descriptions :column="2" |
| | | border> |
| | | <el-descriptions-item label="设备异常情况">{{ process.equipmentMalfunction || '-' }}</el-descriptions-item> |
| | | <el-descriptions-item label="当班设备处置">{{ process.equipmentDisposal || '-' }}</el-descriptions-item> |
| | | <el-descriptions-item label="工艺人员交待" |
| | | :span="2">{{ process.processExplained || '-' }}</el-descriptions-item> |
| | | </el-descriptions> |
| | | </div> |
| | | <!-- 参数信息 --> |
| | | <div class="param-section" |
| | | v-if="getParamList(process.productionProductRouteItemParamDtoList).length > 0"> |
| | | <h5 class="param-title">生产记录</h5> |
| | | <el-card v-for="group in getParamGroups(process.productionProductRouteItemParamDtoList)" |
| | | :key="group.sourceSort" |
| | | class="detail-card" |
| | | style="margin-top: 10px;"> |
| | | <template #header> |
| | | <div class="card-header"> |
| | | <span v-if="Object.keys(getParamGroups(process.productionProductRouteItemParamDtoList)).length > 1">生产记录组 - {{ group.sourceSort }}</span> |
| | | <span v-else>生产记录</span> |
| | | </div> |
| | | </template> |
| | | <el-table :data="group.items" |
| | | <!-- 工序参数 --> |
| | | <div v-if="process.productionProductRouteItemParamDtoList && process.productionProductRouteItemParamDtoList.length > 0"> |
| | | <!-- BOM信息 --> |
| | | <div class="param-section" |
| | | v-if="getBomList(process.productionProductRouteItemParamDtoList).length > 0"> |
| | | <h5 class="param-title">投入品信息</h5> |
| | | <el-table :data="getBomList(process.productionProductRouteItemParamDtoList)" |
| | | style="width: 100%" |
| | | :row-class-name="rowClassName"> |
| | | size="small"> |
| | | <el-table-column prop="paramName" |
| | | label="指标" /> |
| | | label="产品名称" |
| | | min-width="120"></el-table-column> |
| | | <el-table-column prop="model" |
| | | label="规格型号" |
| | | min-width="120"></el-table-column> |
| | | <el-table-column prop="productValue" |
| | | label="投入量" |
| | | min-width="100"></el-table-column> |
| | | <el-table-column prop="unit" |
| | | label="单位" |
| | | width="100"> |
| | | <template #default="scope"> |
| | | {{ scope.row.unit || "/" }} |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="standardText" |
| | | label="标准值" /> |
| | | <el-table-column prop="paramValue" |
| | | label="实际值" /> |
| | | <el-table-column prop="result" |
| | | label="结果" |
| | | width="100"> |
| | | <template #default="scope"> |
| | | <el-tag :type="scope.row.result === '合格' ? 'success' : 'danger'"> |
| | | {{ scope.row.result }} |
| | | </el-tag> |
| | | </template> |
| | | </el-table-column> |
| | | width="80"></el-table-column> |
| | | </el-table> |
| | | </el-card> |
| | | </div> |
| | | <!-- 参数信息 --> |
| | | <div class="param-section" |
| | | v-if="getParamList(process.productionProductRouteItemParamDtoList).length > 0"> |
| | | <h5 class="param-title">生产记录</h5> |
| | | <el-card v-for="group in getParamGroups(process.productionProductRouteItemParamDtoList)" |
| | | :key="group.sourceSort" |
| | | class="detail-card" |
| | | style="margin-top: 10px;"> |
| | | <template #header> |
| | | <div class="card-header"> |
| | | <span v-if="Object.keys(getParamGroups(process.productionProductRouteItemParamDtoList)).length > 1">生产记录组 - {{ group.sourceSort }}</span> |
| | | <span v-else>生产记录</span> |
| | | </div> |
| | | </template> |
| | | <el-table :data="group.items" |
| | | style="width: 100%" |
| | | :row-class-name="rowClassName"> |
| | | <el-table-column prop="paramName" |
| | | label="指标" /> |
| | | <el-table-column prop="unit" |
| | | label="单位" |
| | | width="100"> |
| | | <template #default="scope"> |
| | | {{ scope.row.unit || "/" }} |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="standardText" |
| | | label="标准值" /> |
| | | <el-table-column prop="paramValue" |
| | | label="实际值" /> |
| | | <el-table-column prop="result" |
| | | label="结果" |
| | | width="100"> |
| | | <template #default="scope"> |
| | | <el-tag :type="scope.row.result === '合格' ? 'success' : 'danger'"> |
| | | {{ scope.row.result }} |
| | | </el-tag> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | </el-card> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <!-- 上传文件 --> |
| | | <div class="file-section" |
| | | v-if="process.fileList && process.fileList.length > 0"> |
| | | <h5 class="file-title">上传文件</h5> |
| | | <div class="file-grid"> |
| | | <div v-for="file in process.fileList" |
| | | :key="file.id" |
| | | class="file-item"> |
| | | <el-image style="width: 100px; height: 100px" |
| | | v-if="file.fileUrl" |
| | | :src="baseUrl + file.fileUrl" |
| | | :zoom-rate="1.2" |
| | | :max-scale="7" |
| | | :alt="file.fileName" |
| | | :min-scale="0.2" |
| | | :preview-src-list="formatFileList(process.fileList)" |
| | | show-progress |
| | | :initial-index="4" |
| | | fit="cover" /> |
| | | <div class="file-info"> |
| | | <span class="file-name">{{ file.fileName || '-' }}</span> |
| | | <!-- 上传文件 --> |
| | | <div class="file-section" |
| | | v-if="process.fileList && process.fileList.length > 0"> |
| | | <h5 class="file-title">上传文件</h5> |
| | | <div class="file-grid"> |
| | | <div v-for="file in process.fileList" |
| | | :key="file.id" |
| | | class="file-item"> |
| | | <el-image style="width: 100px; height: 100px" |
| | | v-if="file.fileUrl" |
| | | :src="baseUrl + file.fileUrl" |
| | | :zoom-rate="1.2" |
| | | :max-scale="7" |
| | | :alt="file.fileName" |
| | | :min-scale="0.2" |
| | | :preview-src-list="formatFileList(process.fileList)" |
| | | show-progress |
| | | :initial-index="4" |
| | | fit="cover" /> |
| | | <div class="file-info"> |
| | | <span class="file-name">{{ file.fileName || '-' }}</span> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </el-skeleton> |
| | | </div> |
| | | <template #footer> |
| | | <div class="dialog-footer"> |
| | |
| | | import { ElMessage } from "element-plus"; |
| | | import { useRouter, useRoute } from "vue-router"; |
| | | import dayjs from "dayjs"; |
| | | import { |
| | | trackProgressByNo, |
| | | productionPlanListPage, |
| | | } from "@/api/productionPlan/productionPlan"; |
| | | import { productionReportDetail } from "@/api/productionManagement/productionReporting.js"; |
| | | |
| | | const router = useRouter(); |
| | | const route = useRoute(); |
| | |
| | | remark: "", |
| | | }); |
| | | |
| | | // 搜索表单 |
| | | const searchForm = reactive({ |
| | | applyNo: "", |
| | | }); |
| | | |
| | | // 生产报工详情弹窗 |
| | | const detailDialogVisible = ref(false); |
| | | const detailData = ref({}); |
| | | const baseUrl = import.meta.env.VITE_APP_BASE_API; |
| | | |
| | | // 加载状态 |
| | | const loading = ref(false); |
| | | // 弹窗加载状态 |
| | | const dialogLoading = ref(false); |
| | | |
| | | // 申请单下拉框数据 |
| | | const applyNoOptions = ref([]); |
| | | const applyNoLoading = ref(false); |
| | | const applyNoQuery = ref(""); |
| | | const selectedApplyNo = ref(null); |
| | | |
| | | // 获取状态类型 |
| | | const getStatusType = status => { |
| | |
| | | router.push("/productionPlan/productionPlan"); |
| | | }; |
| | | |
| | | // 处理申请单编号搜索 |
| | | const handleApplyNoSearch = query => { |
| | | if (query) { |
| | | applyNoLoading.value = true; |
| | | productionPlanListPage({ |
| | | current: -1, |
| | | size: -1, |
| | | applyNo: query, |
| | | }) |
| | | .then(res => { |
| | | // 转换数据格式为下拉框所需的格式 |
| | | applyNoOptions.value = res.data.records; |
| | | }) |
| | | .catch(error => { |
| | | console.error(error); |
| | | }) |
| | | .finally(() => { |
| | | applyNoLoading.value = false; |
| | | }); |
| | | } else { |
| | | applyNoOptions.value = []; |
| | | } |
| | | }; |
| | | |
| | | // 处理搜索 |
| | | const handleSearch = () => { |
| | | const applyNo = searchForm.applyNo.trim(); |
| | | if (!applyNo) { |
| | | ElMessage.warning("请输入申请单编号"); |
| | | if (!selectedApplyNo.value) { |
| | | ElMessage.warning("请选择申请单编号"); |
| | | return; |
| | | } |
| | | // 这里可以添加搜索逻辑,例如调用API获取数据 |
| | | // 目前使用模拟数据 |
| | | ElMessage.success(`搜索申请单编号: ${applyNo}`); |
| | | // 模拟搜索结果 |
| | | rowData.applyNo = applyNo; |
| | | rowData.productName = "搜索结果产品"; |
| | | rowData.model = "搜索结果规格"; |
| | | rowData.materialCode = "MAT-" + applyNo; |
| | | rowData.assignedQuantity = 100; |
| | | rowData.status = 1; |
| | | trackProgressForm.progressDetails = generateProgressDetails(1); |
| | | trackProgressForm.completionRate = calculateCompletionRate( |
| | | trackProgressForm.progressDetails |
| | | ); |
| | | rowData.orderList = generateOrderList(); |
| | | // 调用API获取数据 |
| | | loading.value = true; |
| | | trackProgressByNo({ productionPlanId: selectedApplyNo.value }) |
| | | .then(res => { |
| | | console.log(res, "搜索结果"); |
| | | // 合并数据到rowData |
| | | Object.assign(rowData, res.data); |
| | | ElMessage.success("搜索成功"); |
| | | }) |
| | | .catch(error => { |
| | | ElMessage.error("搜索失败,请稍后重试"); |
| | | console.error(error); |
| | | }) |
| | | .finally(() => { |
| | | loading.value = false; |
| | | }); |
| | | }; |
| | | |
| | | // 生成模拟订单数据 |
| | |
| | | |
| | | // 处理点击步骤查看详情 |
| | | const handleClickStep = row => { |
| | | // 这里可以添加获取报工详情数据的逻辑 |
| | | // 目前使用模拟数据 |
| | | detailData.value = { |
| | | npsNo: "NPS-2026-001", |
| | | schedule: "白班", |
| | | postName: "张三", |
| | | materialCode: rowData.materialCode || "MAT-001", |
| | | productName: rowData.productName || "产品A", |
| | | model: rowData.model || "规格A", |
| | | qualifiedQuantity: 100, |
| | | unqualifiedQuantity: 5, |
| | | quantity: 105, |
| | | reportingTime: new Date(), |
| | | createTime: new Date(), |
| | | updateTime: new Date(), |
| | | productionProductRouteItemDtoList: [ |
| | | { |
| | | id: 1, |
| | | processName: "工序1", |
| | | postName: "张三", |
| | | processNo: "PROC-001", |
| | | equipmentMalfunction: "无异常", |
| | | equipmentDisposal: "正常运行", |
| | | processExplained: "按照标准工艺操作", |
| | | productionProductRouteItemParamDtoList: [ |
| | | { |
| | | id: 11, |
| | | paramName: "原材料A", |
| | | model: "型号A", |
| | | productValue: "100", |
| | | unit: "kg", |
| | | bomId: 101, |
| | | }, |
| | | { |
| | | id: 12, |
| | | paramName: "温度", |
| | | paramValue: "25", |
| | | unit: "°C", |
| | | sourceSort: 1, |
| | | valueMode: 2, |
| | | minValue: 20, |
| | | maxValue: 30, |
| | | }, |
| | | { |
| | | id: 13, |
| | | paramName: "压力", |
| | | paramValue: "1.5", |
| | | unit: "MPa", |
| | | sourceSort: 1, |
| | | valueMode: 2, |
| | | minValue: 1.0, |
| | | maxValue: 2.0, |
| | | }, |
| | | { |
| | | id: 14, |
| | | paramName: "转速", |
| | | paramValue: "1500", |
| | | unit: "rpm", |
| | | sourceSort: 2, |
| | | valueMode: 1, |
| | | standardValue: "1500", |
| | | }, |
| | | { |
| | | id: 15, |
| | | paramName: "电流", |
| | | paramValue: "12", |
| | | unit: "A", |
| | | sourceSort: 2, |
| | | valueMode: 2, |
| | | minValue: 10, |
| | | maxValue: 15, |
| | | }, |
| | | ], |
| | | fileList: [ |
| | | { |
| | | id: 21, |
| | | fileName: "生产记录1.jpg", |
| | | fileUrl: "/upload/files/20260301/12345.jpg", |
| | | fileSize: 1024000, |
| | | }, |
| | | { |
| | | id: 22, |
| | | fileName: "生产记录2.jpg", |
| | | fileUrl: "/upload/files/20260301/67890.jpg", |
| | | fileSize: 2048000, |
| | | }, |
| | | ], |
| | | }, |
| | | ], |
| | | }; |
| | | detailDialogVisible.value = true; |
| | | // 获取报工详情数据 |
| | | dialogLoading.value = true; |
| | | productionReportDetail(row.id) |
| | | .then(res => { |
| | | console.log(res, "报工详情"); |
| | | // 将API返回的数据赋值给detailData |
| | | detailData.value = res.data; |
| | | // 打开弹窗 |
| | | detailDialogVisible.value = true; |
| | | }) |
| | | .catch(error => { |
| | | ElMessage.error("获取报工详情失败,请稍后重试"); |
| | | console.error(error); |
| | | }) |
| | | .finally(() => { |
| | | dialogLoading.value = false; |
| | | }); |
| | | }; |
| | | |
| | | // 格式化时间 |
| | |
| | | // 页面加载时获取数据 |
| | | onMounted(() => { |
| | | // 从路由参数中获取数据 |
| | | applyNo.value = route.query.applyNo |
| | | ? decodeURIComponent(route.query.applyNo) |
| | | selectedApplyNo.value = route.query.applyNo |
| | | ? route.query.applyNo + |
| | | "-" + |
| | | route.query.productName + |
| | | "-" + |
| | | route.query.model |
| | | : null; |
| | | searchForm.applyNo = applyNo.value; |
| | | |
| | | // 生成假数据 |
| | | rowData.applyNo = applyNo.value || "APPLY-2026-001"; |
| | | rowData.productName = "测试产品"; |
| | | rowData.model = "测试规格"; |
| | | rowData.materialCode = "MAT-001"; |
| | | rowData.assignedQuantity = 233; |
| | | rowData.status = 1; |
| | | // 赋值给表单数据 |
| | | trackProgressForm.materialCode = rowData.materialCode; |
| | | trackProgressForm.currentStatus = rowData.status; |
| | | trackProgressForm.progressDetails = generateProgressDetails(rowData.status); |
| | | trackProgressForm.completionRate = calculateCompletionRate( |
| | | trackProgressForm.progressDetails |
| | | ); |
| | | trackProgressForm.remark = ""; |
| | | |
| | | // 生成模拟订单数据 |
| | | rowData.orderList = generateOrderList(); |
| | | if (route.query.id) { |
| | | loading.value = true; |
| | | trackProgressByNo({ productionPlanId: route.query.id }) |
| | | .then(res => { |
| | | console.log(res, "追踪进度"); |
| | | // 合并数据到rowData |
| | | Object.assign(rowData, res.data); |
| | | }) |
| | | .finally(() => { |
| | | loading.value = false; |
| | | }); |
| | | } |
| | | }); |
| | | </script> |
| | | |