|
|
<template> <div class="mod-config"> <!-- 查询区:site 来自登录工厂,禁止手改 - rqrq --> <el-form ref="queryForm" :inline="true" label-position="top" style="margin-top: 1px; margin-left: 0px;"> <el-form-item label="工厂编码"> <el-input v-model="queryData.site" style="width: 100px" disabled></el-input> </el-form-item> <el-form-item label="托盘号"> <el-input v-model="queryData.searchPalletId" style="width: 140px" clearable placeholder="请输入托盘号" @keyup.enter.native="getDataList()"></el-input> </el-form-item> <el-form-item label="运输任务号"> <el-input v-model="queryData.searchTransportTaskNo" style="width: 160px" clearable placeholder="请输入运输任务号" @keyup.enter.native="getDataList()"></el-input> </el-form-item> <el-form-item label="状态"> <el-select v-model="queryData.searchStatus" placeholder="请选择" style="width: 120px" 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-select> </el-form-item> <el-form-item label="失败码"> <el-select v-model="queryData.searchErrorCode" placeholder="请选择" style="width: 130px" clearable> <el-option label="全部" value=""></el-option> <el-option label="无失败码" value="NONE"></el-option> <el-option label="移库失败" value="移库失败"></el-option> <el-option label="发料失败" value="发料失败"></el-option> <!-- 待核实独立筛选,避免现场把结果不确定的标签直接补发 - rqrq --> <el-option label="发料待核实" value="发料待核实"></el-option> </el-select> </el-form-item> <el-form-item label="创建时间从"> <el-date-picker v-model="queryData.searchStartDate" type="date" value-format="yyyy-MM-dd" style="width: 140px" clearable></el-date-picker> </el-form-item> <el-form-item label="创建时间至"> <el-date-picker v-model="queryData.searchEndDate" type="date" value-format="yyyy-MM-dd" style="width: 140px" clearable></el-date-picker> </el-form-item> <el-form-item label=" "> <el-button type="primary" :loading="dataListLoading" :disabled="dataListLoading" @click="getDataList()">查询</el-button> <el-button :disabled="dataListLoading" @click="resetQuery()">重置</el-button> </el-form-item> </el-form>
<el-table ref="mainTable" :data="dataList" :height="height" border highlight-current-row v-loading="dataListLoading" :row-class-name="tableRowClassName" style="width: 100%;" @row-click="handleRowClick"> <el-table-column prop="id" label="任务ID" 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="transportTaskNo" label="运输任务号" min-width="140" header-align="center" align="center"></el-table-column> <el-table-column prop="status" label="状态" min-width="90" header-align="center" align="center"> <template slot-scope="scope"> <el-tag :type="getStatusTagType(scope.row.status, scope.row.errorCode)" size="small">{{ scope.row.status || '-' }}</el-tag> </template> </el-table-column> <el-table-column prop="errorCode" label="失败码" min-width="100" header-align="center" align="center"> <template slot-scope="scope"> <span :style="scope.row.errorCode ? 'color:#F56C6C' : ''">{{ scope.row.errorCode || '-' }}</span> </template> </el-table-column> <el-table-column prop="labelCount" label="标签数" min-width="80" header-align="center" align="center"> <template slot-scope="scope">{{ formatCount(scope.row.labelCount) }}</template> </el-table-column> <el-table-column label="成功/失败" min-width="100" header-align="center" align="center"> <template slot-scope="scope">{{ formatCount(scope.row.successCount) }} / {{ formatCount(scope.row.failCount) }}</template> </el-table-column> <el-table-column prop="unbindCount" label="已解绑" min-width="80" header-align="center" align="center"> <template slot-scope="scope">{{ formatCount(scope.row.unbindCount) }}</template> </el-table-column> <!-- 待核实数量来自后端 U 状态聚合,单位张,与普通失败分开展示 - rqrq --> <el-table-column prop="unknownCount" label="待核实" min-width="80" header-align="center" align="center"> <template slot-scope="scope">{{ formatCount(scope.row.unknownCount) }}</template> </el-table-column> <el-table-column prop="errorMsg" label="错误说明" min-width="180" header-align="center" align="left" show-overflow-tooltip></el-table-column> <el-table-column prop="createdTime" label="创建时间" min-width="160" header-align="center" align="center"> <template slot-scope="scope">{{ formatDateTime(scope.row.createdTime) }}</template> </el-table-column> <el-table-column prop="processedTime" label="完结时间" min-width="160" header-align="center" align="center"> <template slot-scope="scope">{{ formatDateTime(scope.row.processedTime) }}</template> </el-table-column> </el-table>
<el-pagination ref="pagination" @size-change="sizeChangeHandle" @current-change="currentChangeHandle" :current-page="pageIndex" :page-sizes="[20, 50, 100, 1000]" :page-size="pageSize" :total="totalPage" layout="total, sizes, prev, pager, next, jumper"> </el-pagination>
<!-- 主表与详情页签平分可用高度;未选任务也保留固定页签区域,长错误仅在表格提示中展示 - rqrq --> <div ref="detailPanel" class="detail-panel" :style="{ height: height + 'px' }"> <el-tabs ref="detailTabs" v-model="activeTab" @tab-click="updateTableHeights"> <el-tab-pane label="标签明细" name="label"> <el-table ref="labelTable" :data="labelList" border v-loading="labelListLoading" :height="detailHeight" :empty-text="currentTask.id ? '暂无标签明细' : '请选择一条任务'" style="width: 100%;"> <el-table-column prop="serialNo" label="标签号" min-width="140" 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="notifyNo" label="申请单号" min-width="140" header-align="center" align="center"></el-table-column> <!-- 工单三字段取定时建单已保存的标签快照,空来源保持空白,避免实时关联改变历史任务展示 - rqrq --> <el-table-column prop="orderNo" label="order_no" min-width="140" header-align="center" align="center"></el-table-column> <el-table-column prop="releaseNo" label="release_no" min-width="110" header-align="center" align="center"></el-table-column> <el-table-column prop="sequenceNo" label="sequence_no" min-width="110" header-align="center" align="center"></el-table-column> <!-- 移库结果在全部队列结束进入下一阶段时保存;等待时显示-,不根据主任务失败码把所有标签判成失败 - rqrq --> <el-table-column prop="moveFlag" label="移库" min-width="80" header-align="center" align="center"> <template slot-scope="scope"> <el-tag :type="getIssueFlagTag(scope.row.moveFlag)" size="small">{{ getMoveResultLabel(scope.row.moveFlag) }}</el-tag> </template> </el-table-column> <el-table-column prop="issueFlag" label="发料" min-width="120" header-align="center" align="center"> <template slot-scope="scope"> <!-- U仍保留后台待核实保护,页面归为处理中并明确提示,禁止现场误当未发料再次发送 - rqrq --> <el-tooltip :disabled="scope.row.issueFlag !== 'U'" content="发料结果待核实,禁止自动重发" placement="top"> <el-tag :type="getIssueFlagTag(scope.row.issueFlag)" size="small">{{ getIssueFlagLabel(scope.row.issueFlag) }}</el-tag> </el-tooltip> </template> </el-table-column> <el-table-column prop="unbindFlag" label="解绑" min-width="80" header-align="center" align="center"> <!-- 解绑只展示是/否,与移库、发料结果独立,不再显示重复的留盘列 - rqrq --> <template slot-scope="scope">{{ scope.row.unbindFlag === 'Y' ? '是' : '否' }}</template> </el-table-column><!-- <el-table-column prop="errorMsg" label="失败原因" min-width="180" header-align="center" align="left" show-overflow-tooltip></el-table-column>--> <el-table-column prop="updatedTime" label="更新时间" min-width="160" header-align="center" align="center"> <template slot-scope="scope">{{ formatDateTime(scope.row.updatedTime) }}</template> </el-table-column> </el-table> </el-tab-pane> <el-tab-pane label="移库队列" name="move"> <!-- 无关联记录只表示本任务没有队列关联,不据此断言 IFS 已完成 - rqrq --> <el-table ref="moveTable" :data="moveList" border v-loading="moveListLoading" :height="detailHeight" :empty-text="currentTask.id ? '暂无关联移库队列' : '请选择一条任务'" style="width: 100%;"> <!-- 五列均取关联haian_ifs_pallet_move_queue;长标签串/JSON/说明悬浮查看,移库时间只取队列updated_time - rqrq --> <el-table-column prop="serialNoStr" label="标签串" min-width="220" header-align="center" align="left" show-overflow-tooltip></el-table-column> <el-table-column prop="resultFlag" label="结果" min-width="80" header-align="center" align="center"> <template slot-scope="scope">{{ getMoveResultLabel(scope.row.resultFlag) }}</template> </el-table-column><!-- <el-table-column prop="moveGroupJson" label="移库JSON" min-width="300" header-align="center" align="left" show-overflow-tooltip></el-table-column>--> <el-table-column prop="resultMsg" label="结果说明" min-width="220" header-align="center" align="left" show-overflow-tooltip></el-table-column> <el-table-column prop="updatedTime" label="移库时间" min-width="160" header-align="center" align="center"> <template slot-scope="scope">{{ formatDateTime(scope.row.updatedTime) }}</template> </el-table-column> </el-table> </el-tab-pane> </el-tabs> </div> </div></template>
<script>import { getAutoIssueTaskPage, getAutoIssueTaskLabelList, getAutoIssueMoveRefList} from '@/api/haianWarehouse/autoIssueTask.js'
export default { name: 'autoIssueTask54', data () { return { queryData: { site: this.$store.state.user.site, searchPalletId: '', searchTransportTaskNo: '', searchStatus: '', searchErrorCode: '', searchStartDate: '', searchEndDate: '', page: 1, limit: 20 }, dataList: [], pageIndex: 1, pageSize: 20, totalPage: 0, dataListLoading: false, height: 280, detailHeight: 220, currentTask: {}, activeTab: 'label', labelList: [], labelListLoading: false, moveList: [], moveListLoading: false } }, mounted () { // 跟随窗口与查询区换行重算高度;观察查询区避免表格自身高度变化触发循环 - rqrq
window.addEventListener('resize', this.updateTableHeights) if (window.ResizeObserver) { this.queryResizeObserver = new window.ResizeObserver(this.updateTableHeights) this.queryResizeObserver.observe(this.$refs.queryForm.$el) } this.updateTableHeights() }, activated () { // keep-alive 页面重新显示时恢复真实尺寸,再按当前工厂查询 - rqrq
this.updateTableHeights() this.queryData.site = this.$store.state.user.site this.getDataList() }, beforeDestroy () { // 释放窗口与尺寸观察监听,避免关闭页签后继续访问已销毁表格 - rqrq
window.removeEventListener('resize', this.updateTableHeights) if (this.queryResizeObserver) { this.queryResizeObserver.disconnect() } }, methods: { // 扣除查询区、分页、边距后,主表与下方页签各占一半;详情表扣除页签头,数据在表内滚动 - rqrq
updateTableHeights () { this.$nextTick(() => { if (this._isDestroyed || !this.$el.offsetWidth || !this.$refs.mainTable) { return } const pagination = this.$refs.pagination.$el const paginationStyle = window.getComputedStyle(pagination) const panelStyle = window.getComputedStyle(this.$refs.detailPanel) const tabHeader = this.$refs.detailTabs.$el.querySelector('.el-tabs__header') const headerStyle = window.getComputedStyle(tabHeader) const number = value => parseFloat(value) || 0 const paginationHeight = pagination.offsetHeight + number(paginationStyle.marginTop) + number(paginationStyle.marginBottom) const panelSpacing = number(panelStyle.marginTop) + number(panelStyle.marginBottom) const availableHeight = window.innerHeight - this.$refs.mainTable.$el.getBoundingClientRect().top - paginationHeight - panelSpacing - 20 this.height = Math.max(140, Math.floor(availableHeight / 2)) const panelPadding = number(panelStyle.paddingTop) + number(panelStyle.paddingBottom) + number(panelStyle.borderTopWidth) + number(panelStyle.borderBottomWidth) const headerHeight = tabHeader.offsetHeight + number(headerStyle.marginTop) + number(headerStyle.marginBottom) this.detailHeight = Math.max(60, this.height - panelPadding - headerHeight) // 切换页签后重排当前表格,防止隐藏页签首次显示时列宽或滚动条错位 - rqrq
this.$nextTick(() => { if (this._isDestroyed) return this.$refs.mainTable.doLayout() const detailTable = this.activeTab === 'move' ? this.$refs.moveTable : this.$refs.labelTable if (detailTable) detailTable.doLayout() }) }) }, // 查询主表:先写 site 再请求,失败清空列表避免展示过期数据 - rqrq
getDataList () { if (this.dataListLoading) { return } if (!this.queryData.site) { this.$alert('缺少site,无法查询', '提示') return } this.dataListLoading = true this.queryData.page = this.pageIndex this.queryData.limit = this.pageSize this.queryData.site = this.$store.state.user.site getAutoIssueTaskPage(this.queryData).then(({ data }) => { if (data && data.code === 0) { this.dataList = (data.page && data.page.list) || [] this.totalPage = (data.page && data.page.totalCount) || 0 } else { this.dataList = [] this.totalPage = 0 this.$alert((data && data.msg) || '查询失败', '提示') } this.clearDetail() }).catch(() => { this.dataList = [] this.totalPage = 0 this.clearDetail() this.$message.error('查询异常') }).finally(() => { this.dataListLoading = false }) }, // 重置筛选后从第一页重查 - rqrq
resetQuery () { if (this.dataListLoading) { return } this.queryData = { site: this.$store.state.user.site, searchPalletId: '', searchTransportTaskNo: '', searchStatus: '', searchErrorCode: '', searchStartDate: '', searchEndDate: '', page: 1, limit: this.pageSize } this.pageIndex = 1 this.getDataList() }, sizeChangeHandle (val) { this.pageSize = val this.pageIndex = 1 this.getDataList() }, currentChangeHandle (val) { this.pageIndex = val this.getDataList() }, // 点主表行加载标签与移库关联,只刷明细 loading - rqrq
handleRowClick (row) { if (!row || !row.id) { return } this.currentTask = Object.assign({}, row) this.activeTab = 'label' this.loadLabelList() this.loadMoveList() }, loadLabelList () { const taskId = this.currentTask.id this.labelListLoading = true getAutoIssueTaskLabelList({ site: this.$store.state.user.site, searchIssueTaskId: taskId }).then(({ data }) => { if (this.currentTask.id !== taskId) { return } if (data && data.code === 0) { this.labelList = data.rows || [] } else { this.labelList = [] this.$alert((data && data.msg) || '查询标签明细失败', '提示') } }).catch(() => { if (this.currentTask.id !== taskId) { return } this.labelList = [] this.$message.error('查询标签明细异常') }).finally(() => { if (this.currentTask.id === taskId) { this.labelListLoading = false } }) }, loadMoveList () { const taskId = this.currentTask.id this.moveListLoading = true getAutoIssueMoveRefList({ site: this.$store.state.user.site, searchIssueTaskId: taskId }).then(({ data }) => { if (this.currentTask.id !== taskId) { return } if (data && data.code === 0) { this.moveList = data.rows || [] } else { this.moveList = [] this.$alert((data && data.msg) || '查询移库关联失败', '提示') } }).catch(() => { if (this.currentTask.id !== taskId) { return } this.moveList = [] this.$message.error('查询移库关联异常') }).finally(() => { if (this.currentTask.id === taskId) { this.moveListLoading = false } }) }, clearDetail () { // 清空选择后旧请求会被任务ID校验忽略,固定详情区的 loading 必须同步复位 - rqrq
this.currentTask = {} this.labelList = [] this.moveList = [] this.labelListLoading = false this.moveListLoading = false }, formatCount (value) { if (value === null || value === undefined || value === '') { return 0 } return value }, formatDateTime (value) { if (!value) { return '' } const date = new Date(value) if (isNaN(date.getTime())) { return value } const pad = num => (num < 10 ? '0' + num : '' + num) return date.getFullYear() + '-' + pad(date.getMonth() + 1) + '-' + pad(date.getDate()) + ' ' + pad(date.getHours()) + ':' + pad(date.getMinutes()) + ':' + pad(date.getSeconds()) }, getStatusTagType (status, errorCode) { if (errorCode) { return 'danger' } if (status === '已完成') { return 'success' } if (status === '待发料') { return 'warning' } if (status === '处理中') { return 'info' } return '' }, tableRowClassName ({ row }) { if (row && row.errorCode) { return 'error-row' } return '' }, // 发料展示统一四态;P请求已开始、U结果待核实均为处理中,U另有悬浮提示,后台防重语义保留 - rqrq
getIssueFlagLabel (flag) { if (flag === 'P') { return '处理中' } if (flag === 'U') { return '处理中' } if (flag === 'S') { return '成功' } if (flag === 'F') { return '失败' } return '未发料' }, // 不确定状态使用警示色,提示先核实 IFS,禁止据此自动补发 - rqrq
getIssueFlagTag (flag) { if (flag === 'P' || flag === 'U') { return 'warning' } if (flag === 'S') { return 'success' } if (flag === 'F') { return 'danger' } return 'info' }, // 留盘仅以解绑标记为准,S+N 表示成功后尚未解绑,仍必须显示留盘 - rqrq
isRemainOnPallet (row) { if (!row) { return false } return row.unbindFlag !== 'Y' }, getMoveResultLabel (flag) { if (flag === 'S') { return '成功' } if (flag === 'F') { return '失败' } return flag || '-' } }}</script>
<style scoped>.mod-config { padding: 10px;}.detail-panel { margin-top: 12px; padding: 10px; border: 1px solid #ebeef5; background: #fff; box-sizing: border-box;} /deep/ .el-table .error-row { background: #fef0f0;}</style>
|