feat(wms): 添加钢卷暂存单据管理功能
- 新增钢卷暂存单据列表展示界面 - 实现创建、删除、编辑暂存单据功能 - 添加钢卷选择对话框及查询筛选功能 - 实现已选钢卷列表查看和移除功能 - 集成本地存储管理暂存单据数据 - 添加钢卷重量统计和计算功能 - 实现钢卷去重选择机制防止重复添加
This commit is contained in:
@@ -607,6 +607,178 @@
|
||||
</div>
|
||||
</div>
|
||||
</el-dialog>
|
||||
|
||||
<!-- 钢卷暂存单据管理 -->
|
||||
<el-card class="box-card" style="margin-top: 20px;" :body-style="{ padding: '20px' }">
|
||||
<div slot="header" class="clearfix">
|
||||
<span>钢卷暂存单据管理</span>
|
||||
<el-button style="float: right; padding: 3px 0" type="text" @click="createTempOrder">创建暂存单据</el-button>
|
||||
</div>
|
||||
|
||||
<!-- 暂存单据列表 -->
|
||||
<el-table :data="tempOrderList" style="width: 100%" :height="'calc(100vh - 500px)'">
|
||||
<el-table-column prop="orderName" label="单据名称">
|
||||
<template slot-scope="scope">
|
||||
<div style="display: flex; align-items: center; gap: 5px;">
|
||||
<el-link type="primary" @click="viewSelectedCoils(scope.row)">{{ scope.row.orderName }}</el-link>
|
||||
<el-button size="mini" type="text" icon="el-icon-edit" @click="editOrderName(scope.row)"></el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="createTime" label="创建时间"></el-table-column>
|
||||
<el-table-column prop="coilCount" label="钢卷数量">
|
||||
<template slot-scope="scope">
|
||||
<el-tag size="small">{{ (scope.row.coils && scope.row.coils.length) ? scope.row.coils.length : 0 }}</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="totalWeight" label="总重量(t)">
|
||||
<template slot-scope="scope">
|
||||
{{ calculateTotalWeight(scope.row.coils || []).toFixed(3) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作">
|
||||
<template slot-scope="scope">
|
||||
<el-button size="mini" type="text" @click="openCoilSelection(scope.row)">选择钢卷</el-button>
|
||||
<el-button size="mini" type="text" style="color: #f56c6c;" @click="deleteTempOrder(scope.row)">删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<!-- 当没有数据时显示提示 -->
|
||||
<div v-if="!tempOrderList || tempOrderList.length === 0" style="text-align: center; padding: 50px; color: #909399;">
|
||||
<i class="el-icon-document" style="font-size: 48px; margin-bottom: 10px;"></i>
|
||||
<div>暂无暂存单据</div>
|
||||
<div style="font-size: 12px; margin-top: 5px;">点击右上角"创建暂存单据"开始使用</div>
|
||||
</div>
|
||||
</el-card>
|
||||
|
||||
<!-- 钢卷选择对话框 -->
|
||||
<el-dialog title="选择钢卷" :visible.sync="coilSelectionVisible" width="95%" append-to-body>
|
||||
<!-- 上方:查询条件 -->
|
||||
<el-card class="query-card" style="margin-bottom: 15px;">
|
||||
<el-form :model="coilQueryParams" size="small" :inline="true">
|
||||
<el-form-item label="入场卷号">
|
||||
<el-input v-model="coilQueryParams.enterCoilNo" placeholder="请输入入场钢卷号" clearable style="width: 200px;" />
|
||||
</el-form-item>
|
||||
<el-form-item label="当前卷号">
|
||||
<el-input v-model="coilQueryParams.currentCoilNo" placeholder="请输入当前钢卷号" clearable style="width: 200px;" />
|
||||
</el-form-item>
|
||||
<el-form-item label="产品名称">
|
||||
<el-input v-model="coilQueryParams.itemName" placeholder="请选择物料" clearable style="width: 200px;" />
|
||||
</el-form-item>
|
||||
<el-form-item label="规格">
|
||||
<el-input v-model="coilQueryParams.itemSpecification" placeholder="请选择规格" clearable style="width: 200px;" />
|
||||
</el-form-item>
|
||||
<el-form-item label="材质">
|
||||
<el-input v-model="coilQueryParams.itemMaterial" placeholder="请选择材质" clearable style="width: 200px;" />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="searchCoils">查询</el-button>
|
||||
<el-button @click="resetCoilQuery">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
|
||||
<!-- 下方:钢卷列表 -->
|
||||
<div style="height: 500px;">
|
||||
<el-table v-loading="coilLoading" :data="availableCoils" @selection-change="handleCoilSelection" border height="450">
|
||||
<el-table-column type="selection" width="55" align="center" />
|
||||
<el-table-column label="入场钢卷号" align="center" prop="enterCoilNo">
|
||||
<template slot-scope="scope">
|
||||
<coil-no :coil-no="scope.row.enterCoilNo"></coil-no>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="当前钢卷号" align="center" prop="currentCoilNo">
|
||||
<template slot-scope="scope">
|
||||
<current-coil-no :current-coil-no="scope.row.currentCoilNo"></current-coil-no>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="净重" align="center" prop="netWeight" />
|
||||
<el-table-column label="逻辑库位" align="center" prop="warehouseName" />
|
||||
<el-table-column label="实际库区" align="center" prop="actualWarehouseName" />
|
||||
<el-table-column label="产品类型" align="center" width="180">
|
||||
<template slot-scope="scope">
|
||||
<ProductInfo v-if="scope.row.itemType == 'product'" :product="scope.row" />
|
||||
<RawMaterialInfo v-else-if="scope.row.itemType === 'raw_material'" :material="scope.row" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="规格" prop="specification"></el-table-column>
|
||||
<el-table-column label="物料" prop="itemName"></el-table-column>
|
||||
<el-table-column label="材质" prop="material"></el-table-column>
|
||||
<el-table-column label="厂家" prop="manufacturer"></el-table-column>
|
||||
<el-table-column label="表面处理" prop="surfaceTreatmentDesc"></el-table-column>
|
||||
<el-table-column label="品质" prop="qualityStatus"></el-table-column>
|
||||
<el-table-column label="切边" prop="trimmingRequirement"></el-table-column>
|
||||
<el-table-column label="包装" prop="packagingRequirement"></el-table-column>
|
||||
<el-table-column label="状态" align="center" prop="status">
|
||||
<template slot-scope="scope">
|
||||
<el-tag v-if="scope.row.status === 0" type="info" size="mini">未发货</el-tag>
|
||||
<el-tag v-else type="success" size="mini">已发货</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="备注" align="center" prop="remark" show-overflow-tooltip />
|
||||
</el-table>
|
||||
|
||||
<div style="margin-top: 10px; text-align: center;">
|
||||
<el-pagination
|
||||
@size-change="handleCoilSizeChange"
|
||||
@current-change="handleCoilCurrentChange"
|
||||
:current-page="coilQueryParams.pageNum"
|
||||
:page-sizes="[10, 20, 50, 100]"
|
||||
:page-size="coilQueryParams.pageSize"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
:total="coilTotal">
|
||||
</el-pagination>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<div style="margin-bottom: 10px;">
|
||||
<span>已选择 {{ selectedCoils.length }} 个钢卷,总重量:{{ calculateSelectedWeight().toFixed(3) }}t</span>
|
||||
</div>
|
||||
<el-button @click="coilSelectionVisible = false">取消</el-button>
|
||||
<el-button type="primary" @click="saveSelectedCoils">确认选择</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
|
||||
<!-- 已选钢卷列表对话框 -->
|
||||
<el-dialog title="已选钢卷列表" :visible.sync="selectedCoilsVisible" width="90%" append-to-body>
|
||||
<el-table :data="currentTempOrder ? (currentTempOrder.coils || []) : []" border>
|
||||
<el-table-column label="入场钢卷号" align="center" prop="enterCoilNo">
|
||||
<template slot-scope="scope">
|
||||
<coil-no :coil-no="scope.row.enterCoilNo"></coil-no>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="当前钢卷号" align="center" prop="currentCoilNo">
|
||||
<template slot-scope="scope">
|
||||
<current-coil-no :current-coil-no="scope.row.currentCoilNo"></current-coil-no>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="净重" align="center" prop="netWeight" />
|
||||
<el-table-column label="逻辑库位" align="center" prop="warehouseName" />
|
||||
<el-table-column label="实际库区" align="center" prop="actualWarehouseName" />
|
||||
<el-table-column label="产品类型" align="center" width="180">
|
||||
<template slot-scope="scope">
|
||||
<ProductInfo v-if="scope.row.itemType == 'product'" :product="scope.row" />
|
||||
<RawMaterialInfo v-else-if="scope.row.itemType === 'raw_material'" :material="scope.row" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="规格" prop="specification"></el-table-column>
|
||||
<el-table-column label="物料" prop="itemName"></el-table-column>
|
||||
<el-table-column label="材质" prop="material"></el-table-column>
|
||||
<el-table-column label="厂家" prop="manufacturer"></el-table-column>
|
||||
<el-table-column label="表面处理" prop="surfaceTreatmentDesc"></el-table-column>
|
||||
<el-table-column label="品质" prop="qualityStatus"></el-table-column>
|
||||
<el-table-column label="切边" prop="trimmingRequirement"></el-table-column>
|
||||
<el-table-column label="包装" prop="packagingRequirement"></el-table-column>
|
||||
<el-table-column label="备注" align="center" prop="remark" show-overflow-tooltip />
|
||||
<el-table-column label="操作" align="center" width="100">
|
||||
<template slot-scope="scope">
|
||||
<el-button size="mini" type="text" style="color: #f56c6c;" @click="removeCoilFromOrder(scope.$index)">移除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -994,6 +1166,31 @@ export default {
|
||||
// 调拨记录弹窗
|
||||
transferRecordVisible: false,
|
||||
transferRecordList: [],
|
||||
// 暂存单据管理相关数据
|
||||
tempOrderList: [],
|
||||
currentTempOrder: null,
|
||||
coilSelectionVisible: false,
|
||||
selectedCoilsVisible: false,
|
||||
coilLoading: false,
|
||||
availableCoils: [],
|
||||
selectedCoils: [],
|
||||
coilTotal: 0,
|
||||
coilQueryParams: {
|
||||
pageNum: 1,
|
||||
pageSize: 20,
|
||||
enterCoilNo: '',
|
||||
currentCoilNo: '',
|
||||
itemName: '',
|
||||
itemSpecification: '',
|
||||
itemMaterial: '',
|
||||
status: 0,
|
||||
orderBy: true,
|
||||
dataType: 1,
|
||||
materialType: '成品',
|
||||
itemType: 'product',
|
||||
excludeBound: true,
|
||||
selectType: 'product'
|
||||
},
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
@@ -1021,8 +1218,257 @@ export default {
|
||||
this.warehouseIds = this.warehouseOptions.map(item => item.value).join(',');
|
||||
}
|
||||
this.getList();
|
||||
// 初始化暂存单据列表
|
||||
this.loadTempOrderList();
|
||||
},
|
||||
methods: {
|
||||
// === 暂存单据管理相关方法 ===
|
||||
// 加载暂存单据列表
|
||||
loadTempOrderList() {
|
||||
const savedOrders = localStorage.getItem('tempCoilOrders');
|
||||
if (savedOrders) {
|
||||
this.tempOrderList = JSON.parse(savedOrders);
|
||||
} else {
|
||||
this.tempOrderList = [];
|
||||
}
|
||||
},
|
||||
|
||||
// 保存暂存单据列表到本地存储
|
||||
saveTempOrderList() {
|
||||
localStorage.setItem('tempCoilOrders', JSON.stringify(this.tempOrderList));
|
||||
},
|
||||
|
||||
// 创建暂存单据
|
||||
createTempOrder() {
|
||||
const orderName = `暂存单据_${new Date().toLocaleString().replace(/[/:]/g, '-')}`;
|
||||
const newOrder = {
|
||||
orderId: Date.now().toString(),
|
||||
orderName: orderName,
|
||||
createTime: new Date().toLocaleString(),
|
||||
coils: []
|
||||
};
|
||||
|
||||
this.tempOrderList.unshift(newOrder);
|
||||
this.saveTempOrderList();
|
||||
|
||||
this.$message.success('暂存单据创建成功');
|
||||
},
|
||||
|
||||
// 删除暂存单据
|
||||
deleteTempOrder(order) {
|
||||
this.$confirm(`确认删除暂存单据"${order.orderName}"吗?`, '提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
const index = this.tempOrderList.findIndex(item => item.orderId === order.orderId);
|
||||
if (index > -1) {
|
||||
this.tempOrderList.splice(index, 1);
|
||||
this.saveTempOrderList();
|
||||
this.$message.success('删除成功');
|
||||
}
|
||||
}).catch(() => {
|
||||
this.$message.info('已取消删除');
|
||||
});
|
||||
},
|
||||
|
||||
// 查看已选钢卷列表
|
||||
viewSelectedCoils(order) {
|
||||
this.currentTempOrder = order;
|
||||
this.selectedCoilsVisible = true;
|
||||
},
|
||||
|
||||
// 编辑单据名称
|
||||
editOrderName(order) {
|
||||
this.$prompt('请输入新的单据名称', '编辑单据名称', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
inputValue: order.orderName,
|
||||
inputValidator: (value) => {
|
||||
if (!value || value.trim() === '') {
|
||||
return '单据名称不能为空';
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}).then(({ value }) => {
|
||||
const newName = value.trim();
|
||||
// 检查名称是否重复
|
||||
const duplicateOrder = this.tempOrderList.find(item =>
|
||||
item.orderId !== order.orderId && item.orderName === newName
|
||||
);
|
||||
|
||||
if (duplicateOrder) {
|
||||
this.$message.warning('单据名称已存在,请使用其他名称');
|
||||
return;
|
||||
}
|
||||
|
||||
// 更新单据名称
|
||||
order.orderName = newName;
|
||||
this.saveTempOrderList();
|
||||
this.$message.success('单据名称修改成功');
|
||||
}).catch(() => {
|
||||
this.$message.info('已取消编辑');
|
||||
});
|
||||
},
|
||||
|
||||
// 打开钢卷选择对话框
|
||||
openCoilSelection(order) {
|
||||
this.currentTempOrder = order;
|
||||
this.coilSelectionVisible = true;
|
||||
this.searchCoils();
|
||||
},
|
||||
|
||||
// 计算总重量
|
||||
calculateTotalWeight(coils) {
|
||||
if (!coils || coils.length === 0) return 0;
|
||||
return coils.reduce((total, coil) => {
|
||||
return total + (parseFloat(coil.netWeight) || 0);
|
||||
}, 0);
|
||||
},
|
||||
|
||||
// 计算选中钢卷的总重量
|
||||
calculateSelectedWeight() {
|
||||
return this.calculateTotalWeight(this.selectedCoils);
|
||||
},
|
||||
|
||||
// 查询钢卷
|
||||
async searchCoils() {
|
||||
this.coilLoading = true;
|
||||
try {
|
||||
// 构建查询参数
|
||||
const params = { ...this.coilQueryParams };
|
||||
|
||||
// 移除空值参数
|
||||
Object.keys(params).forEach(key => {
|
||||
if (params[key] === '' || params[key] === null || params[key] === undefined) {
|
||||
delete params[key];
|
||||
}
|
||||
});
|
||||
|
||||
// 调用接口查询钢卷
|
||||
const response = await listMaterialCoil(params);
|
||||
this.availableCoils = response.rows || [];
|
||||
this.coilTotal = response.total || 0;
|
||||
|
||||
// 过滤掉所有单据中已选择的钢卷,确保钢卷在所有单据中唯一
|
||||
const allExistingCoilIds = [];
|
||||
this.tempOrderList.forEach(order => {
|
||||
if (order.coils && Array.isArray(order.coils)) {
|
||||
order.coils.forEach(coil => {
|
||||
if (coil.coilId) {
|
||||
allExistingCoilIds.push(coil.coilId);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// 如果是当前正在编辑的单据,排除当前单据中的钢卷(因为它们已经在allExistingCoilIds中了)
|
||||
// 这样可以确保其他单据不能选择当前单据已选的钢卷
|
||||
this.availableCoils = this.availableCoils.filter(coil => !allExistingCoilIds.includes(coil.coilId));
|
||||
|
||||
} catch (error) {
|
||||
console.error('查询钢卷失败:', error);
|
||||
this.$message.error('查询钢卷失败');
|
||||
} finally {
|
||||
this.coilLoading = false;
|
||||
}
|
||||
},
|
||||
|
||||
// 重置钢卷查询条件
|
||||
resetCoilQuery() {
|
||||
this.coilQueryParams = {
|
||||
pageNum: 1,
|
||||
pageSize: 20,
|
||||
enterCoilNo: '',
|
||||
currentCoilNo: '',
|
||||
itemName: '',
|
||||
itemSpecification: '',
|
||||
itemMaterial: '',
|
||||
status: 0,
|
||||
orderBy: true,
|
||||
dataType: 1,
|
||||
materialType: '成品',
|
||||
itemType: 'product',
|
||||
excludeBound: true,
|
||||
selectType: 'product'
|
||||
};
|
||||
this.searchCoils();
|
||||
},
|
||||
|
||||
// 处理钢卷选择变化
|
||||
handleCoilSelection(selection) {
|
||||
this.selectedCoils = selection;
|
||||
},
|
||||
|
||||
// 保存选中的钢卷
|
||||
saveSelectedCoils() {
|
||||
if (!this.currentTempOrder) {
|
||||
this.$message.error('请先选择暂存单据');
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.selectedCoils.length === 0) {
|
||||
this.$message.warning('请选择要添加的钢卷');
|
||||
return;
|
||||
}
|
||||
|
||||
// 确保coils数组存在
|
||||
if (!this.currentTempOrder.coils) {
|
||||
this.currentTempOrder.coils = [];
|
||||
}
|
||||
|
||||
// 由于在查询阶段已经过滤了所有重复的钢卷,这里不需要再次检查
|
||||
// 但为了安全起见,保留基本的检查逻辑
|
||||
if (this.currentTempOrder.coils && this.currentTempOrder.coils.length > 0) {
|
||||
const existingCoilIds = this.currentTempOrder.coils.map(coil => coil.coilId);
|
||||
const duplicateCoils = this.selectedCoils.filter(coil => existingCoilIds.includes(coil.coilId));
|
||||
|
||||
if (duplicateCoils.length > 0) {
|
||||
this.$message.warning(`钢卷 ${duplicateCoils.map(coil => coil.enterCoilNo).join(', ')} 已存在,不能重复添加`);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// 添加钢卷到当前单据
|
||||
this.currentTempOrder.coils.push(...this.selectedCoils);
|
||||
this.saveTempOrderList();
|
||||
|
||||
this.$message.success(`成功添加 ${this.selectedCoils.length} 个钢卷`);
|
||||
|
||||
// 关闭对话框并重置选择
|
||||
this.coilSelectionVisible = false;
|
||||
this.selectedCoils = [];
|
||||
},
|
||||
|
||||
// 从单据中移除钢卷
|
||||
removeCoilFromOrder(index) {
|
||||
if (!this.currentTempOrder || !this.currentTempOrder.coils || !this.currentTempOrder.coils[index]) return;
|
||||
|
||||
this.$confirm('确认移除该钢卷吗?', '提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
this.currentTempOrder.coils.splice(index, 1);
|
||||
this.saveTempOrderList();
|
||||
this.$message.success('移除成功');
|
||||
}).catch(() => {
|
||||
this.$message.info('已取消移除');
|
||||
});
|
||||
},
|
||||
|
||||
// 钢卷分页相关方法
|
||||
handleCoilSizeChange(val) {
|
||||
this.coilQueryParams.pageSize = val;
|
||||
this.coilQueryParams.pageNum = 1;
|
||||
this.searchCoils();
|
||||
},
|
||||
|
||||
handleCoilCurrentChange(val) {
|
||||
this.coilQueryParams.pageNum = val;
|
||||
this.searchCoils();
|
||||
},
|
||||
|
||||
// 进入数字钢卷页面
|
||||
handleNumberCoilClick(row) {
|
||||
this.$router.push({
|
||||
|
||||
Reference in New Issue
Block a user