2167 lines
77 KiB
Vue
2167 lines
77 KiB
Vue
<template>
|
||
<div class="app-container">
|
||
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
|
||
|
||
<el-form :model="queryParams">
|
||
<el-form-item label="项目令号" prop="routeDescription">
|
||
<el-select v-model="queryParams.routeDescription" filterable remote :remote-method="handleQuery1"
|
||
placeholder="请输入令号" clearable :loading="loading">
|
||
<el-option v-for="item in projectCodes" :key="item" :label="item" :value="item"></el-option>
|
||
</el-select>
|
||
</el-form-item>
|
||
<el-form-item>
|
||
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
|
||
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
|
||
</el-form-item>
|
||
</el-form>
|
||
|
||
|
||
</el-form>
|
||
|
||
<el-row :gutter="10" class="mb8">
|
||
<!-- <el-col :span="1.5">
|
||
<el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd"
|
||
v-hasPermi="['system:route:add']">新增
|
||
</el-button>
|
||
</el-col>
|
||
|
||
<el-col :span="1.5">
|
||
<el-button type="success" plain icon="el-icon-edit" size="mini" :disabled="single" @click="handleUpdate"
|
||
v-hasPermi="['system:route:edit']">修改
|
||
</el-button>
|
||
</el-col>
|
||
|
||
<el-col :span="1.5">
|
||
<el-button type="danger" plain icon="el-icon-delete" size="mini" :disabled="multiple" @click="handleDelete"
|
||
v-hasPermi="['system:route:remove']">删除
|
||
</el-button>
|
||
</el-col>-->
|
||
|
||
<el-col :span="1.5">
|
||
<el-button type="primary" plain icon="el-icon-download" size="mini" @click="handleExport"
|
||
v-hasPermi="['system:route:export']">导出
|
||
</el-button>
|
||
</el-col>
|
||
<el-col :span="1.5">
|
||
<el-button type="success" plain icon="el-icon-upload" size="mini" @click="handleImport"
|
||
v-hasPermi="['system:route:importRoute']">导入工艺
|
||
</el-button>
|
||
</el-col>
|
||
<el-col :span="1.5">
|
||
<el-button type="warning" plain icon="el-icon-time" size="mini" @click="handleImportTime"
|
||
v-hasPermi="['system:route:importDataTime']">导入时间
|
||
</el-button>
|
||
</el-col>
|
||
<el-col :span="1.5">
|
||
<el-button type="info" plain icon="el-icon-share" size="mini" @click="pushRouteBom"
|
||
v-hasPermi="['system:route:pushRouteBom']">推送工艺
|
||
</el-button>
|
||
</el-col>
|
||
<el-col :span="3">
|
||
<el-input
|
||
v-model="routeGroupName"
|
||
placeholder="请输入推送分组"
|
||
size="mini"
|
||
clearable
|
||
/>
|
||
</el-col>
|
||
<el-col :span="1.5">
|
||
<el-button type="danger" plain icon="el-icon-edit" size="mini" :disabled="multiple" @click="updateProcessPlan"
|
||
v-hasPermi="['system:route:updateProcessPlan']">更新计划时间
|
||
</el-button>
|
||
</el-col>
|
||
<el-col :span="1.5">
|
||
<el-button type="success" plain icon="el-icon-setting" size="mini" @click="updateProcesTime"
|
||
v-hasPermi="['system:route:updateProcesTime']">更新生产订单
|
||
</el-button>
|
||
</el-col>
|
||
<el-col :span="1.5">
|
||
<el-button type="primary" plain icon="el-icon-document" size="mini" @click="generatePDFs1"
|
||
v-hasPermi="['system:route:generatePDFs']">生成PDF
|
||
</el-button>
|
||
</el-col>
|
||
<el-col :span="1.5">
|
||
<el-button type="danger" plain icon="el-icon-warning" size="mini" @click="getKindeeExcel"
|
||
v-hasPermi="['system:route:getKindeeExcel']">获取标准工艺
|
||
</el-button>
|
||
</el-col>
|
||
<el-col :span="1.5">
|
||
<el-button type="danger" plain icon="el-icon-warning" size="mini" @click="getAllRouteAndUse"
|
||
v-hasPermi="['system:route:getAllRouteAndUse']">获取全部工艺
|
||
</el-button>
|
||
</el-col>
|
||
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
|
||
</el-row>
|
||
|
||
<el-form :inline="true" :model="form" ref="ruleForm" size="mini" :rules="rules">
|
||
<el-table v-if="showtable" v-loading="loading" row-key="id" ref="tree" v-drag:[config]="form.routeList"
|
||
:tree-props="{ children: 'children' }" :data="form.routeList" stripe :row-class-name="tableRowClassName"
|
||
border max-height="680px" @cell-click="cellhand" :default-expand-all="true"
|
||
@selection-change="handleSelectionChange">
|
||
|
||
<el-table-column type="selection" width="55" align="center"/>
|
||
<!-- <el-table-column label="主键ID" align="center" prop="id" v-if="true"/>-->
|
||
<el-table-column label="操作" width="55" align="center">
|
||
<template slot-scope="props">
|
||
<!-- <el-button type="text" icon="el-icon-check" v-if="scope.row.id < 0" @click="onSaveChild()" /> -->
|
||
<!-- <fromed v-if="props.row.parentId" /> -->
|
||
<!-- {{props.row.materialCode}} -->
|
||
<el-button v-if="props.row.parentId" size="mini" class="handle" icon="el-icon el-icon-rank"/>
|
||
</template>
|
||
</el-table-column>
|
||
|
||
<!-- <el-table-column label="项目令号" align="center">
|
||
<template slot-scope="scope">
|
||
<router-link :to="'/route1/' + scope.row.routeDescription" type="primary" :underline="false">{{
|
||
scope.row.routeDescription }}</router-link>
|
||
</template>
|
||
</el-table-column> -->
|
||
<el-table-column label="物料编码" width="120" align="center" prop="materialCode" fixed="left"/>
|
||
<el-table-column label="名称" width="120" align="center" prop="materialName" fixed="left"/>
|
||
|
||
<el-table-column label="材质" width="80" align="center" prop="material"/>
|
||
<el-table-column label="单重" width="60" align="center" prop="discWeight"/>
|
||
<el-table-column label="单台数" width="60" align="center" prop="unitQuantity">
|
||
<template slot-scope="scope">
|
||
<span :style="{
|
||
color: scope.row.firstBatchQuantity > 0 ? 'green' : 'red',
|
||
fontWeight: 'bold'
|
||
}">
|
||
{{ scope.row.firstBatchQuantity }}
|
||
</span>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column label="本批数" width="60" align="center" prop="batchQuantity"/>
|
||
|
||
<!--
|
||
<el-table-column label="材料BOM物料编码" width="220"align="center" prop="ra wMaterialCode" />
|
||
<el-table-column label="材料BOM物料名称"width="220" align="center" prop="rawMaterialName" />
|
||
<el-table-column label="用量"width="60"align="center" prop="discUsage" />
|
||
<el-table-column label="单位"width="60" align="center" prop="bomUnit" />-->
|
||
<el-table-column label="工序号" width="60" align="center" prop="processNo"/>
|
||
<el-table-column label="工作中心" width="96" align="center">
|
||
<template slot-scope="scope">
|
||
<el-form-item v-if="scope.row.isEdit" :prop="'routeList.' + scope.$index + '.workCenter'">
|
||
<el-select v-model="scope.row.workCenter" placeholder="请选择工作中心" clearable>
|
||
<el-option v-for="dict in dict.type.work_center" :key="dict.value" :label="dict.label"
|
||
:value="dict.value"/>
|
||
</el-select>
|
||
</el-form-item>
|
||
<span v-else>
|
||
<dict-tag :options="dict.type.work_center" :value="scope.row.workCenter"/>
|
||
</span>
|
||
</template>
|
||
</el-table-column>
|
||
|
||
<el-table-column label="工序名称" width="160" align="center">
|
||
<template slot-scope="scope">
|
||
<el-form-item v-if="scope.row.id < 0 || scope.row.isEdit"
|
||
:prop="'routeList.' + scope.$index + '.processName'">
|
||
<el-select v-model="scope.row.processName" filterable remote :remote-method="handleQuery3"
|
||
placeholder="请输入工序名称" clearable :loading="loading"
|
||
@change="handleProcessNameChange(scope)">
|
||
<el-option v-for="item in processName" :key="item" :label="item" :value="item"></el-option>
|
||
</el-select>
|
||
</el-form-item>
|
||
<span v-else>{{ scope.row.processName }}</span>
|
||
</template>
|
||
</el-table-column>
|
||
|
||
<el-table-column label="序说明" width="300" align="center">
|
||
<template slot-scope="scope">
|
||
<el-form-item v-if="scope.row.id < 0 || scope.row.isEdit"
|
||
:prop="'routeList.' + scope.$index + '.processDescription'">
|
||
<el-input v-model="scope.row.processDescription"></el-input>
|
||
</el-form-item>
|
||
<span v-else>{{ scope.row.processDescription }}</span>
|
||
</template>
|
||
</el-table-column>
|
||
|
||
<!-- 工序控制列 -->
|
||
<el-table-column label="工序控制码" width="100" align="center">
|
||
<template slot-scope="scope">
|
||
<el-form-item v-if="scope.row.isEdit" :prop="'routeList.' + scope.$index + '.processControl'">
|
||
<el-select v-model="scope.row.processControl" placeholder="请选择工序控制码" clearable>
|
||
<el-option label="汇报+免检" value="汇报+免检"></el-option>
|
||
<el-option label="委外+质量" value="委外+质量"></el-option>
|
||
<el-option label="汇报+质量" value="汇报+质量"></el-option>
|
||
</el-select>
|
||
</el-form-item>
|
||
<span v-else>{{ scope.row.processControl }}</span>
|
||
</template>
|
||
</el-table-column>
|
||
|
||
<el-table-column label="活动时长" align="center">
|
||
<template slot-scope="scope">
|
||
<el-form-item v-if="scope.row.id < 0 || scope.row.isEdit"
|
||
:prop="'routeList.' + scope.$index + '.activityDuration'">
|
||
<el-input v-model="scope.row.activityDuration"></el-input>
|
||
</el-form-item>
|
||
<span v-else>{{ scope.row.activityDuration }}</span>
|
||
</template>
|
||
</el-table-column>
|
||
|
||
<el-table-column label="活动单位" align="center" prop="activityUnit"/>
|
||
<el-table-column label="序开始时间" align="center" prop="xuStartTime" width="100">
|
||
<template slot-scope="scope">
|
||
<el-form-item v-if="scope.row.id < 0 || scope.row.isEdit"
|
||
:prop="'routeList.' + scope.$index + '.xuStartTime'">
|
||
<el-date-picker v-model="scope.row.xuStartTime" type="date" placeholder="选择序开始时间"
|
||
value-format="yyyy-MM-dd" format="yyyy-MM-dd">
|
||
</el-date-picker>
|
||
</el-form-item>
|
||
<span v-else>{{ parseTime(scope.row.xuStartTime, '{y}-{m}-{d}') }}</span>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column label="序结束时间" align="center" prop="xuEndTime" width="100">
|
||
<template slot-scope="scope">
|
||
<el-form-item v-if="scope.row.id < 0 || scope.row.isEdit"
|
||
:prop="'routeList.' + scope.$index + '.xuEndTime'">
|
||
<el-date-picker v-model="scope.row.xuEndTime" type="date" placeholder="选择序结束时间"
|
||
value-format="yyyy-MM-dd"
|
||
format="yyyy-MM-dd">
|
||
</el-date-picker>
|
||
</el-form-item>
|
||
<span v-else>{{ parseTime(scope.row.xuEndTime, '{y}-{m}-{d}') }}</span>
|
||
</template>
|
||
</el-table-column>
|
||
<!-- //<el-table-column label="单位" align="center" prop="bomUnit" /> -->
|
||
<!-- <el-table-column label="单台数量" align="center" prop="unitQuantity" /> -->
|
||
|
||
<el-table-column label="计划开始时间" align="center" prop="planStartTime" width="180">
|
||
<template slot-scope="scope">
|
||
<span>{{ parseTime(scope.row.planStartTime, '{y}-{m}-{d}') }}</span>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column label="计划结束时间" align="center" prop="planEndTime" width="180">
|
||
<template slot-scope="scope">
|
||
<span>{{ parseTime(scope.row.planEndTime, '{y}-{m}-{d}') }}</span>
|
||
</template>
|
||
</el-table-column>
|
||
|
||
<el-table-column class="maxWidth" label="操作" width="220" fixed="right" align="center"
|
||
class-name="small-padding fixed-width">
|
||
<template slot-scope="scope">
|
||
<el-button class="btn" size="mini" @click="onAddChild(scope)" v-if="!scope.row.parentId">
|
||
添加工艺
|
||
</el-button>
|
||
<el-button class="btn" size="mini" type="success" @click="onSave(scope)"
|
||
v-if="!scope.row.parentId && showParentSaveBtn === scope.row.id">
|
||
保存工艺
|
||
</el-button>
|
||
<template v-else-if="scope.row.parentId">
|
||
<template v-if="scope.row.isEdit">
|
||
<el-button class="btn" size="mini" type="success" @click="onSaveRow(scope)">
|
||
确定
|
||
</el-button>
|
||
<el-button class="btn" size="mini" type="info" @click="cancelEdit(scope)">
|
||
取消
|
||
</el-button>
|
||
</template>
|
||
<template v-else>
|
||
<template v-if="scope.row.id > 0">
|
||
<el-button class="btn" size="mini" type="primary" @click="handleRowEdit(scope)"
|
||
v-hasPermi="['system:route:edit']">
|
||
修改
|
||
</el-button>
|
||
<el-button class="btn" size="mini" type="danger" @click="handleDelete(scope)"
|
||
v-hasPermi="['system:route:remove']">
|
||
删除
|
||
</el-button>
|
||
</template>
|
||
<template v-else>
|
||
<el-button class="btn" size="mini" type="danger" @click="onDeleteUnsaved(scope)">
|
||
删除
|
||
</el-button>
|
||
</template>
|
||
</template>
|
||
</template>
|
||
</template>
|
||
</el-table-column>
|
||
</el-table>
|
||
</el-form>
|
||
|
||
<pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize"
|
||
@pagination="getList"/>
|
||
|
||
<el-dialog :title="title" :visible.sync="open" width="800px" append-to-body>
|
||
<el-form ref="form" :model="form" :rules="rules" label-width="100px">
|
||
<!-- 基本信息 -->
|
||
<el-row>
|
||
<el-col :span="12">
|
||
<el-form-item label="物料编码" prop="materialCode">
|
||
<el-input v-model="form.materialCode" placeholder="请输入物料编码"/>
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="12">
|
||
<el-form-item label="物料名称" prop="materialName">
|
||
<el-input v-model="form.materialName" placeholder="请输入物料名称"/>
|
||
</el-form-item>
|
||
</el-col>
|
||
</el-row>
|
||
|
||
<el-row>
|
||
<el-col :span="12">
|
||
<el-form-item label="材质" prop="material">
|
||
<el-input v-model="form.material" placeholder="请输入材质"/>
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="12">
|
||
<el-form-item label="单重" prop="discWeight">
|
||
<el-input v-model="form.discWeight" placeholder="请输入单重"/>
|
||
</el-form-item>
|
||
</el-col>
|
||
</el-row>
|
||
|
||
<el-row>
|
||
<el-col :span="12">
|
||
<el-form-item label="单位" prop="bomUnit">
|
||
<el-select v-model="form.bomUnit" placeholder="请选择单位">
|
||
<el-option label="件" value="件"></el-option>
|
||
<el-option label="套" value="套"></el-option>
|
||
<el-option label="个" value="个"></el-option>
|
||
<el-option label="米" value="米"></el-option>
|
||
<el-option label="千克" value="千克"></el-option>
|
||
<el-option label="吨" value="吨"></el-option>
|
||
</el-select>
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="12">
|
||
<el-form-item label="单台数量" prop="unitQuantity">
|
||
<el-input-number v-model="form.unitQuantity" :min="0" placeholder="请输入单台数量"/>
|
||
</el-form-item>
|
||
</el-col>
|
||
</el-row>
|
||
|
||
<el-row>
|
||
<el-col :span="12">
|
||
<el-form-item label="本批数量" prop="batchQuantity">
|
||
<el-input-number v-model="form.batchQuantity" :min="0" placeholder="请输入本批数量"/>
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="12">
|
||
<el-form-item label="首批数量" prop="firstBatchQuantity">
|
||
<el-input-number v-model="form.firstBatchQuantity" :min="0" placeholder="请输入首批数量"/>
|
||
</el-form-item>
|
||
</el-col>
|
||
</el-row>
|
||
|
||
<!-- 工艺信息 -->
|
||
<el-row>
|
||
<el-col :span="12">
|
||
<el-form-item label="工作中心" prop="workCenter">
|
||
<el-select v-model="form.workCenter" placeholder="请选择工作中心" clearable>
|
||
<el-option label="机一工段" value="机一工段"></el-option>
|
||
<el-option label="机二工段" value="机二工段"></el-option>
|
||
<el-option label="机三工段" value="机三工段"></el-option>
|
||
<el-option label="装一工段" value="装一工段"></el-option>
|
||
<el-option label="装二工段" value="装二工段"></el-option>
|
||
<el-option label="铆焊工段" value="铆焊工段"></el-option>
|
||
<el-option label="电钳工段" value="电钳工段"></el-option>
|
||
<el-option label="委外中心" value="委外中心"></el-option>
|
||
</el-select>
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="12">
|
||
<el-form-item label="工序名称" prop="processName">
|
||
<el-select v-model="form.processName" filterable remote :remote-method="handleQuery3"
|
||
placeholder="请输入工序名称" clearable :loading="loading" @change="handleProcessNameChange">
|
||
<el-option v-for="item in processName" :key="item" :label="item" :value="item"></el-option>
|
||
</el-select>
|
||
</el-form-item>
|
||
</el-col>
|
||
</el-row>
|
||
|
||
<el-row>
|
||
<el-col :span="24">
|
||
<el-form-item label="工序说明" prop="processDescription">
|
||
<el-input type="textarea" v-model="form.processDescription" placeholder="请输入工序说明"/>
|
||
</el-form-item>
|
||
</el-col>
|
||
</el-row>
|
||
|
||
<el-row>
|
||
<el-col :span="12">
|
||
<el-form-item label="工序控制" prop="processControl">
|
||
<el-select v-model="form.processControl" placeholder="请选择工序控制码" clearable>
|
||
<el-option label="汇报+免检" value="汇报+免检"></el-option>
|
||
<el-option label="委外+质量" value="委外+质量"></el-option>
|
||
<el-option label="汇报+质量" value="汇报+质量"></el-option>
|
||
</el-select>
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="12">
|
||
<el-form-item label="活动时长" prop="activityDuration">
|
||
<el-input v-model="form.activityDuration" placeholder="请输入活动时长"/>
|
||
</el-form-item>
|
||
</el-col>
|
||
</el-row>
|
||
|
||
<el-row>
|
||
<el-col :span="12">
|
||
<el-form-item label="序开始时间" prop="xuStartTime">
|
||
<el-date-picker v-model="form.xuStartTime" type="date" placeholder="选择序开始时间"
|
||
value-format="yyyy-MM-dd"
|
||
format="yyyy-MM-dd">
|
||
</el-date-picker>
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="12">
|
||
<el-form-item label="序结束时间" prop="xuEndTime">
|
||
<el-date-picker v-model="form.xuEndTime" type="date" placeholder="选择序结束时间"
|
||
value-format="yyyy-MM-dd"
|
||
format="yyyy-MM-dd">
|
||
</el-date-picker>
|
||
</el-form-item>
|
||
</el-col>
|
||
</el-row>
|
||
</el-form>
|
||
<div slot="footer" class="dialog-footer">
|
||
<el-button :loading="buttonLoading" type="primary" @click="submitForm">确 定</el-button>
|
||
<el-button @click="cancel">取 消</el-button>
|
||
</div>
|
||
</el-dialog>
|
||
<!-- 导入导入对话框 -->
|
||
<el-dialog :title="upload.title" :visible.sync="upload.open" width="400px" append-to-body>
|
||
<el-upload ref="upload" :limit="1" accept=".xlsx, .xls" :headers="upload.headers"
|
||
:action="upload.url + '?updateSupport=' + upload.updateSupport" :disabled="upload.isUploading"
|
||
:on-progress="handleFileUploadProgress" :on-success="handleFileSuccess" :auto-upload="false" drag>
|
||
<i class="el-icon-upload"></i>
|
||
<div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
|
||
<div class="el-upload__tip text-center" slot="tip">
|
||
<div class="el-upload__tip" slot="tip">
|
||
<el-checkbox v-model="upload.updateSupport"/>
|
||
是否更新已经存在的物料数据
|
||
</div>
|
||
<span>仅允许导入xls、xlsx格式文件。</span>
|
||
<!-- <el-link type="primary" :underline="false" style="font-size:12px;vertical-align: baseline;"
|
||
@click="importTemplate">下载模板
|
||
</el-link>-->
|
||
</div>
|
||
</el-upload>
|
||
<div slot="footer" class="dialog-footer">
|
||
<el-button type="primary" @click="submitFileForm">确 定</el-button>
|
||
<el-button @click="upload.open = false">取 消</el-button>
|
||
</div>
|
||
</el-dialog>
|
||
|
||
<el-dialog :title="timeUpload.title" :visible.sync="timeUpload.open" width="400px" append-to-body>
|
||
<el-upload ref="timeUpload" :limit="1" accept=".xlsx, .xls" :headers="timeUpload.headers" :action="timeUpload.url"
|
||
:disabled="timeUpload.isUploading" :on-progress="handleTimeFileUploadProgress"
|
||
:on-success="handleTimeFileSuccess" :auto-upload="false" drag>
|
||
<i class="el-icon-upload"></i>
|
||
<div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
|
||
<div class="el-upload__tip text-center" slot="tip">
|
||
<span>仅允许导入xls、xlsx格式文件。</span>
|
||
</div>
|
||
</el-upload>
|
||
<div slot="footer" class="dialog-footer">
|
||
<el-button type="primary" @click="submitTimeFileForm">确 定</el-button>
|
||
<el-button @click="timeUpload.open = false">取 消</el-button>
|
||
</div>
|
||
</el-dialog>
|
||
<!-- 抽屉 -->
|
||
<el-drawer title="BOM信息" :visible.sync="BOMpop" :before-close="bomClose" :size="1100" :destroy-on-close="true" :modal="false">
|
||
<div style="padding: 20px;">
|
||
<!-- BOM信息头部 -->
|
||
<div class="bom-header">
|
||
<el-descriptions :column="3" border>
|
||
<el-descriptions-item label="当前物料编码">{{ currentMaterial.materialCode }}</el-descriptions-item>
|
||
<el-descriptions-item label="当前物料名称">{{ currentMaterial.materialName }}</el-descriptions-item>
|
||
<el-descriptions-item label="生产令号">{{ currentMaterial.productionOrderNo }}</el-descriptions-item>
|
||
</el-descriptions>
|
||
</div>
|
||
|
||
<!-- 搜索和操作按钮 -->
|
||
<div class="table-operations" style="margin: 15px 0;">
|
||
|
||
<div class="right-operations">
|
||
<el-button-group>
|
||
<el-button type="primary" size="small" @click="handleBomAdd">
|
||
<i class="el-icon-plus"></i> 新增
|
||
</el-button>
|
||
<el-button type="primary" size="small" @click="handleBomRefresh">
|
||
<i class="el-icon-refresh"></i> 刷新
|
||
</el-button>
|
||
<el-button type="success" size="small" @click="handleBomExport">
|
||
<i class="el-icon-download"></i> 导出
|
||
</el-button>
|
||
</el-button-group>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- BOM数据表格 -->
|
||
<el-table :data="filteredBomData" stripe max-height="400px" border v-loading="bomLoading"
|
||
@selection-change="handleBomSelectionChange" element-loading-text="加载中..."
|
||
element-loading-spinner="el-icon-loading">
|
||
<el-table-column type="selection" width="55" align="center"/>
|
||
<el-table-column label="生产令号" width="150" align="center" prop="projectNumber"/>
|
||
<el-table-column label="物料编码" width="200" align="center" prop="materialCode" show-overflow-tooltip/>
|
||
<el-table-column label="物料名称" width="200" align="center" prop="materialName" show-overflow-tooltip/>
|
||
<el-table-column label="材质" width="70" align="center" prop="materialType"/>
|
||
|
||
<el-table-column label="库存" width="88" align="center" prop="singleWeight ">
|
||
<template slot-scope="scope">
|
||
<span>{{ scope.row.singleWeight || '0' }}</span>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column label="用量" width="88" align="center" prop="quantity">
|
||
<template slot-scope="scope">
|
||
<span>{{ scope.row.quantity || '0' }}</span>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column label="单位" width="88" align="center" prop="unit"/>
|
||
<el-table-column label="操作" align="center" width="150">
|
||
<template slot-scope="scope">
|
||
<el-button size="mini" type="text" icon="el-icon-edit" @click="handleBomEdit(scope.row)">修改</el-button>
|
||
<el-button size="mini" type="text" icon="el-icon-delete"
|
||
@click="handleBomDelete(scope.row)">删除
|
||
</el-button>
|
||
</template>
|
||
</el-table-column>
|
||
</el-table>
|
||
<!-- BOM编辑对话框 -->
|
||
<el-dialog :title="bomDialogTitle" :visible.sync="bomDialogVisible" width="500px" append-to-body>
|
||
<el-form ref="bomForm" :model="bomForm" :rules="bomRules" label-width="100px">
|
||
<input type="hidden" v-model="bomForm.projectNumber">
|
||
<input type="hidden" v-model="bomForm.parentMaterialCode">
|
||
<input type="hidden" v-model="bomForm.parentMaterialName">
|
||
|
||
<!-- 物料名称 - 支持搜索或手动输入 -->
|
||
<el-form-item label="物料名称" prop="materialName">
|
||
<el-autocomplete v-model="bomForm.materialName" :fetch-suggestions="handleMaterialSearch"
|
||
:trigger-on-focus="false" @select="handleMaterialSelect" placeholder="请输入物料名称"
|
||
clearable
|
||
popper-class="material-autocomplete-dropdown">
|
||
<template slot-scope="{ item }">
|
||
<div class="material-suggestion-item">
|
||
<div class="material-name">{{ item.materialName }}</div>
|
||
<div class="material-info">
|
||
<span>编码: {{ item.materialCode }}</span>
|
||
<span>材质: {{ item.materialType }}</span>
|
||
<span>单位: {{ item.classificationName }}</span>
|
||
<span>库存: {{ item.singleWeight || '0' }}</span>
|
||
</div>
|
||
</div>
|
||
</template>
|
||
</el-autocomplete>
|
||
</el-form-item>
|
||
|
||
<!-- 物料编码 - 允许手动输入 -->
|
||
<el-form-item label="物料编码" prop="materialCode">
|
||
<el-input v-model="bomForm.materialCode" placeholder="请输入物料编码"></el-input>
|
||
</el-form-item>
|
||
|
||
<!-- 材质 - 允许手动输入 -->
|
||
<el-form-item label="材质" prop="materialType">
|
||
<el-input v-model="bomForm.materialType" placeholder="请输入材质"></el-input>
|
||
</el-form-item>
|
||
|
||
<!-- 单位 -->
|
||
<el-form-item label="单位" prop="unit">
|
||
<el-select v-model="bomForm.unit" placeholder="请选择单位" clearable>
|
||
<el-option label="件" value="件"></el-option>
|
||
<el-option label="根" value="根"></el-option>
|
||
<el-option label="mm" value="mm"></el-option>
|
||
<el-option label="kg" value="kg"></el-option>
|
||
<el-option label="套" value="套"></el-option>
|
||
<el-option label="个" value="个"></el-option>
|
||
</el-select>
|
||
</el-form-item>
|
||
|
||
<!-- 当前库存 - 允许手动输入 -->
|
||
<el-form-item label="当前库存" prop="stock">
|
||
<el-input-number v-model="bomForm.stock" :min="0" :precision="2"
|
||
placeholder="请输入库存"></el-input-number>
|
||
</el-form-item>
|
||
|
||
<!-- 用量 -->
|
||
<el-form-item label="用量" prop="quantity">
|
||
<el-input-number v-model="bomForm.quantity" :min="0" :precision="2"
|
||
placeholder="请输入用量"></el-input-number>
|
||
</el-form-item>
|
||
</el-form>
|
||
|
||
<div slot="footer" class="dialog-footer">
|
||
<el-button type="primary" @click="submitBomForm">确 定</el-button>
|
||
<el-button @click="bomDialogVisible = false">取 消</el-button>
|
||
</div>
|
||
</el-dialog>
|
||
|
||
<!-- 工艺路线信息部分 -->
|
||
<div class="section-title" style="margin: 20px 0 15px;">
|
||
<h3>工艺路线信息</h3>
|
||
</div>
|
||
<el-table :data="processRoutes" stripe border v-loading="processLoading">
|
||
<el-table-column label="工艺编号" prop="fnumber" width="120" align="center"/>
|
||
<el-table-column label="项目令号" prop="project_code" width="180" align="center"/>
|
||
<el-table-column label="物料编码" prop="materialCode" fixed="left" width="140" align="center"/>
|
||
<el-table-column label="物料名称" prop="materialName" fixed="left" min-width="140" align="center"/>
|
||
<el-table-column label="操作" width="120" align="center">
|
||
<template slot-scope="scope">
|
||
<el-button
|
||
type="text"
|
||
@click="handleViewRoute(scope.row)"
|
||
:type="selectedRouteId === scope.row.id ? 'success' : 'primary'">
|
||
{{ selectedRouteId === scope.row.id ? '查看中' : '查看' }}
|
||
</el-button>
|
||
</template>
|
||
</el-table-column>
|
||
</el-table>
|
||
|
||
<!-- 选中的工艺路线工序信息 -->
|
||
<div v-if="selectedRoute" class="process-detail" style="margin-top: 15px;">
|
||
<div class="sub-title" style="margin-bottom: 10px;">
|
||
<h4>工序信息 - {{ selectedRoute.fnumber }}</h4>
|
||
</div>
|
||
<el-table :data="currentProcessList" stripe border max-height="300px">
|
||
<el-table-column label="工序号" prop="processNo" width="80" align="center"/>
|
||
<el-table-column label="工作中心" prop="workCenter" width="120" align="center"/>
|
||
<el-table-column label="工序名称" prop="processName" width="120" align="center"/>
|
||
<el-table-column label="工序说明" prop="processDescription" min-width="200" show-overflow-tooltip/>
|
||
<el-table-column label="工序控制" prop="processControl" width="120" align="center"/>
|
||
<el-table-column label="活动时长" align="center" width="120">
|
||
<template slot-scope="scope">
|
||
{{ scope.row.activityDuration }} {{ scope.row.activityUnit }}
|
||
</template>
|
||
</el-table-column>
|
||
</el-table>
|
||
</div>
|
||
</div>
|
||
</el-drawer>
|
||
</div>
|
||
</template>
|
||
|
||
<script>
|
||
import {
|
||
listRoute,
|
||
getRoute,
|
||
delRoute,
|
||
addRoute,
|
||
updateRoute,
|
||
getDistinctProjectCodes,
|
||
updateProcessPlan, generatePDFs, updateBom, addBom, deleteBom, getKindeeExcel,getAllRouteAndUse,updateProcesTime
|
||
|
||
} from "@/api/system/route";
|
||
import {getToken} from "../../../utils/auth";
|
||
import Fromed from './fromed'
|
||
import Bomfrom from './bomfrom'
|
||
import {getProcessInfoList, pushRouteBom, onSave, getBomInfo, getProcessRouteList} from "@/api/system/route";
|
||
import {listMaterial} from "@/api/system/material";
|
||
|
||
import dict from "@/utils/dict";
|
||
import DictData from "@/components/DictData";
|
||
|
||
DictData.install();
|
||
export default {
|
||
name: "",
|
||
dicts: ['work_center'],
|
||
|
||
components: {
|
||
Fromed,
|
||
Bomfrom
|
||
},
|
||
props: {
|
||
params:{},
|
||
showdel: {
|
||
type: Boolean,
|
||
default: true
|
||
},
|
||
obj: {
|
||
type: Object,
|
||
default() {
|
||
return {}
|
||
}
|
||
}
|
||
},
|
||
data() {
|
||
return {
|
||
timeUpload: {
|
||
open: false,
|
||
title: "",
|
||
isUploading: false,
|
||
headers: {Authorization: "Bearer " + getToken()},
|
||
url: process.env.VUE_APP_BASE_API + "/system/route/importDataTime"
|
||
},
|
||
materialOptions: [], // 用于存储物料信息
|
||
showtable: true,
|
||
expand: true,
|
||
bomData: [],
|
||
bomLoading: false,
|
||
bomSearchKey: '',
|
||
currentMaterial: {
|
||
materialCode: '',
|
||
materialName: '',
|
||
productionOrderNo: ''
|
||
},
|
||
bomPagination: {
|
||
currentPage: 1,
|
||
pageSize: 10
|
||
},
|
||
totalBomCount: 0,
|
||
BOMpop: false,
|
||
bomList: [],
|
||
//expandRowKeys:[],
|
||
omdelData: '',
|
||
routeDescription: '', // 用于存储 productionOrderNo 的变量
|
||
// 按钮loading
|
||
buttonLoading: false,
|
||
// 遮罩层
|
||
loading: true,
|
||
// 选中数组
|
||
ids: [],
|
||
// 非单禁用
|
||
single: true,
|
||
// 非多个禁用
|
||
multiple: false,
|
||
// 显示搜索条件
|
||
showSearch: true,
|
||
// 显示父级的保存工艺按钮
|
||
showParentSaveBtn: null,
|
||
// 总条数
|
||
total: 0,
|
||
form: {
|
||
// 工艺路线表格数据
|
||
routeList: [],
|
||
},
|
||
// 弹出层标题
|
||
title: "",
|
||
// 是否显示弹出层
|
||
open: false,
|
||
// 工序详情对话框显示状态
|
||
processDetailsVisible: false,
|
||
// 当前显示的工序列表
|
||
// 查询参数
|
||
queryParams: {
|
||
pageNum: 1,
|
||
pageSize: 500,
|
||
routeDescription: [],
|
||
materialCode: undefined,
|
||
materialName: undefined,
|
||
bomUnit: undefined,
|
||
processNo: undefined,
|
||
workCenter: undefined,
|
||
processName: undefined,
|
||
rawMaterialCode: undefined,
|
||
rawMaterialName: undefined,
|
||
discWeight: undefined,
|
||
discUsage: undefined,
|
||
firstBatchQuantity: undefined,
|
||
processDescription: undefined,
|
||
processControl: undefined,
|
||
activityDuration: undefined,
|
||
activityUnit: undefined,
|
||
},
|
||
// 对应关系映射:工序名称 -> 工作中心
|
||
processToWorkCenterMap: {
|
||
// 铆焊工段
|
||
'数控火焰下料': '铆焊工段',
|
||
'数控激光下料': '铆焊工段',
|
||
'数控切管下料': '铆焊工段',
|
||
'水虎鱼剪折冲': '铆焊工段',
|
||
'锯床下料': '铆焊工段',
|
||
'抛丸': '铆焊工段',
|
||
'组焊': '铆焊工段',
|
||
'普车': '机一工段',
|
||
'普铣': '机一工段',
|
||
'龙门铣': '机一工段',
|
||
'立磨': '机一工段',
|
||
'平磨': '机一工段',
|
||
'钻床': '机一工段',
|
||
'数车': '机二工段',
|
||
'数控外圆磨': '机二工段',
|
||
'走芯机': '机二工段',
|
||
'双主轴': '机二工段',
|
||
'车铣复合': '机二工段',
|
||
'线切割': '机二工段',
|
||
'卧加63': '机三工段',
|
||
'5032龙门': '机三工段',
|
||
'3018龙门': '机三工段',
|
||
'2013龙门': '机三工段',
|
||
'立加1370': '机三工段',
|
||
'立加1177': '机三工段',
|
||
'立加850': '机三工段',
|
||
'数插5035': '机三工段',
|
||
'装配1': '装一工段',
|
||
'装配2': '装二工段',
|
||
'电装': '电钳工段',
|
||
'正火': '委外中心',
|
||
'回火': '委外中心',
|
||
'调质': '委外中心',
|
||
'真空调质': '委外中心',
|
||
'整体淬火': '委外中心',
|
||
'表面淬火': '委外中心',
|
||
'真空淬火': '委外中心',
|
||
'渗碳淬火': '委外中心',
|
||
'渗氮': '委外中心',
|
||
'碳氮共渗': '委外中心',
|
||
'制齿': '委外中心',
|
||
'电火花': '委外中心',
|
||
'插床': '委外中心',
|
||
'按图订制': '委外中心',
|
||
'磷化处理': '委外中心',
|
||
'发蓝处理': '委外中心',
|
||
'QPQ处理': '委外中心',
|
||
'镀锌': '委外中心',
|
||
'镀硬铬': '委外中心',
|
||
'镀锌镍合金': '委外中心',
|
||
'阳极氧化': '委外中心',
|
||
'达克罗': '委外中心',
|
||
'喷漆': '委外中心',
|
||
'喷塑': '委外中心',
|
||
'喷砂': '委外中心',
|
||
'喷砂底漆': '委外中心'
|
||
},
|
||
// 表单参数
|
||
|
||
projectCodes: [], // 存储查询到的项令号
|
||
processName: [],
|
||
activeRows: [], // 转换为列表的数据
|
||
config: {
|
||
elementSeletor: "tbody", //元素选择
|
||
filter: ".filtered", // 过滤
|
||
onEnd: (event, oldValue, newValue) => {
|
||
// 找到父节点
|
||
const parentIndex = this.form.routeList.findIndex(item =>
|
||
item.children && item.children.some(child => child.id === newValue.id)
|
||
);
|
||
|
||
if (parentIndex !== -1) {
|
||
// 获取子节点列表
|
||
const children = this.form.routeList[parentIndex].children;
|
||
|
||
// 重新排序工序号
|
||
children.forEach((child, index) => {
|
||
child.processNo = (index + 1) * 10;
|
||
});
|
||
}
|
||
},
|
||
},
|
||
upload: {
|
||
// 是否显示弹出层
|
||
open: false,
|
||
// 弹出层标题
|
||
title: "",
|
||
// 是否禁用上传
|
||
isUploading: false,
|
||
// 是否更新已经存在的用户数据
|
||
updateSupport: 0,
|
||
// 设置上传的请求头部
|
||
headers: {Authorization: "Bearer " + getToken()},
|
||
// 上传的地址
|
||
url: process.env.VUE_APP_BASE_API + "/system/route/importData"
|
||
},
|
||
id: 0,//动态增加表格列的ID
|
||
// 表单校验
|
||
rules: {
|
||
id: [
|
||
{required: true, message: "主键ID不能为空", trigger: "blur"}
|
||
],
|
||
routeDescription: [
|
||
{required: true, message: "工艺路线描述不能为空", trigger: "blur"}
|
||
],
|
||
materialCode: [
|
||
{required: true, message: "物料编码不能为空", trigger: "blur"}
|
||
],
|
||
materialName: [
|
||
{required: true, message: "物料名称不能为空", trigger: "blur"}
|
||
],
|
||
processControl: [ // 添加工序控制码的验证
|
||
{required: true, message: "工序控制码不能为空", trigger: "blur"}
|
||
],
|
||
processName: [ // 添加工序名称的验证
|
||
{required: true, message: "工序名称不能为空", trigger: "blur"}
|
||
],
|
||
activityDuration: [ // 添加活动时长的验证
|
||
{required: true, message: "活动时长不能为空", trigger: "blur"}
|
||
]
|
||
},
|
||
bomDialogVisible: false,
|
||
bomDialogTitle: '',
|
||
bomForm: {
|
||
id: undefined,
|
||
projectNumber: '', // 添加项目令号
|
||
materialCode: '',
|
||
materialName: '',
|
||
materialType: '',
|
||
quantity: 0,
|
||
unit: '',
|
||
stock: 0,
|
||
parentMaterialCode: '', // 添加父级物料编码
|
||
parentMaterialName: '', // 添加父级物料名称
|
||
},
|
||
bomRules: {
|
||
materialName: [
|
||
{required: true, message: '请输入物料名称', trigger: 'blur'}
|
||
],
|
||
materialCode: [
|
||
{required: true, message: '请输入物料编码', trigger: 'blur'}
|
||
],
|
||
materialType: [
|
||
{required: true, message: '请选择材质', trigger: 'change'}
|
||
],
|
||
unit: [
|
||
{required: true, message: '请选择单位', trigger: 'change'}
|
||
],
|
||
quantity: [
|
||
{required: true, message: '请输入用量', trigger: 'blur'}
|
||
],
|
||
projectNumber: [
|
||
{required: true, message: '项目令号不能为空', trigger: 'blur'}
|
||
],
|
||
parentMaterialCode: [
|
||
{required: true, message: '父级物料编码不能为空', trigger: 'blur'}
|
||
],
|
||
parentMaterialName: [
|
||
{required: true, message: '父级物料名称不能为空', trigger: 'blur'}
|
||
],
|
||
stock: [
|
||
{required: true, message: '库存不能为空', trigger: 'blur'}
|
||
]
|
||
},
|
||
selectedBomRows: [],
|
||
materialSearchLoading: false,
|
||
materialQuery: '', // 当前搜索关键字
|
||
materialPagination: {
|
||
pageNum: 1,
|
||
pageSize: 10,
|
||
total: 0
|
||
},
|
||
materialLoading: false, // 加载更多状态
|
||
hasMoreMaterial: true, // 是否还有更多数据
|
||
activeTab: 'bom', // 当前激活的标签页
|
||
processRouteData: [], // 工艺路线数据
|
||
processLoading: false, // 工艺信息加载状态
|
||
processRoutes: [], // 所有工艺路线
|
||
selectedRouteId: null, // 当前选中的工艺路线ID
|
||
selectedRoute: null, // 当前选中的工艺路线完整信息
|
||
currentProcessList: [], // 当前显示的工序列表
|
||
dataList: [], // 存储获取到的数据
|
||
routeGroupName: ''
|
||
};
|
||
},
|
||
created() {
|
||
this.queryParams.routeDescription = "";
|
||
console.log(this.params)
|
||
if (this.params && this.params.productionOrderNo) {
|
||
this.queryParams.routeDescription = this.params.productionOrderNo;
|
||
}
|
||
|
||
|
||
// const productionOrderNo = this.params.productionOrderNo;
|
||
// if (productionOrderNo) {
|
||
// this.queryParams.routeDescription = productionOrderNo;
|
||
// } else {
|
||
// }
|
||
this.getList();
|
||
},
|
||
watch: {
|
||
'$route.query.productionOrderNo': function (newVal) {
|
||
// 当路由参数 productionOrderNo 变化时,重新获取
|
||
this.setTotalWeight();
|
||
this.getList();
|
||
// 设置查询参数中的 routeDescription
|
||
if (newVal) {
|
||
this.queryParams.routeDescription = newVal;
|
||
}
|
||
}
|
||
},
|
||
mounted() {
|
||
this.rowDrop();
|
||
},
|
||
computed: {
|
||
filteredBomData() {
|
||
if (!this.bomSearchKey) return this.bomData;
|
||
const searchKey = this.bomSearchKey.toLowerCase();
|
||
return this.bomData.filter(item => {
|
||
return Object.values(item).some(value =>
|
||
String(value).toLowerCase().includes(searchKey)
|
||
);
|
||
});
|
||
}
|
||
},
|
||
methods: {
|
||
// dict,
|
||
getKindeeExcel() {
|
||
// 显示加载状态
|
||
const loadingInstance = this.$loading({
|
||
lock: true,
|
||
text: '正在获取已投放的工艺数据...',
|
||
spinner: 'el-icon-loading',
|
||
background: 'rgba(255, 255, 255, 0.7)',
|
||
});
|
||
this.loading = true;
|
||
|
||
// 调用 reset 方法,重置表单或状态
|
||
this.reset();
|
||
|
||
// 获取生产订单号
|
||
const rooteProdet = this.params.productionOrderNo;
|
||
|
||
// 调用 getKindeeExcel 方法
|
||
getKindeeExcel(rooteProdet)
|
||
.then(data => {
|
||
// 处理返回的数据
|
||
this.$message.success('获取工艺成功!');
|
||
})
|
||
.catch(error => {
|
||
this.$message.error(error.message); // 显示错误消息
|
||
})
|
||
.finally(() => {
|
||
// 关闭加载状态
|
||
loadingInstance.close();
|
||
this.loading = false; // 关闭 loading 状态
|
||
});
|
||
this.handleBomRefresh();
|
||
},
|
||
|
||
|
||
getAllRouteAndUse() {
|
||
// 显示加载状态
|
||
const loadingInstance = this.$loading({
|
||
lock: true,
|
||
text: '正在获取全部工艺数据...',
|
||
spinner: 'el-icon-loading',
|
||
background: 'rgba(255, 255, 255, 0.7)',
|
||
});
|
||
this.loading = true;
|
||
|
||
// 调用 reset 方法,重置表单或状态
|
||
this.reset();
|
||
|
||
// 获取生产订单号
|
||
const rooteProdet = this.params.productionOrderNo;
|
||
|
||
// 调用 getAllRouteAndUse 方法
|
||
getAllRouteAndUse(rooteProdet)
|
||
.then(data => {
|
||
// 处理返回的数据
|
||
this.$message.success('获取全部工艺成功!');
|
||
})
|
||
.catch(error => {
|
||
this.$message.error(error.message); // 显示错误消息
|
||
})
|
||
.finally(() => {
|
||
// 关闭加载状态
|
||
loadingInstance.close();
|
||
this.loading = false; // 关闭 loading 状态
|
||
});
|
||
this.handleBomRefresh();
|
||
},
|
||
|
||
|
||
// 处理工作中心变化
|
||
handleWorkCenterChange(scope) {
|
||
const {row} = scope;
|
||
const currentIndex = this.form.routeList.findIndex(item => item === row);
|
||
|
||
// 移除自动设置工序控制码的逻辑
|
||
// 只需记录工作中心的变化,不再自动填写
|
||
console.log("工作中心变化:", row.workCenter);
|
||
},
|
||
|
||
// 验证工序控制
|
||
validateProcessControl(row, index) {
|
||
// 验证逻辑保持不变
|
||
if (row.workCenter === '委外中心' && row.processControl !== '委外+质量') {
|
||
return {
|
||
valid: false,
|
||
message: '委外中心的工序控制必须为"委外+质量"',
|
||
correctValue: '委外+质量'
|
||
};
|
||
}
|
||
|
||
if (index > 0) {
|
||
const previousRow = this.form.routeList[index - 1];
|
||
if (previousRow.workCenter === row.workCenter &&
|
||
previousRow.workCenter !== '委外中心' &&
|
||
row.processControl !== '汇报+免检') {
|
||
return {
|
||
valid: false,
|
||
message: '与上道工序工作中心相同时,工序控制应为"汇报+免检"',
|
||
correctValue: '汇报+免检'
|
||
};
|
||
}
|
||
}
|
||
|
||
return {valid: true};
|
||
},
|
||
|
||
// 开始编辑行
|
||
handleRowEdit(scope) {
|
||
// 保存原始数据
|
||
scope.row.originalData = JSON.parse(JSON.stringify(scope.row));
|
||
// 设置编辑状态
|
||
this.$set(scope.row, 'isEdit', true);
|
||
|
||
// 如果是委外中心,确保工序控制正确
|
||
if (scope.row.workCenter === '委外中心') {
|
||
this.$set(scope.row, 'processControl', '委外+质量');
|
||
}
|
||
},
|
||
|
||
// 判断工序控制是否应该禁用
|
||
isProcessControlDisabled(row, index) {
|
||
return row.workCenter === '委外中心' || this.shouldBeAutoFreeInspection(row, index);
|
||
},
|
||
|
||
// 设置工序控制
|
||
setProcessControl(row, index) {
|
||
console.log('进入setProcessControl方法'); // 添加日志
|
||
if (row.workCenter === '委外中心') {
|
||
console.log('设置委外+质量'); // 添加日志
|
||
this.$set(row, 'processControl', '委外+质量');
|
||
} else if (this.shouldBeAutoFreeInspection(row, index)) {
|
||
console.log('设置汇报+免检'); // 添加日志
|
||
this.$set(row, 'processControl', '汇报+免检');
|
||
}
|
||
},
|
||
// 验证工序控制
|
||
|
||
// 判断是否应该自动设置为免检
|
||
shouldBeAutoFreeInspection(row, index) {
|
||
if (!row.parentId || index === 0 || row.workCenter === '委外中心') {
|
||
return false;
|
||
}
|
||
|
||
// 获取上一道工序
|
||
const parent = this.form.routeList.find(item => item.id === row.parentId);
|
||
if (!parent || !parent.children) {
|
||
return false;
|
||
}
|
||
|
||
const currentIndex = parent.children.findIndex(item => item === row);
|
||
if (currentIndex <= 0) {
|
||
return false;
|
||
}
|
||
|
||
const prevProcess = parent.children[currentIndex - 1];
|
||
|
||
|
||
return prevProcess && prevProcess.workCenter === row.workCenter;
|
||
},
|
||
|
||
|
||
/** 导入时间按钮操作 */
|
||
handleImportTime() {
|
||
this.timeUpload.title = "导入时间";
|
||
this.timeUpload.open = true;
|
||
},
|
||
// 处理时间文件上传进度
|
||
handleTimeFileUploadProgress(event, file, fileList) {
|
||
this.timeUpload.isUploading = true;
|
||
},
|
||
// 处理时间文件上传成功
|
||
handleTimeFileSuccess(response, file, fileList) {
|
||
this.timeUpload.open = false;
|
||
this.timeUpload.isUploading = false;
|
||
this.$refs.timeUpload.clearFiles();
|
||
this.$alert("<div style='overflow: auto;overflow-x: hidden;max-height: 70vh;padding: 10px 20px 0;'>"
|
||
+ response.msg + "</div>", "导入结果", {dangerouslyUseHTMLString: true});
|
||
this.getList();
|
||
},
|
||
// 提交时间文件上传
|
||
submitTimeFileForm() {
|
||
this.$refs.timeUpload.submit();
|
||
},
|
||
rowDrop() {
|
||
const tbody = document.querySelector('.el-table__body-wrapper tbody');
|
||
const _this = this;
|
||
// Sortable.create(tbody, {
|
||
// onEnd({newIndex, oldIndex}) {
|
||
// const currRow = _this.form.routeList[oldIndex];
|
||
// // 只处理子工序
|
||
// if (currRow.parentId) {
|
||
// const parentIndex = _this.form.routeList.findIndex(item => item.id === currRow.parentId);
|
||
// if (parentIndex > -1) {
|
||
// const children = _this.form.routeList[parentIndex].children;
|
||
// // 移动数组元素
|
||
// const targetRow = children.splice(oldIndex, 1)[0];
|
||
// children.splice(newIndex, 0, targetRow);
|
||
// // 重新计算工序号
|
||
// children.forEach((item, index) => {
|
||
// item.processNo = (index + 1) * 10; // 按10、20、30...排序
|
||
// });
|
||
// }
|
||
// }
|
||
// },
|
||
// filter: ".filtered" // 过滤掉父节点
|
||
// });
|
||
},
|
||
|
||
reorderProcessNo() {
|
||
this.form.routeList.forEach(parent => {
|
||
if (parent.children && parent.children.length) {
|
||
parent.children.forEach((child, index) => {
|
||
child.processNo = index + 1; // 使用下标+1
|
||
});
|
||
}
|
||
});
|
||
},
|
||
// BOM抽屉相关方法
|
||
bomClose(done) {
|
||
// 直接清空数据并关闭
|
||
this.bomData = [];
|
||
this.currentMaterial = {
|
||
materialCode: '',
|
||
materialName: '',
|
||
productionOrderNo: ''
|
||
};
|
||
done();
|
||
},
|
||
|
||
handleBomSearch() {
|
||
this.bomPagination.currentPage = 1;
|
||
},
|
||
|
||
handleBomRefresh() {
|
||
this.fetchBomInfo().then(response => {
|
||
this.bomData = response || [];
|
||
this.totalBomCount = this.bomData.length;
|
||
}).catch(error => {
|
||
this.$message.error('获取BOM数据失败');
|
||
this.bomData = [];
|
||
}).finally(() => {
|
||
this.bomLoading = false;
|
||
});
|
||
},
|
||
|
||
handleBomExport() {
|
||
this.download('system/bom/export', {
|
||
materialCode: this.currentMaterial.materialCode,
|
||
materialName: this.currentMaterial.materialName,
|
||
productionOrderNo: this.currentMaterial.productionOrderNo
|
||
}, `bom_${new Date().getTime()}.xlsx`);
|
||
},
|
||
|
||
handleBomSizeChange(val) {
|
||
this.bomPagination.pageSize = val;
|
||
},
|
||
|
||
handleBomCurrentChange(val) {
|
||
this.bomPagination.currentPage = val;
|
||
},
|
||
|
||
handleProcessNameChange(scope) {
|
||
console.log(scope)
|
||
const selectedProcessName = scope.row.processName;
|
||
console.log(selectedProcessName)
|
||
if (this.processToWorkCenterMap[selectedProcessName]) {
|
||
scope.row.workCenter = this.processToWorkCenterMap[selectedProcessName];
|
||
} else {
|
||
scope.row.workCenter = '';
|
||
}
|
||
},
|
||
|
||
handleQuery3(query) {
|
||
if (query === '') {
|
||
this.processName = [];
|
||
return;
|
||
}
|
||
// 开始加载
|
||
this.loading = true;
|
||
// 调用后端接口获取匹配的项目令号
|
||
getProcessInfoList(query).then((response) => {
|
||
// 加载完成
|
||
this.loading = false;
|
||
this.processName = response;
|
||
|
||
}).catch(() => {
|
||
this.loading = false; // 加载失败
|
||
this.processName = []; // 如果请求失败,清空选项
|
||
});
|
||
},
|
||
// 控制表格可移动部分
|
||
tableRowClassName({row, rowIndex}) {
|
||
// 过滤掉父节点
|
||
if (!row.parentId) {
|
||
return "filtered";
|
||
}
|
||
return "";
|
||
},
|
||
// 添加子集
|
||
onAddChild(props) {
|
||
// 是否为父级,返回父级所在下标
|
||
var index = this.form.routeList.findIndex(item => item.id === props.row.id);
|
||
// -1为未检索到,不为父级
|
||
if (index === -1) {
|
||
alert("刷新试试,为检索到此目录,可能不存在")
|
||
return;
|
||
}
|
||
|
||
var routeList = this.form.routeList[index].children;
|
||
var route = routeList.sort(function (a, b) {
|
||
return a.processNo - b.processNo
|
||
})[routeList.length - 1];
|
||
var processNo = !route ? 0 : route.processNo + 10;
|
||
//routeList.push({ id: --this.id, parentId: props.row.id, processNo: processNo, children: null });
|
||
//this.showParentSaveBtn = props.row.id;
|
||
const newRow = {
|
||
id: --this.id,
|
||
parentId: props.row.id,
|
||
processNo: processNo,
|
||
children: null
|
||
};
|
||
routeList.push(newRow);
|
||
this.showParentSaveBtn = props.row.id;
|
||
|
||
// 添加新行后,监听工作中心变化
|
||
this.$nextTick(() => {
|
||
if (newRow.workCenter) {
|
||
this.setProcessControl(newRow, routeList.length - 1);
|
||
}
|
||
});
|
||
|
||
},
|
||
|
||
// 删除子集
|
||
onDelete(props) {
|
||
// 获取父级的所在下标
|
||
var index = this.form.routeList.findIndex(item => item.id === props.row.parentId);
|
||
// 获取子集的所在下标
|
||
var childrenIndex = this.form.routeList[index].children.findIndex(item => item.id === props.row.id);
|
||
// 找到子集并删除
|
||
this.form.routeList[index].children.splice(childrenIndex, 1);
|
||
// 修改其它子集的工序号
|
||
for (let i = 0; i < this.form.routeList[index].children.length; i++) {
|
||
// 修改子集中工序号
|
||
this.form.routeList[index].children[i].processNo = (i + 1) * 10;
|
||
}
|
||
},
|
||
// 修改现有的cellhand方法
|
||
cellhand(row, column) {
|
||
// 只在点击物料编码列时触发
|
||
if (column.property === 'materialCode') {
|
||
this.BOMpop = true;
|
||
this.bomLoading = true;
|
||
this.processLoading = true;
|
||
|
||
// 设置当前物料信息
|
||
this.currentMaterial = {
|
||
materialCode: row.materialCode,
|
||
materialName: row.materialName,
|
||
productionOrderNo: this.params.productionOrderNo
|
||
};
|
||
|
||
// 调用获取BOM信息的接口
|
||
getBomInfo(
|
||
row.materialCode,
|
||
row.materialName,
|
||
this.currentMaterial.productionOrderNo
|
||
)
|
||
.then(response => {
|
||
this.bomData = response || [];
|
||
this.totalBomCount = this.bomData.length;
|
||
})
|
||
.catch(error => {
|
||
console.error('获取BOM数据失败:', error);
|
||
this.$message.error('获取BOM数据失败');
|
||
this.bomData = [];
|
||
})
|
||
.finally(() => {
|
||
this.bomLoading = false;
|
||
});
|
||
|
||
// 获取工艺信息
|
||
this.getProcessRouteList();
|
||
}
|
||
},
|
||
|
||
|
||
setTotalWeight() {
|
||
const totalWeight = this.params.productionOrderNo;
|
||
if (totalWeight) {
|
||
this.queryParams.totalWeight = totalWeight;
|
||
}
|
||
},
|
||
|
||
/** 查询工艺路线列表 */
|
||
// 修改原有的 getList 方法,获取列表后自动刷新库存
|
||
async getList() {
|
||
this.loading = true;
|
||
try {
|
||
const response = await listRoute(this.queryParams);
|
||
this.form.routeList = response.rows;
|
||
this.total = response.total;
|
||
} catch (error) {
|
||
console.error('获取数据失败:', error);
|
||
|
||
} finally {
|
||
this.loading = false;
|
||
}
|
||
},
|
||
// 表单重置
|
||
reset() {
|
||
this.form = {
|
||
id: undefined,
|
||
// 物料信息
|
||
materialCode: undefined,
|
||
materialName: undefined,
|
||
material: undefined,
|
||
discWeight: undefined,
|
||
bomUnit: undefined,
|
||
unitQuantity: undefined,
|
||
batchQuantity: undefined,
|
||
firstBatchQuantity: undefined,
|
||
// 工艺信息
|
||
workCenter: undefined,
|
||
processName: undefined,
|
||
processDescription: undefined,
|
||
processControl: undefined,
|
||
activityDuration: undefined,
|
||
activityUnit: undefined,
|
||
xuStartTime: undefined,
|
||
xuEndTime: undefined
|
||
};
|
||
this.resetForm("form");
|
||
},
|
||
/** 导入钮操作 */
|
||
handleImport() {
|
||
this.upload.title = "工艺导入";
|
||
this.upload.open = true;
|
||
},
|
||
/** 下载模板操作 */
|
||
importTemplate() {
|
||
this.download('system/route/importTemplate', {}, `route_template_${new Date().getTime()}.xlsx`)
|
||
},
|
||
// 文件上传中处理
|
||
handleFileUploadProgress(event, file, fileList) {
|
||
this.upload.isUploading = true;
|
||
},
|
||
// 文件上传成功处理
|
||
handleFileSuccess(response, file, fileList) {
|
||
this.upload.open = false;
|
||
this.upload.isUploading = false;
|
||
this.$refs.upload.clearFiles();
|
||
this.$alert("<div style='overflow: auto;overflow-x: hidden;max-height: 70vh;padding: 10px 20px 0;'>"
|
||
+ response.msg + "</div>", "导入结果", {dangerouslyUseHTMLString: true});
|
||
this.getList();
|
||
},
|
||
// 提交上传文件
|
||
submitFileForm() {
|
||
this.$refs.upload.submit();
|
||
},
|
||
// 取消按钮
|
||
cancel() {
|
||
this.open = false;
|
||
this.reset();
|
||
},
|
||
/** 搜索按钮操作 */
|
||
handleQuery() {
|
||
this.queryParams.pageNum = 1;
|
||
this.getList();
|
||
},
|
||
handleQuery1(query) {
|
||
if (query === '') {
|
||
this.projectCodes = []; // 如果没有输入任何关键字,清空选项
|
||
return;
|
||
}
|
||
// 开始加载
|
||
this.loading = true;
|
||
// 调用后端接口获取匹配的项目令号
|
||
getDistinctProjectCodes(query).then((response) => {
|
||
// 加载完成
|
||
this.loading = false;
|
||
this.projectCodes = response;
|
||
|
||
}).catch(() => {
|
||
this.loading = false; // 加载失败
|
||
this.projectCodes = []; // 如果请求失败,清空选项
|
||
});
|
||
},
|
||
//获取工序列表
|
||
|
||
|
||
/** 重置按钮操作 */
|
||
resetQuery() {
|
||
this.resetForm("queryForm");
|
||
this.handleQuery();
|
||
},
|
||
// 多选框选中数据
|
||
handleSelectionChange(selection) {
|
||
this.ids = selection.map(item => item.id)
|
||
this.single = selection.length !== 1
|
||
this.multiple = !selection.length
|
||
},
|
||
/** 新增按钮操作 */
|
||
handleAdd() {
|
||
this.reset();
|
||
this.open = true;
|
||
this.title = "添加工艺路线";
|
||
},
|
||
/** 修改按钮操作 */
|
||
handleUpdate(row) {
|
||
|
||
this.loading = true;
|
||
const id = row.id || this.ids;
|
||
getRoute(id).then(response => {
|
||
this.loading = false;
|
||
// 只提取工艺相关字段
|
||
const {workCenter, processName, processDescription, processControl, activityDuration} = response.data;
|
||
this.form = {
|
||
...this.form, // 保留现有数据
|
||
id: id,
|
||
workCenter,
|
||
processName,
|
||
processDescription,
|
||
processControl,
|
||
activityDuration
|
||
};
|
||
this.open = true;
|
||
this.title = "修改工艺信息";
|
||
}).catch(() => {
|
||
this.loading = false;
|
||
});
|
||
},
|
||
|
||
|
||
/**推送工艺 */
|
||
async pushRouteBom() {
|
||
// 获取生产订单号
|
||
const productionOrderNo = this.params.productionOrderNo;
|
||
if (!productionOrderNo) {
|
||
this.$modal.msgError("未获取到生产订单号,请检查!");
|
||
return;
|
||
}
|
||
if (!this.routeGroupName || !this.routeGroupName.trim()) {
|
||
this.$modal.msgError("请填写分组名称!");
|
||
return;
|
||
}
|
||
try {
|
||
// 显示确认对话框
|
||
await this.$confirm(
|
||
'推送工艺可能需要较长时间,请耐心等待。是否继续?',
|
||
'提示',
|
||
{
|
||
confirmButtonText: '确定',
|
||
cancelButtonText: '取消',
|
||
type: 'warning'
|
||
}
|
||
);
|
||
// 显示全屏 loading
|
||
const loading = this.$loading({
|
||
lock: true,
|
||
text: '正在推送工艺,请稍候...',
|
||
spinner: 'el-icon-loading',
|
||
background: 'rgba(0, 0, 0, 0.7)'
|
||
});
|
||
// 重置表单状态
|
||
this.reset();
|
||
// 设置超时检测
|
||
const timeout = 600000; // 10分钟超时
|
||
const timeoutPromise = new Promise((_, reject) => {
|
||
setTimeout(() => {
|
||
reject(new Error('推送操作超时,请检查后台处理状态'));
|
||
}, timeout);
|
||
});
|
||
// 调用推送 API 并设置超时
|
||
const response = await Promise.race([
|
||
pushRouteBom(productionOrderNo, this.routeGroupName.trim()),
|
||
timeoutPromise
|
||
]);
|
||
// 处理后端返回的数据 - 适配新的返回结构 R<ProcessRoutePushResultDTO>
|
||
const {duplicateRoutes, failedRoutes, successfulRoutes} = response.data;
|
||
// 提取物料编码和错误信息
|
||
const duplicateCodes = duplicateRoutes.join(', ');
|
||
const failedInfo = failedRoutes.map(route =>
|
||
`${route.materialCode} (${route.errorMessage || '未知错误'})`
|
||
).join(', ');
|
||
const successfulCodes = successfulRoutes.map(route => route.materialCode).join(', ');
|
||
// 显示成功消息
|
||
this.$alert(`
|
||
<div><strong>成功 (${successfulRoutes.length}):</strong></div>
|
||
<div style="margin-left: 20px;">${successfulCodes || '无'}</div>
|
||
<div><strong>失败 (${failedRoutes.length}):</strong></div>
|
||
<div style="margin-left: 20px;">${failedInfo || '无'}</div>
|
||
<div><strong>重复 (${duplicateRoutes.length}):</strong></div>
|
||
<div style="margin-left: 20px;">${duplicateCodes || '无'}</div>
|
||
`, '推送完成', {
|
||
dangerouslyUseHTMLString: true,
|
||
confirmButtonText: '确定'
|
||
});
|
||
|
||
// 刷新列表
|
||
await this.getList();
|
||
|
||
// 关闭 loading
|
||
loading.close();
|
||
|
||
} catch (error) {
|
||
// 错误处理
|
||
console.error('[推送工艺失败]:', error);
|
||
|
||
// 显示错误通知
|
||
this.$notify({
|
||
title: '推送失败',
|
||
message: error.message || '推送失败,请重试!',
|
||
type: 'error',
|
||
duration: 0,
|
||
showClose: true
|
||
});
|
||
|
||
} finally {
|
||
// 确保 loading 被关闭
|
||
if (this.$loading) {
|
||
this.$loading().close();
|
||
}
|
||
this.loading = false;
|
||
}
|
||
},
|
||
/** 更新计划时间间*/
|
||
updateProcessPlan(row) {
|
||
// 若未勾选任何行,则提示并返回
|
||
if (!this.ids || this.ids.length === 0) {
|
||
this.$modal.msgError("请先勾选至少一条数据再更新计划时间");
|
||
return;
|
||
}
|
||
// 显示加载状态
|
||
this.loading = true;
|
||
// 调用 reset 方法,重置表单或状态
|
||
this.reset();
|
||
// 获取生产订单号
|
||
const rooteProdet = this.params.productionOrderNo;
|
||
//获取物料编码
|
||
const materialCode = this.params.materialCode;
|
||
|
||
console.log(rooteProdet);
|
||
|
||
// 调用封装好的 API 方法(带勾选的 ids)
|
||
updateProcessPlan(rooteProdet, this.ids)
|
||
.then(response => {
|
||
// 假设后端返回的数据可以直接赋值给表单
|
||
this.form = response;
|
||
// 弹出成功消息
|
||
this.$modal.msgSuccess("更新" + rooteProdet + "工序计划时间成功");
|
||
// 调用方法更新列表
|
||
this.getList();
|
||
})
|
||
.catch(error => {
|
||
// 处理错误,弹出错误提示
|
||
this.$modal.msgError("更新,请重试!");
|
||
console.error('更新工序计划失败:', error);
|
||
})
|
||
.finally(() => {
|
||
// 隐藏加载状态
|
||
this.loading = false;
|
||
});
|
||
},
|
||
/** 更新生产订单时间*/
|
||
updateProcesTime(row) {
|
||
// 显示加载状态
|
||
this.loading = true;
|
||
// 调用 reset 方法,重置表单或状态
|
||
this.reset();
|
||
// 获取生产订单号
|
||
const rooteProdet = this.params.productionOrderNo;
|
||
console.log(rooteProdet);
|
||
|
||
// 调用封装好的 API 方法
|
||
updateProcesTime(rooteProdet)
|
||
.then(response => {
|
||
// 假设后端返回的数据可以直接赋值给表单
|
||
this.form = response;
|
||
// 弹出成功消息
|
||
this.$modal.msgSuccess("更新" + rooteProdet + "生产订单成功");
|
||
// 调用方法更新列表
|
||
this.getList();
|
||
})
|
||
.catch(error => {
|
||
// 处理错误,弹出错误提示
|
||
this.$modal.msgError("更新,请重试!");
|
||
console.error('更新生产订单失败:', error);
|
||
})
|
||
.finally(() => {
|
||
// 隐藏加载状态
|
||
this.loading = false;
|
||
});
|
||
},
|
||
generatePDFs1(row) {
|
||
// 显示加载状态
|
||
this.loading = true;
|
||
// 调用 reset 方法,重置表单或状态
|
||
this.reset();
|
||
// 获取生产订单号
|
||
const rooteProdet = this.params.productionOrderNo;
|
||
console.log(rooteProdet);
|
||
|
||
// 调用封装好的 API 方法
|
||
generatePDFs(rooteProdet)
|
||
.then(response => {
|
||
|
||
let blob = new Blob([response], {type: 'application/zip'})
|
||
let url = window.URL.createObjectURL(blob)
|
||
const link = document.createElement('a') // 创建a标签
|
||
link.href = url
|
||
link.download = rooteProdet + '.zip' // 重命名文件
|
||
link.click()
|
||
URL.revokeObjectURL(url) // 释放内存
|
||
// 弹出成功消息
|
||
this.$modal.msgSuccess("生成" + rooteProdet + "的PDF 成功 ");
|
||
// 调用方法更新列表
|
||
this.getList();
|
||
})
|
||
.catch(error => {
|
||
// 处理错误,弹出错误提示
|
||
this.$modal.msgError("生成PDF失败,请重试!");
|
||
console.error('生成PDF失败:', error);
|
||
})
|
||
.finally(() => {
|
||
// 隐藏加载状态
|
||
this.loading = false;
|
||
});
|
||
},
|
||
|
||
|
||
/** 提交按钮 */
|
||
submitForm() {
|
||
this.$refs.form.validate(valid => {
|
||
if (valid) {
|
||
// 提交逻辑
|
||
this.buttonLoading = true;
|
||
if (this.form.id != null) {
|
||
updateRoute(this.form).then(response => {
|
||
this.$modal.msgSuccess("修改成功");
|
||
this.open = false;
|
||
this.getList();
|
||
}).finally(() => {
|
||
this.buttonLoading = false;
|
||
});
|
||
} else {
|
||
addRoute(this.form).then(response => {
|
||
this.$modal.msgSuccess("新增成功");
|
||
this.open = false;
|
||
this.getList();
|
||
}).finally(() => {
|
||
this.buttonLoading = false;
|
||
});
|
||
}
|
||
} else {
|
||
this.$message.error("请填写必填项");
|
||
}
|
||
});
|
||
},
|
||
// 验证所有工序控制
|
||
|
||
/** 删除按钮操作 */
|
||
handleDelete(scope) {
|
||
const ids = [scope.row.id];
|
||
this.$modal.confirm('是否确认删除工艺路线编号为"' + ids + '"的数据项?').then(() => {
|
||
return delRoute(ids);
|
||
}).then(() => {
|
||
this.getList();
|
||
this.$modal.msgSuccess("删除成功");
|
||
}).catch(error => {
|
||
if (error !== 'cancel') {
|
||
console.error('Delete error:', error);
|
||
this.$modal.msgError("删除失败:" + (error.message || "未知错误"));
|
||
}
|
||
});
|
||
},
|
||
/** 导出按钮操作 */
|
||
handleExport() {
|
||
this.download('system/route/export', {
|
||
...this.queryParams
|
||
}, `route_${new Date().getTime()}.xlsx`)
|
||
},
|
||
// BOM选择项改变
|
||
handleBomSelectionChange(selection) {
|
||
this.selectedBomRows = selection;
|
||
},
|
||
|
||
// 新增BOM
|
||
handleBomAdd() {
|
||
this.bomDialogTitle = '新增BOM';
|
||
this.bomForm = {
|
||
id: undefined,
|
||
projectNumber: this.currentMaterial.productionOrderNo, // 使用当<E794A8><E5BD93>的项目令号
|
||
materialCode: '',
|
||
materialName: '',
|
||
materialType: '',
|
||
quantity: 0,
|
||
unit: '',
|
||
stock: 0,
|
||
parentMaterialCode: this.currentMaterial.materialCode, // 使用当前物料作为父级
|
||
parentMaterialName: this.currentMaterial.materialName
|
||
};
|
||
this.bomDialogVisible = true;
|
||
},
|
||
|
||
// 修改BOM
|
||
handleBomEdit(row) {
|
||
this.bomDialogTitle = '修改BOM';
|
||
this.bomForm = JSON.parse(JSON.stringify(row));
|
||
this.bomDialogVisible = true;
|
||
},
|
||
|
||
// 删除BOM
|
||
handleBomDelete(row) {
|
||
this.$confirm('是否确认删除该BOM数据?', '警告', {
|
||
confirmButtonText: '确定',
|
||
cancelButtonText: '取消',
|
||
type: 'warning'
|
||
}).then(() => {
|
||
return deleteBom(row.id);
|
||
}).then(() => {
|
||
this.$message.success('删除成功');
|
||
this.handleBomRefresh();
|
||
}).catch(() => {
|
||
});
|
||
},
|
||
|
||
// 提交BOM表单
|
||
submitBomForm() {
|
||
this.$refs.bomForm.validate((valid) => {
|
||
if (valid) {
|
||
const isUpdate = this.bomForm.id !== undefined;
|
||
const promise = isUpdate ? updateBom(this.bomForm) : addBom(this.bomForm);
|
||
|
||
promise.then(() => {
|
||
this.$message.success(isUpdate ? '修改成功' : '新增成功');
|
||
this.bomDialogVisible = false;
|
||
this.handleBomRefresh();
|
||
}).catch(() => {
|
||
this.$message.error(isUpdate ? '修改失败' : '新增失败');
|
||
});
|
||
}
|
||
});
|
||
},
|
||
fetchBomInfo() {
|
||
return getBomInfo(
|
||
this.currentMaterial.materialCode,
|
||
this.currentMaterial.materialName,
|
||
this.currentMaterial.productionOrderNo
|
||
);
|
||
},
|
||
// 处理物料搜
|
||
handleMaterialSearch(queryString, callback) {
|
||
if (queryString.length === 0) {
|
||
callback([]);
|
||
return;
|
||
}
|
||
|
||
this.materialSearchLoading = true;
|
||
listMaterial({
|
||
pageNum: 1,
|
||
pageSize: 10,
|
||
materialName: queryString
|
||
}).then(response => {
|
||
const suggestions = response.rows.map(item => ({
|
||
materialName: item.materialName,
|
||
materialCode: item.materialCode,
|
||
materialType: item.materialQuality,
|
||
classificationName: item.classificationName,
|
||
singleWeight: item.singleWeight || 0
|
||
}));
|
||
callback(suggestions);
|
||
}).catch(() => {
|
||
callback([]);
|
||
}).finally(() => {
|
||
this.materialSearchLoading = false;
|
||
});
|
||
},
|
||
// 处理物料选择
|
||
handleMaterialSelect(item) {
|
||
if (item) {
|
||
// 如果是从建议中选择
|
||
this.bomForm.materialName = item.materialName;
|
||
this.bomForm.materialCode = item.materialCode;
|
||
this.bomForm.materialType = item.materialType;
|
||
this.bomForm.stock = item.singleWeight;
|
||
this.bomForm.unit = item.classificationName;
|
||
}
|
||
},
|
||
// 取消编辑
|
||
cancelEdit(scope) {
|
||
// 恢复原始数据
|
||
Object.assign(scope.row, scope.row.originalData);
|
||
// 退出编辑状态
|
||
this.$set(scope.row, 'isEdit', false);
|
||
},
|
||
// 保存单行数据
|
||
onSaveRow(scope) {
|
||
// 显示加载状态
|
||
this.loading = true;
|
||
// 获取行数据并创建副本
|
||
const row = scope.row;
|
||
// 验证委外中心的工序控制
|
||
|
||
const saveData = {
|
||
id: row.id,
|
||
parentId: row.parentId,
|
||
routeDescription: row.routeDescription,
|
||
materialCode: row.materialCode,
|
||
materialName: row.materialName,
|
||
unit: row.unit,
|
||
processNo: row.processNo,
|
||
bomMaterial: row.bomMaterial,
|
||
workCenter: row.workCenter,
|
||
processName: row.processName,
|
||
rawMaterialCode: row.rawMaterialCode,
|
||
rawMaterialName: row.rawMaterialName,
|
||
discWeight: row.discWeight,
|
||
discUsage: row.discUsage,
|
||
processDescription: row.processDescription,
|
||
processControl: row.processControl,
|
||
activityDuration: row.activityDuration,
|
||
activityUnit: row.activityUnit,
|
||
material: row.material,
|
||
bomUnit: row.bomUnit,
|
||
unitQuantity: row.unitQuantity,
|
||
batchQuantity: row.batchQuantity,
|
||
firstBatchQuantity: row.firstBatchQuantity,
|
||
planStartTime: row.planStartTime,
|
||
planEndTime: row.planEndTime,
|
||
xuStartTime: row.xuStartTime,
|
||
xuEndTime: row.xuEndTime
|
||
};
|
||
|
||
// 显示加载状态
|
||
this.loading = true;
|
||
|
||
// 调用更新接口
|
||
updateRoute(saveData)
|
||
.then(response => {
|
||
this.$modal.msgSuccess("修改成功");
|
||
// 退出编辑状态
|
||
this.$set(row, 'isEdit', false);
|
||
// 刷新列表
|
||
this.getList();
|
||
})
|
||
.catch(error => {
|
||
this.$modal.msgError("修改失败:" + (error.message || "未知错误"));
|
||
})
|
||
.finally(() => {
|
||
this.loading = false;
|
||
});
|
||
},
|
||
|
||
// 同样修改整体保存方法
|
||
onSave(props) {
|
||
this.$confirm('确认保存工艺路线数据?', '提示', {
|
||
confirmButtonText: '确定',
|
||
cancelButtonText: '取消',
|
||
type: 'warning'
|
||
}).then(() => {
|
||
this.loading = true;
|
||
|
||
var list = this.form.routeList.find(item => item.id === props.row.id);
|
||
var newChildrenList = list.children.filter(item => item.id < 0).map(v => ({
|
||
id: v.parentId,
|
||
routeDescription: list.routeDescription,
|
||
materialCode: list.materialCode,
|
||
materialName: list.materialName,
|
||
unit: list.unit,
|
||
processNo: v.processNo,
|
||
bomMaterial: list.bomMaterial,
|
||
workCenter: v.workCenter,
|
||
processName: v.processName,
|
||
rawMaterialCode: list.rawMaterialCode,
|
||
rawMaterialName: list.rawMaterialName,
|
||
discWeight: list.discWeight,
|
||
discUsage: list.discUsage,
|
||
processDescription: v.processDescription,
|
||
processControl: v.processControl,
|
||
activityDuration: v.activityDuration,
|
||
activityUnit: v.activityUnit,
|
||
material: list.material,
|
||
bomUnit: list.bomUnit,
|
||
unitQuantity: list.unitQuantity,
|
||
batchQuantity: list.batchQuantity,
|
||
firstBatchQuantity: list.firstBatchQuantity,
|
||
planStartTime: v.planStartTime,
|
||
planEndTime: v.planEndTime,
|
||
xuStartTime: v.xuStartTime || null,
|
||
xuEndTime: v.xuEndTime || null
|
||
}));
|
||
|
||
return onSave(newChildrenList);
|
||
}).then((response) => {
|
||
this.$modal.msgSuccess("工艺路线保存成功");
|
||
this.showParentSaveBtn = null;
|
||
this.getList();
|
||
}).catch((error) => {
|
||
if (error !== 'cancel') {
|
||
this.$modal.msgError(error.message || "工艺路线保存失败");
|
||
}
|
||
}).finally(() => {
|
||
this.loading = false;
|
||
});
|
||
},
|
||
// 删除未保存的工艺
|
||
onDeleteUnsaved(scope) {
|
||
const parentRow = this.form.routeList.find(item => item.id === scope.row.parentId);
|
||
if (parentRow && parentRow.children) {
|
||
const index = parentRow.children.findIndex(item => item === scope.row);
|
||
if (index > -1) {
|
||
// 删除当前行
|
||
parentRow.children.splice(index, 1);
|
||
|
||
// 重新排序剩余的工序号
|
||
parentRow.children.forEach((child, idx) => {
|
||
child.processNo = (idx + 1) * 10; // 按10、20、30...重新排序
|
||
});
|
||
}
|
||
}
|
||
},
|
||
|
||
// 获取工艺信息列表
|
||
getProcessRouteList() {
|
||
this.processLoading = true;
|
||
getProcessRouteList(
|
||
this.currentMaterial.materialCode,
|
||
this.currentMaterial.materialName,
|
||
this.currentMaterial.productionOrderNo
|
||
)
|
||
.then(response => {
|
||
this.processRoutes = response || [];
|
||
// 默认选中第一条工艺路线
|
||
if (this.processRoutes.length > 0) {
|
||
this.handleViewRoute(this.processRoutes[0]);
|
||
}
|
||
})
|
||
.catch(error => {
|
||
console.error('获取工艺路线数据失败:', error);
|
||
this.$message.error('获取工艺路线数据失败');
|
||
this.processRoutes = [];
|
||
this.resetRouteSelection();
|
||
})
|
||
.finally(() => {
|
||
this.processLoading = false;
|
||
});
|
||
},
|
||
|
||
// 查看工艺路线
|
||
handleViewRoute(route) {
|
||
this.selectedRouteId = route.id;
|
||
this.selectedRoute = route;
|
||
this.currentProcessList = route.processRouteDT || [];
|
||
},
|
||
|
||
// 重置工艺路线选择
|
||
resetRouteSelection() {
|
||
this.selectedRouteId = null;
|
||
this.selectedRoute = null;
|
||
this.currentProcessList = [];
|
||
}
|
||
|
||
},
|
||
|
||
// 处理工艺路线选择变化
|
||
handleRouteChange(routeId) {
|
||
const route = this.processRoutes.find(r => r.id === routeId);
|
||
if (route) {
|
||
this.selectedRoute = route;
|
||
this.currentProcessList = route.processRouteDT || [];
|
||
} else {
|
||
this.selectedRoute = null;
|
||
this.currentProcessList = [];
|
||
}
|
||
},
|
||
|
||
};
|
||
</script>
|
||
<style>
|
||
.btn {
|
||
font-size: 12px;
|
||
padding: 7px 10px !important;
|
||
border-radius: 0;
|
||
}
|
||
|
||
.handle {
|
||
position: absolute;
|
||
left: 50%;
|
||
top: 50%;
|
||
transform: translate(-50%, -50%);
|
||
font-size: 20px;
|
||
border: none;
|
||
background-color: #FAFAFA;
|
||
}
|
||
|
||
.bom-header {
|
||
margin-bottom: 15px;
|
||
}
|
||
|
||
.table-operations {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
}
|
||
|
||
.pagination-container {
|
||
display: flex;
|
||
justify-content: flex-end;
|
||
}
|
||
|
||
.table-operations {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
margin-bottom: 15px;
|
||
}
|
||
|
||
.left-operations,
|
||
.right-operations {
|
||
display: flex;
|
||
align-items: center;
|
||
}
|
||
|
||
.right-operations .el-button {
|
||
margin-left: 8px;
|
||
}
|
||
|
||
.material-select-dropdown {
|
||
max-height: 300px !important;
|
||
}
|
||
|
||
.material-select-dropdown .el-select-dropdown__wrap {
|
||
max-height: 300px !important;
|
||
}
|
||
|
||
|
||
.material-autocomplete-dropdown {
|
||
min-width: 500px !important;
|
||
/* 设置下拉框最小宽度 */
|
||
}
|
||
|
||
.material-suggestion-item {
|
||
padding: 8px 10px;
|
||
border-bottom: 1px solid #eee;
|
||
}
|
||
|
||
.material-suggestion-item:last-child {
|
||
border-bottom: none;
|
||
}
|
||
|
||
.material-name {
|
||
font-size: 14px;
|
||
color: #303133;
|
||
margin-bottom: 4px;
|
||
}
|
||
|
||
.material-info {
|
||
font-size: 12px;
|
||
color: #909399;
|
||
}
|
||
|
||
.material-info span {
|
||
margin-right: 15px;
|
||
}
|
||
|
||
.material-info span:last-child {
|
||
margin-right: 0;
|
||
}
|
||
|
||
/* 调整输入框宽度 */
|
||
.el-form-item[label="物料名称"] .el-autocomplete {
|
||
width: 100%;
|
||
}
|
||
|
||
/* 可以添加一些提示样式 */
|
||
.el-select.is-disabled .el-input__inner {
|
||
background-color: #f5f7fa;
|
||
border-color: #e4e7ed;
|
||
color: #909399;
|
||
cursor: not-allowed;
|
||
}
|
||
</style>
|