✨ feat(mes): 优化工艺路线管理功能,调整状态处理逻辑
移除工艺路线状态的必填验证,调整状态字段为可选。更新状态切换逻辑,增强用户交互体验,确保状态操作的可用性和提示信息的准确性。pull/871/MERGE
parent
375d5a2236
commit
cfa787530e
|
|
@ -6,7 +6,7 @@ export interface ProRouteVO {
|
|||
code: string // 工艺路线编码
|
||||
name: string // 工艺路线名称
|
||||
description?: string // 工艺路线说明
|
||||
status: number // 状态
|
||||
status?: number // 状态
|
||||
remark?: string // 备注
|
||||
createTime?: Date // 创建时间
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 @AI:生成时,默认是禁用的;后端默认禁用状态;save 不要接收状态;
|
||||
status: [{ required: true, message: '状态不能为空', trigger: 'change' }]
|
||||
name: [{ required: true, message: '名称不能为空', trigger: 'blur' }]
|
||||
})
|
||||
const formRef = ref() // 表单 Ref
|
||||
|
||||
/** 生成编码 */
|
||||
const generateCode = () => {
|
||||
// TODO @AI:编码规则;mysql 也需要插入下;
|
||||
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()
|
||||
|
|
|
|||
|
|
@ -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 @AI:unocss 哈 -->
|
||||
<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 @AI:keyFlag、checkFlag 必填;
|
||||
linkType: [{ required: true, message: '工序关系不能为空', trigger: 'change' }],
|
||||
keyFlag: [{ required: true, message: '是否关键工序不能为空', trigger: 'change' }],
|
||||
checkFlag: [{ required: true, message: '是否需要质检确认不能为空', trigger: 'change' }]
|
||||
})
|
||||
const formRef = ref() // 表单 Ref
|
||||
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue