feat(mes): 优化工艺路线管理功能,调整状态处理逻辑

移除工艺路线状态的必填验证,调整状态字段为可选。更新状态切换逻辑,增强用户交互体验,确保状态操作的可用性和提示信息的准确性。
pull/871/MERGE
YunaiV 2026-04-04 16:42:26 +08:00
parent 375d5a2236
commit cfa787530e
6 changed files with 89 additions and 115 deletions

View File

@ -6,7 +6,7 @@ export interface ProRouteVO {
code: string // 工艺路线编码
name: string // 工艺路线名称
description?: string // 工艺路线说明
status: number // 状态
status?: number // 状态
remark?: string // 备注
createTime?: Date // 创建时间
}

View File

@ -10,7 +10,7 @@
:disabled="isDetail"
>
<el-row :gutter="20">
<el-col :span="8">
<el-col :span="12">
<el-form-item label="编码" prop="code">
<el-input v-model="formData.code" placeholder="请输入编码" :disabled="isHeaderReadonly">
<template #append>
@ -19,7 +19,7 @@
</el-input>
</el-form-item>
</el-col>
<el-col :span="8">
<el-col :span="12">
<el-form-item label="名称" prop="name">
<el-input
v-model="formData.name"
@ -28,19 +28,6 @@
/>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="状态" prop="status">
<el-radio-group v-model="formData.status" :disabled="isHeaderReadonly">
<el-radio
v-for="dict in getIntDictOptions(DICT_TYPE.COMMON_STATUS)"
:key="dict.value"
:value="dict.value"
>
{{ dict.label }}
</el-radio>
</el-radio-group>
</el-form-item>
</el-col>
</el-row>
<el-form-item label="说明" prop="description">
<el-input
@ -61,7 +48,6 @@
</el-form-item>
<!-- 编辑/启用/详情时展示 Tab -->
<template v-if="formData.id">
<el-divider content-position="left">详细信息</el-divider>
<el-tabs v-model="activeTab">
<el-tab-pane label="组成工序" name="process">
<RouteProcessList :routeId="formData.id" :form-type="formType" />
@ -73,20 +59,10 @@
</template>
</el-form>
<template #footer>
<el-button
v-if="isEditable"
type="primary"
@click="submitForm"
:disabled="formLoading"
>
<el-button v-if="isEditable" type="primary" @click="submitForm" :disabled="formLoading">
</el-button>
<el-button
v-if="isEnable"
type="success"
@click="handleEnable"
:disabled="formLoading"
>
<el-button v-if="isEnable" type="success" @click="handleEnable" :disabled="formLoading">
确认启用
</el-button>
<el-button @click="dialogVisible = false"> </el-button>
@ -95,10 +71,10 @@
</template>
<script setup lang="ts">
import { getIntDictOptions, DICT_TYPE } from '@/utils/dict'
import { CommonStatusEnum } from '@/utils/constants'
import { generateRandomStr } from '@/utils'
import { ProRouteApi, ProRouteVO } from '@/api/mes/pro/route'
import { AutoCodeRecordApi } from '@/api/mes/md/autocode/record'
import { MesAutoCodeRuleCode } from '@/views/mes/utils/constants'
import RouteProcessList from './RouteProcessList.vue'
import RouteProductList from './RouteProductList.vue'
@ -128,21 +104,17 @@ const formData = ref<ProRouteVO>({
code: '',
name: '',
description: '',
status: CommonStatusEnum.ENABLE,
remark: ''
})
const formRules = reactive({
code: [{ required: true, message: '编码不能为空', trigger: 'blur' }],
name: [{ required: true, message: '名称不能为空', trigger: 'blur' }],
// TODO @AIsave
status: [{ required: true, message: '状态不能为空', trigger: 'change' }]
name: [{ required: true, message: '名称不能为空', trigger: 'blur' }]
})
const formRef = ref() // Ref
/** 生成编码 */
const generateCode = () => {
// TODO @AImysql
formData.value.code = 'ROUTE' + generateRandomStr(8)
const generateCode = async () => {
formData.value.code = await AutoCodeRecordApi.generateAutoCode(MesAutoCodeRuleCode.PRO_ROUTE_CODE)
}
/** 打开弹窗 */
@ -173,7 +145,6 @@ const submitForm = async () => {
message.success('新增成功')
//
formData.value.id = res
formData.value.status = CommonStatusEnum.DISABLE
formType.value = 'update'
} else {
await ProRouteApi.updateRoute(data)
@ -188,7 +159,9 @@ const submitForm = async () => {
/** 确认启用 */
const handleEnable = async () => {
try {
await message.confirm('确认启用"' + formData.value.name + '"工艺路线吗?启用前请确认工序和产品 BOM 配置完整。')
await message.confirm(
'确认启用"' + formData.value.name + '"工艺路线吗?启用前请确认工序和产品 BOM 配置完整。'
)
formLoading.value = true
await ProRouteApi.updateRouteStatus(formData.value.id!, CommonStatusEnum.ENABLE)
message.success('启用成功')
@ -207,7 +180,6 @@ const resetForm = () => {
code: '',
name: '',
description: '',
status: CommonStatusEnum.ENABLE,
remark: ''
}
formRef.value?.resetFields()

View File

@ -52,17 +52,10 @@
</el-table-column>
<el-table-column label="甘特图颜色" align="center" prop="colorCode" width="100">
<template #default="scope">
<div
v-if="scope.row.colorCode"
style="display: flex; align-items: center; justify-content: center; gap: 4px"
>
<div v-if="scope.row.colorCode" class="flex items-center justify-center gap-4px">
<div
:style="{
backgroundColor: scope.row.colorCode,
width: '16px',
height: '16px',
borderRadius: '4px'
}"
:style="{ backgroundColor: scope.row.colorCode }"
class="w-16px h-16px rounded-4px"
></div>
<span>{{ scope.row.colorCode }}</span>
</div>
@ -78,7 +71,7 @@
<!-- 表单弹窗添加/修改 -->
<Dialog :title="formTitle" v-model="formVisible" width="960px">
<el-form ref="formRef" :model="formData" :rules="formRules" label-width="130px">
<el-form ref="formRef" :model="formData" :rules="formRules" label-width="140px">
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="序号" prop="sort">
@ -113,8 +106,7 @@
</el-col>
<el-col :span="12">
<el-form-item label="甘特图颜色" prop="colorCode">
<!-- TODO @AIunocss -->
<div style="display: flex; align-items: center; gap: 8px">
<div class="flex items-center gap-8px">
<el-color-picker v-model="formData.colorCode" />
<span v-if="formData.colorCode">{{ formData.colorCode }}</span>
</div>
@ -200,8 +192,9 @@ const formData = ref<any>({}) // 表单数据
const formRules = reactive({
sort: [{ required: true, message: '序号不能为空', trigger: 'blur' }],
processId: [{ required: true, message: '工序不能为空', trigger: 'change' }],
linkType: [{ required: true, message: '工序关系不能为空', trigger: 'change' }]
// TODO @AIkeyFlagcheckFlag
linkType: [{ required: true, message: '工序关系不能为空', trigger: 'change' }],
keyFlag: [{ required: true, message: '是否关键工序不能为空', trigger: 'change' }],
checkFlag: [{ required: true, message: '是否需要质检确认不能为空', trigger: 'change' }]
})
const formRef = ref() // Ref

View File

@ -13,7 +13,6 @@
<el-table-column label="产品物料名称" align="center" prop="itemName" width="150" />
<el-table-column label="规格型号" align="center" prop="specification" width="150" />
<el-table-column label="单位" align="center" prop="unitName" width="80" />
<!-- TODO @AI对齐的话生产数量生产用时生产单位是不是不需要这些字段 -->
<el-table-column label="生产数量" align="center" prop="quantity" width="100" />
<el-table-column label="生产用时" align="center" width="120">
<template #default="scope">
@ -35,26 +34,31 @@
<!-- 表单弹窗添加/修改 -->
<Dialog :title="formTitle" v-model="formVisible" width="960px">
<el-form ref="formRef" :model="formData" :rules="formRules" label-width="100px">
<el-form-item label="产品" prop="itemId">
<MdItemSelect v-model="formData.itemId" />
</el-form-item>
<el-form-item label="生产数量" prop="quantity">
<el-input-number v-model="formData.quantity" :min="1" controls-position="right" />
</el-form-item>
<el-row :gutter="20">
<el-col :span="14">
<el-col :span="12">
<el-form-item label="产品" prop="itemId">
<MdItemSelect v-model="formData.itemId" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="生产数量" prop="quantity">
<el-input-number v-model="formData.quantity" :min="1" controls-position="right" class="!w-1/1" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="生产用时" prop="productionTime">
<el-input-number
v-model="formData.productionTime"
:min="0"
:precision="2"
controls-position="right"
class="!w-1/1"
/>
</el-form-item>
</el-col>
<el-col :span="10">
<el-col :span="12">
<el-form-item label="时间单位" prop="timeUnitType">
<el-select v-model="formData.timeUnitType" placeholder="请选择">
<el-select v-model="formData.timeUnitType" placeholder="请选择" class="!w-1/1">
<el-option
v-for="dict in getStrDictOptions(DICT_TYPE.MES_TIME_UNIT_TYPE)"
:key="dict.value"

View File

@ -73,10 +73,15 @@
</el-table-column>
<el-table-column label="路线名称" align="center" prop="name" min-width="200" />
<el-table-column label="路线说明" align="center" prop="description" min-width="200" />
<!-- TODO @AI改成 el-switch 形式 -->
<el-table-column label="状态" align="center" prop="status" min-width="100">
<template #default="scope">
<dict-tag :type="DICT_TYPE.COMMON_STATUS" :value="scope.row.status" />
<el-switch
v-model="scope.row.status"
:active-value="0"
:inactive-value="1"
@change="handleStatusChange(scope.row)"
:disabled="!checkPermi(['mes:pro-route:update'])"
/>
</template>
</el-table-column>
<el-table-column label="备注" align="center" prop="remark" min-width="120" />
@ -89,45 +94,40 @@
/>
<el-table-column label="操作" align="center" width="220" fixed="right">
<template #default="scope">
<!-- 停用状态编辑启用删除 -->
<!-- TODO @AI禁用不可编辑删除时有个 tooltip disable 这样不要直接隐藏 -->
<el-button
link
type="primary"
@click="openForm('update', scope.row.id)"
v-hasPermi="['mes:pro-route:update']"
v-if="scope.row.status === CommonStatusEnum.DISABLE"
<el-tooltip
:disabled="scope.row.status === CommonStatusEnum.DISABLE"
content="仅停用状态,才可以操作"
placement="top"
>
编辑
</el-button>
<el-button
link
type="success"
@click="openForm('enable', scope.row.id)"
v-hasPermi="['mes:pro-route:update']"
v-if="scope.row.status === CommonStatusEnum.DISABLE"
<span class="inline-block cursor-not-allowed">
<el-button
link
type="primary"
@click="openForm('update', scope.row.id)"
v-hasPermi="['mes:pro-route:update']"
:disabled="scope.row.status !== CommonStatusEnum.DISABLE"
>
编辑
</el-button>
</span>
</el-tooltip>
<el-tooltip
:disabled="scope.row.status === CommonStatusEnum.DISABLE"
content="仅停用状态,才可以操作"
placement="top"
>
启用
</el-button>
<el-button
link
type="danger"
@click="handleDelete(scope.row.id)"
v-hasPermi="['mes:pro-route:delete']"
v-if="scope.row.status === CommonStatusEnum.DISABLE"
>
删除
</el-button>
<!-- 启用状态禁用 -->
<el-button
link
type="warning"
@click="handleDisable(scope.row)"
v-hasPermi="['mes:pro-route:update']"
v-if="scope.row.status === CommonStatusEnum.ENABLE"
>
禁用
</el-button>
<span class="inline-block cursor-not-allowed">
<el-button
link
type="danger"
@click="handleDelete(scope.row.id)"
v-hasPermi="['mes:pro-route:delete']"
:disabled="scope.row.status !== CommonStatusEnum.DISABLE"
>
删除
</el-button>
</span>
</el-tooltip>
</template>
</el-table-column>
</el-table>
@ -148,6 +148,7 @@
import { getIntDictOptions, DICT_TYPE } from '@/utils/dict'
import { dateFormatter } from '@/utils/formatTime'
import { CommonStatusEnum } from '@/utils/constants'
import { checkPermi } from '@/utils/permission'
import download from '@/utils/download'
import { ProRouteApi, ProRouteVO } from '@/api/mes/pro/route'
import RouteForm from './RouteForm.vue'
@ -195,21 +196,24 @@ const resetQuery = () => {
handleQuery()
}
/** 状态开关操作 */
const handleStatusChange = async (row: ProRouteVO) => {
try {
const text = row.status === CommonStatusEnum.ENABLE ? '启用' : '停用'
await message.confirm('确认要“' + text + '”“' + row.name + '”工艺路线吗?')
await ProRouteApi.updateRouteStatus(row.id!, row.status!)
await getList()
} catch {
row.status =
row.status === CommonStatusEnum.ENABLE ? CommonStatusEnum.DISABLE : CommonStatusEnum.ENABLE
}
}
/** 添加/修改操作 */
const openForm = (type: string, id?: number) => {
formRef.value.open(type, id)
}
/** 禁用按钮操作 */
const handleDisable = async (row: ProRouteVO) => {
try {
await message.confirm('确认要停用"' + row.name + '"工艺路线吗?')
await ProRouteApi.updateRouteStatus(row.id!, CommonStatusEnum.DISABLE)
message.success('停用成功')
await getList()
} catch {}
}
/** 删除按钮操作 */
const handleDelete = async (id: number) => {
try {

View File

@ -455,6 +455,7 @@ export const MesAutoCodeRuleCode = {
DV_SUBJECT_CODE: 'DV_SUBJECT_CODE', // 点检保养项目编码
DV_REPAIR_CODE: 'DV_REPAIR_CODE', // 维修单编码
PRO_PROCESS_CODE: 'PRO_PROCESS_CODE', // 工序编码
PRO_ROUTE_CODE: 'PRO_ROUTE_CODE', // 工艺路线编码
PRO_WORK_ORDER_CODE: 'PRO_WORK_ORDER_CODE' // 生产工单编码
} as const