feat(material): 基础信息双胞胎页面:移除人工「标记已采购」,改自动「采购在途」

list.vue 与 buyOdoo.vue 同步改造。这两个文件是手工维护的副本、不是共享组件,
改动必须两边都做 —— 本项目已多次因只改单边导致同一 bug 在另一页长期存活
(参考价格脏检查、表单禁用守卫、发起采购申请按钮等都曾漏同步)。

改动:
  - 移除「标记已采购」按钮、handleMarkOrdered 函数与 markWarningOrdered 引用
  - 操作列改为只读 el-tag「采购在途」,由后端 isPurchasing 派生
  - 预警状态列降级:缺货但已有在途采购单时显示蓝色「缺货(已采购)」而非红/黄

★ 降级只改前端展示,后端 warningStatus 原样保留 —— 预警强排
  (enableWarningSort 的 order_by case())依赖它,改后端会连带影响排序。

★ 顺带修掉一个历史问题:前端 `scope.row.warningOrdered` 这个字段后端从未输出过
  (后端只给 isOrdered,且列表接口根本没查这一列),所以那个 disabled 的
  「采购在途」按钮从来不会显示,用户标记后永远看不到已标记状态。
This commit is contained in:
yueli
2026-09-18 14:31:22 +08:00
parent 70dd257392
commit 970c03fb44
2 changed files with 43 additions and 43 deletions

View File

