|
|
@@ -2,16 +2,102 @@
|
|
|
<el-dialog
|
|
|
:title="dialogTitle"
|
|
|
:visible.sync="visible"
|
|
|
- width="1050px"
|
|
|
+ width="92%"
|
|
|
:close-on-click-modal="false"
|
|
|
@close="reset"
|
|
|
>
|
|
|
<template v-if="mode === 'records'">
|
|
|
+ <el-form
|
|
|
+ size="mini"
|
|
|
+ label-width="72px"
|
|
|
+ class="record-search"
|
|
|
+ @submit.native.prevent="searchRecords"
|
|
|
+ >
|
|
|
+ <el-row :gutter="16">
|
|
|
+ <el-col :xs="24" :md="12" :lg="5">
|
|
|
+ <el-form-item label="审核代码">
|
|
|
+ <el-input
|
|
|
+ v-model="recordQuery.changeNo"
|
|
|
+ clearable
|
|
|
+ placeholder="请输入审核代码"
|
|
|
+ />
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ <el-col :xs="24" :md="12" :lg="5">
|
|
|
+ <el-form-item label="审批人">
|
|
|
+ <el-input
|
|
|
+ v-model="recordQuery.approverName"
|
|
|
+ clearable
|
|
|
+ placeholder="请输入审批人"
|
|
|
+ />
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ <el-col :xs="24" :md="12" :lg="5">
|
|
|
+ <el-form-item label="仓库名称">
|
|
|
+ <el-input
|
|
|
+ v-model="recordQuery.warehouseName"
|
|
|
+ clearable
|
|
|
+ placeholder="请输入仓库名称"
|
|
|
+ />
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ <el-col :xs="24" :md="12" :lg="5">
|
|
|
+ <el-form-item label="批次号">
|
|
|
+ <el-input
|
|
|
+ v-model="recordQuery.batchNo"
|
|
|
+ clearable
|
|
|
+ placeholder="请输入批次号"
|
|
|
+ />
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ <el-col :xs="24" :md="12" :lg="5">
|
|
|
+ <el-form-item label="物品编码">
|
|
|
+ <el-input
|
|
|
+ v-model="recordQuery.categoryCode"
|
|
|
+ clearable
|
|
|
+ placeholder="请输入物品编码"
|
|
|
+ />
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ <el-col :xs="24" :md="12" :lg="5">
|
|
|
+ <el-form-item label="类型">
|
|
|
+ <el-select
|
|
|
+ v-model="recordQuery.changeType"
|
|
|
+ clearable
|
|
|
+ placeholder="请选择类型"
|
|
|
+ >
|
|
|
+ <el-option label="拆批" :value="1" />
|
|
|
+ <el-option label="合批" :value="2" />
|
|
|
+ </el-select>
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ <el-col :xs="24" :md="12" :lg="5">
|
|
|
+ <el-form-item label="审批状态">
|
|
|
+ <el-select
|
|
|
+ v-model="recordQuery.verifyStatus"
|
|
|
+ clearable
|
|
|
+ placeholder="请选择审批状态"
|
|
|
+ >
|
|
|
+ <el-option
|
|
|
+ v-for="item in verifyStatusOptions"
|
|
|
+ :key="item.value"
|
|
|
+ :label="item.label"
|
|
|
+ :value="item.value"
|
|
|
+ />
|
|
|
+ </el-select>
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ <el-col :xs="24" :lg="4" class="record-search-actions">
|
|
|
+ <el-button type="primary" @click="searchRecords">查询</el-button>
|
|
|
+ <el-button @click="resetRecordQuery">重置</el-button>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+ </el-form>
|
|
|
<ele-pro-table
|
|
|
ref="recordTable"
|
|
|
:columns="recordColumns"
|
|
|
:datasource="recordSource"
|
|
|
- height="450px"
|
|
|
+ height="600px"
|
|
|
:pageSize="10"
|
|
|
>
|
|
|
<template v-slot:status="{ row }">
|
|
|
@@ -43,6 +129,7 @@
|
|
|
<el-alert
|
|
|
v-if="mode === 'merge'"
|
|
|
title="仅允许同仓库、批次号、物品属性、供应商和价格完全一致的库存合批,审批通过后生成新系统批次。"
|
|
|
+ style="color: red"
|
|
|
type="info"
|
|
|
:closable="false"
|
|
|
/>
|
|
|
@@ -64,7 +151,7 @@
|
|
|
<el-table :data="sources" size="mini" border>
|
|
|
<el-table-column
|
|
|
prop="systemBatchNo"
|
|
|
- label="来源系统批次"
|
|
|
+ label="来源系统批次号"
|
|
|
min-width="150"
|
|
|
/>
|
|
|
<el-table-column prop="batchNo" label="业务批次" />
|
|
|
@@ -94,6 +181,8 @@
|
|
|
:disabled="Boolean(pendingApproveId)"
|
|
|
size="mini"
|
|
|
placeholder="请输入"
|
|
|
+ @input="markMeasureQuantityManual(row.target)"
|
|
|
+ @blur="validateTargetLimit(row.target, 'measureQuantity')"
|
|
|
/>
|
|
|
</template>
|
|
|
</el-table-column>
|
|
|
@@ -118,6 +207,7 @@
|
|
|
:disabled="Boolean(pendingApproveId)"
|
|
|
size="mini"
|
|
|
placeholder="请输入"
|
|
|
+ @blur="validateTargetLimit(row.target, 'weight')"
|
|
|
/>
|
|
|
</template>
|
|
|
</el-table-column>
|
|
|
@@ -149,7 +239,43 @@
|
|
|
|
|
|
<template v-if="packingRows.length">
|
|
|
<div class="section-title">整包装分配</div>
|
|
|
- <el-table :data="packingRows" size="mini" border max-height="260">
|
|
|
+ <div v-if="mode === 'split'" class="packing-batch-actions">
|
|
|
+ <span>已选择 {{ selectedPackingRows.length }} 个整包装</span>
|
|
|
+ <el-select
|
|
|
+ v-model="batchPackingTargetId"
|
|
|
+ size="mini"
|
|
|
+ :disabled="Boolean(pendingApproveId)"
|
|
|
+ placeholder="请选择目标子批次"
|
|
|
+ >
|
|
|
+ <el-option
|
|
|
+ v-for="target in targets"
|
|
|
+ :key="target.targetDetailId"
|
|
|
+ :label="targetLabel(target.targetDetailId)"
|
|
|
+ :value="target.targetDetailId"
|
|
|
+ />
|
|
|
+ </el-select>
|
|
|
+ <el-button
|
|
|
+ type="primary"
|
|
|
+ size="mini"
|
|
|
+ :disabled="Boolean(pendingApproveId)"
|
|
|
+ @click="assignSelectedPackingTarget"
|
|
|
+ >批量分配</el-button
|
|
|
+ >
|
|
|
+ </div>
|
|
|
+ <el-table
|
|
|
+ ref="packingTable"
|
|
|
+ :data="packingRows"
|
|
|
+ size="mini"
|
|
|
+ border
|
|
|
+ max-height="260"
|
|
|
+ @selection-change="handlePackingSelectionChange"
|
|
|
+ >
|
|
|
+ <el-table-column
|
|
|
+ v-if="mode === 'split'"
|
|
|
+ type="selection"
|
|
|
+ width="45"
|
|
|
+ :selectable="packingRowSelectable"
|
|
|
+ />
|
|
|
<el-table-column
|
|
|
prop="systemBatchNo"
|
|
|
label="来源系统批次"
|
|
|
@@ -243,68 +369,178 @@
|
|
|
<el-dialog
|
|
|
title="批次变更申请详情"
|
|
|
:visible.sync="detailVisible"
|
|
|
- width="850px"
|
|
|
+ width="95%"
|
|
|
append-to-body
|
|
|
>
|
|
|
- <el-descriptions
|
|
|
- v-loading="detailLoading"
|
|
|
- :column="3"
|
|
|
- border
|
|
|
- size="small"
|
|
|
- >
|
|
|
- <el-descriptions-item label="审核代码">{{
|
|
|
- detailData.changeNo || '-'
|
|
|
- }}</el-descriptions-item>
|
|
|
- <el-descriptions-item label="变更类型">{{
|
|
|
- detailData.changeType === 1 ? '拆批' : '合批'
|
|
|
- }}</el-descriptions-item>
|
|
|
- <el-descriptions-item label="审批状态">{{
|
|
|
- statusText(detailData.verifyStatus)
|
|
|
- }}</el-descriptions-item>
|
|
|
- <el-descriptions-item label="仓库">{{
|
|
|
- detailData.warehouseName || '-'
|
|
|
- }}</el-descriptions-item>
|
|
|
- <el-descriptions-item label="申请时间">{{
|
|
|
- detailData.createTime || '-'
|
|
|
- }}</el-descriptions-item>
|
|
|
- <el-descriptions-item label="说明">{{
|
|
|
- detailData.remark || '-'
|
|
|
- }}</el-descriptions-item>
|
|
|
- </el-descriptions>
|
|
|
- <el-table
|
|
|
- :data="detailData.details || []"
|
|
|
- size="mini"
|
|
|
- border
|
|
|
- class="detail-table"
|
|
|
- >
|
|
|
- <el-table-column prop="sourceStockBatchId" label="来源批次ID" />
|
|
|
- <el-table-column
|
|
|
- prop="systemBatchNo"
|
|
|
- label="来源系统批次"
|
|
|
- min-width="140"
|
|
|
- />
|
|
|
- <el-table-column
|
|
|
- prop="targetSystemBatchNo"
|
|
|
- label="目标系统批次"
|
|
|
- min-width="140"
|
|
|
- />
|
|
|
- <el-table-column prop="measureQuantity" label="计量数量" />
|
|
|
- <el-table-column prop="packageQuantity" label="包装数量" />
|
|
|
- <el-table-column prop="weight" label="重量" />
|
|
|
- <el-table-column prop="lockQuantity" label="锁库数量" />
|
|
|
- <el-table-column
|
|
|
- prop="packingStockIds"
|
|
|
- label="包装库存分配"
|
|
|
- min-width="180"
|
|
|
- show-overflow-tooltip
|
|
|
- />
|
|
|
- <el-table-column
|
|
|
- prop="lockAllocations"
|
|
|
- label="锁定单分配"
|
|
|
- min-width="220"
|
|
|
- show-overflow-tooltip
|
|
|
- />
|
|
|
- </el-table>
|
|
|
+ <el-tabs v-model="detailTab" v-loading="detailLoading">
|
|
|
+ <el-tab-pane label="业务详情" name="business">
|
|
|
+ <el-descriptions :column="3" border size="small">
|
|
|
+ <el-descriptions-item label="审核代码">{{
|
|
|
+ detailData.changeNo || '-'
|
|
|
+ }}</el-descriptions-item>
|
|
|
+ <el-descriptions-item label="变更类型">{{
|
|
|
+ detailData.changeType === 1 ? '拆批' : '合批'
|
|
|
+ }}</el-descriptions-item>
|
|
|
+ <el-descriptions-item label="审批状态">{{
|
|
|
+ statusText(detailData.verifyStatus)
|
|
|
+ }}</el-descriptions-item>
|
|
|
+ <el-descriptions-item label="当前审批人">{{
|
|
|
+ detailData.currentApproverName || '-'
|
|
|
+ }}</el-descriptions-item>
|
|
|
+ <el-descriptions-item label="仓库">{{
|
|
|
+ detailData.warehouseName || '-'
|
|
|
+ }}</el-descriptions-item>
|
|
|
+ <el-descriptions-item label="申请时间">{{
|
|
|
+ detailData.createTime || '-'
|
|
|
+ }}</el-descriptions-item>
|
|
|
+ <el-descriptions-item label="说明">{{
|
|
|
+ detailData.remark || '-'
|
|
|
+ }}</el-descriptions-item>
|
|
|
+ </el-descriptions>
|
|
|
+ <el-table
|
|
|
+ :data="detailData.details || []"
|
|
|
+ size="mini"
|
|
|
+ border
|
|
|
+ class="detail-table"
|
|
|
+ >
|
|
|
+ <el-table-column
|
|
|
+ prop="systemBatchNo"
|
|
|
+ label="来源系统批次号"
|
|
|
+ min-width="140"
|
|
|
+ >
|
|
|
+ <template slot-scope="{ row }">{{
|
|
|
+ displayValue(row.systemBatchNo)
|
|
|
+ }}</template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column prop="batchNo" label="业务批次" min-width="110">
|
|
|
+ <template slot-scope="{ row }">{{
|
|
|
+ displayValue(row.batchNo)
|
|
|
+ }}</template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column
|
|
|
+ prop="warehouseName"
|
|
|
+ label="仓库名称"
|
|
|
+ min-width="120"
|
|
|
+ >
|
|
|
+ <template slot-scope="{ row }">{{
|
|
|
+ displayValue(row.warehouseName)
|
|
|
+ }}</template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column
|
|
|
+ prop="categoryCode"
|
|
|
+ label="物品编码"
|
|
|
+ min-width="120"
|
|
|
+ >
|
|
|
+ <template slot-scope="{ row }">{{
|
|
|
+ displayValue(row.categoryCode)
|
|
|
+ }}</template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column
|
|
|
+ prop="categoryName"
|
|
|
+ label="物品名称"
|
|
|
+ min-width="120"
|
|
|
+ >
|
|
|
+ <template slot-scope="{ row }">{{
|
|
|
+ displayValue(row.categoryName)
|
|
|
+ }}</template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column prop="specification" label="规格" min-width="100">
|
|
|
+ <template slot-scope="{ row }">{{
|
|
|
+ displayValue(row.specification)
|
|
|
+ }}</template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column prop="categoryModel" label="型号" min-width="100">
|
|
|
+ <template slot-scope="{ row }">{{
|
|
|
+ displayValue(row.categoryModel)
|
|
|
+ }}</template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column prop="brandNum" label="牌号" min-width="100">
|
|
|
+ <template slot-scope="{ row }">{{
|
|
|
+ displayValue(row.brandNum)
|
|
|
+ }}</template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column prop="colorKey" label="颜色" min-width="100">
|
|
|
+ <template slot-scope="{ row }">{{
|
|
|
+ displayValue(row.colorKey)
|
|
|
+ }}</template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column prop="unitPrice" label="单价" min-width="100">
|
|
|
+ <template slot-scope="{ row }">{{
|
|
|
+ displayValue(row.unitPrice)
|
|
|
+ }}</template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column
|
|
|
+ prop="supplierName"
|
|
|
+ label="供应商名称"
|
|
|
+ min-width="130"
|
|
|
+ >
|
|
|
+ <template slot-scope="{ row }">{{
|
|
|
+ displayValue(row.supplierName)
|
|
|
+ }}</template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column
|
|
|
+ prop="supplierCode"
|
|
|
+ label="供应商代号"
|
|
|
+ min-width="120"
|
|
|
+ >
|
|
|
+ <template slot-scope="{ row }">{{
|
|
|
+ displayValue(row.supplierCode)
|
|
|
+ }}</template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column
|
|
|
+ prop="targetSystemBatchNo"
|
|
|
+ label="目标系统批次"
|
|
|
+ min-width="140"
|
|
|
+ >
|
|
|
+ <template slot-scope="{ row }">{{
|
|
|
+ displayValue(row.targetSystemBatchNo || targetBatchText(row))
|
|
|
+ }}</template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column
|
|
|
+ prop="measureQuantity"
|
|
|
+ label="计量数量"
|
|
|
+ min-width="100"
|
|
|
+ >
|
|
|
+ <template slot-scope="{ row }">{{
|
|
|
+ displayValue(row.measureQuantity)
|
|
|
+ }}</template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column
|
|
|
+ prop="packageQuantity"
|
|
|
+ label="包装数量"
|
|
|
+ min-width="100"
|
|
|
+ >
|
|
|
+ <template slot-scope="{ row }">{{
|
|
|
+ displayValue(row.packageQuantity)
|
|
|
+ }}</template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column prop="weight" label="重量" min-width="90">
|
|
|
+ <template slot-scope="{ row }">{{
|
|
|
+ displayValue(row.weight)
|
|
|
+ }}</template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column
|
|
|
+ prop="lockQuantity"
|
|
|
+ label="锁库数量"
|
|
|
+ min-width="100"
|
|
|
+ >
|
|
|
+ <template slot-scope="{ row }">{{
|
|
|
+ displayValue(row.lockQuantity)
|
|
|
+ }}</template>
|
|
|
+ </el-table-column>
|
|
|
+ </el-table>
|
|
|
+ </el-tab-pane>
|
|
|
+ <el-tab-pane
|
|
|
+ v-if="detailProcessInstanceId"
|
|
|
+ label="流程详情"
|
|
|
+ name="process"
|
|
|
+ >
|
|
|
+ <bpm-detail
|
|
|
+ v-if="detailTab === 'process'"
|
|
|
+ :id="detailProcessInstanceId"
|
|
|
+ />
|
|
|
+ </el-tab-pane>
|
|
|
+ </el-tabs>
|
|
|
</el-dialog>
|
|
|
</el-dialog>
|
|
|
</template>
|
|
|
@@ -312,6 +548,7 @@
|
|
|
<script>
|
|
|
import BigNumber from 'bignumber.js';
|
|
|
import stockBatchChange from '@/api/warehouseManagement/stockBatchChange';
|
|
|
+ import bpmDetail from '@/views/bpm/processInstance/detail.vue';
|
|
|
|
|
|
function decimal(value) {
|
|
|
const result = new BigNumber(value == null || value === '' ? 0 : value);
|
|
|
@@ -341,6 +578,7 @@
|
|
|
const DECIMAL_INPUT_PATTERN = /^\d{1,12}(?:\.\d{1,6})?$/;
|
|
|
|
|
|
export default {
|
|
|
+ components: { bpmDetail },
|
|
|
data() {
|
|
|
return {
|
|
|
visible: false,
|
|
|
@@ -353,11 +591,30 @@
|
|
|
detailVisible: false,
|
|
|
detailLoading: false,
|
|
|
detailData: {},
|
|
|
+ detailTab: 'business',
|
|
|
pendingApproveId: null,
|
|
|
- recordActionId: null
|
|
|
+ recordActionId: null,
|
|
|
+ selectedPackingRows: [],
|
|
|
+ batchPackingTargetId: null,
|
|
|
+ recordQuery: {
|
|
|
+ changeNo: '',
|
|
|
+ approverName: '',
|
|
|
+ warehouseName: '',
|
|
|
+ batchNo: '',
|
|
|
+ categoryCode: '',
|
|
|
+ changeType: null,
|
|
|
+ verifyStatus: null
|
|
|
+ }
|
|
|
};
|
|
|
},
|
|
|
computed: {
|
|
|
+ detailProcessInstanceId() {
|
|
|
+ return (
|
|
|
+ this.detailData.processInstanceId ||
|
|
|
+ this.detailData.flowableTaskId ||
|
|
|
+ ''
|
|
|
+ );
|
|
|
+ },
|
|
|
dialogTitle() {
|
|
|
if (this.mode === 'records') return '批次变更申请记录';
|
|
|
return this.mode === 'split' ? '库存拆批申请' : '库存合批申请';
|
|
|
@@ -409,7 +666,84 @@
|
|
|
label: '类型',
|
|
|
formatter: (row) => (row.changeType === 1 ? '拆批' : '合批')
|
|
|
},
|
|
|
+ {
|
|
|
+ prop: 'warehouseName',
|
|
|
+ label: '仓库名称',
|
|
|
+ minWidth: 120,
|
|
|
+ formatter: (row) => this.recordValues(row, 'warehouseName')
|
|
|
+ },
|
|
|
+ {
|
|
|
+ prop: 'batchNo',
|
|
|
+ label: '业务批次',
|
|
|
+ minWidth: 110,
|
|
|
+ formatter: (row) => this.recordValues(row, 'batchNo')
|
|
|
+ },
|
|
|
+ {
|
|
|
+ prop: 'systemBatchNo',
|
|
|
+ label: '来源系统批次号',
|
|
|
+ minWidth: 150,
|
|
|
+ formatter: (row) => this.recordValues(row, 'systemBatchNo')
|
|
|
+ },
|
|
|
+ {
|
|
|
+ prop: 'categoryCode',
|
|
|
+ label: '物品编码',
|
|
|
+ minWidth: 120,
|
|
|
+ formatter: (row) => this.recordValues(row, 'categoryCode')
|
|
|
+ },
|
|
|
+ {
|
|
|
+ prop: 'categoryName',
|
|
|
+ label: '物品名称',
|
|
|
+ minWidth: 120,
|
|
|
+ formatter: (row) => this.recordValues(row, 'categoryName')
|
|
|
+ },
|
|
|
+ {
|
|
|
+ prop: 'specification',
|
|
|
+ label: '规格',
|
|
|
+ minWidth: 100,
|
|
|
+ formatter: (row) => this.recordValues(row, 'specification')
|
|
|
+ },
|
|
|
+ {
|
|
|
+ prop: 'categoryModel',
|
|
|
+ label: '型号',
|
|
|
+ minWidth: 100,
|
|
|
+ formatter: (row) => this.recordValues(row, 'categoryModel')
|
|
|
+ },
|
|
|
+ {
|
|
|
+ prop: 'brandNum',
|
|
|
+ label: '牌号',
|
|
|
+ minWidth: 100,
|
|
|
+ formatter: (row) => this.recordValues(row, 'brandNum')
|
|
|
+ },
|
|
|
+ {
|
|
|
+ prop: 'colorKey',
|
|
|
+ label: '颜色',
|
|
|
+ minWidth: 90,
|
|
|
+ formatter: (row) => this.recordValues(row, 'colorKey')
|
|
|
+ },
|
|
|
+ {
|
|
|
+ prop: 'unitPrice',
|
|
|
+ label: '单价',
|
|
|
+ minWidth: 90,
|
|
|
+ formatter: (row) => this.recordValues(row, 'unitPrice')
|
|
|
+ },
|
|
|
+ {
|
|
|
+ prop: 'supplierName',
|
|
|
+ label: '供应商名称',
|
|
|
+ minWidth: 130,
|
|
|
+ formatter: (row) => this.recordValues(row, 'supplierName')
|
|
|
+ },
|
|
|
+ {
|
|
|
+ prop: 'supplierCode',
|
|
|
+ label: '供应商代号',
|
|
|
+ minWidth: 120,
|
|
|
+ formatter: (row) => this.recordValues(row, 'supplierCode')
|
|
|
+ },
|
|
|
{ prop: 'verifyStatus', slot: 'status', label: '审批状态' },
|
|
|
+ {
|
|
|
+ prop: 'currentApproverName',
|
|
|
+ label: '当前审批人',
|
|
|
+ formatter: (row) => row.currentApproverName || '-'
|
|
|
+ },
|
|
|
{ prop: 'createTime', label: '申请时间' },
|
|
|
{
|
|
|
columnKey: 'action',
|
|
|
@@ -419,14 +753,24 @@
|
|
|
fixed: 'right'
|
|
|
}
|
|
|
];
|
|
|
+ },
|
|
|
+ verifyStatusOptions() {
|
|
|
+ return [
|
|
|
+ { value: 1, label: '审批中' },
|
|
|
+ { value: 2, label: '已通过' },
|
|
|
+ { value: 3, label: '已驳回' },
|
|
|
+ { value: 4, label: '已撤回' }
|
|
|
+ ];
|
|
|
}
|
|
|
},
|
|
|
methods: {
|
|
|
async open(mode, rows) {
|
|
|
this.mode = mode;
|
|
|
this.pendingApproveId = null;
|
|
|
- this.visible = true;
|
|
|
- if (mode === 'records') return;
|
|
|
+ if (mode === 'records') {
|
|
|
+ this.visible = true;
|
|
|
+ return;
|
|
|
+ }
|
|
|
this.sourceLoading = true;
|
|
|
try {
|
|
|
const selectedRows = rows || [];
|
|
|
@@ -449,8 +793,8 @@
|
|
|
? [this.createTarget(1)]
|
|
|
: [this.createTarget(1), this.createTarget(2)];
|
|
|
if (mode === 'merge') this.assignMergeTarget();
|
|
|
+ this.visible = true;
|
|
|
} catch (error) {
|
|
|
- this.visible = false;
|
|
|
this.$message.error(error.message || '批次来源详情加载失败');
|
|
|
} finally {
|
|
|
this.sourceLoading = false;
|
|
|
@@ -498,6 +842,7 @@
|
|
|
return {
|
|
|
targetDetailId,
|
|
|
measureQuantity: '0',
|
|
|
+ measureQuantityManual: false,
|
|
|
packageQuantity: '0',
|
|
|
weight: '0'
|
|
|
};
|
|
|
@@ -508,7 +853,11 @@
|
|
|
this.remark = '';
|
|
|
this.detailVisible = false;
|
|
|
this.detailData = {};
|
|
|
+ this.detailTab = 'business';
|
|
|
this.pendingApproveId = null;
|
|
|
+ this.selectedPackingRows = [];
|
|
|
+ this.batchPackingTargetId = null;
|
|
|
+ this.clearRecordQuery();
|
|
|
},
|
|
|
addTarget() {
|
|
|
const maxId = this.targets.reduce(
|
|
|
@@ -531,6 +880,9 @@
|
|
|
this.targets = this.targets.filter(
|
|
|
(target) => target.targetDetailId !== targetDetailId
|
|
|
);
|
|
|
+ if (this.batchPackingTargetId === targetDetailId) {
|
|
|
+ this.batchPackingTargetId = null;
|
|
|
+ }
|
|
|
},
|
|
|
assignMergeTarget() {
|
|
|
this.packingRows.forEach((row) => {
|
|
|
@@ -545,8 +897,76 @@
|
|
|
target.weight = this.sum(this.sources, 'weight');
|
|
|
this.syncTargetPackingMinimums();
|
|
|
},
|
|
|
+ handlePackingSelectionChange(rows) {
|
|
|
+ this.selectedPackingRows = rows;
|
|
|
+ },
|
|
|
+ packingRowSelectable() {
|
|
|
+ if (this.pendingApproveId || !this.batchPackingTargetId) return false;
|
|
|
+ const target = this.targets.find(
|
|
|
+ (item) => item.targetDetailId === this.batchPackingTargetId
|
|
|
+ );
|
|
|
+ return Boolean(target && !isEmptyDecimal(target.measureQuantity));
|
|
|
+ },
|
|
|
+ /** 将勾选的整包装一次分配到同一目标子批次。 */
|
|
|
+ assignSelectedPackingTarget() {
|
|
|
+ if (!this.batchPackingTargetId) {
|
|
|
+ return this.$message.warning('请选择目标子批次');
|
|
|
+ }
|
|
|
+ const target = this.targets.find(
|
|
|
+ (item) => item.targetDetailId === this.batchPackingTargetId
|
|
|
+ );
|
|
|
+ if (!target || isEmptyDecimal(target.measureQuantity)) {
|
|
|
+ return this.$message.warning('请先填写目标子批次的计量数量');
|
|
|
+ }
|
|
|
+ const assignedMeasureQuantity = this.packingRows
|
|
|
+ .filter((row) => row.targetDetailId === target.targetDetailId)
|
|
|
+ .reduce(
|
|
|
+ (sum, row) => sum.plus(decimal(row.measureQuantity)),
|
|
|
+ new BigNumber(0)
|
|
|
+ );
|
|
|
+ const remainingMeasureQuantity = decimal(target.measureQuantity).minus(
|
|
|
+ assignedMeasureQuantity
|
|
|
+ );
|
|
|
+ if (remainingMeasureQuantity.lte(0)) {
|
|
|
+ return this.$message.warning('该目标子批次已按计量数量分配整包装');
|
|
|
+ }
|
|
|
+ const selectedRows = [];
|
|
|
+ let selectedMeasureQuantity = new BigNumber(0);
|
|
|
+ this.packingRows
|
|
|
+ .filter((row) => !row.targetDetailId)
|
|
|
+ .some((packing) => {
|
|
|
+ const packingMeasureQuantity = decimal(packing.measureQuantity);
|
|
|
+ if (
|
|
|
+ selectedMeasureQuantity
|
|
|
+ .plus(packingMeasureQuantity)
|
|
|
+ .gt(remainingMeasureQuantity)
|
|
|
+ ) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ selectedRows.push(packing);
|
|
|
+ selectedMeasureQuantity = selectedMeasureQuantity.plus(
|
|
|
+ packingMeasureQuantity
|
|
|
+ );
|
|
|
+ return selectedMeasureQuantity.eq(remainingMeasureQuantity);
|
|
|
+ });
|
|
|
+ if (!selectedRows.length) {
|
|
|
+ return this.$message.warning('没有可按该计量数量分配的整包装');
|
|
|
+ }
|
|
|
+ selectedRows.forEach((packing) => {
|
|
|
+ packing.targetDetailId = this.batchPackingTargetId;
|
|
|
+ this.assignPackingTarget(packing, this.batchPackingTargetId, false);
|
|
|
+ });
|
|
|
+ this.syncTargetPackingMinimums();
|
|
|
+ this.selectedPackingRows = selectedRows;
|
|
|
+ this.$refs.packingTable.clearSelection();
|
|
|
+ this.$nextTick(() => {
|
|
|
+ selectedRows.forEach((packing) => {
|
|
|
+ this.$refs.packingTable.toggleRowSelection(packing, true);
|
|
|
+ });
|
|
|
+ });
|
|
|
+ },
|
|
|
/** 包装分配变化时,同步其关联锁定单的全部明细和包装。 */
|
|
|
- assignPackingTarget(packing, targetDetailId) {
|
|
|
+ assignPackingTarget(packing, targetDetailId, shouldSync = true) {
|
|
|
const relatedLocks = this.lockRows.filter((lock) =>
|
|
|
lock.lockedPackingStockIds.some(
|
|
|
(id) => String(id) === String(packing.packingStockId)
|
|
|
@@ -555,7 +975,7 @@
|
|
|
if (relatedLocks.length) {
|
|
|
this.assignConnectedLockRows(relatedLocks, targetDetailId);
|
|
|
}
|
|
|
- this.syncTargetPackingMinimums();
|
|
|
+ if (shouldSync) this.syncTargetPackingMinimums();
|
|
|
},
|
|
|
/** 锁定单必须整单分配,且所有关联包装必须与锁定单落到同一目标。 */
|
|
|
assignLockOrderTarget(lock, targetDetailId) {
|
|
|
@@ -608,7 +1028,10 @@
|
|
|
);
|
|
|
const measureMinimum = decimal(this.sum(packages, 'measureQuantity'));
|
|
|
const weightMinimum = decimal(this.sum(packages, 'weight'));
|
|
|
- if (decimal(target.measureQuantity).lt(measureMinimum)) {
|
|
|
+ if (
|
|
|
+ !target.measureQuantityManual ||
|
|
|
+ decimal(target.measureQuantity).lt(measureMinimum)
|
|
|
+ ) {
|
|
|
target.measureQuantity = measureMinimum.toFixed(6);
|
|
|
}
|
|
|
if (decimal(target.weight).lt(weightMinimum)) {
|
|
|
@@ -616,6 +1039,28 @@
|
|
|
}
|
|
|
});
|
|
|
},
|
|
|
+ markMeasureQuantityManual(target) {
|
|
|
+ target.measureQuantityManual = true;
|
|
|
+ },
|
|
|
+ validateTargetLimit(target, field) {
|
|
|
+ if (this.mode !== 'split' || !this.sources.length) return;
|
|
|
+ const source = this.sources[0];
|
|
|
+ const sourceField =
|
|
|
+ field === 'measureQuantity' ? 'stockCountBase' : 'weight';
|
|
|
+ const total = decimal(
|
|
|
+ this.targets.reduce(
|
|
|
+ (sum, target) => sum.plus(decimal(target[field])),
|
|
|
+ new BigNumber(0)
|
|
|
+ )
|
|
|
+ );
|
|
|
+ const limit = decimal(source[sourceField]);
|
|
|
+ if (total.lte(limit)) return;
|
|
|
+ const label = field === 'measureQuantity' ? '计量数量' : '重量';
|
|
|
+ target[field] = '';
|
|
|
+ this.$message.warning(
|
|
|
+ `目标子批次${label}累计不能超过来源库存${label} ${limit.toFixed(6)}`
|
|
|
+ );
|
|
|
+ },
|
|
|
targetLabel(id) {
|
|
|
return this.mode === 'merge' ? '合并目标' : `子批次 ${id}`;
|
|
|
},
|
|
|
@@ -648,13 +1093,56 @@
|
|
|
statusType(value) {
|
|
|
return value === 2 ? 'success' : value === 3 ? 'danger' : 'info';
|
|
|
},
|
|
|
+ displayValue(value) {
|
|
|
+ return value == null || value === '' ? '-' : value;
|
|
|
+ },
|
|
|
+ recordValues(row, key) {
|
|
|
+ const values = [
|
|
|
+ row[key],
|
|
|
+ ...(row.details || []).map((item) => item[key])
|
|
|
+ ]
|
|
|
+ .filter((value) => value != null && value !== '')
|
|
|
+ .map((value) => String(value));
|
|
|
+ return [...new Set(values)].join('、') || '-';
|
|
|
+ },
|
|
|
+ targetBatchText(row) {
|
|
|
+ return row.targetDetailId
|
|
|
+ ? `目标 ${row.targetDetailId}(审批通过后生成)`
|
|
|
+ : '审批通过后生成';
|
|
|
+ },
|
|
|
recordSource({ page, limit, where }) {
|
|
|
- return stockBatchChange.page({ ...where, pageNum: page, size: limit });
|
|
|
+ return stockBatchChange.page({
|
|
|
+ ...where,
|
|
|
+ ...this.recordQuery,
|
|
|
+ pageNum: page,
|
|
|
+ size: limit
|
|
|
+ });
|
|
|
+ },
|
|
|
+ searchRecords() {
|
|
|
+ if (this.$refs.recordTable) {
|
|
|
+ this.$refs.recordTable.reload({ page: 1 });
|
|
|
+ }
|
|
|
+ },
|
|
|
+ clearRecordQuery() {
|
|
|
+ this.recordQuery = {
|
|
|
+ changeNo: '',
|
|
|
+ approverName: '',
|
|
|
+ warehouseName: '',
|
|
|
+ batchNo: '',
|
|
|
+ categoryCode: '',
|
|
|
+ changeType: null,
|
|
|
+ verifyStatus: null
|
|
|
+ };
|
|
|
+ },
|
|
|
+ resetRecordQuery() {
|
|
|
+ this.clearRecordQuery();
|
|
|
+ this.searchRecords();
|
|
|
},
|
|
|
async showDetail(row) {
|
|
|
this.detailVisible = true;
|
|
|
this.detailLoading = true;
|
|
|
this.detailData = {};
|
|
|
+ this.detailTab = 'business';
|
|
|
try {
|
|
|
this.detailData = (await stockBatchChange.detail(row.id)) || {};
|
|
|
} catch (error) {
|
|
|
@@ -787,6 +1275,25 @@
|
|
|
)
|
|
|
)
|
|
|
return '目标子批次锁库数量不能大于计量数量';
|
|
|
+ const source = this.sources[0];
|
|
|
+ if (this.mode === 'split') {
|
|
|
+ const targetMeasureQuantity = decimal(
|
|
|
+ this.sum(this.targetRows, 'measureQuantity')
|
|
|
+ );
|
|
|
+ const sourceMeasureQuantity = decimal(source.stockCountBase);
|
|
|
+ if (targetMeasureQuantity.gt(sourceMeasureQuantity)) {
|
|
|
+ return `目标子批次计量数量累计不能超过来源库存数量 ${sourceMeasureQuantity.toFixed(
|
|
|
+ 6
|
|
|
+ )}`;
|
|
|
+ }
|
|
|
+ const targetWeight = decimal(this.sum(this.targetRows, 'weight'));
|
|
|
+ const sourceWeight = decimal(source.weight);
|
|
|
+ if (targetWeight.gt(sourceWeight)) {
|
|
|
+ return `目标子批次重量累计不能超过来源库存重量 ${sourceWeight.toFixed(
|
|
|
+ 6
|
|
|
+ )}`;
|
|
|
+ }
|
|
|
+ }
|
|
|
if (
|
|
|
this.hasPacking &&
|
|
|
this.targetRows.some(
|
|
|
@@ -797,7 +1304,6 @@
|
|
|
)
|
|
|
)
|
|
|
return '目标计量数量和重量不能小于所选整包装汇总';
|
|
|
- const source = this.sources[0];
|
|
|
if (this.mode === 'split') {
|
|
|
if (
|
|
|
!decimal(this.sum(this.targetRows, 'measureQuantity')).eq(
|
|
|
@@ -932,10 +1438,41 @@
|
|
|
</script>
|
|
|
|
|
|
<style scoped>
|
|
|
+ .record-search {
|
|
|
+ padding: 14px 16px 2px;
|
|
|
+ margin-bottom: 12px;
|
|
|
+ background-color: #f5f7fa;
|
|
|
+ border: 1px solid #ebeef5;
|
|
|
+ }
|
|
|
+ .record-search :deep(.el-form-item),
|
|
|
+ .record-search :deep(.el-select) {
|
|
|
+ width: 100%;
|
|
|
+ }
|
|
|
+ .record-search-actions {
|
|
|
+ display: flex;
|
|
|
+ justify-content: flex-end;
|
|
|
+ padding-top: 1px;
|
|
|
+ }
|
|
|
+ @media (max-width: 1199px) {
|
|
|
+ .record-search-actions {
|
|
|
+ justify-content: flex-start;
|
|
|
+ padding: 0 8px 12px;
|
|
|
+ }
|
|
|
+ }
|
|
|
.section-title {
|
|
|
margin: 14px 0 8px;
|
|
|
font-weight: 600;
|
|
|
}
|
|
|
+ .packing-batch-actions {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ gap: 8px;
|
|
|
+ margin-bottom: 8px;
|
|
|
+ color: #606266;
|
|
|
+ }
|
|
|
+ .packing-batch-actions .el-select {
|
|
|
+ width: 180px;
|
|
|
+ }
|
|
|
.merge-summary {
|
|
|
padding: 14px 0 0;
|
|
|
color: #606266;
|