Files
klp-oa/klp-ui/src/views/wms/coil/typing.vue

941 lines
29 KiB
Vue
Raw Normal View History

2025-11-03 17:03:03 +08:00
<template>
<div class="typing-coil-container">
<!-- 顶部操作栏 -->
<div class="header-bar">
<div class="header-title">
<i class="el-icon-edit"></i>
<span>钢卷信息更新</span>
</div>
<div class="header-actions">
<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>
<!-- 主内容区 - 左右布局 -->
<div class="content-wrapper">
<!-- 左侧当前信息 -->
<div class="left-panel">
<el-card class="info-card">
<div slot="header" class="card-header">
<span><i class="el-icon-info"></i> 当前信息</span>
</div>
2025-11-03 17:03:03 +08:00
<div class="info-section">
<div class="info-row">
<span class="info-label">入场钢卷号</span>
<span class="info-value">{{ currentInfo.enterCoilNo || '—' }}</span>
</div>
<div class="info-row">
<span class="info-label">当前钢卷号</span>
<span class="info-value">{{ currentInfo.currentCoilNo || '—' }}</span>
</div>
<div class="info-row">
<span class="info-label">厂家原料卷号</span>
<span class="info-value">{{ currentInfo.supplierCoilNo || '—' }}</span>
</div>
<div class="info-row">
<span class="info-label">班组</span>
<span class="info-value">{{ currentInfo.team || '—' }}</span>
</div>
<div class="info-row">
<span class="info-label">物品类型</span>
<span class="info-value">{{ getItemTypeText(currentInfo.itemType) }}</span>
</div>
<div class="info-row">
<span class="info-label">物料名称</span>
<span class="info-value">{{ currentInfo.itemName || '—' }}</span>
</div>
<div class="info-row">
<span class="info-label">毛重</span>
<span class="info-value">{{ currentInfo.grossWeight ? currentInfo.grossWeight + ' t' : '—' }}</span>
</div>
<div class="info-row">
<span class="info-label">净重</span>
<span class="info-value">{{ currentInfo.netWeight ? currentInfo.netWeight + ' t' : '—' }}</span>
</div>
<div class="info-row">
<span class="info-label">逻辑库区</span>
2025-11-03 17:03:03 +08:00
<span class="info-value">{{ currentInfo.nextWarehouseName || '—' }}</span>
</div>
<div class="info-row" v-if="currentInfo.remark">
<span class="info-label">备注</span>
<span class="info-value">{{ currentInfo.remark }}</span>
</div>
</div>
</el-card>
</div>
<!-- 右侧更新表单 -->
<div class="right-panel">
<el-card class="form-card">
<div slot="header" class="card-header">
<span><i class="el-icon-edit-outline"></i> {{ readonly ? '查看信息' : '更新信息' }}</span>
<el-button v-if="!readonly" type="text" size="mini" @click="copyFromCurrent" icon="el-icon-document-copy">
复制当前信息
</el-button>
</div>
<el-form ref="updateForm" :model="updateForm" :rules="rules" label-width="120px" size="small">
2025-11-03 17:03:03 +08:00
<el-form-item label="当前钢卷号" prop="currentCoilNo">
<el-input v-model="updateForm.currentCoilNo" placeholder="请输入当前钢卷号" :disabled="readonly">
2025-11-03 17:03:03 +08:00
<template slot="prepend">
<i class="el-icon-document"></i>
</template>
</el-input>
</el-form-item>
<el-form-item label="班组" prop="team">
<el-input v-model="updateForm.team" placeholder="请输入班组名称" :disabled="readonly">
2025-11-03 17:03:03 +08:00
<template slot="prepend">
<i class="el-icon-user-solid"></i>
</template>
</el-input>
</el-form-item>
2025-11-11 12:21:16 +08:00
<el-form-item label="材料类型" prop="materialType">
<el-select
v-model="updateForm.materialType"
placeholder="请选择材料类型"
style="width: 100%"
:disabled="readonly"
@change="handleMaterialTypeChange">
<el-option label="原料" value="原料" />
<el-option label="成品" value="成品" />
<el-option label="废品" value="废品" />
2025-11-03 17:03:03 +08:00
</el-select>
</el-form-item>
2025-11-11 12:21:16 +08:00
<!-- 物品类型由材料类型自动决定不显示选择框 -->
<el-form-item
:label="getItemLabel"
:prop="updateForm.materialType === '废品' ? '' : 'itemId'"
:rules="updateForm.materialType === '废品' ? [] : rules.itemId">
<el-select
v-model="updateForm.itemId"
:placeholder="getItemPlaceholder"
filterable
remote
:remote-method="searchItems"
:loading="itemSearchLoading"
style="width: 100%"
:disabled="readonly || !updateForm.materialType">
<el-option v-for="item in currentItemList" :key="item.id" :label="item.name" :value="item.id" />
2025-11-03 17:03:03 +08:00
</el-select>
2025-11-11 12:21:16 +08:00
</el-form-item>
2025-11-03 17:03:03 +08:00
<el-form-item label="毛重(t)" prop="grossWeight">
<el-input v-model.number="updateForm.grossWeight" placeholder="请输入毛重" type="number" step="0.01"
:disabled="readonly">
2025-11-03 17:03:03 +08:00
<template slot="append"></template>
</el-input>
</el-form-item>
<el-form-item label="净重(t)" prop="netWeight">
<el-input v-model.number="updateForm.netWeight" placeholder="请输入净重" type="number" step="0.01"
:disabled="readonly">
2025-11-03 17:03:03 +08:00
<template slot="append"></template>
</el-input>
</el-form-item>
<el-form-item label="逻辑库区" prop="warehouseId">
<el-select v-model="updateForm.warehouseId" placeholder="请选择逻辑库区" style="width: 100%" filterable
:disabled="readonly">
<el-option v-for="warehouse in warehouseList" :key="warehouse.warehouseId"
:label="warehouse.warehouseName" :value="warehouse.warehouseId" />
2025-11-03 17:03:03 +08:00
</el-select>
</el-form-item>
<el-form-item label="真实库区" prop="warehouseId">
<ActualWarehouseSelect v-model="updateForm.actualWarehouseId" placeholder="请选择真实库区" style="width: 100%"
filterable :disabled="readonly" />
</el-form-item>
2025-11-03 17:03:03 +08:00
<el-form-item label="备注" prop="remark">
<el-input v-model="updateForm.remark" type="textarea" :rows="4" placeholder="请输入备注信息(非必填)" maxlength="500"
show-word-limit :disabled="readonly" />
2025-11-03 17:03:03 +08:00
</el-form-item>
</el-form>
</el-card>
</div>
</div>
<!-- 变更历史占满整行 -->
<div class="history-section">
<el-card class="history-card">
<div slot="header" class="card-header">
<span><i class="el-icon-time"></i> 变更历史</span>
<el-button type="text" size="mini" @click="loadHistory" :loading="historyLoading">
<i class="el-icon-refresh"></i> 刷新
</el-button>
</div>
2025-11-03 17:03:03 +08:00
<el-timeline v-if="historySteps.length > 0">
<el-timeline-item v-for="(step, index) in historySteps" :key="index"
:timestamp="`步骤 ${step.display_step || step.step}`" placement="top"
:type="step.operation === '新增' ? 'success' : 'primary'">
2025-11-03 17:03:03 +08:00
<div class="history-item">
<div class="history-title">{{ step.operation || step.action }}</div>
<div class="history-detail" v-if="step.operator">
<span class="detail-label">操作人</span>
<span>{{ step.operator }}</span>
</div>
<div class="history-detail" v-if="step.old_current_coil_no">
<span class="detail-label">原钢卷号</span>
<span>{{ step.old_current_coil_no }}</span>
</div>
<div class="history-detail" v-if="step.new_current_coil_no">
<span class="detail-label">新钢卷号</span>
<span>{{ step.new_current_coil_no }}</span>
</div>
</div>
</el-timeline-item>
</el-timeline>
2025-11-03 17:03:03 +08:00
<div v-else class="empty-history">
<i class="el-icon-document"></i>
<p>暂无变更历史</p>
</div>
</el-card>
</div>
</div>
</template>
<script>
import { getMaterialCoil, updateMaterialCoil, getMaterialCoilTrace } from '@/api/wms/coil';
import { completeAction } from '@/api/wms/pendingAction';
import { listWarehouse } from '@/api/wms/warehouse';
import { listRawMaterial } from '@/api/wms/rawMaterial';
import { listProduct } from '@/api/wms/product';
import ActualWarehouseSelect from "@/components/KLPService/ActualWarehouseSelect";
2025-11-03 17:03:03 +08:00
export default {
name: 'TypingCoil',
components: {
2025-11-11 12:21:16 +08:00
ActualWarehouseSelect
},
2025-11-03 17:03:03 +08:00
data() {
return {
loading: false,
historyLoading: false,
// 当前信息(只读)
currentInfo: {
coilId: null,
enterCoilNo: '',
currentCoilNo: '',
supplierCoilNo: '',
team: '',
itemType: null,
itemId: null,
itemName: '',
grossWeight: null,
netWeight: null,
warehouseId: null,
warehouseId: null,
2025-11-03 17:03:03 +08:00
nextWarehouseName: '',
status: 0,
remark: ''
},
// 更新表单
updateForm: {
currentCoilNo: '',
team: '',
2025-11-11 12:21:16 +08:00
materialType: null,
2025-11-03 17:03:03 +08:00
itemType: null,
itemId: null,
grossWeight: null,
netWeight: null,
warehouseId: null,
actualWarehouseId: null,
2025-11-03 17:03:03 +08:00
remark: ''
},
rules: {
currentCoilNo: [
{ required: true, message: '请输入当前钢卷号', trigger: 'blur' }
],
team: [
{ required: true, message: '请输入班组', trigger: 'blur' }
],
2025-11-11 12:21:16 +08:00
materialType: [
{ required: true, message: '请选择材料类型', trigger: 'change' }
],
2025-11-03 17:03:03 +08:00
itemType: [
{ required: true, message: '请选择物品类型', trigger: 'change' }
],
itemId: [
{ required: true, message: '请选择物品', trigger: 'change' }
],
grossWeight: [
{ required: true, message: '请输入毛重', trigger: 'blur' },
{ type: 'number', message: '毛重必须为数字', trigger: 'blur' }
],
netWeight: [
{ required: true, message: '请输入净重', trigger: 'blur' },
{ type: 'number', message: '净重必须为数字', trigger: 'blur' }
],
warehouseId: [
{ required: true, message: '请选择逻辑库区', trigger: 'change' }
],
actualWarehouseId: [
{ required: true, message: '请选择真实库区', trigger: 'change' }
2025-11-03 17:03:03 +08:00
]
},
warehouseList: [],
historySteps: [],
actionId: null,
// 原材料和产品列表
rawMaterialList: [],
productList: [],
2025-11-11 16:21:45 +08:00
// 原始完整列表备份(用于搜索过滤)
allRawMaterials: [],
allProducts: [],
2025-11-03 17:03:03 +08:00
itemSearchLoading: false,
// 只读模式
readonly: false
};
},
computed: {
2025-11-11 12:21:16 +08:00
// 动态显示标签
getItemLabel() {
if (this.updateForm.materialType === '成品') {
return '产品类型';
} else if (this.updateForm.materialType === '原料' || this.updateForm.materialType === '废品') {
return '原料类型';
}
return '物品';
},
// 动态显示占位符
getItemPlaceholder() {
if (this.updateForm.materialType === '成品') {
return '请选择产品类型';
} else if (this.updateForm.materialType === '原料') {
return '请选择原料类型';
} else if (this.updateForm.materialType === '废品') {
return '请选择原料类型(非必填)';
}
return '请先选择材料类型';
},
2025-11-03 17:03:03 +08:00
// 当前物品列表(根据物品类型动态切换)
currentItemList() {
if (this.updateForm.itemType === 'raw_material') {
return this.rawMaterialList.map(item => ({
id: item.rawMaterialId,
name: this.formatItemName(item)
2025-11-03 17:03:03 +08:00
}));
} else if (this.updateForm.itemType === 'product') {
return this.productList.map(item => ({
id: item.productId,
name: this.formatItemName(item)
2025-11-03 17:03:03 +08:00
}));
}
return [];
}
},
watch: {
2025-11-11 14:21:46 +08:00
// 不再需要watch直接用@change事件处理
2025-11-03 17:03:03 +08:00
},
async created() {
// 先加载库区列表
await this.loadWarehouses();
2025-11-11 12:21:16 +08:00
// 🔥 页面加载时直接加载所有原料和产品列表
await this.loadAllItems();
2025-11-03 17:03:03 +08:00
// 从路由参数获取coilId和actionId
const coilId = this.$route.query.coilId;
const actionId = this.$route.query.actionId;
const readonly = this.$route.query.readonly;
2025-11-03 17:03:03 +08:00
if (coilId) {
await this.loadCoilInfo(coilId);
}
2025-11-03 17:03:03 +08:00
if (actionId) {
this.actionId = actionId;
}
2025-11-03 17:03:03 +08:00
// 设置只读模式
if (readonly === 'true' || readonly === true) {
this.readonly = true;
}
},
methods: {
2025-11-11 16:21:45 +08:00
// 处理材料类型变化
handleMaterialTypeChange(value) {
// 清空物品选择
this.$set(this.updateForm, 'itemId', null);
// 根据材料类型设置物品类型
if (value === '成品') {
this.$set(this.updateForm, 'itemType', 'product');
// 恢复完整产品列表
this.productList = [...this.allProducts];
} else if (value === '原料' || value === '废品') {
this.$set(this.updateForm, 'itemType', 'raw_material');
// 恢复完整原料列表
this.rawMaterialList = [...this.allRawMaterials];
}
},
2025-11-03 17:03:03 +08:00
// 加载钢卷信息
async loadCoilInfo(coilId) {
try {
this.loading = true;
const response = await getMaterialCoil(coilId);
if (response.code === 200 && response.data) {
const data = response.data;
2025-11-03 17:03:03 +08:00
// 填充当前信息(左侧)
this.currentInfo = {
coilId: data.coilId,
enterCoilNo: data.enterCoilNo || '',
currentCoilNo: data.currentCoilNo || '',
supplierCoilNo: data.supplierCoilNo || '',
team: data.team || '',
itemType: data.itemType || null,
itemId: data.itemId || null,
itemName: this.getItemName(data),
grossWeight: data.grossWeight,
netWeight: data.netWeight,
warehouseId: data.warehouseId,
actualWarehouseId: data.actualWarehouseId,
nextWarehouseName: this.getWarehouseName(data.warehouseId),
2025-11-03 17:03:03 +08:00
remark: data.remark || ''
};
2025-11-03 17:03:03 +08:00
// 重新获取库区名称确保warehouseList已加载
if (data.warehouseId) {
this.currentInfo.nextWarehouseName = this.getWarehouseName(data.warehouseId);
2025-11-03 17:03:03 +08:00
}
2025-11-03 17:03:03 +08:00
// 加载对应类型的物品列表
if (data.itemType) {
await this.loadItemList(data.itemType);
}
2025-11-03 17:03:03 +08:00
// 加载变更历史
this.loadHistory();
}
} catch (error) {
this.$message.error('加载钢卷信息失败');
} finally {
this.loading = false;
}
},
// 获取物料名称
getItemName(data) {
if (data.rawMaterial) {
return data.rawMaterial.rawMaterialName;
} else if (data.product) {
return data.product.productName;
}
return '';
},
// 获取物品类型文本
getItemTypeText(itemType) {
if (itemType === 'raw_material') return '原材料';
if (itemType === 'product') return '产品';
return '—';
},
// 获取库区名称
getWarehouseName(warehouseId) {
if (!warehouseId) return '';
const warehouse = this.warehouseList.find(w => w.warehouseId === warehouseId);
return warehouse ? warehouse.warehouseName : '';
},
// 格式化物品名称添加规格和BOM信息
2025-11-11 16:21:45 +08:00
formatItemName(item) {
if (!item) return '';
// 获取名称(原材料或产品)
const name = item.rawMaterialName || item.productName || '';
if (!name) return '';
let displayName = name;
2025-11-11 16:21:45 +08:00
const specs = [];
2025-11-11 16:21:45 +08:00
// 1. 优先显示规格从对象的specification字段
if (item.specification) {
specs.push(item.specification);
}
// 2. 添加BOM参数最多2个
if (item.bomItems && item.bomItems.length > 0) {
const bomParams = item.bomItems
.filter(bomItem => bomItem.attrKey && bomItem.attrValue)
.slice(0, 2); // 最多2个BOM参数
2025-11-11 16:21:45 +08:00
bomParams.forEach(param => {
specs.push(`${param.attrKey}:${param.attrValue}`);
});
2025-11-11 16:21:45 +08:00
}
// 3. 拼接成最终格式
if (specs.length > 0) {
displayName += `${specs.join(' ')}`;
}
return displayName;
},
2025-11-03 17:03:03 +08:00
// 加载库区列表
async loadWarehouses() {
try {
const response = await listWarehouse({ pageNum: 1, pageSize: 1000 });
if (response.code === 200) {
this.warehouseList = response.rows || response.data || [];
}
} catch (error) {
console.error('加载库区列表失败', error);
}
},
2025-11-11 12:21:16 +08:00
// 页面加载时一次性加载所有原料和产品列表
async loadAllItems() {
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 || [];
2025-11-11 16:21:45 +08:00
this.allRawMaterials = rawMaterialRes.rows || []; // 保存完整备份
2025-11-11 12:21:16 +08:00
}
if (productRes.code === 200) {
this.productList = productRes.rows || [];
2025-11-11 16:21:45 +08:00
this.allProducts = productRes.rows || []; // 保存完整备份
2025-11-11 12:21:16 +08:00
}
} catch (error) {
2025-11-11 14:52:41 +08:00
console.error('加载物品列表失败', error);
2025-11-11 12:21:16 +08:00
}
},
2025-11-03 17:03:03 +08:00
// 加载物品列表(根据类型)
async loadItemList(itemType) {
2025-11-11 12:21:16 +08:00
if (!itemType) {
return;
}
2025-11-03 17:03:03 +08:00
try {
this.itemSearchLoading = true;
if (itemType === 'raw_material') {
// 使用带BOM的接口
const response = await listRawMaterial({
pageNum: 1,
pageSize: 100,
withBom: true // 请求包含BOM信息
});
2025-11-03 17:03:03 +08:00
if (response.code === 200) {
this.rawMaterialList = response.rows || [];
}
} else if (itemType === 'product') {
// 使用带BOM的接口
const response = await listProduct({
pageNum: 1,
pageSize: 100,
withBom: true // 请求包含BOM信息
});
2025-11-03 17:03:03 +08:00
if (response.code === 200) {
this.productList = response.rows || [];
}
}
} catch (error) {
console.error('加载物品列表失败', error);
} finally {
this.itemSearchLoading = false;
}
},
2025-11-11 16:21:45 +08:00
// 搜索物品(前端过滤,支持名称和规格搜索)
2025-11-03 17:03:03 +08:00
async searchItems(query) {
if (!this.updateForm.itemType) {
2025-11-11 12:21:16 +08:00
this.$message.warning('请先选择材料类型');
2025-11-03 17:03:03 +08:00
return;
}
2025-11-11 16:21:45 +08:00
// 如果没有输入,恢复完整列表
if (!query || query.trim() === '') {
2025-11-03 17:03:03 +08:00
if (this.updateForm.itemType === 'raw_material') {
2025-11-11 16:21:45 +08:00
this.rawMaterialList = [...this.allRawMaterials];
2025-11-03 17:03:03 +08:00
} else if (this.updateForm.itemType === 'product') {
2025-11-11 16:21:45 +08:00
this.productList = [...this.allProducts];
2025-11-03 17:03:03 +08:00
}
2025-11-11 16:21:45 +08:00
return;
}
// 前端过滤:在已加载的数据中搜索
const searchQuery = query.toLowerCase().trim();
if (this.updateForm.itemType === 'raw_material') {
// 从备份列表中过滤原材料
this.rawMaterialList = this.allRawMaterials.filter(item => {
// 搜索名称
const nameMatch = item.rawMaterialName && item.rawMaterialName.toLowerCase().includes(searchQuery);
// 搜索规格
const specMatch = item.specification && item.specification.toLowerCase().includes(searchQuery);
// 搜索 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 (this.updateForm.itemType === 'product') {
// 从备份列表中过滤产品
this.productList = this.allProducts.filter(item => {
// 搜索名称
const nameMatch = item.productName && item.productName.toLowerCase().includes(searchQuery);
// 搜索规格
const specMatch = item.specification && item.specification.toLowerCase().includes(searchQuery);
// 搜索 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;
});
2025-11-03 17:03:03 +08:00
}
},
// 物品选择变化
handleItemChange(itemId) {
2025-11-11 14:52:41 +08:00
// 物品选择变化处理
2025-11-03 17:03:03 +08:00
},
// 加载变更历史
async loadHistory() {
if (!this.currentInfo.enterCoilNo) {
return;
}
2025-11-03 17:03:03 +08:00
try {
this.historyLoading = true;
const response = await getMaterialCoilTrace({
enterCoilNo: this.currentInfo.enterCoilNo,
currentCoilNo: this.currentInfo.currentCoilNo || undefined
});
2025-11-03 17:03:03 +08:00
if (response.code === 200 && response.data) {
this.historySteps = response.data.steps || [];
}
} catch (error) {
console.error('加载变更历史失败', error);
} finally {
this.historyLoading = false;
}
},
// 复制当前信息到更新表单
copyFromCurrent() {
this.updateForm = {
currentCoilNo: this.currentInfo.currentCoilNo,
team: this.currentInfo.team,
2025-11-11 12:21:16 +08:00
materialType: this.currentInfo.materialType,
// 不复制 itemType 和 itemId让它们由 materialType 自动决定
itemType: null,
itemId: null,
2025-11-03 17:03:03 +08:00
grossWeight: parseFloat(this.currentInfo.grossWeight) || null,
netWeight: parseFloat(this.currentInfo.netWeight) || null,
warehouseId: this.currentInfo.warehouseId,
2025-11-03 17:03:03 +08:00
remark: this.currentInfo.remark
};
2025-11-11 12:21:16 +08:00
// materialType 会触发 watch自动设置 itemType 并加载物品列表
2025-11-03 17:03:03 +08:00
this.$message.success('已复制当前信息');
},
// 保存更新
async handleSave() {
this.$refs.updateForm.validate(async (valid) => {
if (!valid) {
return false;
}
const loadingInstance = this.$loading({
lock: true,
text: '正在更新钢卷信息,请稍后...',
background: 'rgba(0, 0, 0, 0.7)'
})
2025-11-03 17:03:03 +08:00
try {
this.loading = true;
// 构造更新数据使用标准update接口直接更新原记录
2025-11-03 17:03:03 +08:00
const updateData = {
coilId: this.currentInfo.coilId,
enterCoilNo: this.currentInfo.enterCoilNo,
supplierCoilNo: this.currentInfo.supplierCoilNo,
2025-11-03 17:03:03 +08:00
currentCoilNo: this.updateForm.currentCoilNo,
team: this.updateForm.team,
2025-11-11 12:21:16 +08:00
materialType: this.updateForm.materialType,
2025-11-03 17:03:03 +08:00
itemType: this.updateForm.itemType,
itemId: this.updateForm.itemId,
grossWeight: this.updateForm.grossWeight,
netWeight: this.updateForm.netWeight,
warehouseId: this.updateForm.warehouseId,
actualWarehouseId: this.updateForm.actualWarehouseId,
2025-11-03 17:03:03 +08:00
remark: this.updateForm.remark
// 注意不要传newCoils否则会走批量更新逻辑
2025-11-03 17:03:03 +08:00
};
2025-11-03 17:03:03 +08:00
const response = await updateMaterialCoil(updateData);
2025-11-03 17:03:03 +08:00
if (response.code === 200) {
this.$message.success('钢卷信息更新成功');
2025-11-03 17:03:03 +08:00
// 如果是从待操作列表进来的,标记操作为完成
if (this.actionId) {
await completeAction(this.actionId);
}
2025-11-03 17:03:03 +08:00
// 延迟返回
setTimeout(() => {
this.$router.back();
}, 1000);
} else {
this.$message.error(response.msg || '更新失败');
}
} catch (error) {
this.$message.error('更新失败');
console.error(error);
} finally {
this.loading = false;
loadingInstance.close();
2025-11-03 17:03:03 +08:00
}
});
},
// 取消操作
handleCancel() {
this.$router.back();
}
}
};
</script>
<style scoped lang="scss">
.typing-coil-container {
padding: 20px;
background: #f5f7fa;
min-height: calc(100vh - 84px);
}
/* 顶部操作栏 */
.header-bar {
display: flex;
justify-content: space-between;
align-items: center;
background: #fff;
padding: 16px 20px;
margin-bottom: 20px;
border-radius: 4px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}
.header-title {
font-size: 18px;
font-weight: 500;
color: #303133;
display: flex;
align-items: center;
gap: 8px;
2025-11-03 17:03:03 +08:00
i {
color: #0066cc;
font-size: 20px;
}
}
/* 主内容区 */
.content-wrapper {
display: grid;
grid-template-columns: 400px 1fr;
gap: 20px;
align-items: stretch; // 改为stretch让子元素高度一致
}
/* 左侧面板 */
.left-panel {
min-width: 0;
display: flex;
flex-direction: column;
}
/* 右侧面板 */
.right-panel {
min-width: 0;
display: flex;
flex-direction: column;
}
/* 确保两侧卡片高度一致 */
.info-card,
.form-card {
flex: 1;
display: flex;
flex-direction: column;
2025-11-03 17:03:03 +08:00
::v-deep .el-card__body {
flex: 1;
display: flex;
flex-direction: column;
}
}
/* 变更历史区域(占满整行) */
.history-section {
margin-top: 20px;
}
/* 卡片头部 */
.card-header {
display: flex;
align-items: center;
justify-content: space-between;
font-weight: 500;
2025-11-03 17:03:03 +08:00
i {
color: #0066cc;
margin-right: 5px;
}
}
/* 当前信息展示 */
.info-section {
.info-row {
display: flex;
align-items: flex-start;
margin-bottom: 12px;
2025-11-03 17:03:03 +08:00
&:last-child {
margin-bottom: 0;
}
2025-11-03 17:03:03 +08:00
.info-label {
color: #909399;
font-size: 14px;
min-width: 110px;
flex-shrink: 0;
}
2025-11-03 17:03:03 +08:00
.info-value {
color: #303133;
font-size: 14px;
font-weight: 500;
flex: 1;
word-break: break-all;
}
}
}
/* 变更历史 */
.history-card {
::v-deep .el-card__body {
max-height: 400px;
overflow-y: auto;
2025-11-03 17:03:03 +08:00
&::-webkit-scrollbar {
width: 6px;
}
2025-11-03 17:03:03 +08:00
&::-webkit-scrollbar-thumb {
background: #dcdfe6;
border-radius: 3px;
}
}
2025-11-03 17:03:03 +08:00
::v-deep .el-timeline {
padding-left: 10px;
}
}
.history-item {
.history-title {
font-weight: 500;
color: #303133;
margin-bottom: 8px;
}
2025-11-03 17:03:03 +08:00
.history-detail {
font-size: 13px;
color: #606266;
margin-bottom: 4px;
2025-11-03 17:03:03 +08:00
.detail-label {
color: #909399;
margin-right: 5px;
}
}
}
.empty-history {
text-align: center;
padding: 40px 0;
color: #909399;
2025-11-03 17:03:03 +08:00
i {
font-size: 48px;
margin-bottom: 10px;
display: block;
}
2025-11-03 17:03:03 +08:00
p {
margin: 0;
}
}
/* 表单样式优化 */
.form-card {
::v-deep .el-input-number {
width: 100%;
2025-11-03 17:03:03 +08:00
.el-input__inner {
text-align: left;
}
}
2025-11-03 17:03:03 +08:00
::v-deep .el-form-item {
margin-bottom: 20px;
}
2025-11-03 17:03:03 +08:00
// 修复数字输入框的样式
::v-deep input[type="number"] {
appearance: textfield;
-moz-appearance: textfield;
2025-11-03 17:03:03 +08:00
&::-webkit-outer-spin-button,
&::-webkit-inner-spin-button {
-webkit-appearance: none;
appearance: none;
margin: 0;
}
}
}
// 优化按钮文字颜色
// 实心primary按钮白色文字
::v-deep .el-button--primary.el-button--small:not(.is-plain) {
color: #fff;
}
// plain按钮和text按钮蓝色文字
::v-deep .el-button--primary.el-button--small.is-plain,
::v-deep .el-button--text {
color: #409eff;
2025-11-03 17:03:03 +08:00
&:hover {
color: #66b1ff;
}
}
</style>