@ -380,9 +380,18 @@
<span v-else style="color: #ccc;">-</span>
</template>
</el-table-column>
<el-table-column v-if="columns.warningStatus.visible && hasColPermission('warningStatus')" label="预警状态" width="120" align="center">
<el-table-column v-if="columns.warningStatus.visible && hasColPermission('warningStatus')" label="预警状态" width="130" align="center">
<template #default="{ row }">
<template v-if="row.warningStatus === 2">
<!-- ★ 预警降级:缺货但已有在途采购单时不再闪红灯 —— 红灯的含义是
「需要你去买」,而这里已经有人在买了。判定来自后端 isPurchasing
与待采购池共用同一份逻辑。只改展示,后端 warningStatus 原样保留。 -->
<template v-if="row.isPurchasing && row.warningStatus > 0">
<el-tag type="primary" size="small">缺货(已采购)</el-tag>
<div style="font-size: 11px; color: #999;">
阈值: {{ row.warningStatus === 2 ? row.warningRed : row.warningYellow }}
</div>
</template>
<template v-else-if="row.warningStatus === 2">
<el-tag type="danger" size="small">红色预警</el-tag>
<div style="font-size: 11px; color: #999;">阈值: {{ row.warningRed }}</div>
</template>
@ -400,10 +409,9 @@
<template #default="scope">
<el-button v-if="userStore.hasPermission('material_list:operation')" link type="primary" size="small" @click="handleEdit(scope.row)">编辑</el-button>
<el-button v-if="userStore.hasPermission('material_list:edit_warning')" link type="warning" size="small" @click="handleSetSingleWarning(scope.row)">设置预警</el-button>
<template v-if="userStore.hasPermission('material_list:edit_warning') && scope.row.warningStatus > 0">
<el-button v-if="scope.row.warningOrdered" disabled size="small" type="info">采购在途</el-button>
<el-button v-else link type="success" size="small" @click="handleMarkOrdered(scope.row)">标记已采购</el-button>
</template>
<!-- 采购在途:由后端 isPurchasing 自动派生(与待采购池同一判定)。
不再提供人工标记入口 —— 建单即在途,驳回 / 强制结案即自动解除。 -->
<el-tag v-if="scope.row.isPurchasing" type="primary" size="small">采购在途</el-tag>
<el-button v-if="userStore.hasPermission('material_list:operation')" link type="danger" size="small" @click="handleDelete(scope.row)">删除</el-button>
</template>
</el-table-column>
@ -785,7 +793,6 @@ import {
batchSetWarning,
batchSetInspection,
batchSetApprovalRequired,
markWarningOrdered,
getMaterialUnitsAPI,
getOdooSummary
} from '@/api/material_base';
@ -837,7 +844,8 @@ interface MaterialBaseVO {
inventoryCount?: number;
availableCount?: number;
warningStatus?: number;
warningOrdered?: boolean;
// 采购在途:后端自动派生(有活跃采购单即 true取代了原先人工标记的 warningOrdered
isPurchasing?: boolean;
warningRedEmails?: string;
warningYellowEmails?: string;
referencePrice?: number;
@ -1567,13 +1575,10 @@ const handleSetSingleWarning = (row: MaterialBaseVO) => {
warningDialog.title = '设置预警'; warningDialog.visible = true;
};
const handleMarkOrdered = (row: MaterialBaseVO) => {
ElMessageBox.confirm('确认已对该预警物料下单?标记后在途期间将不再发送预警邮件。', '确认标记已采购', { confirmButtonText: '确认', cancelButtonText: '取消', type: 'warning' })
.then(async () => {
try { await markWarningOrdered({ baseId: row.id, isOrdered: true }); ElMessage.success('已标记为已采购'); getList(); }
catch (error: any) { ElMessage.error(error?.msg || '标记失败'); }
}).catch(() => {});
};
// ★ 原「标记已采购」人工入口已移除:采购在途状态改由后端 isPurchasing 自动派生
// (见列表操作列的 el-tag。人工标记要靠人记得点、也靠人记得取消
// 而自动判定在建单时即在途、单据驳回/强制结案时即解除,且与待采购池、
// 预警邮件静音共用同一份逻辑,三处口径不会各说各话。
const submitWarning = async () => {
if (!warningFormRef.value) return; await warningFormRef.value.validate();

View File

@ -359,9 +359,20 @@
<span v-else style="color: #ccc;">-</span>
</template>
</el-table-column>
<el-table-column v-if="columns.warningStatus.visible && hasColPermission('warningStatus')" label="预警状态" width="120" align="center">
<el-table-column v-if="columns.warningStatus.visible && hasColPermission('warningStatus')" label="预警状态" width="130" align="center">
<template #default="{ row }">
<template v-if="row.warningStatus === 2">
<!-- ★ 预警降级:物料缺货但**已有在途采购单**时不再闪红灯。
红灯的含义是「需要你去买」,而这里已经有人在买了 ——
继续亮红只会制造重复采购的冲动。降级为蓝色「缺货(已采购)」。
判定由后端 isPurchasing 给出,与待采购池共用同一份逻辑。
注意这里只改**展示**:后端 warningStatus 原样保留(预警强排依赖它)。 -->
<template v-if="row.isPurchasing && row.warningStatus > 0">
<el-tag type="primary" size="small">缺货(已采购)</el-tag>
<div style="font-size: 11px; color: #999;">
阈值: {{ row.warningStatus === 2 ? row.warningRed : row.warningYellow }}
</div>
</template>
<template v-else-if="row.warningStatus === 2">
<el-tag type="danger" size="small">红色预警</el-tag>
<div style="font-size: 11px; color: #999;">阈值: {{ row.warningRed }}</div>
</template>
@ -379,10 +390,10 @@
<template #default="scope">
<el-button v-if="userStore.hasPermission('material_list:operation')" link type="primary" size="small" @click="handleEdit(scope.row)">编辑</el-button>
<el-button v-if="userStore.hasPermission('material_list:edit_warning')" link type="warning" size="small" @click="handleSetSingleWarning(scope.row)">设置预警</el-button>
<template v-if="userStore.hasPermission('material_list:edit_warning') && scope.row.warningStatus > 0">
<el-button v-if="scope.row.warningOrdered" disabled size="small" type="info">采购在途</el-button>
<el-button v-else link type="success" size="small" @click="handleMarkOrdered(scope.row)">标记已采购</el-button>
</template>
<!-- 采购在途:由后端 isPurchasing 自动派生(与待采购池同一判定)。
不再提供人工标记入口 —— 人工标记要靠人记得去点、也靠人记得取消;
这个是算出来的:建单即在途,驳回 / 强制结案即自动解除。 -->
<el-tag v-if="scope.row.isPurchasing" type="primary" size="small">采购在途</el-tag>
<el-button v-if="userStore.hasPermission('material_list:operation')" link type="danger" size="small" @click="handleDelete(scope.row)">删除</el-button>
</template>
</el-table-column>
@ -785,7 +796,6 @@ import {
batchSetWarning,
batchSetInspection,
batchSetApprovalRequired,
markWarningOrdered,
getMaterialUnitsAPI
} from '@/api/material_base';
import { uploadFile, deleteFile } from '@/api/common/upload';
@ -816,7 +826,8 @@ interface MaterialBaseVO {
inventoryCount?: number;
availableCount?: number;
warningStatus?: number;
warningOrdered?: boolean;
// 采购在途:后端自动派生(有活跃采购单即 true取代了原先人工标记的 warningOrdered
isPurchasing?: boolean;
warningRedEmails?: string;
warningYellowEmails?: string;
referencePrice?: number;
@ -1756,26 +1767,10 @@ const handleSetSingleWarning = (row: MaterialBaseVO) => {
warningDialog.visible = true;
};
// 标记预警物料已采购
const handleMarkOrdered = (row: MaterialBaseVO) => {
ElMessageBox.confirm(
'确认已对该预警物料下单?标记后在途期间将不再发送预警邮件。',
'确认标记已采购',
{
confirmButtonText: '确认',
cancelButtonText: '取消',
type: 'warning'
}
).then(async () => {
try {
await markWarningOrdered({ baseId: row.id, isOrdered: true });
ElMessage.success('已标记为已采购');
getList();
} catch (error: any) {
ElMessage.error(error?.msg || '标记失败');
}
}).catch(() => {});
};
// ★ 原「标记已采购」人工入口已移除:采购在途状态改由后端 isPurchasing 自动派生
// (见列表操作列的 el-tag。人工标记要靠人记得点、也靠人记得取消
// 而自动判定在建单时即在途、单据驳回/强制结案时即解除,且与待采购池、
// 预警邮件静音共用同一份逻辑,三处口径不会各说各话。
// 提交预警设置
const submitWarning = async () => {