refactor(wms): 优化钢卷操作界面组件和交互逻辑

替换通用选择器为专用组件,优化按钮加载状态
统一操作后的页面返回延迟时间
This commit is contained in:
砂糖
2025-11-18 15:15:05 +08:00
parent 1a5eadd99e
commit cb77562cdf
4 changed files with 68 additions and 53 deletions

View File

@@ -52,6 +52,8 @@
icon="el-icon-refresh" icon="el-icon-refresh"
size="mini" size="mini"
@click="handleRefresh" @click="handleRefresh"
:disabled="buttonLoading"
v-loading="buttonLoading"
>刷新</el-button> >刷新</el-button>
</el-col> </el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar> <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
@@ -137,6 +139,8 @@
type="primary" type="primary"
icon="el-icon-edit" icon="el-icon-edit"
@click="handleProcess(scope.row)" @click="handleProcess(scope.row)"
v-loading="buttonLoading"
:disabled="buttonLoading"
>操作</el-button> >操作</el-button>
<el-button <el-button
size="mini" size="mini"
@@ -152,6 +156,8 @@
type="warning" type="warning"
icon="el-icon-edit" icon="el-icon-edit"
@click="handleProcess(scope.row)" @click="handleProcess(scope.row)"
:disabled="buttonLoading"
v-loading="buttonLoading"
>继续</el-button> >继续</el-button>
<el-button <el-button
size="mini" size="mini"
@@ -250,7 +256,7 @@
</el-form-item> </el-form-item>
</el-form> </el-form>
<div slot="footer" class="dialog-footer"> <div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitForm"> </el-button> <el-button type="primary" @click="submitForm" :disabled="buttonLoading" v-loading="buttonLoading"> </el-button>
<el-button @click="cancel"> </el-button> <el-button @click="cancel"> </el-button>
</div> </div>
</el-dialog> </el-dialog>
@@ -286,6 +292,7 @@ export default {
return { return {
// 遮罩层 // 遮罩层
loading: true, loading: true,
buttonLoading: false,
// 选中数组 // 选中数组
ids: [], ids: [],
// 非单个禁用 // 非单个禁用
@@ -359,11 +366,13 @@ export default {
/** 查询待操作列表 */ /** 查询待操作列表 */
getList() { getList() {
this.loading = true; this.loading = true;
this.buttonLoading = true;
listPendingAction(this.queryParams).then(response => { listPendingAction(this.queryParams).then(response => {
console.log('response.rows', response.rows); console.log('response.rows', response.rows);
this.actionList = response.rows; this.actionList = response.rows;
this.total = response.total; this.total = response.total;
this.buttonLoading = false;
this.loading = false; this.loading = false;
}); });
}, },
@@ -429,6 +438,7 @@ export default {
}, },
/** 提交按钮 */ /** 提交按钮 */
submitForm() { submitForm() {
this.buttonLoading = true;
this.$refs['form'].validate(valid => { this.$refs['form'].validate(valid => {
if (valid) { if (valid) {
if (this.form.actionId != null) { if (this.form.actionId != null) {
@@ -436,12 +446,14 @@ export default {
this.$message.success('修改成功'); this.$message.success('修改成功');
this.open = false; this.open = false;
this.getList(); this.getList();
this.buttonLoading = false;
}); });
} else { } else {
addPendingAction(this.form).then(response => { addPendingAction(this.form).then(response => {
this.$message.success('新增成功'); this.$message.success('新增成功');
this.open = false; this.open = false;
this.getList(); this.getList();
this.buttonLoading = false;
}); });
} }
} }
@@ -468,10 +480,12 @@ export default {
console.log('操作类型:', row.actionType); console.log('操作类型:', row.actionType);
console.log('钢卷ID:', row.coilId); console.log('钢卷ID:', row.coilId);
this.buttonLoading = true;
this.$forceUpdate();
const actionType = parseInt(row.actionType); const actionType = parseInt(row.actionType);
// 特殊处理:发货和移库操作不需要跳转 // 特殊处理:发货和移库操作不需要跳转
if (actionType === 4 || actionType === 5) { if (actionType === 4 || actionType === 5 || actionType === 401 || actionType === 402) {
this.$message.info(actionType === 4 ? '发货操作已在移动端完成' : '移库操作已在移动端完成'); this.$message.info(actionType === 4 ? '发货操作已在移动端完成' : '移库操作已在移动端完成');
return; return;
} }
@@ -516,10 +530,11 @@ export default {
actionId: row.actionId actionId: row.actionId
} }
}); });
this.buttonLoading = false;
}).catch(error => { }).catch(error => {
console.error('更新状态失败:', error); console.error('更新状态失败:', error);
this.$message.error('更新状态失败: ' + (error.message || error)); this.$message.error('更新状态失败: ' + (error.message || error));
}); })
}, },
/** 取消操作 */ /** 取消操作 */
handleCancel(row) { handleCancel(row) {

View File

@@ -7,7 +7,7 @@
<span>钢卷合卷</span> <span>钢卷合卷</span>
</div> </div>
<div class="header-actions"> <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" :disabled="buttonLoading" v-loading="buttonLoading">保存合卷</el-button>
<el-button size="small" @click="handleCancel" :disabled="loading">{{ readonly ? '返回' : '取消' }}</el-button> <el-button size="small" @click="handleCancel" :disabled="loading">{{ readonly ? '返回' : '取消' }}</el-button>
</div> </div>
</div> </div>
@@ -74,8 +74,8 @@
@click="selectPendingCoil(pending, index)"> @click="selectPendingCoil(pending, index)">
<div class="pending-coil-no">{{ pending.currentCoilNo }}</div> <div class="pending-coil-no">{{ pending.currentCoilNo }}</div>
<div class="pending-coil-info"> <div class="pending-coil-info">
<span class="pending-label">扫码时间</span> <span class="pending-label">更新时间</span>
<span class="pending-value">{{ formatTime(pending.scanTime) }}</span> <span class="pending-value">{{ formatTime(pending.updateTime) }}</span>
</div> </div>
</div> </div>
</div> </div>
@@ -163,11 +163,11 @@
</el-form-item> </el-form-item>
<el-form-item :label="getItemLabel"> <el-form-item :label="getItemLabel">
<el-select v-model="targetCoil.itemId" :placeholder="getItemPlaceholder" filterable remote <raw-material-selector v-if="targetCoil.materialType === '原料' || targetCoil.materialType === '废品'" v-model="targetCoil.itemId" placeholder="请选择原料" style="width: 100%"
:remote-method="searchItems" :loading="itemSearchLoading" style="width: 100%" clearable :disabled="readonly || !targetCoil.materialType" />
:disabled="readonly || !targetCoil.materialType"> <product-selector v-else-if="targetCoil.materialType === '成品'" v-model="targetCoil.itemId" placeholder="请选择成品" style="width: 100%"
<el-option v-for="item in currentItemList" :key="item.id" :label="item.name" :value="item.id" /> clearable :disabled="readonly || !targetCoil.materialType" />
</el-select> <div v-else>请先选择物料类型</div>
</el-form-item> </el-form-item>
<el-form-item label="毛重(t)"> <el-form-item label="毛重(t)">
@@ -225,12 +225,17 @@ import { listProductWithBom } from '@/api/wms/product';
import { listPendingAction, completeAction } from '@/api/wms/pendingAction'; import { listPendingAction, completeAction } from '@/api/wms/pendingAction';
import CoilSelector from '@/components/CoilSelector'; import CoilSelector from '@/components/CoilSelector';
import ActualWarehouseSelect from "@/components/KLPService/ActualWarehouseSelect"; import ActualWarehouseSelect from "@/components/KLPService/ActualWarehouseSelect";
import RawMaterialSelector from "@/components/KLPService/RawMaterialSelect";
import ProductSelector from "@/components/KLPService/ProductSelect";
export default { export default {
name: 'MergeCoil', name: 'MergeCoil',
components: { components: {
CoilSelector, CoilSelector,
ActualWarehouseSelect ActualWarehouseSelect,
RawMaterialSelector,
ProductSelector
}, },
data() { data() {
return { return {
@@ -252,6 +257,7 @@ export default {
packingStatus: '', packingStatus: '',
trimmingRequirement: '' trimmingRequirement: ''
}, },
buttonLoading: false,
loading: false, loading: false,
// 钢卷选择器可见性 // 钢卷选择器可见性
coilSelectorVisible: false, coilSelectorVisible: false,
@@ -370,23 +376,6 @@ export default {
} }
}, },
methods: { methods: {
// 处理材料类型变化
handleMaterialTypeChange(value) {
// 清空物品选择
this.$set(this.targetCoil, 'itemId', null);
// 根据材料类型设置物品类型
if (value === '成品') {
this.$set(this.targetCoil, 'itemType', 'product');
// 清空列表,等待用户搜索
this.productList = [];
} else if (value === '原料' || value === '废品') {
this.$set(this.targetCoil, 'itemType', 'raw_material');
// 清空列表,等待用户搜索
this.rawMaterialList = [];
}
},
// 加载第一个钢卷(从待操作进入时) // 加载第一个钢卷(从待操作进入时)
async loadFirstCoil(coilId) { async loadFirstCoil(coilId) {
try { try {
@@ -409,7 +398,6 @@ export default {
productName: data.productName || (data.product ? data.product.productName : ''), productName: data.productName || (data.product ? data.product.productName : ''),
specification: data.rawMaterial?.specification || data.product?.specification || '', specification: data.rawMaterial?.specification || data.product?.specification || '',
bomItems: data.bomItemList || [], bomItems: data.bomItemList || [],
}, },
{ {
coilId: null, coilId: null,
@@ -450,13 +438,13 @@ export default {
// 分别查询待处理和处理中的记录 // 分别查询待处理和处理中的记录
const responses = await Promise.all([ const responses = await Promise.all([
listPendingAction({ listPendingAction({
actionType: 1, // 合卷操作 actionType: 200, // 合卷操作
actionStatus: 0, // 待处理 actionStatus: 0, // 待处理
pageNum: 1, pageNum: 1,
pageSize: 1000 pageSize: 1000
}), }),
listPendingAction({ listPendingAction({
actionType: 1, // 合卷操作 actionType: 200, // 合卷操作
actionStatus: 1, // 处理中 actionStatus: 1, // 处理中
pageNum: 1, pageNum: 1,
pageSize: 1000 pageSize: 1000
@@ -753,7 +741,7 @@ export default {
// 延迟返回,让用户看到成功提示 // 延迟返回,让用户看到成功提示
setTimeout(() => { setTimeout(() => {
this.$router.back(); this.$router.back();
}, 1000); }, 100);
} else { } else {
this.$message.error(response.msg || '合卷保存失败'); this.$message.error(response.msg || '合卷保存失败');
} }

View File

@@ -121,37 +121,34 @@
</el-form-item> </el-form-item>
<el-form-item v-if="item.materialType === '成品'" label="质量状态" prop="qualityStatus"> <el-form-item v-if="item.materialType === '成品'" label="质量状态" prop="qualityStatus">
<el-input v-model="item.qualityStatus" placeholder="请输入质量状态" <el-input v-model="item.qualityStatus" placeholder="请输入质量状态" :disabled="readonly">
:disabled="readonly">
</el-input> </el-input>
</el-form-item> </el-form-item>
<el-form-item v-if="item.materialType === '成品'" label="切边要求" prop="trimmingRequirement"> <el-form-item v-if="item.materialType === '成品'" label="切边要求" prop="trimmingRequirement">
<el-input v-model="item.trimmingRequirement" placeholder="请输入切边要求" <el-input v-model="item.trimmingRequirement" placeholder="请输入切边要求" :disabled="readonly">
:disabled="readonly">
</el-input> </el-input>
</el-form-item> </el-form-item>
<el-form-item v-if="item.materialType === '成品'" label="打包状态" prop="packingStatus"> <el-form-item v-if="item.materialType === '成品'" label="打包状态" prop="packingStatus">
<el-input v-model="item.packingStatus" placeholder="请输入打包状态" <el-input v-model="item.packingStatus" placeholder="请输入打包状态" :disabled="readonly">
:disabled="readonly">
</el-input> </el-input>
</el-form-item> </el-form-item>
<el-form-item v-if="item.materialType === '成品'" label="包装要求" prop="packagingRequirement"> <el-form-item v-if="item.materialType === '成品'" label="包装要求" prop="packagingRequirement">
<el-input v-model="item.packagingRequirement" placeholder="请输入包装要求" <el-input v-model="item.packagingRequirement" placeholder="请输入包装要求" :disabled="readonly">
:disabled="readonly">
</el-input> </el-input>
</el-form-item> </el-form-item>
<!-- 物品类型由材料类型自动决定不显示选择框 --> <!-- 物品类型由材料类型自动决定不显示选择框 -->
<el-form-item :label="getItemLabel(item.materialType)" :required="item.materialType !== '废品'"> <el-form-item :label="getItemLabel(item.materialType)" :required="item.materialType !== '废品'">
<el-select v-model="item.itemId" :placeholder="getItemPlaceholder(item.materialType)" filterable <raw-material-select v-if="item.materialType === '原料' || item.materialType === '废品'"
remote :remote-method="(query) => searchItemsForSplit(query, index)" :loading="itemSearchLoading" v-model="item.itemId" placeholder="请选择原料" style="width: 100%" clearable
style="width: 100%" :disabled="readonly || !item.materialType"> :disabled="readonly || !item.materialType" />
<el-option v-for="option in getItemListForSplit(item.itemType)" :key="option.id" <product-select v-else-if="item.materialType === '成品'" v-model="item.itemId"
:label="option.name" :value="option.id" /> placeholder="请选择成品" style="width: 100%" clearable
</el-select> :disabled="readonly || !item.materialType" />
<div v-else>请先选择物料类型</div>
</el-form-item> </el-form-item>
<el-form-item label="毛重(t)" required> <el-form-item label="毛重(t)" required>
@@ -205,12 +202,16 @@ import { listProductWithBom } from '@/api/wms/product';
import { completeAction } from '@/api/wms/pendingAction'; import { completeAction } from '@/api/wms/pendingAction';
import CoilSelector from '@/components/CoilSelector'; import CoilSelector from '@/components/CoilSelector';
import ActualWarehouseSelect from "@/components/KLPService/ActualWarehouseSelect"; import ActualWarehouseSelect from "@/components/KLPService/ActualWarehouseSelect";
import RawMaterialSelect from "@/components/KLPService/RawMaterialSelect";
import ProductSelect from "@/components/KLPService/ProductSelect";
export default { export default {
name: 'SplitCoil', name: 'SplitCoil',
components: { components: {
CoilSelector, CoilSelector,
ActualWarehouseSelect ActualWarehouseSelect,
RawMaterialSelect,
ProductSelect,
}, },
data() { data() {
return { return {
@@ -618,7 +619,7 @@ export default {
// 延迟返回,让用户看到成功提示 // 延迟返回,让用户看到成功提示
setTimeout(() => { setTimeout(() => {
this.$router.back(); this.$router.back();
}, 1000); }, 100);
} else { } else {
this.$message.error(response.msg || '分条保存失败'); this.$message.error(response.msg || '分条保存失败');
} }

View File

@@ -130,11 +130,18 @@
<el-form-item :label="getItemLabel" :prop="updateForm.materialType === '废品' ? '' : 'itemId'" <el-form-item :label="getItemLabel" :prop="updateForm.materialType === '废品' ? '' : 'itemId'"
:rules="updateForm.materialType === '废品' ? [] : rules.itemId"> :rules="updateForm.materialType === '废品' ? [] : rules.itemId">
<el-select v-model="updateForm.itemId" :placeholder="getItemPlaceholder" filterable remote <!-- <el-select v-model="updateForm.itemId" :placeholder="getItemPlaceholder" filterable remote
:remote-method="searchItems" :loading="itemSearchLoading" style="width: 100%" :remote-method="searchItems" :loading="itemSearchLoading" style="width: 100%"
:disabled="readonly || !updateForm.materialType"> :disabled="readonly || !updateForm.materialType">
<el-option v-for="item in currentItemList" :key="item.id" :label="item.name" :value="item.id" /> <el-option v-for="item in currentItemList" :key="item.id" :label="item.name" :value="item.id" />
</el-select> </el-select> -->
<RawMaterialSelect v-if="updateForm.materialType === '原料'" v-model="updateForm.itemId"
placeholder="请选择原料" style="width: 100%" clearable
:disabled="readonly || !updateForm.materialType" />
<ProductSelect v-else-if="updateForm.materialType === '成品'" v-model="updateForm.itemId"
placeholder="请选择成品" style="width: 100%" clearable
:disabled="readonly || !updateForm.materialType" />
<div v-else>请先选择物料类型</div>
</el-form-item> </el-form-item>
<el-form-item label="毛重(t)" prop="grossWeight"> <el-form-item label="毛重(t)" prop="grossWeight">
@@ -221,11 +228,15 @@ import { listWarehouse } from '@/api/wms/warehouse';
import { listRawMaterialWithBom } from '@/api/wms/rawMaterial'; import { listRawMaterialWithBom } from '@/api/wms/rawMaterial';
import { listProductWithBom } from '@/api/wms/product'; import { listProductWithBom } from '@/api/wms/product';
import ActualWarehouseSelect from "@/components/KLPService/ActualWarehouseSelect"; import ActualWarehouseSelect from "@/components/KLPService/ActualWarehouseSelect";
import RawMaterialSelect from "@/components/KLPService/RawMaterialSelect";
import ProductSelect from "@/components/KLPService/ProductSelect";
export default { export default {
name: 'TypingCoil', name: 'TypingCoil',
components: { components: {
ActualWarehouseSelect ActualWarehouseSelect,
RawMaterialSelect,
ProductSelect,
}, },
data() { data() {
return { return {
@@ -627,7 +638,7 @@ export default {
// 延迟返回 // 延迟返回
setTimeout(() => { setTimeout(() => {
this.$router.back(); this.$router.back();
}, 1000); }, 100);
} else { } else {
this.$message.error(response.msg || '更新失败'); this.$message.error(response.msg || '更新失败');
} }