feat(钢卷管理): 添加成品钢卷的质量状态、切边要求等字段

在钢卷管理的分条、合卷和基础信息页面中,为成品类型的钢卷新增质量状态、切边要求、打包状态和包装要求字段
同时移除未使用的采购计划相关代码
This commit is contained in:
砂糖
2025-11-14 09:49:33 +08:00
parent 6f448faa45
commit bbbe7cefd8
6 changed files with 266 additions and 346 deletions

View File

@@ -88,8 +88,10 @@
<div class="flow-section-title">
<span>子卷列表</span>
<div>
<el-button v-if="!readonly" type="text" size="mini" @click="copyToAllSubCoils" icon="el-icon-document-copy">复制到全部</el-button>
<el-button v-if="!readonly" type="text" size="mini" @click="addSplitItem" icon="el-icon-plus">添加子卷</el-button>
<el-button v-if="!readonly" type="text" size="mini" @click="copyToAllSubCoils"
icon="el-icon-document-copy">复制到全部</el-button>
<el-button v-if="!readonly" type="text" size="mini" @click="addSplitItem"
icon="el-icon-plus">添加子卷</el-button>
</div>
</div>
@@ -97,14 +99,8 @@
<div class="sub-coil-card" v-for="(item, index) in splitList" :key="index">
<div class="sub-coil-header">
<span class="sub-coil-number">{{ index + 1 }}</span>
<el-button
v-if="!readonly"
type="text"
size="mini"
icon="el-icon-delete"
@click="removeSplitItem(index)"
class="btn-remove"
></el-button>
<el-button v-if="!readonly" type="text" size="mini" icon="el-icon-delete" @click="removeSplitItem(index)"
class="btn-remove"></el-button>
</div>
<div class="sub-coil-body">
<el-form size="small" label-width="90px">
@@ -116,11 +112,7 @@
</el-form-item>
<el-form-item label="材料类型" required>
<el-select
v-model="item.materialType"
placeholder="请选择材料类型"
style="width: 100%"
:disabled="readonly"
<el-select v-model="item.materialType" placeholder="请选择材料类型" style="width: 100%" :disabled="readonly"
@change="handleMaterialTypeChange(item, index)">
<el-option label="原料" value="原料" />
<el-option label="成品" value="成品" />
@@ -128,75 +120,62 @@
</el-select>
</el-form-item>
<el-form-item v-if="updateForm.materialType === '成品'" label="质量状态" prop="qualityStatus">
<el-input v-model="item.qualityStatus" placeholder="请输入质量状态"
:disabled="readonly">
</el-input>
</el-form-item>
<el-form-item v-if="updateForm.materialType === '成品'" label="切边要求" prop="trimmingRequirement">
<el-input v-model="item.trimmingRequirement" placeholder="请输入切边要求"
:disabled="readonly">
</el-input>
</el-form-item>
<el-form-item v-if="updateForm.materialType === '成品'" label="打包状态" prop="packingStatus">
<el-input v-model="item.packingStatus" placeholder="请输入打包状态"
:disabled="readonly">
</el-input>
</el-form-item>
<el-form-item v-if="updateForm.materialType === '成品'" label="包装要求" prop="packagingRequirement">
<el-input v-model="item.packagingRequirement" placeholder="请输入包装要求"
:disabled="readonly">
</el-input>
</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-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
v-model.number="item.grossWeight"
placeholder="请输入毛重"
type="number"
step="0.01"
:disabled="readonly"
>
<el-input v-model.number="item.grossWeight" placeholder="请输入毛重" type="number" step="0.01"
:disabled="readonly">
<template slot="append">吨</template>
</el-input>
</el-form-item>
<el-form-item label="净重(t)" required>
<el-input
v-model.number="item.netWeight"
placeholder="请输入净重"
type="number"
step="0.01"
:disabled="readonly"
>
<el-input v-model.number="item.netWeight" placeholder="请输入净重" type="number" step="0.01"
:disabled="readonly">
<template slot="append">吨</template>
</el-input>
</el-form-item>
<el-form-item label="逻辑库区" required>
<el-select
v-model="item.warehouseId"
placeholder="请选择逻辑库区"
style="width: 100%"
filterable
:disabled="readonly"
>
<el-option
v-for="warehouse in warehouseList"
:key="warehouse.warehouseId"
:label="warehouse.warehouseName"
:value="warehouse.warehouseId"
/>
<el-select v-model="item.warehouseId" placeholder="请选择逻辑库区" style="width: 100%" filterable
:disabled="readonly">
<el-option v-for="warehouse in warehouseList" :key="warehouse.warehouseId"
:label="warehouse.warehouseName" :value="warehouse.warehouseId" />
</el-select>
</el-form-item>
<el-form-item label="真实库区" required>
<ActualWarehouseSelect
v-model="item.actualWarehouseId"
placeholder="请选择真实库区"
style="width: 100%"
filterable
:disabled="readonly"
/>
<ActualWarehouseSelect v-model="item.actualWarehouseId" placeholder="请选择真实库区" style="width: 100%"
filterable :disabled="readonly" />
</el-form-item>
</el-form>
</div>
@@ -214,10 +193,7 @@
</div>
<!-- 钢卷选择器 -->
<coil-selector
:visible.sync="coilSelectorVisible"
@select="handleCoilSelect"
/>
<coil-selector :visible.sync="coilSelectorVisible" @select="handleCoilSelect" />
</div>
</template>
@@ -299,16 +275,16 @@ export default {
const coilId = this.$route.query.coilId;
const actionId = this.$route.query.actionId;
const readonly = this.$route.query.readonly;
if (coilId) {
await this.loadMotherCoil(coilId);
}
// 保存待操作ID
if (actionId) {
this.actionId = actionId;
}
// 设置只读模式
if (readonly === 'true' || readonly === true) {
this.readonly = true;
@@ -319,7 +295,7 @@ export default {
handleMaterialTypeChange(item, index) {
// 清空物品选择
this.$set(item, 'itemId', null);
// 根据材料类型设置物品类型并恢复完整列表
if (item.materialType === '成品') {
this.$set(item, 'itemType', 'product');
@@ -331,7 +307,7 @@ export default {
this.rawMaterialList = [...this.allRawMaterials];
}
},
// 动态获取标签
getItemLabel(materialType) {
if (materialType === '成品') {
@@ -371,35 +347,35 @@ export default {
// 格式化物品名称(添加规格和参数信息)
formatItemName(item) {
if (!item) return '';
// 获取名称(原材料或产品)
const name = item.rawMaterialName || item.productName || '';
if (!name) return '';
let displayName = name;
const specs = [];
// 1. 优先显示规格从对象的specification字段
if (item.specification) {
specs.push(item.specification);
}
// 2. 添加参数参数最多2个
if (item.bomItems && item.bomItems.length > 0) {
const bomParams = item.bomItems
.filter(bomItem => bomItem.attrKey && bomItem.attrValue)
.slice(0, 2); // 最多2个参数参数
bomParams.forEach(param => {
specs.push(`${param.attrKey}:${param.attrValue}`);
});
}
// 3. 拼接成最终格式
if (specs.length > 0) {
displayName += `${specs.join(' ')}`;
}
return displayName;
},
@@ -412,13 +388,13 @@ export default {
// 搜索子卷物品(前端过滤,支持名称和规格搜索)
async searchItemsForSplit(query, index) {
const item = this.splitList[index];
const itemType = item.itemType;
if (!itemType) {
this.$message.warning('请先选择材料类型');
return;
}
// 如果没有输入,恢复完整列表
if (!query || query.trim() === '') {
if (itemType === 'raw_material') {
@@ -428,10 +404,10 @@ export default {
}
return;
}
// 前端过滤:在已加载的数据中搜索
const searchQuery = query.toLowerCase().trim();
if (itemType === 'raw_material') {
// 从备份列表中过滤原材料
this.rawMaterialList = this.allRawMaterials.filter(item => {
@@ -440,11 +416,11 @@ export default {
// 搜索规格
const specMatch = item.specification && item.specification.toLowerCase().includes(searchQuery);
// 搜索 参数 参数
const bomMatch = item.bomItems && item.bomItems.some(bom =>
const bomMatch = item.bomItems && item.bomItems.some(bom =>
(bom.attrKey && bom.attrKey.toLowerCase().includes(searchQuery)) ||
(bom.attrValue && bom.attrValue.toLowerCase().includes(searchQuery))
);
return nameMatch || specMatch || bomMatch;
});
} else if (itemType === 'product') {
@@ -455,11 +431,11 @@ export default {
// 搜索规格
const specMatch = item.specification && item.specification.toLowerCase().includes(searchQuery);
// 搜索 参数 参数
const bomMatch = item.bomItems && item.bomItems.some(bom =>
const bomMatch = item.bomItems && item.bomItems.some(bom =>
(bom.attrKey && bom.attrKey.toLowerCase().includes(searchQuery)) ||
(bom.attrValue && bom.attrValue.toLowerCase().includes(searchQuery))
);
return nameMatch || specMatch || bomMatch;
});
}
@@ -493,12 +469,12 @@ export default {
if (!itemType) {
return;
}
try {
this.itemSearchLoading = true;
if (itemType === 'raw_material') {
const response = await listRawMaterial({
pageNum: 1,
const response = await listRawMaterial({
pageNum: 1,
pageSize: 100,
withBom: true
});
@@ -506,8 +482,8 @@ export default {
this.rawMaterialList = response.rows || [];
}
} else if (itemType === 'product') {
const response = await listProduct({
pageNum: 1,
const response = await listProduct({
pageNum: 1,
pageSize: 100,
withBom: true
});
@@ -661,11 +637,11 @@ export default {
}
}
const loadingInstance = this.$loading({
lock: true,
text: '正在分条,请稍后...',
background: 'rgba(0, 0, 0, 0.7)'
})
const loadingInstance = this.$loading({
lock: true,
text: '正在分条,请稍后...',
background: 'rgba(0, 0, 0, 0.7)'
})
try {
this.loading = true;
@@ -694,12 +670,12 @@ export default {
const response = await splitMaterialCoil(splitData);
if (response.code === 200) {
this.$message.success('分条保存成功');
// 如果是从待操作列表进来的,标记操作为完成
if (this.actionId) {
await completeAction(this.actionId);
}
// 延迟返回,让用户看到成功提示
setTimeout(() => {
this.$router.back();
@@ -707,7 +683,7 @@ export default {
} else {
this.$message.error(response.msg || '分条保存失败');
}
} catch (error) {
this.$message.error('分条保存失败');
console.error(error);
@@ -1107,4 +1083,3 @@ export default {
}
}
</style>