app三级后端修改
This commit is contained in:
@@ -4,10 +4,10 @@
|
||||
<div class="header-bar">
|
||||
<div class="header-title">
|
||||
<i class="el-icon-s-operation"></i>
|
||||
<span>钢卷分卷</span>
|
||||
<span>钢卷分条</span>
|
||||
</div>
|
||||
<div class="header-actions">
|
||||
<el-button v-if="!readonly" type="primary" size="small" @click="handleSave" :loading="loading">保存分卷</el-button>
|
||||
<el-button v-if="!readonly" type="primary" size="small" @click="handleSave" :loading="loading">保存分条</el-button>
|
||||
<el-button size="small" @click="handleCancel" :disabled="loading">{{ readonly ? '返回' : '取消' }}</el-button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -115,7 +115,36 @@
|
||||
<el-input v-model="item.team" placeholder="输入班组名称" :disabled="readonly"></el-input>
|
||||
</el-form-item>
|
||||
|
||||
<MaterialSelect :hideType="hideType" :itemId.sync="item.itemId" :itemType.sync="item.itemType" />
|
||||
<el-form-item label="材料类型" required>
|
||||
<el-select v-model="item.materialType" placeholder="请选择材料类型" style="width: 100%" :disabled="readonly">
|
||||
<el-option label="原料" value="原料" />
|
||||
<el-option label="成品" value="成品" />
|
||||
<el-option label="废品" value="废品" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
<!-- 物品类型由材料类型自动决定,不显示选择框 -->
|
||||
<el-form-item
|
||||
:label="getItemLabel(item.materialType)"
|
||||
:required="item.materialType !== '废品'">
|
||||
<el-select
|
||||
v-model="item.itemId"
|
||||
:placeholder="getItemPlaceholder(item.materialType)"
|
||||
filterable
|
||||
remote
|
||||
:remote-method="(query) => searchItemsForSplit(query, index)"
|
||||
:loading="itemSearchLoading"
|
||||
style="width: 100%"
|
||||
:disabled="readonly || !item.materialType"
|
||||
>
|
||||
<el-option
|
||||
v-for="option in getItemListForSplit(item.itemType)"
|
||||
:key="option.id"
|
||||
:label="option.name"
|
||||
:value="option.id"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="毛重(t)" required>
|
||||
<el-input
|
||||
@@ -195,14 +224,12 @@ import { listProduct } from '@/api/wms/product';
|
||||
import { completeAction } from '@/api/wms/pendingAction';
|
||||
import CoilSelector from '@/components/CoilSelector';
|
||||
import ActualWarehouseSelect from "@/components/KLPService/ActualWarehouseSelect";
|
||||
import MaterialSelect from "@/components/KLPService/MaterialSelect";
|
||||
|
||||
export default {
|
||||
name: 'SplitCoil',
|
||||
components: {
|
||||
CoilSelector,
|
||||
ActualWarehouseSelect,
|
||||
MaterialSelect
|
||||
ActualWarehouseSelect
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
@@ -227,6 +254,7 @@ export default {
|
||||
{
|
||||
currentCoilNo: '',
|
||||
team: '',
|
||||
materialType: null,
|
||||
itemType: null,
|
||||
itemId: null,
|
||||
grossWeight: null,
|
||||
@@ -253,9 +281,14 @@ export default {
|
||||
computed: {
|
||||
},
|
||||
async created() {
|
||||
console.log('🚀 split.vue created 钩子执行');
|
||||
|
||||
// 先加载库区列表
|
||||
await this.loadWarehouses();
|
||||
|
||||
// 🔥 页面加载时直接加载所有原料和产品列表
|
||||
await this.loadAllItems();
|
||||
|
||||
// 从路由参数获取coilId、actionId和readonly
|
||||
const coilId = this.$route.query.coilId;
|
||||
const actionId = this.$route.query.actionId;
|
||||
@@ -275,20 +308,107 @@ export default {
|
||||
this.readonly = true;
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
// 深度监听子卷列表中每个元素的 materialType 变化
|
||||
splitList: {
|
||||
handler(newList, oldList) {
|
||||
console.log('🔥 split.vue watch 触发! splitList 变化', {
|
||||
newList: newList.map(i => ({materialType: i.materialType, itemType: i.itemType})),
|
||||
oldList: oldList?.map(i => ({materialType: i.materialType, itemType: i.itemType}))
|
||||
});
|
||||
|
||||
newList.forEach((item, index) => {
|
||||
// 检查 materialType 是否变化
|
||||
const oldItem = oldList && oldList[index];
|
||||
const materialTypeChanged = !oldItem || oldItem.materialType !== item.materialType;
|
||||
|
||||
// 检查 itemType 是否需要设置(materialType有值但itemType为空)
|
||||
const needSetItemType = item.materialType && !item.itemType;
|
||||
|
||||
console.log(`👀 子卷${index} 检查:`, {
|
||||
materialTypeChanged,
|
||||
needSetItemType,
|
||||
'oldItem?.materialType': oldItem?.materialType,
|
||||
'item.materialType': item.materialType,
|
||||
'item.itemType': item.itemType
|
||||
});
|
||||
|
||||
if (materialTypeChanged) {
|
||||
console.log(`🔥 split.vue 子卷${index} materialType 变化:`, oldItem?.materialType, '->', item.materialType);
|
||||
}
|
||||
|
||||
// 如果 materialType 变化了,或者 itemType 需要设置
|
||||
if ((materialTypeChanged || needSetItemType) && item.materialType) {
|
||||
// 使用 Vue.set 确保响应式更新
|
||||
this.$set(item, 'itemId', null);
|
||||
|
||||
// 设置物料类型
|
||||
if (item.materialType === '成品') {
|
||||
this.$set(item, 'itemType', 'product');
|
||||
console.log(`✅ 子卷${index} 使用$set设置 itemType = product`);
|
||||
} else if (item.materialType === '原料' || item.materialType === '废品') {
|
||||
this.$set(item, 'itemType', 'raw_material');
|
||||
console.log(`✅ 子卷${index} 使用$set设置 itemType = raw_material`);
|
||||
}
|
||||
|
||||
console.log(`📊 子卷${index} 当前状态:`, {
|
||||
materialType: item.materialType,
|
||||
itemType: item.itemType,
|
||||
itemId: item.itemId
|
||||
});
|
||||
|
||||
// 验证数据是否正确
|
||||
console.log(`📦 原材料列表数量:`, this.rawMaterialList.length);
|
||||
console.log(`📦 产品列表数量:`, this.productList.length);
|
||||
}
|
||||
});
|
||||
},
|
||||
deep: true
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 动态获取标签
|
||||
getItemLabel(materialType) {
|
||||
if (materialType === '成品') {
|
||||
return '产品类型';
|
||||
} else if (materialType === '原料' || materialType === '废品') {
|
||||
return '原料类型';
|
||||
}
|
||||
return '物品';
|
||||
},
|
||||
// 动态获取占位符
|
||||
getItemPlaceholder(materialType) {
|
||||
if (materialType === '成品') {
|
||||
return '请选择产品类型';
|
||||
} else if (materialType === '原料') {
|
||||
return '请选择原料类型';
|
||||
} else if (materialType === '废品') {
|
||||
return '请选择原料类型(非必填)';
|
||||
}
|
||||
return '请先选择材料类型';
|
||||
},
|
||||
// 获取子卷的物品列表
|
||||
getItemListForSplit(itemType) {
|
||||
console.log(`📋 getItemListForSplit 被调用,itemType:`, itemType);
|
||||
console.log(`📋 rawMaterialList 长度:`, this.rawMaterialList?.length);
|
||||
console.log(`📋 productList 长度:`, this.productList?.length);
|
||||
|
||||
if (itemType === 'raw_material') {
|
||||
return this.rawMaterialList.map(item => ({
|
||||
const list = this.rawMaterialList.map(item => ({
|
||||
id: item.rawMaterialId,
|
||||
name: this.formatItemName(item)
|
||||
}));
|
||||
console.log(`📋 返回原材料列表,数量:`, list.length);
|
||||
return list;
|
||||
} else if (itemType === 'product') {
|
||||
return this.productList.map(item => ({
|
||||
const list = this.productList.map(item => ({
|
||||
id: item.productId,
|
||||
name: this.formatItemName(item)
|
||||
}));
|
||||
console.log(`📋 返回产品列表,数量:`, list.length);
|
||||
return list;
|
||||
}
|
||||
console.log(`📋 返回空列表`);
|
||||
return [];
|
||||
},
|
||||
|
||||
@@ -335,9 +455,17 @@ export default {
|
||||
|
||||
// 搜索子卷物品
|
||||
async searchItemsForSplit(query, index) {
|
||||
const itemType = this.splitList[index].itemType;
|
||||
const item = this.splitList[index];
|
||||
console.log(`🔍 searchItemsForSplit 调用,子卷${index}:`, {
|
||||
materialType: item.materialType,
|
||||
itemType: item.itemType,
|
||||
query: query
|
||||
});
|
||||
|
||||
const itemType = item.itemType;
|
||||
if (!itemType) {
|
||||
this.$message.warning('请先选择物品类型');
|
||||
console.log(`❌ 子卷${index} itemType 为空!`);
|
||||
this.$message.warning('请先选择材料类型');
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -376,9 +504,38 @@ export default {
|
||||
}
|
||||
},
|
||||
|
||||
// 页面加载时一次性加载所有原料和产品列表
|
||||
async loadAllItems() {
|
||||
console.log('🔥 split.vue 开始加载所有物品列表');
|
||||
try {
|
||||
// 同时加载原料和产品
|
||||
const [rawMaterialRes, productRes] = await Promise.all([
|
||||
listRawMaterial({ pageNum: 1, pageSize: 99999, withBom: true }),
|
||||
listProduct({ pageNum: 1, pageSize: 99999, withBom: true })
|
||||
]);
|
||||
|
||||
if (rawMaterialRes.code === 200) {
|
||||
this.rawMaterialList = rawMaterialRes.rows || [];
|
||||
console.log('✅ split.vue 原材料列表加载成功,数量:', this.rawMaterialList.length);
|
||||
}
|
||||
|
||||
if (productRes.code === 200) {
|
||||
this.productList = productRes.rows || [];
|
||||
console.log('✅ split.vue 产品列表加载成功,数量:', this.productList.length);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('❌ split.vue 加载物品列表失败', error);
|
||||
}
|
||||
},
|
||||
|
||||
// 加载子卷物品列表
|
||||
async loadItemListForSplit(itemType) {
|
||||
if (!itemType) return;
|
||||
if (!itemType) {
|
||||
console.log('loadItemListForSplit: itemType 为空');
|
||||
return;
|
||||
}
|
||||
|
||||
console.log('split.vue 开始加载物品列表,类型:', itemType);
|
||||
|
||||
try {
|
||||
this.itemSearchLoading = true;
|
||||
@@ -388,8 +545,10 @@ export default {
|
||||
pageSize: 100,
|
||||
withBom: true
|
||||
});
|
||||
console.log('split.vue 原材料列表响应:', response);
|
||||
if (response.code === 200) {
|
||||
this.rawMaterialList = response.rows || [];
|
||||
console.log('split.vue 原材料列表加载成功,数量:', this.rawMaterialList.length);
|
||||
}
|
||||
} else if (itemType === 'product') {
|
||||
const response = await listProduct({
|
||||
@@ -397,12 +556,14 @@ export default {
|
||||
pageSize: 100,
|
||||
withBom: true
|
||||
});
|
||||
console.log('split.vue 产品列表响应:', response);
|
||||
if (response.code === 200) {
|
||||
this.productList = response.rows || [];
|
||||
console.log('split.vue 产品列表加载成功,数量:', this.productList.length);
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('加载物品列表失败', error);
|
||||
console.error('split.vue 加载物品列表失败', error);
|
||||
} finally {
|
||||
this.itemSearchLoading = false;
|
||||
}
|
||||
@@ -482,6 +643,7 @@ export default {
|
||||
this.splitList.push({
|
||||
currentCoilNo: '',
|
||||
team: '',
|
||||
materialType: null,
|
||||
itemType: null,
|
||||
itemId: null,
|
||||
grossWeight: null,
|
||||
@@ -500,7 +662,7 @@ export default {
|
||||
}
|
||||
},
|
||||
|
||||
// 保存分卷
|
||||
// 保存分条
|
||||
async handleSave() {
|
||||
// 验证母卷信息
|
||||
if (!this.motherCoil.coilId) {
|
||||
@@ -549,23 +711,24 @@ export default {
|
||||
|
||||
const loadingInstance = this.$loading({
|
||||
lock: true,
|
||||
text: '正在分卷,请稍后...',
|
||||
text: '正在分条,请稍后...',
|
||||
background: 'rgba(0, 0, 0, 0.7)'
|
||||
})
|
||||
|
||||
try {
|
||||
this.loading = true;
|
||||
|
||||
// 构造分卷数据
|
||||
// 构造分条数据
|
||||
const splitData = {
|
||||
coilId: this.motherCoil.coilId,
|
||||
enterCoilNo: this.motherCoil.enterCoilNo, // 入场钢卷号(必填)
|
||||
currentCoilNo: this.motherCoil.currentCoilNo,
|
||||
hasMergeSplit: 1, // 1表示分卷
|
||||
hasMergeSplit: 1, // 1表示分条
|
||||
newCoils: this.splitList.map(item => ({
|
||||
enterCoilNo: this.motherCoil.enterCoilNo, // 子卷继承母卷的入场钢卷号
|
||||
currentCoilNo: item.currentCoilNo,
|
||||
team: item.team,
|
||||
materialType: item.materialType,
|
||||
itemType: item.itemType || this.motherCoil.itemType,
|
||||
itemId: item.itemId || this.motherCoil.itemId,
|
||||
grossWeight: item.grossWeight,
|
||||
@@ -576,11 +739,11 @@ export default {
|
||||
}))
|
||||
};
|
||||
|
||||
console.log('提交的分卷数据:', splitData);
|
||||
console.log('提交的分条数据:', splitData);
|
||||
|
||||
const response = await splitMaterialCoil(splitData);
|
||||
if (response.code === 200) {
|
||||
this.$message.success('分卷保存成功');
|
||||
this.$message.success('分条保存成功');
|
||||
|
||||
// 如果是从待操作列表进来的,标记操作为完成
|
||||
if (this.actionId) {
|
||||
@@ -592,11 +755,11 @@ export default {
|
||||
this.$router.back();
|
||||
}, 1000);
|
||||
} else {
|
||||
this.$message.error(response.msg || '分卷保存失败');
|
||||
this.$message.error(response.msg || '分条保存失败');
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
this.$message.error('分卷保存失败');
|
||||
this.$message.error('分条保存失败');
|
||||
console.error(error);
|
||||
} finally {
|
||||
this.loading = false;
|
||||
@@ -628,13 +791,7 @@ export default {
|
||||
item.team = this.motherCoil.team;
|
||||
}
|
||||
|
||||
// 复制物品类型和物品ID
|
||||
if (!item.itemType) {
|
||||
item.itemType = this.motherCoil.itemType;
|
||||
}
|
||||
if (!item.itemId) {
|
||||
item.itemId = this.motherCoil.itemId;
|
||||
}
|
||||
// 不复制 itemType 和 itemId,让它们由 materialType 自动决定
|
||||
});
|
||||
|
||||
// 加载物品列表
|
||||
|
||||
Reference in New Issue
Block a user