Browse Source
feat(check): 新增当前盘点单页面及任务单功能
feat(check): 新增当前盘点单页面及任务单功能
- 新增 getCurrentActiveCount API 接口用于获取当前活动盘点单 - 新增 pushCountToWcs 和 continuePushCount API 接口用于推送盘点单到 WCS - 新增任务单相关 API:searchOrderTaskByCountNo、searchOrderTaskDetail、hasUncompletedTask、createReviewTask - 新建 currentPhysicalInventory.vue 页面展示当前盘点单详情 - 在搜索盘点单页面增加任务单 tab 页签及相关数据加载逻辑 - 修改盘点进度显示字段从标签数改为栈板数 - 更新标签明细和栈板明细表格列配置,新增所在层数字段 - 调整表格高度自适应并优化操作按钮布局 - 增加复核任务相关功能,包括复核弹窗和任务创建逻辑 - 优化页面加载逻辑,支持自动选择首条记录并加载明细数据master
3 changed files with 973 additions and 13 deletions
-
25src/api/check/physicalInventory.js
-
801src/views/modules/check/currentPhysicalInventory.vue
-
160src/views/modules/check/searchPhysicalInventory.vue
@ -0,0 +1,801 @@ |
|||
<template> |
|||
<!-- 当前盘点单页面 - rqrq --> |
|||
<div class="mod-config yzz"> |
|||
<!-- 顶部操作区域 --> |
|||
<div style="margin-bottom: 10px;"> |
|||
<el-button type="primary" @click="loadCurrentCount" :loading="headerLoading">刷 新</el-button> |
|||
<el-button type="success" @click="handleRelease" v-if="headerData && headerData.status === 'DRAFT'" :disabled="headerLoading">下 达</el-button> |
|||
<el-button type="warning" @click="handlePush" v-if="headerData && headerData.status === 'RELEASED'" :disabled="headerLoading">推 送</el-button> |
|||
<!-- <el-button type="info" @click="handleContinuePush" v-if="headerData && headerData.status === 'CHECKING'" :disabled="headerLoading">继续推送</el-button> 自动触发--> |
|||
<el-button type="success" @click="handleComplete" v-if="headerData && headerData.status === 'CHECKING'" :disabled="headerLoading">完 成</el-button> |
|||
<el-button type="danger" @click="handleCancel" v-if="headerData && headerData.status !== 'COMPLETED' && headerData.status !== 'CANCELLED'" :disabled="headerLoading">取 消</el-button> |
|||
<!-- 复核按钮 - 当栈板盘点进度满了后显示 - rqrq --> |
|||
<el-button type="primary" @click="openReviewDialog" |
|||
v-if="headerData && headerData.status === 'CHECKING' && headerData.checkedPalletCount >= headerData.totalPalletCount && headerData.totalPalletCount > 0" |
|||
:disabled="headerLoading || reviewLoading">复 核</el-button> |
|||
</div> |
|||
|
|||
<!-- Header信息展示区域 - 一行6个input框 --> |
|||
<div class="header-info" v-loading="headerLoading"> |
|||
<el-form label-position="top" :inline="true" v-if="headerData"> |
|||
<el-row :gutter="10"> |
|||
<el-col :span="4"> |
|||
<el-form-item label="盘点单号"> |
|||
<el-input v-model="headerData.countNo" readonly style="width: 100%;"></el-input> |
|||
</el-form-item> |
|||
</el-col> |
|||
<el-col :span="4"> |
|||
<el-form-item label="盘点类型"> |
|||
<el-input v-model="headerData.countTypeDesc" readonly style="width: 100%;"></el-input> |
|||
</el-form-item> |
|||
</el-col> |
|||
<el-col :span="4"> |
|||
<el-form-item label="状态"> |
|||
<el-input v-model="headerData.statusDesc" readonly :style="{width: '100%', color: getStatusColor(headerData.status)}"></el-input> |
|||
</el-form-item> |
|||
</el-col> |
|||
<el-col :span="4"> |
|||
<el-form-item label="循环比例"> |
|||
<el-input :value="headerData.countPercent ? headerData.countPercent + '%' : '-'" readonly style="width: 100%;"></el-input> |
|||
</el-form-item> |
|||
</el-col> |
|||
<el-col :span="4"> |
|||
<el-form-item label="盘点进度(栈板)"> |
|||
<el-input :value="headerData.checkedPalletCount + '/' + headerData.totalPalletCount" readonly style="width: 100%;"></el-input> |
|||
</el-form-item> |
|||
</el-col> |
|||
<el-col :span="4"> |
|||
<el-form-item label="标签数"> |
|||
<el-input :value="headerData.totalLabelCount" readonly style="width: 100%;"></el-input> |
|||
</el-form-item> |
|||
</el-col> |
|||
</el-row> |
|||
<el-row :gutter="10"> |
|||
<el-col :span="4"> |
|||
<el-form-item label="申请人"> |
|||
<el-input v-model="headerData.applyUser" readonly style="width: 100%;"></el-input> |
|||
</el-form-item> |
|||
</el-col> |
|||
<el-col :span="4"> |
|||
<el-form-item label="申请日期"> |
|||
<el-input :value="formatDateTime(headerData.applyDate)" readonly style="width: 100%;"></el-input> |
|||
</el-form-item> |
|||
</el-col> |
|||
<el-col :span="4"> |
|||
<el-form-item label="下达人"> |
|||
<el-input v-model="headerData.releaseUser" readonly style="width: 100%;"></el-input> |
|||
</el-form-item> |
|||
</el-col> |
|||
<el-col :span="4"> |
|||
<el-form-item label="下达日期"> |
|||
<el-input :value="formatDateTime(headerData.releaseDate)" readonly style="width: 100%;"></el-input> |
|||
</el-form-item> |
|||
</el-col> |
|||
<el-col :span="8"> |
|||
<el-form-item label="备注"> |
|||
<el-input v-model="headerData.remark" readonly style="width: 100%;"></el-input> |
|||
</el-form-item> |
|||
</el-col> |
|||
</el-row> |
|||
</el-form> |
|||
<el-empty v-else description="当前没有进行中的盘点单"></el-empty> |
|||
</div> |
|||
|
|||
<!-- Tab标签页 - 和searchPhysicalInventory.vue一致 --> |
|||
<el-tabs style="font-size: 12px;min-height: 200px" class="customer-tab" v-model="activeName" type="border-card" @tab-click="tabClick" v-if="headerData"> |
|||
<el-tab-pane label="标签明细" name="label"> |
|||
<!-- 标签明细表格 - rqrq --> |
|||
<el-table :data="labelList" :height="height" border v-loading="labelListLoading" style="width: 100%;"> |
|||
<el-table-column |
|||
v-for="(item,index) in labelColumnList" :key="index" |
|||
:sortable="item.columnSortable" |
|||
:prop="item.columnProp" |
|||
:header-align="item.headerAlign" |
|||
:show-overflow-tooltip="item.showOverflowTooltip" |
|||
:align="item.align" |
|||
:fixed="item.fixed==''?false:item.fixed" |
|||
:min-width="item.columnWidth" |
|||
:label="item.columnLabel"> |
|||
<template slot-scope="scope"> |
|||
<span v-if="item.columnProp === 'countFlagDesc'" :style="{color: scope.row.countFlag === 'Y' ? '#67C23A' : '#F56C6C'}">{{ scope.row.countFlagDesc }}</span> |
|||
<span v-else-if="item.columnProp === 'countDate'">{{ formatDateTime(scope.row.countDate) }}</span> |
|||
<span v-else>{{ scope.row[item.columnProp] }}</span> |
|||
</template> |
|||
</el-table-column> |
|||
</el-table> |
|||
</el-tab-pane> |
|||
<el-tab-pane label="栈板明细" name="pallet"> |
|||
<!-- 栈板明细表格 - rqrq --> |
|||
<el-table :data="palletList" :height="height" border v-loading="palletListLoading" style="width: 100%;"> |
|||
<el-table-column |
|||
v-for="(item,index) in palletColumnList" :key="index" |
|||
:sortable="item.columnSortable" |
|||
:prop="item.columnProp" |
|||
:header-align="item.headerAlign" |
|||
:show-overflow-tooltip="item.showOverflowTooltip" |
|||
:align="item.align" |
|||
:fixed="item.fixed==''?false:item.fixed" |
|||
:min-width="item.columnWidth" |
|||
:label="item.columnLabel"> |
|||
<template slot-scope="scope"> |
|||
<span v-if="item.columnProp === 'countFlagDesc'" :style="{color: scope.row.countFlag === 'Y' ? '#67C23A' : '#F56C6C'}">{{ scope.row.countFlagDesc }}</span> |
|||
<span v-else-if="item.columnProp === 'countDate'">{{ formatDateTime(scope.row.countDate) }}</span> |
|||
<span v-else>{{ scope.row[item.columnProp] }}</span> |
|||
</template> |
|||
</el-table-column> |
|||
</el-table> |
|||
</el-tab-pane> |
|||
<el-tab-pane label="盘点结果" name="result"> |
|||
<!-- 盘点结果表格 - rqrq --> |
|||
<el-table :data="resultList" :height="height" border v-loading="resultListLoading" style="width: 100%;"> |
|||
<el-table-column |
|||
v-for="(item,index) in resultColumnList" :key="index" |
|||
:sortable="item.columnSortable" |
|||
:prop="item.columnProp" |
|||
:header-align="item.headerAlign" |
|||
:show-overflow-tooltip="item.showOverflowTooltip" |
|||
:align="item.align" |
|||
:fixed="item.fixed==''?false:item.fixed" |
|||
:min-width="item.columnWidth" |
|||
:label="item.columnLabel"> |
|||
<template slot-scope="scope"> |
|||
<span v-if="item.columnProp === 'countResultDesc'" :style="{color: getResultColor(scope.row.countResult)}">{{ scope.row.countResultDesc }}</span> |
|||
<span v-else-if="item.columnProp === 'countDate'">{{ formatDateTime(scope.row.countDate) }}</span> |
|||
<span v-else>{{ scope.row[item.columnProp] }}</span> |
|||
</template> |
|||
</el-table-column> |
|||
</el-table> |
|||
</el-tab-pane> |
|||
<el-tab-pane label="物料汇总" name="summary"> |
|||
<!-- 物料汇总表格 - rqrq --> |
|||
<el-table :data="summaryList" :height="height" border v-loading="summaryListLoading" style="width: 100%;"> |
|||
<el-table-column |
|||
v-for="(item,index) in summaryColumnList" :key="index" |
|||
:sortable="item.columnSortable" |
|||
:prop="item.columnProp" |
|||
:header-align="item.headerAlign" |
|||
:show-overflow-tooltip="item.showOverflowTooltip" |
|||
:align="item.align" |
|||
:fixed="item.fixed==''?false:item.fixed" |
|||
:min-width="item.columnWidth" |
|||
:label="item.columnLabel"> |
|||
<template slot-scope="scope"> |
|||
<span>{{ scope.row[item.columnProp] }}</span> |
|||
</template> |
|||
</el-table-column> |
|||
</el-table> |
|||
</el-tab-pane> |
|||
<!-- 任务单页签 - rqrq --> |
|||
<el-tab-pane label="任务单" name="task"> |
|||
<div style="display: flex; gap: 10px;"> |
|||
<!-- 左边:任务单主表 - rqrq --> |
|||
<div style="flex: 1;"> |
|||
<div style="font-weight: bold; margin-bottom: 5px; font-size: 12px;">任务单</div> |
|||
<el-table :data="taskList" :height="height" border v-loading="taskListLoading" |
|||
highlight-current-row @row-click="onTaskRowClick" style="width: 100%;"> |
|||
<el-table-column prop="taskNo" label="任务号" min-width="120" header-align="center" align="center"></el-table-column> |
|||
<el-table-column prop="sourceType" label="来源类型" min-width="140" header-align="center" align="center"></el-table-column> |
|||
<el-table-column prop="status" label="状态" min-width="80" header-align="center" align="center"> |
|||
<template slot-scope="scope"> |
|||
<span :style="{color: scope.row.status === '已完成' ? '#67C23A' : '#E6A23C'}">{{ scope.row.status }}</span> |
|||
</template> |
|||
</el-table-column> |
|||
<el-table-column prop="createdBy" label="创建人" min-width="80" header-align="center" align="center"></el-table-column> |
|||
<el-table-column prop="createdTime" label="创建时间" min-width="140" header-align="center" align="center"> |
|||
<template slot-scope="scope"> |
|||
<span>{{ formatDateTime(scope.row.createdTime) }}</span> |
|||
</template> |
|||
</el-table-column> |
|||
</el-table> |
|||
</div> |
|||
<!-- 右边:任务单明细 - rqrq --> |
|||
<div style="flex: 1;"> |
|||
<div style="font-weight: bold; margin-bottom: 5px; font-size: 12px;">任务单明细</div> |
|||
<el-table :data="taskDetailList" :height="height" border v-loading="taskDetailListLoading" style="width: 100%;"> |
|||
<el-table-column prop="seqNo" label="序号" min-width="60" header-align="center" align="center"></el-table-column> |
|||
<el-table-column prop="palletId" label="栈板号" min-width="150" header-align="center" align="center"></el-table-column> |
|||
<el-table-column prop="wmsStatus" label="WMS状态" min-width="100" header-align="center" align="center"> |
|||
<template slot-scope="scope"> |
|||
<span :style="{color: scope.row.wmsStatus === '已盘点' ? '#67C23A' : '#909399'}">{{ scope.row.wmsStatus }}</span> |
|||
</template> |
|||
</el-table-column> |
|||
</el-table> |
|||
</div> |
|||
</div> |
|||
</el-tab-pane> |
|||
</el-tabs> |
|||
|
|||
<!-- 复核弹框 - rqrq --> |
|||
<el-dialog title="盘点复核" :visible.sync="reviewDialogVisible" :close-on-click-modal="false" v-drag width="80%"> |
|||
<div style="margin-bottom: 10px;"> |
|||
<el-checkbox v-model="onlyShowAbnormal" @change="filterReviewResult">只看异常</el-checkbox> |
|||
<span style="margin-left: 20px;">复核类型:</span> |
|||
<el-radio-group v-model="reviewType"> |
|||
<el-radio label="MANUAL">人工复核</el-radio> |
|||
<el-radio label="CYCLE">循环复核</el-radio> |
|||
</el-radio-group> |
|||
</div> |
|||
|
|||
<el-table :data="filteredReviewResultList" height="400" border |
|||
@selection-change="handleReviewSelectionChange" ref="reviewTable"> |
|||
<el-table-column type="selection" width="50" header-align="center" align="center"></el-table-column> |
|||
<el-table-column prop="unitId" label="标签号" min-width="150" header-align="center" align="center"></el-table-column> |
|||
<el-table-column prop="partNo" label="物料号" min-width="120" header-align="center" align="center"></el-table-column> |
|||
<el-table-column prop="partDesc" label="物料描述" min-width="180" header-align="center" align="left"></el-table-column> |
|||
<el-table-column prop="qty" label="数量" min-width="80" header-align="center" align="center"></el-table-column> |
|||
<el-table-column prop="palletId" label="栈板号" min-width="120" header-align="center" align="center"></el-table-column> |
|||
<el-table-column prop="countResultDesc" label="盘点结果" min-width="80" header-align="center" align="center"> |
|||
<template slot-scope="scope"> |
|||
<span :style="{color: getResultColor(scope.row.countResult)}">{{ scope.row.countResultDesc }}</span> |
|||
</template> |
|||
</el-table-column> |
|||
<el-table-column prop="remark" label="备注" min-width="150" header-align="center" align="left"></el-table-column> |
|||
</el-table> |
|||
|
|||
<div slot="footer" class="dialog-footer"> |
|||
<el-button type="primary" @click="confirmReview" :disabled="reviewLoading"> |
|||
{{ reviewLoading ? '提交中...' : '确认复核' }} |
|||
</el-button> |
|||
<el-button @click="reviewDialogVisible = false" :disabled="reviewLoading">取消</el-button> |
|||
</div> |
|||
</el-dialog> |
|||
</div> |
|||
</template> |
|||
|
|||
<script> |
|||
import { getCurrentActiveCount, releaseCount, pushCountToWcs, continuePushCount, completeCount, cancelCount, searchCountLabelList, searchCountPalletList, searchCountResultList, searchMaterialSummary, searchOrderTaskByCountNo, searchOrderTaskDetail, hasUncompletedTask, createReviewTask } from '@/api/check/physicalInventory' |
|||
|
|||
export default { |
|||
name: 'currentPhysicalInventory', |
|||
data() { |
|||
return { |
|||
// Header信息 - rqrq |
|||
headerData: null, |
|||
headerLoading: false, |
|||
height: 300, |
|||
|
|||
// Tab相关 - rqrq |
|||
activeName: 'label', |
|||
labelList: [], |
|||
labelListLoading: false, |
|||
palletList: [], |
|||
palletListLoading: false, |
|||
resultList: [], |
|||
resultListLoading: false, |
|||
summaryList: [], |
|||
summaryListLoading: false, |
|||
|
|||
// 标签明细列配置 - rqrq |
|||
labelColumnList: [ |
|||
{ columnProp: "unitId", headerAlign: "center", align: "center", columnLabel: "标签号", columnWidth: 150, columnSortable: false, showOverflowTooltip: true, fixed: "" }, |
|||
{ columnProp: "partNo", headerAlign: "center", align: "center", columnLabel: "物料号", columnWidth: 120, columnSortable: false, showOverflowTooltip: true, fixed: "" }, |
|||
{ columnProp: "partDesc", headerAlign: "center", align: "left", columnLabel: "物料描述", columnWidth: 180, columnSortable: false, showOverflowTooltip: true, fixed: "" }, |
|||
{ columnProp: "qty", headerAlign: "center", align: "center", columnLabel: "数量", columnWidth: 80, columnSortable: false, showOverflowTooltip: true, fixed: "" }, |
|||
{ columnProp: "batchNo", headerAlign: "center", align: "center", columnLabel: "批号", columnWidth: 100, columnSortable: false, showOverflowTooltip: true, fixed: "" }, |
|||
{ columnProp: "palletId", headerAlign: "center", align: "center", columnLabel: "栈板号", columnWidth: 120, columnSortable: false, showOverflowTooltip: true, fixed: "" }, |
|||
{ columnProp: "locationZ", headerAlign: "center", align: "center", columnLabel: "所在层数", columnWidth: 80, columnSortable: false, showOverflowTooltip: true, fixed: "" }, |
|||
{ columnProp: "labelTypeDesc", headerAlign: "center", align: "center", columnLabel: "标签类型", columnWidth: 100, columnSortable: false, showOverflowTooltip: true, fixed: "" }, |
|||
{ columnProp: "countFlagDesc", headerAlign: "center", align: "center", columnLabel: "盘点状态", columnWidth: 80, columnSortable: false, showOverflowTooltip: true, fixed: "" }, |
|||
{ columnProp: "countUser", headerAlign: "center", align: "center", columnLabel: "盘点人", columnWidth: 100, columnSortable: false, showOverflowTooltip: true, fixed: "" }, |
|||
{ columnProp: "countDate", headerAlign: "center", align: "center", columnLabel: "盘点时间", columnWidth: 140, columnSortable: false, showOverflowTooltip: true, fixed: "" }, |
|||
{ columnProp: "warehouseName", headerAlign: "center", align: "center", columnLabel: "仓库", columnWidth: 100, columnSortable: false, showOverflowTooltip: true, fixed: "" }, |
|||
{ columnProp: "locationName", headerAlign: "center", align: "center", columnLabel: "库位", columnWidth: 100, columnSortable: false, showOverflowTooltip: true, fixed: "" } |
|||
], |
|||
|
|||
// 栈板明细列配置 - rqrq |
|||
palletColumnList: [ |
|||
{ columnProp: "seqNo", headerAlign: "center", align: "center", columnLabel: "序号", columnWidth: 60, columnSortable: false, showOverflowTooltip: true, fixed: "" }, |
|||
{ columnProp: "palletId", headerAlign: "center", align: "center", columnLabel: "栈板号", columnWidth: 150, columnSortable: false, showOverflowTooltip: true, fixed: "" }, |
|||
{ columnProp: "labelCount", headerAlign: "center", align: "center", columnLabel: "标签数", columnWidth: 80, columnSortable: false, showOverflowTooltip: true, fixed: "" }, |
|||
{ columnProp: "checkedCount", headerAlign: "center", align: "center", columnLabel: "已盘点", columnWidth: 80, columnSortable: false, showOverflowTooltip: true, fixed: "" }, |
|||
{ columnProp: "progressPercent", headerAlign: "center", align: "center", columnLabel: "进度", columnWidth: 80, columnSortable: false, showOverflowTooltip: true, fixed: "" }, |
|||
{ columnProp: "countFlagDesc", headerAlign: "center", align: "center", columnLabel: "盘点状态", columnWidth: 80, columnSortable: false, showOverflowTooltip: true, fixed: "" }, |
|||
{ columnProp: "stationArea", headerAlign: "center", align: "center", columnLabel: "站点区域", columnWidth: 100, columnSortable: false, showOverflowTooltip: true, fixed: "" }, |
|||
{ columnProp: "stationId", headerAlign: "center", align: "center", columnLabel: "站点ID", columnWidth: 100, columnSortable: false, showOverflowTooltip: true, fixed: "" }, |
|||
{ columnProp: "locationZ", headerAlign: "center", align: "center", columnLabel: "所在层数", columnWidth: 80, columnSortable: false, showOverflowTooltip: true, fixed: "" }, |
|||
{ columnProp: "countUser", headerAlign: "center", align: "center", columnLabel: "盘点人", columnWidth: 100, columnSortable: false, showOverflowTooltip: true, fixed: "" }, |
|||
{ columnProp: "countDate", headerAlign: "center", align: "center", columnLabel: "盘点时间", columnWidth: 140, columnSortable: false, showOverflowTooltip: true, fixed: "" } |
|||
], |
|||
|
|||
// 盘点结果列配置 - rqrq |
|||
resultColumnList: [ |
|||
{ columnProp: "unitId", headerAlign: "center", align: "center", columnLabel: "标签号", columnWidth: 150, columnSortable: false, showOverflowTooltip: true, fixed: "" }, |
|||
{ columnProp: "partNo", headerAlign: "center", align: "center", columnLabel: "物料号", columnWidth: 120, columnSortable: false, showOverflowTooltip: true, fixed: "" }, |
|||
{ columnProp: "partDesc", headerAlign: "center", align: "left", columnLabel: "物料描述", columnWidth: 180, columnSortable: false, showOverflowTooltip: true, fixed: "" }, |
|||
{ columnProp: "qty", headerAlign: "center", align: "center", columnLabel: "数量", columnWidth: 80, columnSortable: false, showOverflowTooltip: true, fixed: "" }, |
|||
{ columnProp: "batchNo", headerAlign: "center", align: "center", columnLabel: "批号", columnWidth: 100, columnSortable: false, showOverflowTooltip: true, fixed: "" }, |
|||
{ columnProp: "palletId", headerAlign: "center", align: "center", columnLabel: "栈板号", columnWidth: 120, columnSortable: false, showOverflowTooltip: true, fixed: "" }, |
|||
{ columnProp: "countResultDesc", headerAlign: "center", align: "center", columnLabel: "盘点结果", columnWidth: 80, columnSortable: false, showOverflowTooltip: true, fixed: "" }, |
|||
{ columnProp: "countUser", headerAlign: "center", align: "center", columnLabel: "盘点人", columnWidth: 100, columnSortable: false, showOverflowTooltip: true, fixed: "" }, |
|||
{ columnProp: "countDate", headerAlign: "center", align: "center", columnLabel: "盘点时间", columnWidth: 140, columnSortable: false, showOverflowTooltip: true, fixed: "" }, |
|||
{ columnProp: "remark", headerAlign: "center", align: "left", columnLabel: "备注", columnWidth: 150, columnSortable: false, showOverflowTooltip: true, fixed: "" } |
|||
], |
|||
|
|||
// 物料汇总列配置 - rqrq |
|||
summaryColumnList: [ |
|||
{ columnProp: "partNo", headerAlign: "center", align: "center", columnLabel: "物料号", columnWidth: 120, columnSortable: false, showOverflowTooltip: true, fixed: "" }, |
|||
{ columnProp: "partDesc", headerAlign: "center", align: "left", columnLabel: "物料描述", columnWidth: 180, columnSortable: false, showOverflowTooltip: true, fixed: "" }, |
|||
{ columnProp: "batchNo", headerAlign: "center", align: "center", columnLabel: "批号", columnWidth: 100, columnSortable: false, showOverflowTooltip: true, fixed: "" }, |
|||
{ columnProp: "wdr", headerAlign: "center", align: "center", columnLabel: "WDR号", columnWidth: 120, columnSortable: false, showOverflowTooltip: true, fixed: "" }, |
|||
{ columnProp: "warehouseName", headerAlign: "center", align: "center", columnLabel: "仓库", columnWidth: 100, columnSortable: false, showOverflowTooltip: true, fixed: "" }, |
|||
{ columnProp: "locationName", headerAlign: "center", align: "center", columnLabel: "库位", columnWidth: 100, columnSortable: false, showOverflowTooltip: true, fixed: "" }, |
|||
{ columnProp: "labelCount", headerAlign: "center", align: "center", columnLabel: "标签数", columnWidth: 80, columnSortable: false, showOverflowTooltip: true, fixed: "" }, |
|||
{ columnProp: "totalQty", headerAlign: "center", align: "center", columnLabel: "总数量", columnWidth: 100, columnSortable: false, showOverflowTooltip: true, fixed: "" }, |
|||
{ columnProp: "palletCount", headerAlign: "center", align: "center", columnLabel: "栈板数", columnWidth: 80, columnSortable: false, showOverflowTooltip: true, fixed: "" }, |
|||
{ columnProp: "checkedLabelCount", headerAlign: "center", align: "center", columnLabel: "已盘点", columnWidth: 80, columnSortable: false, showOverflowTooltip: true, fixed: "" }, |
|||
{ columnProp: "progressPercent", headerAlign: "center", align: "center", columnLabel: "进度", columnWidth: 80, columnSortable: false, showOverflowTooltip: true, fixed: "" } |
|||
], |
|||
|
|||
// 任务单相关 - rqrq |
|||
taskList: [], |
|||
taskListLoading: false, |
|||
taskDetailList: [], |
|||
taskDetailListLoading: false, |
|||
currentTask: null, |
|||
|
|||
// 复核弹框相关 - rqrq |
|||
reviewDialogVisible: false, |
|||
reviewLoading: false, |
|||
reviewResultList: [], // 全部盘点结果 |
|||
filteredReviewResultList: [], // 过滤后的盘点结果 |
|||
onlyShowAbnormal: true, // 只看异常,默认勾选 |
|||
reviewType: 'CYCLE', // 复核类型:MANUAL=人工复核,CYCLE=循环复核 |
|||
selectedReviewLabels: [] // 选中的复核标签 |
|||
} |
|||
}, |
|||
mounted() { |
|||
// 计算表格高度 - rqrq |
|||
this.$nextTick(() => { |
|||
this.height = window.innerHeight - 340; |
|||
}) |
|||
this.loadCurrentCount() |
|||
}, |
|||
methods: { |
|||
// 加载当前盘点单 - rqrq |
|||
loadCurrentCount() { |
|||
this.headerLoading = true |
|||
const params = { |
|||
site: this.$store.state.user.site |
|||
} |
|||
getCurrentActiveCount(params).then(({ data }) => { |
|||
if (data && data.code === 0) { |
|||
this.headerData = data.row |
|||
if (this.headerData) { |
|||
this.loadTabData() |
|||
} else { |
|||
// 清空Tab数据 - rqrq |
|||
this.labelList = [] |
|||
this.palletList = [] |
|||
this.resultList = [] |
|||
this.summaryList = [] |
|||
} |
|||
} else { |
|||
this.$message.error(data.msg || '查询失败') |
|||
} |
|||
}).catch(() => { |
|||
this.$message.error('网络错误') |
|||
}).finally(() => { |
|||
this.headerLoading = false |
|||
}) |
|||
}, |
|||
|
|||
// Tab点击 - rqrq |
|||
tabClick() { |
|||
this.loadTabData() |
|||
}, |
|||
|
|||
// 加载Tab数据 - rqrq |
|||
loadTabData() { |
|||
if (!this.headerData) return |
|||
const params = { |
|||
site: this.$store.state.user.site, |
|||
countNo: this.headerData.countNo |
|||
} |
|||
|
|||
if (this.activeName === 'label') { |
|||
this.loadLabelList(params) |
|||
} else if (this.activeName === 'pallet') { |
|||
this.loadPalletList(params) |
|||
} else if (this.activeName === 'result') { |
|||
this.loadResultList(params) |
|||
} else if (this.activeName === 'summary') { |
|||
this.loadSummaryList(params) |
|||
} else if (this.activeName === 'task') { |
|||
this.loadTaskList(params) |
|||
} |
|||
}, |
|||
|
|||
// 加载标签明细 - rqrq |
|||
loadLabelList(params) { |
|||
this.labelListLoading = true |
|||
searchCountLabelList(params).then(({ data }) => { |
|||
if (data && data.code === 0) { |
|||
this.labelList = data.rows |
|||
} |
|||
}).finally(() => { |
|||
this.labelListLoading = false |
|||
}) |
|||
}, |
|||
|
|||
// 加载栈板明细 - rqrq |
|||
loadPalletList(params) { |
|||
this.palletListLoading = true |
|||
searchCountPalletList(params).then(({ data }) => { |
|||
if (data && data.code === 0) { |
|||
this.palletList = data.rows |
|||
} |
|||
}).finally(() => { |
|||
this.palletListLoading = false |
|||
}) |
|||
}, |
|||
|
|||
// 加载盘点结果 - rqrq |
|||
loadResultList(params) { |
|||
this.resultListLoading = true |
|||
searchCountResultList(params).then(({ data }) => { |
|||
if (data && data.code === 0) { |
|||
this.resultList = data.rows |
|||
} |
|||
}).finally(() => { |
|||
this.resultListLoading = false |
|||
}) |
|||
}, |
|||
|
|||
// 加载物料汇总 - rqrq |
|||
loadSummaryList(params) { |
|||
this.summaryListLoading = true |
|||
searchMaterialSummary(params).then(({ data }) => { |
|||
if (data && data.code === 0) { |
|||
this.summaryList = data.rows |
|||
} |
|||
}).finally(() => { |
|||
this.summaryListLoading = false |
|||
}) |
|||
}, |
|||
|
|||
// 加载任务单列表 - rqrq |
|||
loadTaskList(params) { |
|||
this.taskListLoading = true |
|||
this.taskList = [] |
|||
this.taskDetailList = [] |
|||
this.currentTask = null |
|||
searchOrderTaskByCountNo(params).then(({ data }) => { |
|||
if (data && data.code === 0) { |
|||
this.taskList = data.rows || [] |
|||
// 默认选中第一行 |
|||
if (this.taskList.length > 0) { |
|||
this.currentTask = this.taskList[0] |
|||
this.loadTaskDetailList() |
|||
} |
|||
} |
|||
}).finally(() => { |
|||
this.taskListLoading = false |
|||
}) |
|||
}, |
|||
|
|||
// 任务单行点击 - rqrq |
|||
onTaskRowClick(row) { |
|||
this.currentTask = row |
|||
this.loadTaskDetailList() |
|||
}, |
|||
|
|||
// 加载任务单明细 - rqrq |
|||
loadTaskDetailList() { |
|||
if (!this.currentTask) { |
|||
this.taskDetailList = [] |
|||
return |
|||
} |
|||
this.taskDetailListLoading = true |
|||
const params = { |
|||
site: this.$store.state.user.site, |
|||
taskNo: this.currentTask.taskNo |
|||
} |
|||
searchOrderTaskDetail(params).then(({ data }) => { |
|||
if (data && data.code === 0) { |
|||
this.taskDetailList = data.rows || [] |
|||
} |
|||
}).finally(() => { |
|||
this.taskDetailListLoading = false |
|||
}) |
|||
}, |
|||
|
|||
// 下达盘点单 - rqrq |
|||
handleRelease() { |
|||
if (!this.headerData) return |
|||
this.$confirm('确认下达盘点单 ' + this.headerData.countNo + '?', '提示', { |
|||
confirmButtonText: '确定', |
|||
cancelButtonText: '取消', |
|||
type: 'warning' |
|||
}).then(() => { |
|||
const params = { |
|||
site: this.$store.state.user.site, |
|||
countNo: this.headerData.countNo, |
|||
username: this.$store.state.user.name |
|||
} |
|||
releaseCount(params).then(({ data }) => { |
|||
if (data && data.code === 0) { |
|||
this.$message.success('下达成功') |
|||
this.loadCurrentCount() |
|||
} else { |
|||
this.$alert(data.msg || '下达失败', '提示', { type: 'error' }) |
|||
} |
|||
}).catch(() => { |
|||
this.$message.error('网络错误') |
|||
}) |
|||
}).catch(() => {}) |
|||
}, |
|||
|
|||
// 推送盘点单到WCS - rqrq |
|||
handlePush() { |
|||
if (!this.headerData) return |
|||
this.$confirm('确认推送盘点单 ' + this.headerData.countNo + ' 到WCS?将开始出库前10个栈板。', '提示', { |
|||
confirmButtonText: '确定', |
|||
cancelButtonText: '取消', |
|||
type: 'warning' |
|||
}).then(() => { |
|||
const params = { |
|||
site: this.$store.state.user.site, |
|||
countNo: this.headerData.countNo, |
|||
username: this.$store.state.user.name |
|||
} |
|||
pushCountToWcs(params).then(({ data }) => { |
|||
if (data && data.code === 0) { |
|||
this.$message.success('推送成功,本次推送栈板数: ' + data.result) |
|||
this.loadCurrentCount() |
|||
} else { |
|||
this.$alert(data.msg || '推送失败', '提示', { type: 'error' }) |
|||
} |
|||
}).catch(() => { |
|||
this.$message.error('网络错误') |
|||
}) |
|||
}).catch(() => {}) |
|||
}, |
|||
|
|||
// 继续推送 - rqrq |
|||
handleContinuePush() { |
|||
if (!this.headerData) return |
|||
this.$confirm('确认继续推送盘点单 ' + this.headerData.countNo + ' 的后续栈板到WCS?', '提示', { |
|||
confirmButtonText: '确定', |
|||
cancelButtonText: '取消', |
|||
type: 'warning' |
|||
}).then(() => { |
|||
const params = { |
|||
site: this.$store.state.user.site, |
|||
countNo: this.headerData.countNo, |
|||
username: this.$store.state.user.name |
|||
} |
|||
continuePushCount(params).then(({ data }) => { |
|||
if (data && data.code === 0) { |
|||
this.$message.success('推送成功,本次推送栈板数: ' + data.result) |
|||
this.loadCurrentCount() |
|||
} else { |
|||
this.$alert(data.msg || '推送失败', '提示', { type: 'error' }) |
|||
} |
|||
}).catch(() => { |
|||
this.$message.error('网络错误') |
|||
}) |
|||
}).catch(() => {}) |
|||
}, |
|||
|
|||
// 完成盘点单 - rqrq |
|||
handleComplete() { |
|||
if (!this.headerData) return |
|||
this.$confirm('确认完成盘点单 ' + this.headerData.countNo + '?', '提示', { |
|||
confirmButtonText: '确定', |
|||
cancelButtonText: '取消', |
|||
type: 'warning' |
|||
}).then(() => { |
|||
const params = { |
|||
site: this.$store.state.user.site, |
|||
countNo: this.headerData.countNo, |
|||
username: this.$store.state.user.name |
|||
} |
|||
completeCount(params).then(({ data }) => { |
|||
if (data && data.code === 0) { |
|||
this.$message.success('操作成功') |
|||
this.loadCurrentCount() |
|||
} else { |
|||
this.$alert(data.msg || '操作失败', '提示', { type: 'error' }) |
|||
} |
|||
}).catch(() => { |
|||
this.$message.error('网络错误') |
|||
}) |
|||
}).catch(() => {}) |
|||
}, |
|||
|
|||
// 取消盘点单 - rqrq |
|||
handleCancel() { |
|||
if (!this.headerData) return |
|||
this.$confirm('确认取消盘点单 ' + this.headerData.countNo + '?', '提示', { |
|||
confirmButtonText: '确定', |
|||
cancelButtonText: '取消', |
|||
type: 'warning' |
|||
}).then(() => { |
|||
const params = { |
|||
site: this.$store.state.user.site, |
|||
countNo: this.headerData.countNo, |
|||
username: this.$store.state.user.name |
|||
} |
|||
cancelCount(params).then(({ data }) => { |
|||
if (data && data.code === 0) { |
|||
this.$message.success('取消成功') |
|||
this.loadCurrentCount() |
|||
} else { |
|||
this.$alert(data.msg || '取消失败', '提示', { type: 'error' }) |
|||
} |
|||
}).catch(() => { |
|||
this.$message.error('网络错误') |
|||
}) |
|||
}).catch(() => {}) |
|||
}, |
|||
|
|||
// 格式化日期时间 - rqrq |
|||
formatDateTime(dateTime) { |
|||
if (!dateTime) return '' |
|||
const date = new Date(dateTime) |
|||
const year = date.getFullYear() |
|||
const month = String(date.getMonth() + 1).padStart(2, '0') |
|||
const day = String(date.getDate()).padStart(2, '0') |
|||
const hours = String(date.getHours()).padStart(2, '0') |
|||
const minutes = String(date.getMinutes()).padStart(2, '0') |
|||
return `${year}-${month}-${day} ${hours}:${minutes}` |
|||
}, |
|||
|
|||
// 获取状态颜色 - rqrq |
|||
getStatusColor(status) { |
|||
const colorMap = { |
|||
'DRAFT': '#909399', |
|||
'RELEASED': '#409EFF', |
|||
'CHECKING': '#E6A23C', |
|||
'COMPLETED': '#67C23A', |
|||
'CANCELLED': '#F56C6C' |
|||
} |
|||
return colorMap[status] || '#909399' |
|||
}, |
|||
|
|||
// 获取盘点结果颜色 - rqrq |
|||
getResultColor(result) { |
|||
const colorMap = { |
|||
'OK': '#67C23A', |
|||
'MISSING': '#F56C6C', |
|||
'SURPLUS': '#E6A23C' |
|||
} |
|||
return colorMap[result] || '#909399' |
|||
}, |
|||
|
|||
// 打开复核弹框 - rqrq |
|||
openReviewDialog() { |
|||
if (!this.headerData) return |
|||
|
|||
// 先检查是否存在未完成的任务单 |
|||
const checkParams = { |
|||
site: this.$store.state.user.site, |
|||
countNo: this.headerData.countNo |
|||
} |
|||
hasUncompletedTask(checkParams).then(({ data }) => { |
|||
if (data && data.code === 0) { |
|||
if (data.hasUncompleted) { |
|||
this.$alert('存在未完成的任务单,请等待任务完成后再创建复核单', '提示', { type: 'warning' }) |
|||
return |
|||
} |
|||
// 加载盘点结果 |
|||
this.loadReviewResultList() |
|||
} else { |
|||
this.$message.error(data.msg || '检查失败') |
|||
} |
|||
}).catch(() => { |
|||
this.$message.error('网络错误') |
|||
}) |
|||
}, |
|||
|
|||
// 加载复核盘点结果 - rqrq |
|||
loadReviewResultList() { |
|||
const params = { |
|||
site: this.$store.state.user.site, |
|||
countNo: this.headerData.countNo |
|||
} |
|||
searchCountResultList(params).then(({ data }) => { |
|||
if (data && data.code === 0) { |
|||
this.reviewResultList = data.rows || [] |
|||
this.filterReviewResult() |
|||
this.reviewDialogVisible = true |
|||
} else { |
|||
this.$message.error('加载盘点结果失败') |
|||
} |
|||
}).catch(() => { |
|||
this.$message.error('网络错误') |
|||
}) |
|||
}, |
|||
|
|||
// 过滤复核结果 - rqrq |
|||
filterReviewResult() { |
|||
if (this.onlyShowAbnormal) { |
|||
// 只看异常:过滤出MISSING和SURPLUS |
|||
this.filteredReviewResultList = this.reviewResultList.filter(item => item.countResult !== 'OK') |
|||
} else { |
|||
this.filteredReviewResultList = this.reviewResultList |
|||
} |
|||
}, |
|||
|
|||
// 复核选择变化 - rqrq |
|||
handleReviewSelectionChange(selection) { |
|||
this.selectedReviewLabels = selection |
|||
}, |
|||
|
|||
// 确认复核 - rqrq |
|||
confirmReview() { |
|||
if (this.selectedReviewLabels.length === 0) { |
|||
this.$message.warning('请选择需要复核的标签') |
|||
return |
|||
} |
|||
|
|||
// 获取选中标签涉及的栈板(去重) |
|||
const palletIds = [...new Set(this.selectedReviewLabels.map(item => item.palletId))] |
|||
const palletListStr = palletIds.join('、') |
|||
|
|||
this.$confirm(`确认要复核以下栈板?\n${palletListStr}`, '复核确认', { |
|||
confirmButtonText: '确定', |
|||
cancelButtonText: '取消', |
|||
type: 'warning' |
|||
}).then(() => { |
|||
this.reviewLoading = true |
|||
const params = { |
|||
site: this.$store.state.user.site, |
|||
countNo: this.headerData.countNo, |
|||
reviewType: this.reviewType, |
|||
palletIds: palletIds, |
|||
username: this.$store.state.user.name |
|||
} |
|||
createReviewTask(params).then(({ data }) => { |
|||
if (data && data.code === 0) { |
|||
this.$message.success('复核任务创建成功,任务号:' + data.taskNo) |
|||
this.reviewDialogVisible = false |
|||
// 刷新任务单页签 |
|||
if (this.activeName === 'task') { |
|||
this.loadTaskList({ |
|||
site: this.$store.state.user.site, |
|||
countNo: this.headerData.countNo |
|||
}) |
|||
} |
|||
} else { |
|||
this.$alert(data.msg || '创建复核任务失败', '提示', { type: 'error' }) |
|||
} |
|||
}).catch(() => { |
|||
this.$message.error('网络错误') |
|||
}).finally(() => { |
|||
this.reviewLoading = false |
|||
}) |
|||
}).catch(() => {}) |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style scoped> |
|||
.header-info { |
|||
background-color: #f5f7fa; |
|||
padding: 15px; |
|||
margin-bottom: 10px; |
|||
border-radius: 4px; |
|||
min-height: 100px; |
|||
} |
|||
.header-info /deep/ .el-form-item { |
|||
margin-bottom: 8px; |
|||
} |
|||
.header-info /deep/ .el-form-item__label { |
|||
font-size: 12px; |
|||
color: #606266; |
|||
padding-bottom: 2px; |
|||
} |
|||
.header-info /deep/ .el-input__inner { |
|||
background-color: #fff; |
|||
} |
|||
/deep/ .el-table a { |
|||
color: #409EFF; |
|||
cursor: pointer; |
|||
} |
|||
/deep/ .el-table a:hover { |
|||
text-decoration: underline; |
|||
} |
|||
</style> |
|||
|
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue