1. 修改钢卷追踪页面标题,调整crm钢卷表格列宽与按钮文本 2. 优化采购审核、到货、计划页面表格列配置,添加材质列 3. 为多个页面添加详情加载状态,统一按钮间距样式 4. 新增采购到货页面模板下载功能,修复产品内容组件单元格内边距
1773 lines
59 KiB
Vue
1773 lines
59 KiB
Vue
<template>
|
||
<div class="app-container acid-do-container">
|
||
<div class="search-section">
|
||
<h3 class="page-title">钢卷追踪</h3>
|
||
<el-form :model="materialQueryParams" ref="materialQueryForm" size="small" :inline="true" class="search-form">
|
||
<el-form-item label="入场钢卷号" prop="enterCoilNo">
|
||
<el-input v-model="materialQueryParams.enterCoilNo" placeholder="请输入入场钢卷号" clearable
|
||
@keyup.enter.native="handleMaterialQuery" style="width: 200px;" />
|
||
</el-form-item>
|
||
<el-form-item label="当前钢卷号" prop="currentCoilNo">
|
||
<el-input v-model="materialQueryParams.currentCoilNo" placeholder="请输入当前钢卷号" clearable
|
||
@keyup.enter.native="handleMaterialQuery" style="width: 200px;" />
|
||
</el-form-item>
|
||
<el-form-item>
|
||
<el-button type="primary" icon="el-icon-search" @click="handleMaterialQuery">搜索</el-button>
|
||
<el-button icon="el-icon-refresh" @click="resetMaterialQuery">重置</el-button>
|
||
</el-form-item>
|
||
<el-form-item>
|
||
<span class="search-tip">提示:请至少填写其中一个钢卷号进行搜索</span>
|
||
</el-form-item>
|
||
</el-form>
|
||
</div>
|
||
|
||
<!-- 未搜索状态 -->
|
||
<div v-if="!searched" class="empty-search-state">
|
||
<i class="el-icon-search"></i>
|
||
<p>请先输入钢卷号进行搜索</p>
|
||
</div>
|
||
|
||
<!-- 搜索结果区域 -->
|
||
<div v-else>
|
||
<!-- 2×2 钢卷信息 -->
|
||
<div class="two-by-two-layout mb20">
|
||
<!-- 当前钢卷 -->
|
||
<div class="coil-column">
|
||
<div class="column-header column-header--now">
|
||
<h4 class="column-title">当前钢卷</h4>
|
||
<span class="column-count">{{ nowCoilList.length }}</span>
|
||
</div>
|
||
<div v-loading="nowLoading" class="column-body">
|
||
<template v-if="nowCoilList.length > 0">
|
||
<KLPTable :data="nowCoilList" :max-height="280" :float-layer="true"
|
||
:float-layer-config="floatLayerConfig" :row-style="getRowStyle" size="mini">
|
||
<el-table-column prop="currentCoilNo" label="当前钢卷号" show-overflow-tooltip>
|
||
<template slot-scope="scope">
|
||
<current-coil-no :current-coil-no="scope.row.currentCoilNo" />
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column prop="enterCoilNo" label="入场钢卷号" width="140" show-overflow-tooltip />
|
||
<el-table-column prop="supplierCoilNo" label="厂家卷号" width="120" show-overflow-tooltip />
|
||
<el-table-column prop="specification" label="规格" width="90" show-overflow-tooltip />
|
||
<el-table-column prop="netWeight" label="净重" width="80" show-overflow-tooltip />
|
||
<el-table-column label="操作" width="80">
|
||
<template slot-scope="scope">
|
||
<el-button type="text" icon="el-icon-view" size="mini" @click="handlePreviewLabel(scope.row)" title="预览标签" />
|
||
<el-button type="text" icon="el-icon-printer" size="mini" @click="handlePrintLabel(scope.row)" title="打印标签" />
|
||
<el-button type="text" icon="el-icon-printer" size="mini" @click="handleNumberCoilClick(scope.row)" title="数字钢卷" />
|
||
<el-button type="text" icon="el-icon-time" size="mini" @click="handleTrace(scope.row)" title="追溯" :loading="scope.row.picking" />
|
||
</template>
|
||
</el-table-column>
|
||
</KLPTable>
|
||
</template>
|
||
<div v-else class="column-empty">暂无数据</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 已发货钢卷 -->
|
||
<div class="coil-column">
|
||
<div class="column-header column-header--trans">
|
||
<h4 class="column-title">已发货钢卷</h4>
|
||
<span class="column-count">{{ transCoilList.length }}</span>
|
||
</div>
|
||
<div v-loading="transLoading" class="column-body">
|
||
<template v-if="transCoilList.length > 0">
|
||
<KLPTable :data="transCoilList" :max-height="280" :float-layer="true"
|
||
:float-layer-config="floatLayerConfig" :row-style="getRowStyle" size="mini">
|
||
<el-table-column prop="currentCoilNo" label="当前钢卷号" show-overflow-tooltip>
|
||
<template slot-scope="scope">
|
||
<current-coil-no :current-coil-no="scope.row.currentCoilNo" />
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column prop="enterCoilNo" label="入场钢卷号" width="140" show-overflow-tooltip />
|
||
<el-table-column prop="supplierCoilNo" label="厂家卷号" width="120" show-overflow-tooltip />
|
||
<el-table-column prop="specification" label="规格" width="90" show-overflow-tooltip />
|
||
<el-table-column prop="netWeight" label="净重" width="80" show-overflow-tooltip />
|
||
<el-table-column label="操作" width="80">
|
||
<template slot-scope="scope">
|
||
<el-button type="text" icon="el-icon-view" size="mini" @click="handlePreviewLabel(scope.row)" title="预览标签" />
|
||
<el-button type="text" icon="el-icon-printer" size="mini" @click="handlePrintLabel(scope.row)" title="打印标签" />
|
||
<el-button type="text" icon="el-icon-printer" size="mini" @click="handleNumberCoilClick(scope.row)" title="数字钢卷" />
|
||
<el-button type="text" icon="el-icon-time" size="mini" @click="handleTrace(scope.row)" title="追溯" :loading="scope.row.picking" />
|
||
</template>
|
||
</el-table-column>
|
||
</KLPTable>
|
||
</template>
|
||
<div v-else class="column-empty">暂无数据</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 历史钢卷 -->
|
||
<div class="coil-column">
|
||
<div class="column-header column-header--history">
|
||
<h4 class="column-title">历史钢卷</h4>
|
||
<span class="column-count">{{ historyCoilList.length }}</span>
|
||
</div>
|
||
<div v-loading="historyLoading" class="column-body">
|
||
<template v-if="historyCoilList.length > 0">
|
||
<KLPTable :data="historyCoilList" :max-height="280" :float-layer="true"
|
||
:float-layer-config="floatLayerConfig" :row-style="getRowStyle" size="mini">
|
||
<el-table-column prop="currentCoilNo" label="当前钢卷号" show-overflow-tooltip>
|
||
<template slot-scope="scope">
|
||
<current-coil-no :current-coil-no="scope.row.currentCoilNo" />
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column prop="enterCoilNo" label="入场钢卷号" width="140" show-overflow-tooltip />
|
||
<el-table-column prop="supplierCoilNo" label="厂家卷号" width="120" show-overflow-tooltip />
|
||
<el-table-column prop="specification" label="规格" width="90" show-overflow-tooltip />
|
||
<el-table-column prop="netWeight" label="净重" width="80" show-overflow-tooltip />
|
||
<el-table-column label="操作" width="80">
|
||
<template slot-scope="scope">
|
||
<el-button type="text" icon="el-icon-view" size="mini" @click="handlePreviewLabel(scope.row)" title="预览标签" />
|
||
<el-button type="text" icon="el-icon-printer" size="mini" @click="handlePrintLabel(scope.row)" title="打印标签" />
|
||
<el-button type="text" icon="el-icon-printer" size="mini" @click="handleNumberCoilClick(scope.row)" title="数字钢卷" />
|
||
<el-button type="text" icon="el-icon-time" size="mini" @click="handleTrace(scope.row)" title="追溯" :loading="scope.row.picking" />
|
||
</template>
|
||
</el-table-column>
|
||
</KLPTable>
|
||
</template>
|
||
<div v-else class="column-empty">暂无数据</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 未入库钢卷 -->
|
||
<div class="coil-column">
|
||
<div class="column-header column-header--unIn">
|
||
<h4 class="column-title">未入库钢卷</h4>
|
||
<span class="column-count">{{ unInCoilList.length }}</span>
|
||
</div>
|
||
<div v-loading="unInLoading" class="column-body">
|
||
<template v-if="unInCoilList.length > 0">
|
||
<KLPTable :data="unInCoilList" max-height="280" :float-layer="true"
|
||
:float-layer-config="floatLayerConfig" :row-style="getRowStyle" size="mini">
|
||
<el-table-column prop="currentCoilNo" label="当前钢卷号" show-overflow-tooltip>
|
||
<template slot-scope="scope">
|
||
<current-coil-no :current-coil-no="scope.row.currentCoilNo" />
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column prop="enterCoilNo" label="入场钢卷号" width="140" show-overflow-tooltip />
|
||
<el-table-column prop="supplierCoilNo" label="厂家卷号" width="120" show-overflow-tooltip />
|
||
<el-table-column prop="specification" label="规格" width="90" show-overflow-tooltip />
|
||
<el-table-column prop="netWeight" label="净重" width="80" show-overflow-tooltip />
|
||
<el-table-column label="操作" width="80">
|
||
<template slot-scope="scope">
|
||
<el-button type="text" icon="el-icon-view" size="mini" @click="handlePreviewLabel(scope.row)" title="预览标签" />
|
||
<el-button type="text" icon="el-icon-printer" size="mini" @click="handlePrintLabel(scope.row)" title="打印标签" />
|
||
<el-button type="text" icon="el-icon-printer" size="mini" @click="handleNumberCoilClick(scope.row)" title="数字钢卷" />
|
||
<el-button type="text" icon="el-icon-time" size="mini" @click="handleTrace(scope.row)" title="追溯" :loading="scope.row.picking" />
|
||
</template>
|
||
</el-table-column>
|
||
</KLPTable>
|
||
</template>
|
||
<div v-else class="column-empty">暂无数据</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 下部:操作记录 -->
|
||
<div class="section-card action-section">
|
||
<div class="section-header">
|
||
<h3 class="section-title">操作记录</h3>
|
||
<div class="section-actions">
|
||
<el-button type="danger" plain icon="el-icon-delete" size="mini" :disabled="multiple"
|
||
@click="handleDeleteAction">删除</el-button>
|
||
<el-button type="warning" plain icon="el-icon-refresh" size="mini" @click="handleRefreshAction"
|
||
:disabled="buttonLoading" v-loading="buttonLoading">刷新</el-button>
|
||
<el-checkbox style="margin-left: 10px;" v-model="rubbish" label="1"
|
||
@change="getActionList">查看被删除操作</el-checkbox>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 操作记录搜索 -->
|
||
<el-form :model="actionQueryParams" ref="actionQueryForm" size="small" :inline="true" class="query-form mb10">
|
||
<el-form-item label="操作类型" prop="actionType">
|
||
<el-select v-model="actionQueryParams.actionType" placeholder="请选择操作类型" clearable filterable>
|
||
<el-option v-for="item in dict.type.action_type" :key="item.value" :label="item.label"
|
||
:value="item.value" />
|
||
</el-select>
|
||
</el-form-item>
|
||
<el-form-item label="操作状态" prop="actionStatus">
|
||
<el-select v-model="actionQueryParams.actionStatus" placeholder="请选择操作状态" clearable>
|
||
<el-option label="待处理" :value="0" />
|
||
<el-option label="处理中" :value="1" />
|
||
<el-option label="已完成" :value="2" />
|
||
<el-option label="已取消" :value="3" />
|
||
</el-select>
|
||
</el-form-item>
|
||
<el-form-item>
|
||
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleActionQuery">搜索</el-button>
|
||
<el-button icon="el-icon-refresh" size="mini" @click="resetActionQuery">重置</el-button>
|
||
</el-form-item>
|
||
</el-form>
|
||
|
||
<!-- 操作记录表格 -->
|
||
<div v-loading="actionLoading" class="action-list-container">
|
||
<el-table :data="actionList" style="width: 100%" @selection-change="handleSelectionChange">
|
||
<el-table-column type="selection" width="55" align="center" />
|
||
<el-table-column label="操作类型" align="center" prop="actionType" width="160">
|
||
<template slot-scope="scope">
|
||
<el-select @change="handleStatusChange(scope.row)" v-model="scope.row.actionType" placeholder="请选择操作类型"
|
||
clearable filterable>
|
||
<el-option label="入库/收货操作" :value="401" />
|
||
<el-option label="发货操作" :value="402" />
|
||
<el-option label="移库操作" :value="403" />
|
||
<el-option label="通过库区编辑钢卷" :value="404" />
|
||
<el-option label="钢卷打包" :value="405" />
|
||
<el-option v-for="item in dict.type.action_type" :key="item.value" :label="item.label"
|
||
:value="parseInt(item.value)" />
|
||
</el-select>
|
||
</template>
|
||
</el-table-column>
|
||
|
||
<el-table-column label="操作状态" align="center" prop="actionStatus" width="120">
|
||
<template slot-scope="scope">
|
||
<el-tag v-if="scope.row.actionStatus === 0" type="info" size="mini">待处理</el-tag>
|
||
<el-tag v-else-if="scope.row.actionStatus === 1" type="warning" size="mini">处理中</el-tag>
|
||
<el-tag v-else-if="scope.row.actionStatus === 2" type="success" size="mini">已完成</el-tag>
|
||
<el-tag v-else-if="scope.row.actionStatus === 3" type="danger" size="mini">已取消</el-tag>
|
||
</template>
|
||
</el-table-column>
|
||
|
||
<el-table-column label="优先级" align="center" prop="priority" width="90">
|
||
<template slot-scope="scope">
|
||
<el-tag v-if="scope.row.priority === 0" type="info" size="mini">普通</el-tag>
|
||
<el-tag v-else-if="scope.row.priority === 1" type="warning" size="mini">重要</el-tag>
|
||
<el-tag v-else-if="scope.row.priority === 2" type="danger" size="mini">紧急</el-tag>
|
||
</template>
|
||
</el-table-column>
|
||
|
||
<el-table-column label="来源" align="center" prop="sourceType" width="80">
|
||
<template slot-scope="scope">
|
||
<el-tag v-if="scope.row.sourceType === 'scan'" type="success" size="mini">
|
||
<i class="el-icon-mobile"></i> 扫码
|
||
</el-tag>
|
||
<el-tag v-else type="info" size="mini">
|
||
<i class="el-icon-edit-outline"></i> 手动
|
||
</el-tag>
|
||
</template>
|
||
</el-table-column>
|
||
|
||
<el-table-column label="新增时间" align="center" prop="createTime" width="155" :show-overflow-tooltip="true">
|
||
<template slot-scope="scope">
|
||
<span>{{ parseTime(scope.row.createTime, '{y}-{m}-{d} {h}:{i}') }}</span>
|
||
</template>
|
||
</el-table-column>
|
||
|
||
<el-table-column label="操作人" align="center" prop="updateBy" width="100" />
|
||
<el-table-column label="创建人" align="center" prop="createByName" width="140">
|
||
<template slot-scope="scope">
|
||
<el-select @change="handleProcessTimeChange(scope.row)" v-model="scope.row.createBy"
|
||
placeholder="请选择创建人" filterable>
|
||
<el-option v-for="item in userList" :key="item.userId" :label="item.nickName"
|
||
:value="item.userName" />
|
||
</el-select>
|
||
</template>
|
||
</el-table-column>
|
||
|
||
<el-table-column label="完成时间" align="center" prop="completeTime" width="220" :show-overflow-tooltip="true">
|
||
<template slot-scope="scope">
|
||
<el-date-picker @change="handleProcessTimeChange(scope.row)" value-format="yyyy-MM-dd HH:mm:ss"
|
||
style="width: 200px" v-model="scope.row.completeTime" type="datetime" placeholder="选择完成时间" />
|
||
</template>
|
||
</el-table-column>
|
||
|
||
<el-table-column label="备注" align="center" prop="remark" :show-overflow-tooltip="true" />
|
||
</el-table>
|
||
|
||
<!-- 分页 -->
|
||
<pagination v-show="actionTotal > 0" :total="actionTotal" :page.sync="actionQueryParams.pageNum"
|
||
:limit.sync="actionQueryParams.pageSize" @pagination="getActionList" />
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 标签预览弹窗 -->
|
||
<el-dialog title="标签预览" :visible.sync="labelRender.visible" append-to-body>
|
||
<label-render :content="labelRender.data" :labelType="labelRender.type" />
|
||
</el-dialog>
|
||
|
||
<label-render ref="labelRender" v-show="false" :content="labelRender.data" :labelType="labelRender.type" />
|
||
|
||
<!-- 钢卷修正对话框 -->
|
||
<el-dialog :title="title" :visible.sync="correctVisible" width="1200px">
|
||
<el-form ref="form" :model="form" :rules="rules" label-width="100px">
|
||
<el-row :gutter="20">
|
||
<el-col :span="12">
|
||
<el-form-item label="入场钢卷号" prop="enterCoilNo">
|
||
<el-input v-model="form.enterCoilNo" placeholder="请输入入场钢卷号" :disabled="!!form.coilId" />
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="12">
|
||
<el-form-item label="当前钢卷号" prop="currentCoilNo">
|
||
<el-input v-model.trim="form.currentCoilNo" placeholder="请输入当前钢卷号" />
|
||
</el-form-item>
|
||
</el-col>
|
||
</el-row>
|
||
<el-row :gutter="20">
|
||
<el-col :span="12">
|
||
<el-form-item label="厂家原料卷号" prop="supplierCoilNo">
|
||
<el-input v-model.trim="form.supplierCoilNo" placeholder="请输入厂家原料卷号" />
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="12">
|
||
<el-form-item label="所在库位" prop="warehouseId">
|
||
<warehouse-select v-model="form.warehouseId" placeholder="请选择仓库/库区/库位" style="width: 100%;" clearable />
|
||
</el-form-item>
|
||
</el-col>
|
||
</el-row>
|
||
<el-row :gutter="20">
|
||
<el-col :span="12">
|
||
<el-form-item label="实际库区" prop="actualWarehouseId">
|
||
<actual-warehouse-select v-model="form.actualWarehouseId" placeholder="请选择实际库区" style="width: 100%;"
|
||
clearable />
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="12">
|
||
<el-form-item label="班组" prop="team">
|
||
<el-select v-model="form.team" placeholder="请选择班组" style="width: 100%">
|
||
<el-option key="甲" label="甲" value="甲" />
|
||
<el-option key="乙" label="乙" value="乙" />
|
||
</el-select>
|
||
</el-form-item>
|
||
</el-col>
|
||
</el-row>
|
||
<el-row :gutter="20">
|
||
<el-col :span="12">
|
||
<el-form-item label="材料类型" prop="materialType">
|
||
<el-select v-model="form.materialType" placeholder="请选择材料类型" @change="handleMaterialTypeChange">
|
||
<el-option label="成品" value="成品" />
|
||
<el-option label="原料" value="原料" />
|
||
</el-select>
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="12">
|
||
<el-form-item :label="getItemLabel" prop="itemId">
|
||
<product-select v-if="form.itemType == 'product'" v-model="form.itemId" placeholder="请选择成品"
|
||
style="width: 100%;" clearable />
|
||
<raw-material-select v-else-if="form.itemType == 'raw_material'" v-model="form.itemId" placeholder="请选择原料"
|
||
style="width: 100%;" clearable />
|
||
<div v-else>请先选择材料类型</div>
|
||
</el-form-item>
|
||
</el-col>
|
||
</el-row>
|
||
<el-row :gutter="20">
|
||
<el-col :span="12">
|
||
<el-form-item label="质量状态" prop="qualityStatus">
|
||
<el-select v-model="form.qualityStatus" placeholder="请选择质量状态" style="width: 100%">
|
||
<el-option v-for="item in dict.type.coil_quality_status" :key="item.value" :label="item.label"
|
||
:value="item.value" />
|
||
</el-select>
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="12">
|
||
<el-form-item label="切边要求" prop="trimmingRequirement">
|
||
<el-select v-model="form.trimmingRequirement" placeholder="请选择切边要求" style="width: 100%">
|
||
<el-option label="净边料" value="净边料" />
|
||
<el-option label="毛边料" value="毛边料" />
|
||
</el-select>
|
||
</el-form-item>
|
||
</el-col>
|
||
</el-row>
|
||
<el-row :gutter="20">
|
||
<el-col :span="12">
|
||
<el-form-item label="原料材质" prop="packingStatus">
|
||
<el-input v-model="form.packingStatus" placeholder="请输入原料材质" />
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="12">
|
||
<el-form-item label="包装要求" prop="packagingRequirement">
|
||
<el-select v-model="form.packagingRequirement" placeholder="请选择包装要求" style="width: 100%">
|
||
<el-option label="裸包" value="裸包" />
|
||
<el-option label="普包" value="普包" />
|
||
<el-option label="简包" value="简包" />
|
||
<el-option label="精包" value="精包" />
|
||
</el-select>
|
||
</el-form-item>
|
||
</el-col>
|
||
</el-row>
|
||
<el-row :gutter="20">
|
||
<el-col :span="12">
|
||
<el-form-item label="毛重" prop="grossWeight">
|
||
<el-input v-model="form.grossWeight" placeholder="请输入毛重" />
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="12">
|
||
<el-form-item label="净重" prop="netWeight">
|
||
<el-input v-model="form.netWeight" placeholder="请输入净重" />
|
||
</el-form-item>
|
||
</el-col>
|
||
</el-row>
|
||
<el-row :gutter="20">
|
||
<el-col :span="12">
|
||
<el-form-item label="实测长度(m)" prop="actualLength">
|
||
<el-input-number :controls="false" v-model="form.actualLength" placeholder="请输入实测长度" type="number"
|
||
:step="0.01" />
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="12">
|
||
<el-form-item label="实测宽度(mm)" prop="actualWidth">
|
||
<el-input-number :controls="false" v-model="form.actualWidth" placeholder="请输入实测宽度" type="number"
|
||
:step="0.01" />
|
||
</el-form-item>
|
||
</el-col>
|
||
</el-row>
|
||
<el-row :gutter="20">
|
||
<el-col :span="12">
|
||
<el-form-item label="实测厚度(mm)" prop="actualThickness">
|
||
<el-input-number :controls="false" v-model="form.actualThickness" placeholder="请输入实测厚度" type="number"
|
||
:step="0.01" />
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="12">
|
||
<el-form-item label="业务目的" prop="businessPurpose">
|
||
<el-select v-model="form.businessPurpose" placeholder="业务目的" filterable>
|
||
<el-option v-for="item in dict.type.coil_business_purpose" :key="item.value" :value="item.value"
|
||
:label="item.label" />
|
||
</el-select>
|
||
</el-form-item>
|
||
</el-col>
|
||
</el-row>
|
||
<el-row :gutter="20">
|
||
<el-col :span="12">
|
||
<el-form-item label="调制度" prop="temperGrade">
|
||
<el-input v-model="form.temperGrade" placeholder="请输入调制度" />
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="12">
|
||
<el-form-item label="镀层种类" prop="coatingType">
|
||
<MemoInput storageKey="coatingType" v-model="form.coatingType" placeholder="请输入镀层种类" />
|
||
</el-form-item>
|
||
</el-col>
|
||
</el-row>
|
||
<el-row :gutter="20">
|
||
<el-col :span="12">
|
||
<el-form-item label="钢卷表面处理" prop="coilSurfaceTreatment">
|
||
<MemoInput storageKey="surfaceTreatmentDesc" v-model="form.coilSurfaceTreatment" placeholder="请输入钢卷表面处理" />
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="12">
|
||
<el-form-item label="排产厚度(mm)" prop="scheduleThickness">
|
||
<el-input-number :controls="false" v-model="form.scheduleThickness" placeholder="请输入排产厚度" type="number"
|
||
:step="0.001" style="width: 100%;" />
|
||
</el-form-item>
|
||
</el-col>
|
||
</el-row>
|
||
<el-row :gutter="20">
|
||
<el-col :span="12">
|
||
<el-form-item label="生产开始时间" prop="productionStartTime">
|
||
<TimeInput v-model="form.productionStartTime" @input="calculateProductionDuration" />
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="12">
|
||
<el-form-item label="生产结束时间" prop="productionEndTime">
|
||
<TimeInput v-model="form.productionEndTime" @input="calculateProductionDuration" :show-now-button="true" />
|
||
</el-form-item>
|
||
</el-col>
|
||
</el-row>
|
||
<el-row :gutter="20">
|
||
<el-col :span="12">
|
||
<el-form-item label="生产耗时" prop="productionDuration">
|
||
<el-input v-model="form.formattedDuration" placeholder="自动计算" disabled />
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="12">
|
||
<el-form-item label="备注" prop="remark">
|
||
<el-input v-model="form.remark" placeholder="请输入备注" />
|
||
</el-form-item>
|
||
</el-col>
|
||
</el-row>
|
||
<el-row :gutter="20" v-if="form.coilId">
|
||
<el-col :span="12">
|
||
<el-form-item label="创建时间" prop="createTime">
|
||
<el-date-picker v-model="form.createTime" type="datetime" value-format="yyyy-MM-dd HH:mm:ss"
|
||
placeholder="请选择创建时间" style="width: 100%;" />
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="12">
|
||
<el-form-item label="创建人" prop="createBy">
|
||
<el-select v-model="form.createBy" placeholder="请选择创建人" style="width: 100%;" clearable filterable>
|
||
<el-option v-for="item in userList" :key="item.userName" :label="item.nickName" :value="item.userName" />
|
||
</el-select>
|
||
</el-form-item>
|
||
</el-col>
|
||
</el-row>
|
||
<el-row :gutter="20" v-if="form.coilId">
|
||
<el-col :span="24">
|
||
<el-form-item label="绑定合同" prop="contractId">
|
||
<div style="display: flex; gap: 10px; width: 100%;">
|
||
<contract-select v-model="form.contractId" placeholder="请选择合同" style="flex: 1;" clearable mode="all" />
|
||
<el-button type="success" :loading="contractLoading" @click="saveContractRel">保存合同</el-button>
|
||
</div>
|
||
</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="钢卷追溯" :visible.sync="traceOpen" width="90%" append-to-body>
|
||
<coil-trace-result v-loading="traceLoading" :trace-result="traceResult"></coil-trace-result>
|
||
</el-dialog>
|
||
</div>
|
||
</template>
|
||
|
||
<script>
|
||
import { listMaterialCoil, getMaterialCoilTrace, updateMaterialCoilSimple, checkCoilNo, restoreMaterialCoil } from '@/api/wms/coil'
|
||
import { listCoilContractRel, addCoilContractRel, updateCoilContractRel } from '@/api/wms/coilContractRel'
|
||
import { listPendingAction, getPendingAction, delPendingAction, addPendingAction, updatePendingAction, startProcess, cancelAction, restorePendingAction } from '@/api/wms/pendingAction'
|
||
import { listUser } from '@/api/system/user'
|
||
import { parseTime } from '@/utils/klp'
|
||
import CoilCard from '@/components/KLPService/Renderer/CoilCard.vue'
|
||
import LabelRender from '../panels/LabelRender/index.vue'
|
||
import WarehouseSelect from "@/components/KLPService/WarehouseSelect";
|
||
import ActualWarehouseSelect from "@/components/KLPService/ActualWarehouseSelect";
|
||
import ProductSelect from "@/components/KLPService/ProductSelect";
|
||
import RawMaterialSelect from "@/components/KLPService/RawMaterialSelect";
|
||
import CoilTraceResult from "../panels/CoilTraceResult.vue";
|
||
import TimeInput from "@/components/TimeInput";
|
||
import ContractSelect from "@/components/KLPService/ContractSelect";
|
||
import CoilSelector from '@/components/CoilSelector';
|
||
import CoilNo from '@/components/KLPService/Renderer/CoilNo.vue';
|
||
import { getCoilTagPrintType } from '@/views/wms/coil/js/coilPrint'
|
||
|
||
export default {
|
||
name: 'CorrentAllPage',
|
||
dicts: ['action_type', 'coil_quality_status', 'coil_business_purpose'],
|
||
components: {
|
||
CoilCard,
|
||
LabelRender,
|
||
WarehouseSelect,
|
||
ActualWarehouseSelect,
|
||
ProductSelect,
|
||
RawMaterialSelect,
|
||
CoilTraceResult,
|
||
TimeInput,
|
||
ContractSelect,
|
||
CoilSelector,
|
||
CoilNo
|
||
},
|
||
data() {
|
||
return {
|
||
// 追溯相关
|
||
traceOpen: false,
|
||
traceLoading: false,
|
||
traceResult: null,
|
||
|
||
// 搜索状态
|
||
searched: false,
|
||
|
||
// 钢卷类型
|
||
nowCoilList: [],
|
||
transCoilList: [],
|
||
historyCoilList: [],
|
||
unInCoilList: [],
|
||
nowLoading: false,
|
||
transLoading: false,
|
||
historyLoading: false,
|
||
unInLoading: false,
|
||
title: '钢卷信息修正',
|
||
|
||
// 物料列表相关
|
||
materialQueryParams: {
|
||
pageNum: 1,
|
||
pageSize: 20,
|
||
enterCoilNo: null,
|
||
currentCoilNo: null,
|
||
warehouseId: null,
|
||
},
|
||
|
||
// 标签预览相关
|
||
labelRender: {
|
||
visible: false,
|
||
data: {},
|
||
type: '2'
|
||
},
|
||
|
||
// 表单相关
|
||
form: {},
|
||
correctVisible: false,
|
||
buttonLoading: false,
|
||
contractLoading: false,
|
||
contractRelId: null,
|
||
userList: [],
|
||
|
||
floatLayerConfig: {
|
||
columns: [
|
||
{ label: '入场钢卷号', prop: 'enterCoilNo' },
|
||
{ label: '当前钢卷号', prop: 'currentCoilNo' },
|
||
{ label: '厂家卷号', prop: 'supplierCoilNo' },
|
||
{ label: '逻辑库位', prop: 'warehouseName' },
|
||
{ label: '实际库位', prop: 'actualWarehouseName' },
|
||
{ label: '物料类型', prop: 'materialType' },
|
||
{ label: '班组', prop: 'team' },
|
||
{ label: '净重', prop: 'netWeight' },
|
||
{ label: '毛重', prop: 'grossWeight' },
|
||
{ label: '备注', prop: 'remark' },
|
||
{ label: '创建人', prop: 'createBy' },
|
||
{ label: '创建时间', prop: 'createTime' },
|
||
{ label: '更新人', prop: 'updateBy' },
|
||
{ label: '更新时间', prop: 'updateTime' },
|
||
{ label: '质量状态', prop: 'qualityStatus' },
|
||
{ label: '原料材质', prop: 'packingStatus' },
|
||
{ label: '切边要求', prop: 'edgeRequirement' },
|
||
{ label: '包装要求', prop: 'packagingRequirement' },
|
||
{ label: '物料名称', prop: 'itemName' },
|
||
{ label: '材质', prop: 'material' },
|
||
{ label: '规格', prop: 'specification' },
|
||
{ label: '镀层质量', prop: 'zincLayer' },
|
||
{ label: '厂家', prop: 'manufacturer' },
|
||
{ label: '调制度', prop: 'temperGrade' },
|
||
{ label: '镀层种类', prop: 'coatingType' },
|
||
{ label: '实测长度(m)', prop: 'actualLength' },
|
||
{ label: '实测宽度(mm)', prop: 'actualWidth' },
|
||
{ label: '实测厚度(mm)', prop: 'actualThickness' },
|
||
{ label: '钢卷表面处理', prop: 'coilSurfaceTreatment' },
|
||
{ label: '排产厚度(mm)', prop: 'scheduleThickness' },
|
||
{ label: '生产开始时间', prop: 'productionStartTime' },
|
||
{ label: '生产结束时间', prop: 'productionEndTime' },
|
||
{ label: '生产耗时', prop: 'formattedDuration' },
|
||
],
|
||
title: '详细信息'
|
||
},
|
||
|
||
// 操作记录相关
|
||
actionDialogVisible: false,
|
||
actionLoading: false,
|
||
actionList: [],
|
||
actionTotal: 0,
|
||
currentCoilId: null,
|
||
actionQueryParams: {
|
||
pageNum: 1,
|
||
pageSize: 20,
|
||
actionType: null,
|
||
actionStatus: null
|
||
},
|
||
// 操作记录表单
|
||
actionForm: {},
|
||
actionOpen: false,
|
||
actionTitle: '',
|
||
// 操作记录选择相关
|
||
ids: [],
|
||
single: true,
|
||
multiple: true,
|
||
rubbish: false,
|
||
// 钢卷选择器可见性
|
||
coilSelectorVisible: false,
|
||
|
||
// 表单校验
|
||
rules: {
|
||
enterCoilNo: [
|
||
{ required: true, message: "入场钢卷号不能为空", trigger: "blur" },
|
||
{
|
||
validator: (rule, value, callback) => {
|
||
if (this.form.coilId) {
|
||
callback();
|
||
} else {
|
||
checkCoilNo({ enterCoilNo: value }).then(res => {
|
||
const { duplicateType } = res.data;
|
||
if (duplicateType === 'enter' || duplicateType === 'both') {
|
||
callback(new Error('入场钢卷号重复,请重新输入'));
|
||
} else {
|
||
callback();
|
||
}
|
||
})
|
||
}
|
||
}, trigger: 'blur'
|
||
},
|
||
],
|
||
currentCoilNo: [
|
||
{ required: true, message: "当前钢卷号不能为空", trigger: "blur" },
|
||
{
|
||
// 当前钢卷号必须大于等于11位
|
||
validator: (rule, value, callback) => {
|
||
if (value.length < 11) {
|
||
callback(new Error('当前钢卷号必须大于等于11位'));
|
||
} else {
|
||
callback();
|
||
}
|
||
}, trigger: 'blur'
|
||
},
|
||
],
|
||
materialType: [
|
||
{ required: true, message: "材料类型不能为空", trigger: "change" }
|
||
],
|
||
itemId: [
|
||
{ required: true, message: "物品ID不能为空", trigger: "blur" }
|
||
],
|
||
itemType: [
|
||
{ required: true, message: "物品类型不能为空", trigger: "change" }
|
||
],
|
||
netWeight: [
|
||
{ required: true, message: "净重不能为空", trigger: "blur" }
|
||
],
|
||
grossWeight: [
|
||
{ required: true, message: "毛重不能为空", trigger: "blur" }
|
||
],
|
||
},
|
||
// 操作记录表单校验
|
||
actionRules: {
|
||
coilId: [
|
||
{ required: true, message: '请选择钢卷', trigger: 'blur' }
|
||
],
|
||
actionType: [
|
||
{ required: true, message: '请选择操作类型', trigger: 'change' }
|
||
]
|
||
},
|
||
coilIds: ''
|
||
}
|
||
},
|
||
computed: {
|
||
// 动态显示标签
|
||
getItemLabel() {
|
||
if (this.form.materialType === '成品') {
|
||
return '产品类型';
|
||
} else if (this.form.materialType === '原料') {
|
||
return '原料类型';
|
||
}
|
||
return '物品类型';
|
||
},
|
||
// 分条操作列表(100-199)
|
||
splitTypes() {
|
||
if (!this.dict.type.action_type) return [];
|
||
return this.dict.type.action_type.filter(item => {
|
||
const value = parseInt(item.value);
|
||
return value >= 100 && value <= 199;
|
||
});
|
||
},
|
||
// 合卷操作列表(200-299)
|
||
mergeTypes() {
|
||
if (!this.dict.type.action_type) return [];
|
||
return this.dict.type.action_type.filter(item => {
|
||
const value = parseInt(item.value);
|
||
return value >= 200 && value <= 299;
|
||
});
|
||
},
|
||
// 其他操作列表(200-299等)
|
||
otherTypes() {
|
||
if (!this.dict.type.action_type) return [];
|
||
return this.dict.type.action_type.filter(item => {
|
||
const value = parseInt(item.value);
|
||
return value < 100 || value > 299;
|
||
});
|
||
}
|
||
},
|
||
created() {
|
||
// 加载用户列表
|
||
this.getUsers()
|
||
},
|
||
methods: {
|
||
parseTime,
|
||
|
||
formatDuration(milliseconds) {
|
||
if (!milliseconds || milliseconds < 0) return '';
|
||
const seconds = Math.floor(milliseconds / 1000);
|
||
const minutes = Math.floor(seconds / 60);
|
||
const hours = Math.floor(minutes / 60);
|
||
const days = Math.floor(hours / 24);
|
||
const remainingHours = hours % 24;
|
||
const remainingMinutes = minutes % 60;
|
||
let result = '';
|
||
if (days > 0) result += `${days}天`;
|
||
if (remainingHours > 0) result += `${remainingHours}小时`;
|
||
if (remainingMinutes > 0) result += `${remainingMinutes}分钟`;
|
||
return result || '0分钟';
|
||
},
|
||
calculateProductionDuration() {
|
||
const { productionStartTime, productionEndTime } = this.form;
|
||
if (productionStartTime && productionEndTime) {
|
||
const start = new Date(productionStartTime).getTime();
|
||
const end = new Date(productionEndTime).getTime();
|
||
if (end < start) {
|
||
this.form.productionDuration = '';
|
||
this.form.formattedDuration = '';
|
||
} else {
|
||
const durationMs = end - start;
|
||
this.form.productionDuration = Math.round(durationMs / (1000 * 60));
|
||
this.form.formattedDuration = this.formatDuration(durationMs);
|
||
}
|
||
} else {
|
||
this.form.productionDuration = '';
|
||
this.form.formattedDuration = '';
|
||
}
|
||
},
|
||
|
||
/** 查询用户列表 */
|
||
getUsers() {
|
||
listUser({ pageNum: 1, pageSize: 1000 }).then(response => {
|
||
this.userList = response.rows || []
|
||
})
|
||
},
|
||
|
||
// 打印标签
|
||
handlePrintLabel(row) {
|
||
this.labelRender.data = {
|
||
...row,
|
||
updateTime: row.updateTime?.split(' ')[0] || '',
|
||
};
|
||
this.$nextTick(() => {
|
||
this.$refs.labelRender.printLabel();
|
||
})
|
||
},
|
||
|
||
// 进入数字钢卷页面
|
||
handleNumberCoilClick(row) {
|
||
console.log(row)
|
||
this.$router.push({
|
||
path: '/wms/coil/' + row.coilId,
|
||
});
|
||
},
|
||
|
||
// 处理材料类型变化
|
||
handleMaterialTypeChange(value) {
|
||
// 清空物品选择
|
||
this.form.itemId = null;
|
||
|
||
// 根据材料类型设置物品类型
|
||
if (value === '成品') {
|
||
this.form.itemType = 'product';
|
||
} else if (value === '原料') {
|
||
this.form.itemType = 'raw_material';
|
||
}
|
||
},
|
||
|
||
/** 预览标签 */
|
||
handlePreviewLabel(row) {
|
||
console.log(row)
|
||
this.labelRender.visible = true;
|
||
const type = getCoilTagPrintType(row);
|
||
this.labelRender.type = type;
|
||
this.labelRender.data = {
|
||
...row,
|
||
updateTime: row.updateTime?.split(' ')[0] || '',
|
||
};
|
||
},
|
||
|
||
/** 追溯按钮操作 */
|
||
handleTrace(row) {
|
||
this.traceOpen = true;
|
||
this.traceLoading = true;
|
||
this.traceResult = null; // 清空历史数据
|
||
getMaterialCoilTrace({
|
||
coilId: row.coilId,
|
||
currentCoilNo: row.currentCoilNo,
|
||
}).then(res => {
|
||
this.traceResult = res.data; // 将结果传递给组件
|
||
}).catch(err => {
|
||
console.error('溯源查询失败:', err);
|
||
this.$message.error('溯源查询失败,请重试');
|
||
}).finally(() => {
|
||
this.traceLoading = false;
|
||
});
|
||
},
|
||
|
||
/** 查询操作记录 */
|
||
getActionList() {
|
||
this.actionLoading = true;
|
||
const payload = {
|
||
...this.materialQueryParams,
|
||
...this.actionQueryParams,
|
||
coilIds: this.coilIds,
|
||
includeDeleted: this.rubbish ? 2 : 0
|
||
};
|
||
listPendingAction(payload).then(response => {
|
||
this.actionList = response.rows || [];
|
||
this.actionTotal = response.total || 0;
|
||
this.actionLoading = false;
|
||
}).catch(() => {
|
||
this.actionLoading = false;
|
||
});
|
||
},
|
||
|
||
/** 操作记录搜索 */
|
||
handleActionQuery() {
|
||
this.actionQueryParams.pageNum = 1;
|
||
this.getActionList();
|
||
},
|
||
|
||
/** 重置操作记录搜索 */
|
||
resetActionQuery() {
|
||
this.resetForm('actionQueryForm');
|
||
this.actionQueryParams.actionType = null;
|
||
this.actionQueryParams.actionStatus = null;
|
||
this.handleActionQuery();
|
||
},
|
||
|
||
// ========== 物料列表相关方法 ==========
|
||
/** 查询物料列表(四栏并行) */
|
||
getMaterialCoil() {
|
||
this.nowLoading = true;
|
||
this.transLoading = true;
|
||
this.historyLoading = true;
|
||
this.unInLoading = true;
|
||
|
||
const basePayload = { ...this.materialQueryParams };
|
||
|
||
const fetchNow = listMaterialCoil({ ...basePayload, dataType: 1, status: 0 });
|
||
const fetchTrans = listMaterialCoil({ ...basePayload, status: 1 });
|
||
const fetchHistory = listMaterialCoil({ ...basePayload, dataType: 0 });
|
||
const fetchUnIn = listMaterialCoil({ ...basePayload, dataType: 10 });
|
||
|
||
Promise.all([fetchNow, fetchTrans, fetchHistory, fetchUnIn]).then(([nowRes, transRes, historyRes, unInRes]) => {
|
||
this.nowCoilList = nowRes.rows || [];
|
||
this.transCoilList = transRes.rows || [];
|
||
this.historyCoilList = historyRes.rows || [];
|
||
this.unInCoilList = unInRes.rows || [];
|
||
|
||
// 合并所有钢卷ID用于操作记录查询
|
||
const allIds = [
|
||
...this.nowCoilList,
|
||
...this.transCoilList,
|
||
...this.historyCoilList,
|
||
...this.unInCoilList,
|
||
].map(item => item.coilId);
|
||
this.coilIds = allIds.join(',');
|
||
if (allIds.length > 0) {
|
||
this.getActionList();
|
||
} else {
|
||
this.actionList = [];
|
||
this.actionTotal = 0;
|
||
}
|
||
}).catch(() => {
|
||
// 单个请求失败不影响其他栏
|
||
}).finally(() => {
|
||
this.nowLoading = false;
|
||
this.transLoading = false;
|
||
this.historyLoading = false;
|
||
this.unInLoading = false;
|
||
});
|
||
},
|
||
|
||
/** 物料搜索 */
|
||
handleMaterialQuery() {
|
||
// 检查是否至少填写了一个钢卷号
|
||
if (!this.materialQueryParams.enterCoilNo && !this.materialQueryParams.currentCoilNo) {
|
||
this.$message.warning('请至少填写一个钢卷号进行搜索');
|
||
return;
|
||
}
|
||
|
||
this.materialQueryParams.pageNum = 1;
|
||
this.searched = true;
|
||
this.getMaterialCoil();
|
||
},
|
||
|
||
/** 重置物料搜索 */
|
||
resetMaterialQuery() {
|
||
this.resetForm('materialQueryForm');
|
||
this.materialQueryParams.enterCoilNo = null;
|
||
this.materialQueryParams.currentCoilNo = null;
|
||
this.searched = false;
|
||
this.nowCoilList = [];
|
||
this.transCoilList = [];
|
||
this.historyCoilList = [];
|
||
this.unInCoilList = [];
|
||
this.actionList = [];
|
||
this.actionTotal = 0;
|
||
},
|
||
|
||
/** 回滚操作 */
|
||
handleRestoreMaterial(row) {
|
||
this.$modal.confirm('是否要将改钢卷还原到上次加工的状态(会删除该钢卷并将上一步的历史钢卷还原)').then(_ => {
|
||
const loading = this.$loading({
|
||
lock: true,
|
||
text: '处理中...',
|
||
spinner: 'el-icon-loading',
|
||
background: 'rgba(0, 0, 0, 0.7)'
|
||
})
|
||
restoreMaterialCoil(row.coilId).then(_ => {
|
||
this.$modal.msgSuccess("还原成功");
|
||
this.getMaterialCoil();
|
||
}).finally(() => {
|
||
loading.close()
|
||
})
|
||
})
|
||
},
|
||
|
||
/** 强制入库操作 */
|
||
handleForceInMaterial(row) {
|
||
this.$modal.confirm('是否要强制入库改钢卷?').then(_ => {
|
||
const loading = this.$loading({
|
||
lock: true,
|
||
text: '处理中...',
|
||
spinner: 'el-icon-loading',
|
||
background: 'rgba(0, 0, 0, 0.7)'
|
||
})
|
||
updateMaterialCoilSimple({
|
||
...row,
|
||
dataType: 1,
|
||
}).then(_ => {
|
||
this.$modal.msgSuccess("强制入库成功");
|
||
this.getMaterialCoil();
|
||
}).finally(() => {
|
||
loading.close()
|
||
})
|
||
})
|
||
},
|
||
|
||
/** 修正按钮操作 */
|
||
handleCorrectMaterial(row) {
|
||
this.form = {
|
||
...row,
|
||
contractId: row.contractId || null,
|
||
};
|
||
if (this.form.productionDuration) {
|
||
this.form.formattedDuration = this.formatDuration(this.form.productionDuration * 60 * 1000);
|
||
}
|
||
this.title = "钢卷信息修正";
|
||
this.correctVisible = true
|
||
this.loadContractRel(row.coilId)
|
||
},
|
||
|
||
/** 加载合同绑定关系 */
|
||
loadContractRel(coilId) {
|
||
if (!coilId) {
|
||
this.contractRelId = null
|
||
this.$set(this.form, 'contractId', null)
|
||
return
|
||
}
|
||
listCoilContractRel({ coilId }).then(res => {
|
||
const rows = res.rows || []
|
||
if (rows.length > 0) {
|
||
this.contractRelId = rows[0].relId
|
||
this.$set(this.form, 'contractId', rows[0].contractId)
|
||
} else {
|
||
this.contractRelId = null
|
||
this.$set(this.form, 'contractId', null)
|
||
}
|
||
})
|
||
},
|
||
|
||
/** 保存合同绑定 */
|
||
saveContractRel() {
|
||
this.contractLoading = true
|
||
listCoilContractRel({ coilId: this.form.coilId }).then(res => {
|
||
const rows = res.rows || []
|
||
if (rows.length > 0) {
|
||
return updateCoilContractRel({
|
||
relId: rows[0].relId,
|
||
coilId: this.form.coilId,
|
||
contractId: this.form.contractId
|
||
})
|
||
} else {
|
||
return addCoilContractRel({
|
||
coilId: this.form.coilId,
|
||
contractId: this.form.contractId
|
||
})
|
||
}
|
||
}).then(() => {
|
||
this.$message.success('合同绑定保存成功')
|
||
}).finally(() => {
|
||
this.contractLoading = false
|
||
})
|
||
},
|
||
|
||
/** 取消按钮 */
|
||
cancel() {
|
||
this.correctVisible = false
|
||
},
|
||
|
||
/** 提交按钮 */
|
||
submitForm() {
|
||
this.$refs['form'].validate(valid => {
|
||
if (!valid) {
|
||
this.$message.error('请填写完整信息')
|
||
return
|
||
}
|
||
this.buttonLoading = true;
|
||
// 更新钢卷信息
|
||
const { status, exclusiveStatus, dataType, ...payload} = {
|
||
...this.form,
|
||
}
|
||
updateMaterialCoilSimple(payload).then(_ => {
|
||
this.$modal.msgSuccess("修正成功");
|
||
this.correctVisible = false;
|
||
this.getMaterialCoil();
|
||
}).finally(() => {
|
||
this.buttonLoading = false;
|
||
});
|
||
})
|
||
},
|
||
|
||
// ========== 操作记录相关方法 ==========
|
||
/** 处理操作状态变化 */
|
||
handleStatusChange(row) {
|
||
updatePendingAction(row).then(response => {
|
||
this.$message.success('操作状态更新成功');
|
||
this.getActionList();
|
||
});
|
||
},
|
||
|
||
/** 完成时间改变时触发 */
|
||
handleProcessTimeChange(row) {
|
||
updatePendingAction(row).then(response => {
|
||
this.$message.success('更新成功');
|
||
});
|
||
},
|
||
|
||
/** 多选框选中数据 */
|
||
handleSelectionChange(selection) {
|
||
this.ids = selection.map(item => item.actionId);
|
||
this.single = selection.length !== 1;
|
||
this.multiple = !selection.length;
|
||
},
|
||
|
||
/** 新增操作 */
|
||
handleAddAction() {
|
||
this.resetActionForm();
|
||
this.actionOpen = true;
|
||
this.actionTitle = '添加操作记录';
|
||
},
|
||
|
||
/** 修改操作 */
|
||
handleUpdateAction(row) {
|
||
this.resetActionForm();
|
||
const actionId = row.actionId || this.ids;
|
||
getPendingAction(actionId).then(response => {
|
||
this.actionForm = response.data;
|
||
this.actionOpen = true;
|
||
this.actionTitle = '修改操作记录';
|
||
});
|
||
},
|
||
|
||
/** 删除操作 */
|
||
handleDeleteAction(row) {
|
||
const actionIds = row.actionId || this.ids;
|
||
this.$confirm('是否确认删除该操作记录?', '警告', {
|
||
confirmButtonText: '确定',
|
||
cancelButtonText: '取消',
|
||
type: 'warning'
|
||
}).then(() => {
|
||
return delPendingAction(actionIds);
|
||
}).then(() => {
|
||
this.getActionList();
|
||
this.$message.success('删除成功');
|
||
}).catch(() => { });
|
||
},
|
||
|
||
/** 还原操作 */
|
||
handleRestoreAction(row) {
|
||
const actionId = row.actionId;
|
||
this.$modal.confirm('是否确认还原该操作记录?', '警告', {
|
||
confirmButtonText: '确定',
|
||
cancelButtonText: '取消',
|
||
type: 'warning'
|
||
}).then(() => {
|
||
restorePendingAction(actionId).then(response => {
|
||
this.$message.success('还原成功');
|
||
this.getActionList();
|
||
});
|
||
});
|
||
},
|
||
|
||
/** 刷新操作记录 */
|
||
handleRefreshAction() {
|
||
this.getActionList();
|
||
this.$message.success('刷新成功');
|
||
},
|
||
|
||
/** 显示钢卷选择器 */
|
||
showCoilSelector() {
|
||
this.coilSelectorVisible = true;
|
||
},
|
||
|
||
/** 钢卷选择回调 */
|
||
handleCoilSelect(coil) {
|
||
this.actionForm.coilId = coil.coilId;
|
||
this.actionForm.currentCoilNo = coil.currentCoilNo;
|
||
},
|
||
|
||
/** 提交操作表单 */
|
||
submitActionForm() {
|
||
this.$refs['actionForm'].validate(valid => {
|
||
if (valid) {
|
||
this.buttonLoading = true;
|
||
if (this.actionForm.actionId != null) {
|
||
updatePendingAction(this.actionForm).then(response => {
|
||
this.$message.success('修改成功');
|
||
this.actionOpen = false;
|
||
this.getActionList();
|
||
this.buttonLoading = false;
|
||
});
|
||
} else {
|
||
addPendingAction(this.actionForm).then(response => {
|
||
this.$message.success('新增成功');
|
||
this.actionOpen = false;
|
||
this.getActionList();
|
||
this.buttonLoading = false;
|
||
});
|
||
}
|
||
}
|
||
});
|
||
},
|
||
|
||
/** 取消操作表单 */
|
||
cancelAction() {
|
||
this.actionOpen = false;
|
||
this.resetActionForm();
|
||
},
|
||
|
||
/** 重置操作表单 */
|
||
resetActionForm() {
|
||
this.actionForm = {
|
||
actionId: null,
|
||
coilId: null,
|
||
currentCoilNo: null,
|
||
actionType: null,
|
||
actionStatus: null,
|
||
priority: 0,
|
||
sourceType: 'manual',
|
||
remark: null
|
||
};
|
||
if (this.$refs['actionForm']) {
|
||
this.$refs['actionForm'].resetFields();
|
||
}
|
||
},
|
||
|
||
/** 获取边框样式 */
|
||
getBorderStyle(row) {
|
||
// 已发货
|
||
if (row.status == 1) {
|
||
return { border: '1.5px solid #007bff' }
|
||
}
|
||
// 历史钢卷
|
||
if (row.dataType == 0 || row.dataType == 2) {
|
||
return { border: '1.5px solid #6c757d' }
|
||
}
|
||
// 当前钢卷
|
||
if (row.dataType == 1) {
|
||
return { border: '1.5px solid #28a745' }
|
||
}
|
||
// 还未入库的钢卷
|
||
if (row.dataType == 10) {
|
||
return { border: '1.5px solid #ffc107' }
|
||
}
|
||
return { border: '1.5px solid #e4e7ed' }
|
||
},
|
||
|
||
/** 获取钢卷类型标签 */
|
||
getTypeLabel(row) {
|
||
if (row.status == 1) {
|
||
return '已发货'
|
||
}
|
||
if (row.dataType == 0 || row.dataType == 2) {
|
||
return '历史钢卷'
|
||
}
|
||
if (row.dataType == 1) {
|
||
return '当前钢卷'
|
||
}
|
||
if (row.dataType == 10) {
|
||
return '未入库'
|
||
}
|
||
return '未知'
|
||
},
|
||
|
||
getRowStyle(row) {
|
||
// 已发货
|
||
if (row.status == 1) {
|
||
return { backgroundColor: '#e6f7ff' }
|
||
}
|
||
// 历史钢卷
|
||
if (row.dataType == 0 || row.dataType == 2) {
|
||
return { backgroundColor: '#f4f4f5' }
|
||
}
|
||
// 当前钢卷
|
||
if (row.dataType == 1) {
|
||
return { backgroundColor: '#f0fdf4' }
|
||
}
|
||
// 还未入库的钢卷
|
||
if (row.dataType == 10) {
|
||
return { backgroundColor: '#fffbe6' }
|
||
}
|
||
return {}
|
||
},
|
||
}
|
||
}
|
||
</script>
|
||
|
||
<style scoped lang="scss">
|
||
.acid-do-container {
|
||
background-color: #f5f7fa;
|
||
padding: 20px;
|
||
min-height: calc(100vh - 84px);
|
||
}
|
||
|
||
// 搜索区域样式
|
||
.search-section {
|
||
margin-bottom: 20px;
|
||
background-color: #ffffff;
|
||
border-radius: 4px;
|
||
padding: 20px;
|
||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
|
||
|
||
.page-title {
|
||
margin: 0 0 16px 0;
|
||
font-size: 18px;
|
||
font-weight: 600;
|
||
color: #303133;
|
||
}
|
||
|
||
.search-form {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 12px;
|
||
|
||
.search-tip {
|
||
font-size: 12px;
|
||
color: #909399;
|
||
margin-left: 12px;
|
||
}
|
||
}
|
||
}
|
||
|
||
// 2×2 布局
|
||
.two-by-two-layout {
|
||
display: grid;
|
||
grid-template-columns: 1fr 1fr;
|
||
gap: 16px;
|
||
}
|
||
|
||
.coil-column {
|
||
background: #fff;
|
||
border: 1px solid #e4e7ed;
|
||
border-radius: 4px;
|
||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
|
||
display: flex;
|
||
flex-direction: column;
|
||
height: 420px;
|
||
overflow: hidden;
|
||
}
|
||
|
||
.column-header {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
padding: 10px 14px;
|
||
border-bottom: 2px solid #e4e7ed;
|
||
|
||
&--now {
|
||
border-bottom-color: #67c23a;
|
||
.column-title { color: #67c23a; }
|
||
}
|
||
&--trans {
|
||
border-bottom-color: #409eff;
|
||
.column-title { color: #409eff; }
|
||
}
|
||
&--history {
|
||
border-bottom-color: #909399;
|
||
.column-title { color: #909399; }
|
||
}
|
||
&--unIn {
|
||
border-bottom-color: #e6a23c;
|
||
.column-title { color: #e6a23c; }
|
||
}
|
||
}
|
||
|
||
.column-title {
|
||
margin: 0;
|
||
font-size: 14px;
|
||
font-weight: 600;
|
||
}
|
||
|
||
.column-count {
|
||
font-size: 12px;
|
||
color: #909399;
|
||
background: #f5f7fa;
|
||
padding: 2px 8px;
|
||
border-radius: 10px;
|
||
}
|
||
|
||
.column-body {
|
||
flex: 1;
|
||
min-height: 0;
|
||
overflow: hidden;
|
||
}
|
||
|
||
.column-empty {
|
||
text-align: center;
|
||
padding: 40px 12px;
|
||
color: #c0c4cc;
|
||
font-size: 13px;
|
||
}
|
||
|
||
// 未搜索状态
|
||
.empty-search-state {
|
||
background-color: #ffffff;
|
||
border-radius: 4px;
|
||
padding: 80px 20px;
|
||
text-align: center;
|
||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
|
||
|
||
i {
|
||
font-size: 48px;
|
||
margin-bottom: 16px;
|
||
display: block;
|
||
color: #c0c4cc;
|
||
}
|
||
|
||
p {
|
||
margin: 0;
|
||
font-size: 16px;
|
||
color: #909399;
|
||
}
|
||
}
|
||
|
||
.section-card {
|
||
background-color: #ffffff;
|
||
border: 1px solid #e4e7ed;
|
||
border-radius: 4px;
|
||
padding: 16px;
|
||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
|
||
display: flex;
|
||
flex-direction: column;
|
||
}
|
||
|
||
.section-header {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
margin-bottom: 16px;
|
||
padding-bottom: 12px;
|
||
border-bottom: 2px solid #e4e7ed;
|
||
}
|
||
|
||
.section-title {
|
||
margin: 0;
|
||
font-size: 16px;
|
||
font-weight: 600;
|
||
color: #303133;
|
||
}
|
||
|
||
.section-desc {
|
||
font-size: 12px;
|
||
color: #909399;
|
||
}
|
||
|
||
.action-section {
|
||
.section-header {
|
||
border-bottom-color: #67c23a;
|
||
}
|
||
|
||
.section-title {
|
||
color: #67c23a;
|
||
}
|
||
}
|
||
|
||
.query-form {
|
||
margin-bottom: 16px;
|
||
padding: 12px;
|
||
background-color: #fafafa;
|
||
border-radius: 4px;
|
||
border: 1px solid #e4e7ed;
|
||
}
|
||
|
||
.mb10 {
|
||
margin-bottom: 10px;
|
||
}
|
||
|
||
// 钢卷信息容器
|
||
.coil-info-container {
|
||
flex: 1;
|
||
overflow-y: auto;
|
||
padding-right: 4px;
|
||
display: grid;
|
||
grid-template-columns: repeat(5, 1fr);
|
||
grid-gap: 12px;
|
||
}
|
||
|
||
// 操作记录容器
|
||
.action-list-container {
|
||
flex: 1;
|
||
overflow-y: auto;
|
||
display: flex;
|
||
flex-direction: column;
|
||
|
||
&::-webkit-scrollbar {
|
||
width: 6px;
|
||
}
|
||
|
||
&::-webkit-scrollbar-track {
|
||
background: #f1f1f1;
|
||
border-radius: 3px;
|
||
}
|
||
|
||
&::-webkit-scrollbar-thumb {
|
||
background: #c1c1c1;
|
||
border-radius: 3px;
|
||
|
||
&:hover {
|
||
background: #a8a8a8;
|
||
}
|
||
}
|
||
|
||
::v-deep .el-table {
|
||
flex: 1;
|
||
min-height: 200px;
|
||
}
|
||
|
||
::v-deep .el-table__body-wrapper {
|
||
overflow-y: auto;
|
||
}
|
||
}
|
||
|
||
// 空状态
|
||
.empty-state {
|
||
text-align: center;
|
||
padding: 60px 20px;
|
||
color: #909399;
|
||
|
||
i {
|
||
font-size: 48px;
|
||
margin-bottom: 16px;
|
||
display: block;
|
||
color: #c0c4cc;
|
||
}
|
||
|
||
p {
|
||
margin: 0;
|
||
font-size: 14px;
|
||
}
|
||
}
|
||
|
||
.param-icon {
|
||
font-size: 13px;
|
||
color: #909399;
|
||
cursor: pointer;
|
||
transition: color 0.3s;
|
||
|
||
&:hover {
|
||
color: #409eff;
|
||
}
|
||
}
|
||
|
||
.material-type {
|
||
font-size: 11px;
|
||
color: #606266;
|
||
font-weight: 500;
|
||
}
|
||
|
||
.coil-no-tag {
|
||
font-weight: 600;
|
||
font-size: 11px;
|
||
padding: 2px 6px;
|
||
}
|
||
|
||
.info-list {
|
||
.info-item {
|
||
display: flex;
|
||
align-items: center;
|
||
margin-bottom: 4px;
|
||
font-size: 11px;
|
||
line-height: 1.4;
|
||
|
||
&:last-child {
|
||
margin-bottom: 0;
|
||
}
|
||
|
||
.info-label {
|
||
color: #909399;
|
||
white-space: nowrap;
|
||
margin-right: 4px;
|
||
min-width: 40px;
|
||
font-size: 11px;
|
||
}
|
||
|
||
.info-value {
|
||
color: #303133;
|
||
flex: 1;
|
||
overflow: hidden;
|
||
text-overflow: ellipsis;
|
||
white-space: nowrap;
|
||
font-size: 11px;
|
||
}
|
||
}
|
||
}
|
||
|
||
// 分页样式
|
||
::v-deep .pagination-container {
|
||
margin-top: 16px;
|
||
padding: 12px;
|
||
background-color: #fafafa;
|
||
border-radius: 4px;
|
||
border: 1px solid #e4e7ed;
|
||
}
|
||
|
||
// 参数弹出框样式
|
||
::v-deep .material-params-popover {
|
||
.material-params-content {
|
||
.params-title {
|
||
font-size: 14px;
|
||
font-weight: 600;
|
||
color: #303133;
|
||
margin-bottom: 12px;
|
||
padding-bottom: 8px;
|
||
border-bottom: 1px solid #e4e7ed;
|
||
}
|
||
|
||
.params-list {
|
||
.param-item {
|
||
.param-row {
|
||
display: flex;
|
||
margin-bottom: 6px;
|
||
font-size: 12px;
|
||
line-height: 1.5;
|
||
|
||
&:last-child {
|
||
margin-bottom: 0;
|
||
}
|
||
|
||
.param-label {
|
||
color: #909399;
|
||
min-width: 70px;
|
||
margin-right: 8px;
|
||
}
|
||
|
||
.param-value {
|
||
color: #303133;
|
||
flex: 1;
|
||
word-break: break-all;
|
||
}
|
||
}
|
||
}
|
||
|
||
.param-divider {
|
||
height: 1px;
|
||
background-color: #e4e7ed;
|
||
margin: 10px 0;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
/* 操作类型卡片样式 */
|
||
.action-type-cards {
|
||
width: 100%;
|
||
|
||
.card-section {
|
||
margin-bottom: 24px;
|
||
|
||
&:last-child {
|
||
margin-bottom: 0;
|
||
}
|
||
}
|
||
|
||
.section-title {
|
||
font-size: 14px;
|
||
font-weight: 600;
|
||
color: #303133;
|
||
margin-bottom: 12px;
|
||
padding-left: 8px;
|
||
border-left: 3px solid #409eff;
|
||
}
|
||
|
||
// 分条操作区域的特殊样式
|
||
.card-section:first-child .section-title {
|
||
border-left-color: #e6a23c;
|
||
}
|
||
|
||
.action-cards-row {
|
||
display: grid;
|
||
grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
|
||
gap: 12px;
|
||
}
|
||
|
||
.action-card {
|
||
min-width: 0;
|
||
padding: 16px;
|
||
border: 2px solid #dcdfe6;
|
||
border-radius: 8px;
|
||
cursor: pointer;
|
||
transition: all 0.3s ease;
|
||
background: #fff;
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 12px;
|
||
|
||
&:hover {
|
||
border-color: #409eff;
|
||
box-shadow: 0 2px 12px 0 rgba(64, 158, 255, 0.15);
|
||
transform: translateY(-2px);
|
||
}
|
||
|
||
&.active {
|
||
border-color: #409eff;
|
||
background: linear-gradient(135deg, #e3f2fd 0%, #f0f7ff 100%);
|
||
box-shadow: 0 2px 12px 0 rgba(64, 158, 255, 0.3);
|
||
|
||
.card-icon {
|
||
background: linear-gradient(135deg, #409eff 0%, #66b1ff 100%);
|
||
color: #fff;
|
||
}
|
||
|
||
.card-title {
|
||
color: #409eff;
|
||
font-weight: 600;
|
||
}
|
||
}
|
||
|
||
&.split-card {
|
||
&.active {
|
||
background: linear-gradient(135deg, #fff3e0 0%, #fff8f0 100%);
|
||
border-color: #e6a23c;
|
||
|
||
.card-icon {
|
||
background: linear-gradient(135deg, #e6a23c 0%, #f0ad4e 100%);
|
||
}
|
||
|
||
.card-title {
|
||
color: #e6a23c;
|
||
}
|
||
}
|
||
|
||
&:hover {
|
||
border-color: #e6a23c;
|
||
box-shadow: 0 2px 12px 0 rgba(230, 162, 60, 0.15);
|
||
}
|
||
}
|
||
}
|
||
|
||
.card-icon {
|
||
width: 48px;
|
||
height: 48px;
|
||
border-radius: 8px;
|
||
background: #f5f7fa;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
font-size: 24px;
|
||
color: #909399;
|
||
transition: all 0.3s ease;
|
||
flex-shrink: 0;
|
||
}
|
||
|
||
.card-content {
|
||
flex: 1;
|
||
}
|
||
|
||
.card-title {
|
||
font-size: 16px;
|
||
font-weight: 500;
|
||
color: #303133;
|
||
margin-bottom: 4px;
|
||
transition: all 0.3s ease;
|
||
}
|
||
|
||
.card-desc {
|
||
font-size: 13px;
|
||
color: #909399;
|
||
line-height: 1.4;
|
||
}
|
||
}
|
||
|
||
// 操作记录对话框内容
|
||
.action-dialog-content {
|
||
max-height: 600px;
|
||
overflow-y: auto;
|
||
}
|
||
|
||
.el-table .el-button + .el-button {
|
||
margin-left: 0px;
|
||
}
|
||
</style> |