✨ feat(mes): 添加报工人和审核人字段,优化审批逻辑
parent
6553ab1875
commit
424f3d04c1
|
|
@ -24,7 +24,7 @@ export interface ProFeedbackVO {
|
|||
itemId: number // 产品物料编号
|
||||
itemCode: string // 物料编码
|
||||
itemName: string // 物料名称
|
||||
itemSpec: string // 规格型号
|
||||
itemSpecification: string // 规格型号
|
||||
unitMeasureId: number // 单位编号
|
||||
unitMeasureName: string // 单位名称
|
||||
expireDate: Date // 过期日期
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ export interface ProRouteProcessVO {
|
|||
waitTime?: number // 等待时间(分钟)
|
||||
colorCode?: string // 甘特图显示颜色
|
||||
keyFlag?: number // 是否关键工序
|
||||
checkFlag?: number // 是否质检工序
|
||||
checkFlag?: boolean // 是否质检工序
|
||||
remark?: string // 备注
|
||||
createTime?: Date // 创建时间
|
||||
}
|
||||
|
|
@ -37,6 +37,14 @@ export const ProRouteProcessApi = {
|
|||
return await request.get({ url: `/mes/pro/route-process/get?id=` + id })
|
||||
},
|
||||
|
||||
// 按工艺路线+工序精确查询工序配置
|
||||
getRouteProcessByRouteAndProcess: async (routeId: number, processId: number) => {
|
||||
return await request.get({
|
||||
url: `/mes/pro/route-process/get-by-route-and-process`,
|
||||
params: { routeId, processId }
|
||||
})
|
||||
},
|
||||
|
||||
// 新增工艺路线工序
|
||||
createRouteProcess: async (data: ProRouteProcessVO) => {
|
||||
return await request.post({ url: `/mes/pro/route-process/create`, data })
|
||||
|
|
|
|||
|
|
@ -1,197 +0,0 @@
|
|||
<!-- MES 物料产品 弹窗选择器 -->
|
||||
<template>
|
||||
<Dialog title="物料产品选择" v-model="dialogVisible" width="80%">
|
||||
<el-row :gutter="20">
|
||||
<!-- 左侧:分类树 -->
|
||||
<el-col :span="5">
|
||||
<el-input
|
||||
v-model="filterText"
|
||||
placeholder="搜索分类"
|
||||
clearable
|
||||
class="mb-12px"
|
||||
:prefix-icon="iconSearch"
|
||||
/>
|
||||
<el-tree
|
||||
ref="treeRef"
|
||||
:data="itemTypeTree"
|
||||
:props="treeProps"
|
||||
:expand-on-click-node="false"
|
||||
:filter-node-method="filterNode"
|
||||
default-expand-all
|
||||
highlight-current
|
||||
@node-click="handleNodeClick"
|
||||
/>
|
||||
</el-col>
|
||||
<!-- 右侧:物料表格 -->
|
||||
<el-col :span="19">
|
||||
<!-- 搜索表单 -->
|
||||
<el-form :inline="true" :model="queryParams" class="mb-10px" label-width="80px">
|
||||
<el-form-item label="物料编码">
|
||||
<el-input
|
||||
v-model="queryParams.code"
|
||||
placeholder="请输入物料编码"
|
||||
clearable
|
||||
@keyup.enter="handleQuery"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="物料名称">
|
||||
<el-input
|
||||
v-model="queryParams.name"
|
||||
placeholder="请输入物料名称"
|
||||
clearable
|
||||
@keyup.enter="handleQuery"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="handleQuery">
|
||||
<Icon icon="ep:search" class="mr-5px" /> 搜索
|
||||
</el-button>
|
||||
<el-button @click="resetQuery">
|
||||
<Icon icon="ep:refresh" class="mr-5px" /> 重置
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<!-- 数据表格 -->
|
||||
<el-table
|
||||
v-loading="loading"
|
||||
:data="list"
|
||||
:stripe="true"
|
||||
:show-overflow-tooltip="true"
|
||||
border
|
||||
@selection-change="handleSelectionChange"
|
||||
>
|
||||
<el-table-column type="selection" width="50" align="center" />
|
||||
<el-table-column label="物料编码" align="center" prop="code" width="120" />
|
||||
<el-table-column label="物料名称" align="center" prop="name" min-width="120" />
|
||||
<el-table-column label="规格型号" align="center" prop="specification" />
|
||||
<el-table-column label="单位" align="center" prop="unitMeasureName" width="80" />
|
||||
<el-table-column label="物料/产品" align="center" prop="itemOrProduct" width="100">
|
||||
<template #default="scope">
|
||||
{{ getItemOrProductLabel(scope.row.itemOrProduct) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="所属分类" align="center" prop="itemTypeName" width="120" />
|
||||
</el-table>
|
||||
<!-- 分页 -->
|
||||
<Pagination
|
||||
:total="total"
|
||||
v-model:page="queryParams.pageNo"
|
||||
v-model:limit="queryParams.pageSize"
|
||||
@pagination="getList"
|
||||
/>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<template #footer>
|
||||
<el-button type="primary" @click="confirmSelect">确 定</el-button>
|
||||
<el-button @click="dialogVisible = false">取 消</el-button>
|
||||
</template>
|
||||
</Dialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { MdItemApi, MdItemVO } from '@/api/mes/md/item'
|
||||
import { MdItemTypeApi, MdItemTypeVO } from '@/api/mes/md/item/type'
|
||||
import { handleTree } from '@/utils/tree'
|
||||
import { getItemOrProductLabel } from '@/views/mes/utils/constants'
|
||||
import { Search as iconSearch } from '@element-plus/icons-vue'
|
||||
|
||||
defineOptions({ name: 'ItemProductSelect' })
|
||||
|
||||
const message = useMessage() // 消息弹窗
|
||||
const emit = defineEmits<{
|
||||
selected: [rows: MdItemVO[]] // 确认选择事件
|
||||
}>()
|
||||
|
||||
const dialogVisible = ref(false) // 弹窗的是否展示
|
||||
const loading = ref(false) // 列表加载中
|
||||
const list = ref<MdItemVO[]>([]) // 物料列表
|
||||
const total = ref(0) // 总条数
|
||||
const selectedRows = ref<MdItemVO[]>([]) // 选中行
|
||||
|
||||
// ==================== 分类树 ====================
|
||||
const treeRef = ref() // 树组件 Ref
|
||||
const filterText = ref('') // 分类搜索文本
|
||||
const itemTypeTree = ref<MdItemTypeVO[]>([]) // 分类树数据
|
||||
const treeProps = { children: 'children', label: 'name' } // 树属性配置
|
||||
|
||||
/** 过滤树节点 */
|
||||
const filterNode = (value: string, data: MdItemTypeVO) => {
|
||||
if (!value) return true
|
||||
return data.name?.includes(value)
|
||||
}
|
||||
|
||||
/** 监听筛选文本变化 */
|
||||
watch(filterText, (val) => {
|
||||
treeRef.value?.filter(val)
|
||||
})
|
||||
|
||||
/** 点击树节点 */
|
||||
const handleNodeClick = (data: MdItemTypeVO) => {
|
||||
queryParams.itemTypeId = data.id
|
||||
handleQuery()
|
||||
}
|
||||
|
||||
// ==================== 物料查询 ====================
|
||||
const queryParams = reactive({
|
||||
pageNo: 1,
|
||||
pageSize: 10,
|
||||
code: undefined as string | undefined,
|
||||
name: undefined as string | undefined,
|
||||
itemTypeId: undefined as number | undefined
|
||||
})
|
||||
|
||||
/** 查询列表 */
|
||||
const getList = async () => {
|
||||
loading.value = true
|
||||
try {
|
||||
const data = await MdItemApi.getItemPage(queryParams)
|
||||
list.value = data.list
|
||||
total.value = data.total
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
/** 搜索 */
|
||||
const handleQuery = () => {
|
||||
queryParams.pageNo = 1
|
||||
getList()
|
||||
}
|
||||
|
||||
/** 重置 */
|
||||
const resetQuery = () => {
|
||||
queryParams.code = undefined
|
||||
queryParams.name = undefined
|
||||
queryParams.itemTypeId = undefined
|
||||
handleQuery()
|
||||
}
|
||||
|
||||
/** 选中变化 */
|
||||
const handleSelectionChange = (rows: MdItemVO[]) => {
|
||||
selectedRows.value = rows
|
||||
}
|
||||
|
||||
/** 确认选择 */
|
||||
const confirmSelect = () => {
|
||||
if (selectedRows.value.length === 0) {
|
||||
message.warning('请至少选择一条数据')
|
||||
return
|
||||
}
|
||||
emit('selected', selectedRows.value)
|
||||
dialogVisible.value = false
|
||||
}
|
||||
|
||||
// ==================== 打开弹窗 ====================
|
||||
|
||||
/** 打开弹窗 */
|
||||
const open = async () => {
|
||||
dialogVisible.value = true
|
||||
selectedRows.value = []
|
||||
// 加载分类树
|
||||
const typeList = await MdItemTypeApi.getItemTypeSimpleList()
|
||||
itemTypeTree.value = handleTree(typeList)
|
||||
// 加载物料列表
|
||||
await getList()
|
||||
}
|
||||
defineExpose({ open }) // 提供 open 方法,用于打开弹窗
|
||||
</script>
|
||||
|
|
@ -66,17 +66,48 @@
|
|||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<!-- 工序 -->
|
||||
<el-row :gutter="20">
|
||||
<!-- 数量区域 -->
|
||||
<el-divider content-position="left">报工数量</el-divider>
|
||||
<!-- 非质检工序:报工数量(只读自动计算) + 合格品 + 不良品 -->
|
||||
<el-row :gutter="20" v-if="!checkFlag">
|
||||
<el-col :span="8">
|
||||
<el-form-item label="工序" prop="processId">
|
||||
<el-input v-model="processDisplay" disabled placeholder="由任务自动带入" />
|
||||
<el-form-item label="报工数量" prop="feedbackQuantity">
|
||||
<el-input-number
|
||||
v-model="formData.feedbackQuantity"
|
||||
:min="0"
|
||||
:precision="2"
|
||||
disabled
|
||||
class="!w-1/1"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="合格品数量" prop="qualifiedQuantity">
|
||||
<el-input-number
|
||||
v-model="formData.qualifiedQuantity"
|
||||
:min="0"
|
||||
:precision="2"
|
||||
:disabled="isDetail"
|
||||
class="!w-1/1"
|
||||
@change="handleQuantityChanged"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="不良品数量" prop="unqualifiedQuantity">
|
||||
<el-input-number
|
||||
v-model="formData.unqualifiedQuantity"
|
||||
:min="0"
|
||||
:precision="2"
|
||||
:disabled="isDetail"
|
||||
class="!w-1/1"
|
||||
@change="handleQuantityChanged"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<!-- 数量区域 -->
|
||||
<el-divider content-position="left">报工数量</el-divider>
|
||||
<el-row :gutter="20">
|
||||
<!-- 质检工序:只填报工数量 -->
|
||||
<el-row :gutter="20" v-else>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="报工数量" prop="feedbackQuantity">
|
||||
<el-input-number
|
||||
|
|
@ -88,46 +119,9 @@
|
|||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<!-- TODO @芋艿:在评审下 -->
|
||||
<el-col :span="8" v-if="!checkFlag">
|
||||
<el-form-item label="合格品数量" prop="qualifiedQuantity">
|
||||
<el-input-number
|
||||
v-model="formData.qualifiedQuantity"
|
||||
:min="0"
|
||||
:precision="2"
|
||||
:disabled="isDetail"
|
||||
class="!w-1/1"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<!-- TODO @芋艿:在评审下 -->
|
||||
<el-col :span="8" v-if="!checkFlag">
|
||||
<el-form-item label="不良品数量" prop="unqualifiedQuantity">
|
||||
<el-input-number
|
||||
v-model="formData.unqualifiedQuantity"
|
||||
:min="0"
|
||||
:precision="2"
|
||||
:disabled="isDetail"
|
||||
class="!w-1/1"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<!-- TODO @芋艿:在评审下 -->
|
||||
<el-col :span="8" v-if="checkFlag">
|
||||
<el-form-item label="待检测数量">
|
||||
<el-input-number
|
||||
v-model="formData.uncheckQuantity"
|
||||
:min="0"
|
||||
:precision="2"
|
||||
:disabled="isDetail"
|
||||
class="!w-1/1"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<!-- 废品分类(不良品>0 时展开) -->
|
||||
<!-- TODO @芋艿:在评审下 -->
|
||||
<el-row :gutter="20" v-if="formData.unqualifiedQuantity > 0">
|
||||
<!-- 废品分类(非质检工序 且 不良品>0 时展开) -->
|
||||
<el-row :gutter="20" v-if="!checkFlag && formData.unqualifiedQuantity > 0">
|
||||
<el-col :span="8">
|
||||
<el-form-item label="工废数量">
|
||||
<el-input-number
|
||||
|
|
@ -136,6 +130,7 @@
|
|||
:precision="2"
|
||||
:disabled="isDetail"
|
||||
class="!w-1/1"
|
||||
@change="handleScrapChanged"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
|
@ -147,6 +142,7 @@
|
|||
:precision="2"
|
||||
:disabled="isDetail"
|
||||
class="!w-1/1"
|
||||
@change="handleScrapChanged"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
|
@ -158,6 +154,7 @@
|
|||
:precision="2"
|
||||
:disabled="isDetail"
|
||||
class="!w-1/1"
|
||||
@change="handleScrapChanged"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
|
@ -178,7 +175,7 @@
|
|||
<el-date-picker
|
||||
v-model="formData.feedbackTime"
|
||||
type="datetime"
|
||||
value-format="YYYY-MM-DD HH:mm:ss"
|
||||
value-format="x"
|
||||
placeholder="请选择报工时间"
|
||||
:disabled="isDetail"
|
||||
class="!w-1/1"
|
||||
|
|
@ -218,22 +215,32 @@
|
|||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { getIntDictOptions, getStrDictOptions, DICT_TYPE } from '@/utils/dict'
|
||||
import { getIntDictOptions, DICT_TYPE } from '@/utils/dict'
|
||||
import { ProFeedbackApi, ProFeedbackVO } from '@/api/mes/pro/feedback'
|
||||
import { ProRouteProcessApi } from '@/api/mes/pro/route/process'
|
||||
import ProWorkOrderSelect from '@/views/mes/pro/workorder/components/ProWorkOrderSelect.vue'
|
||||
import ProTaskSelect from '@/views/mes/pro/task/components/ProTaskSelect.vue'
|
||||
import MdWorkstationSelect from '@/views/mes/md/workstation/components/MdWorkstationSelect.vue'
|
||||
import UserSelect from '@/views/system/user/components/UserSelect.vue'
|
||||
import { useUserStore } from '@/store/modules/user'
|
||||
|
||||
defineOptions({ name: 'FeedbackForm' })
|
||||
|
||||
const { t } = useI18n()
|
||||
const message = useMessage()
|
||||
const { t } = useI18n() // 国际化
|
||||
const message = useMessage() // 消息弹窗
|
||||
|
||||
const dialogVisible = ref(false)
|
||||
const dialogTitle = ref('')
|
||||
const formLoading = ref(false)
|
||||
const formType = ref('') // 'create' | 'update' | 'detail'
|
||||
const dialogVisible = ref(false) // 弹窗的是否展示
|
||||
const formLoading = ref(false) // 表单的加载中
|
||||
const formType = ref('') // 表单的类型:create - 新增;update - 修改;detail - 详情
|
||||
const dialogTitle = computed(() => {
|
||||
if (formType.value === 'detail') {
|
||||
return '查看生产报工记录'
|
||||
}
|
||||
if (formType.value === 'create') {
|
||||
return '添加生产报工记录'
|
||||
}
|
||||
return '修改生产报工记录'
|
||||
})
|
||||
const formData = ref<Record<string, any>>({
|
||||
id: undefined,
|
||||
code: undefined,
|
||||
|
|
@ -243,6 +250,7 @@ const formData = ref<Record<string, any>>({
|
|||
processId: undefined,
|
||||
workOrderId: undefined,
|
||||
taskId: undefined,
|
||||
itemId: undefined,
|
||||
expireDate: undefined,
|
||||
feedbackQuantity: 0,
|
||||
qualifiedQuantity: 0,
|
||||
|
|
@ -261,46 +269,72 @@ const formRules = reactive({
|
|||
workOrderId: [{ required: true, message: '生产工单不能为空', trigger: 'change' }],
|
||||
taskId: [{ required: true, message: '生产任务不能为空', trigger: 'change' }],
|
||||
workstationId: [{ required: true, message: '工作站不能为空', trigger: 'change' }],
|
||||
feedbackQuantity: [{ required: true, message: '报工数量不能为空', trigger: 'blur' }]
|
||||
feedbackQuantity: [{ required: true, message: '报工数量不能为空', trigger: 'blur' }],
|
||||
feedbackUserId: [{ required: true, message: '报工人不能为空', trigger: 'change' }],
|
||||
feedbackTime: [{ required: true, message: '报工时间不能为空', trigger: 'change' }],
|
||||
approveUserId: [{ required: true, message: '审核人不能为空', trigger: 'change' }]
|
||||
})
|
||||
const formRef = ref()
|
||||
|
||||
/** 是否为详情模式 */
|
||||
const isDetail = computed(() => formType.value === 'detail')
|
||||
|
||||
/** 是否需要检验(checkFlag) */
|
||||
const checkFlag = ref(false)
|
||||
|
||||
/** 工序显示(只读) */
|
||||
const processDisplay = ref('')
|
||||
const formRef = ref() // 表单 Ref
|
||||
const isDetail = computed(() => formType.value === 'detail') // 是否为详情模式
|
||||
const checkFlag = ref(true) // 是否需要检验(默认 true,未选任务时只展示报工数量)
|
||||
|
||||
// ==================== 级联选择回调 ====================
|
||||
|
||||
/** 加载工序的 checkFlag */
|
||||
const loadCheckFlag = async (routeId?: number, processId?: number) => {
|
||||
if (!routeId || !processId) {
|
||||
checkFlag.value = true
|
||||
return
|
||||
}
|
||||
try {
|
||||
const routeProcess = await ProRouteProcessApi.getRouteProcessByRouteAndProcess(
|
||||
routeId,
|
||||
processId
|
||||
)
|
||||
checkFlag.value = routeProcess?.checkFlag ?? false
|
||||
} catch {
|
||||
checkFlag.value = true
|
||||
}
|
||||
}
|
||||
|
||||
/** 合格品/不良品变更:自动计算报工数量 = 合格 + 不良 */
|
||||
const handleQuantityChanged = () => {
|
||||
formData.value.feedbackQuantity =
|
||||
(formData.value.qualifiedQuantity || 0) + (formData.value.unqualifiedQuantity || 0)
|
||||
}
|
||||
|
||||
/** 废品明细变更:自动计算不良品数量 = 工废 + 料废 + 其他 */
|
||||
const handleScrapChanged = () => {
|
||||
formData.value.unqualifiedQuantity =
|
||||
(formData.value.laborScrapQuantity || 0) +
|
||||
(formData.value.materialScrapQuantity || 0) +
|
||||
(formData.value.otherScrapQuantity || 0)
|
||||
handleQuantityChanged()
|
||||
}
|
||||
|
||||
/** 工单变更:清空任务相关字段 */
|
||||
const handleWorkOrderChange = () => {
|
||||
formData.value.taskId = undefined
|
||||
formData.value.routeId = undefined
|
||||
formData.value.processId = undefined
|
||||
formData.value.workstationId = undefined
|
||||
processDisplay.value = ''
|
||||
checkFlag.value = false
|
||||
formData.value.itemId = undefined
|
||||
checkFlag.value = true
|
||||
}
|
||||
|
||||
/** 任务变更:自动填充关联字段 */
|
||||
const handleTaskChange = (task: any) => {
|
||||
const handleTaskChange = async (task: any) => {
|
||||
if (!task) {
|
||||
return
|
||||
}
|
||||
formData.value.routeId = task.routeId
|
||||
formData.value.processId = task.processId
|
||||
formData.value.workstationId = task.workstationId
|
||||
processDisplay.value = task.processCode ? task.processCode + ' - ' + task.processName : ''
|
||||
// TODO @芋艿:加载 checkFlag(查询 routeProcess)
|
||||
formData.value.itemId = task.itemId
|
||||
await loadCheckFlag(task.routeId, task.processId)
|
||||
}
|
||||
|
||||
// ==================== 报工单编号生成 ====================
|
||||
|
||||
/** 生成报工单编号(前端生成) */
|
||||
/** 生成报工单编号 */
|
||||
// TODO @芋艿:这块的生成逻辑;
|
||||
const generateCode = () => {
|
||||
const now = new Date()
|
||||
|
|
@ -323,33 +357,26 @@ const generateCode = () => {
|
|||
/** 打开弹窗 */
|
||||
const open = async (type: string, id?: number) => {
|
||||
dialogVisible.value = true
|
||||
// TODO @AI:搞成 computed
|
||||
dialogTitle.value =
|
||||
type === 'detail'
|
||||
? '查看生产报工记录'
|
||||
: type === 'create'
|
||||
? '添加生产报工记录'
|
||||
: '修改生产报工记录'
|
||||
formType.value = type
|
||||
resetForm()
|
||||
// 修改/详情时,设置数据
|
||||
if (id) {
|
||||
formLoading.value = true
|
||||
try {
|
||||
const data = await ProFeedbackApi.getFeedback(id)
|
||||
formData.value = data as any
|
||||
// 填充显示字段
|
||||
processDisplay.value = data.processCode ? data.processCode + ' - ' + data.processName : ''
|
||||
checkFlag.value = (data as any).checkFlag || false
|
||||
await loadCheckFlag(data.routeId, data.processId)
|
||||
} finally {
|
||||
formLoading.value = false
|
||||
}
|
||||
} else {
|
||||
// 创建模式:自动生成报工单号
|
||||
// 创建模式:自动生成报工单号 + 默认报工人为当前用户
|
||||
formData.value.code = generateCode()
|
||||
formData.value.feedbackUserId = useUserStore().getUser.id
|
||||
}
|
||||
}
|
||||
|
||||
defineExpose({ open })
|
||||
defineExpose({ open }) // 提供 open 方法,用于打开弹窗
|
||||
|
||||
/** 提交表单 */
|
||||
const emit = defineEmits(['success'])
|
||||
|
|
@ -358,6 +385,21 @@ const submitForm = async () => {
|
|||
formLoading.value = true
|
||||
try {
|
||||
const data = formData.value as unknown as ProFeedbackVO
|
||||
// 提交前根据 checkFlag 对齐数量
|
||||
if (checkFlag.value) {
|
||||
// 质检工序:报工数量即待检数量,合格/不良/废品归零
|
||||
data.uncheckQuantity = data.feedbackQuantity
|
||||
data.qualifiedQuantity = 0
|
||||
data.unqualifiedQuantity = 0
|
||||
data.laborScrapQuantity = 0
|
||||
data.materialScrapQuantity = 0
|
||||
data.otherScrapQuantity = 0
|
||||
} else {
|
||||
// 非质检工序:报工数量 = 合格 + 不良,待检归零
|
||||
data.feedbackQuantity = (data.qualifiedQuantity || 0) + (data.unqualifiedQuantity || 0)
|
||||
data.uncheckQuantity = 0
|
||||
}
|
||||
// 执行提交
|
||||
if (formType.value === 'create') {
|
||||
await ProFeedbackApi.createFeedback(data)
|
||||
message.success(t('common.createSuccess'))
|
||||
|
|
@ -366,6 +408,7 @@ const submitForm = async () => {
|
|||
message.success(t('common.updateSuccess'))
|
||||
}
|
||||
dialogVisible.value = false
|
||||
// 发送操作成功的事件
|
||||
emit('success')
|
||||
} finally {
|
||||
formLoading.value = false
|
||||
|
|
@ -383,6 +426,7 @@ const resetForm = () => {
|
|||
processId: undefined,
|
||||
workOrderId: undefined,
|
||||
taskId: undefined,
|
||||
itemId: undefined,
|
||||
expireDate: undefined,
|
||||
feedbackQuantity: 0,
|
||||
qualifiedQuantity: 0,
|
||||
|
|
@ -396,8 +440,7 @@ const resetForm = () => {
|
|||
approveUserId: undefined,
|
||||
remark: undefined
|
||||
}
|
||||
processDisplay.value = ''
|
||||
checkFlag.value = false
|
||||
checkFlag.value = true
|
||||
formRef.value?.resetFields()
|
||||
}
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -34,13 +34,21 @@
|
|||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="生产工单" prop="workOrderId">
|
||||
<ProWorkOrderSelect v-model="queryParams.workOrderId" placeholder="请选择工单" class="!w-240px" />
|
||||
<ProWorkOrderSelect
|
||||
v-model="queryParams.workOrderId"
|
||||
placeholder="请选择工单"
|
||||
class="!w-240px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="产品物料" prop="itemId">
|
||||
<MdItemSelect v-model="queryParams.itemId" placeholder="请选择产品物料" class="!w-240px" />
|
||||
</el-form-item>
|
||||
<el-form-item label="报工人" prop="feedbackUserId">
|
||||
<UserSelect v-model="queryParams.feedbackUserId" placeholder="请选择报工人" class="!w-240px" />
|
||||
<UserSelect
|
||||
v-model="queryParams.feedbackUserId"
|
||||
placeholder="请选择报工人"
|
||||
class="!w-240px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="记录人" prop="creator">
|
||||
<UserSelect v-model="queryParams.creator" placeholder="请选择记录人" class="!w-240px" />
|
||||
|
|
@ -99,8 +107,14 @@
|
|||
:show-overflow-tooltip="true"
|
||||
row-key="id"
|
||||
>
|
||||
<!-- TODO @AI:这里点击后,跳转详情;然后,去掉下面的【详情】按钮 -->
|
||||
<el-table-column label="报工单号" align="center" prop="code" width="160" />
|
||||
<!-- DONE @AI:这里点击后,跳转详情;然后,去掉下面的【详情】按钮 -->
|
||||
<el-table-column label="报工单号" align="center" prop="code" width="160">
|
||||
<template #default="scope">
|
||||
<el-button link type="primary" @click="openForm('detail', scope.row.id)">{{
|
||||
scope.row.code
|
||||
}}</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="报工类型" align="center" prop="type" width="100">
|
||||
<template #default="scope">
|
||||
<dict-tag :type="DICT_TYPE.MES_PRO_FEEDBACK_TYPE" :value="scope.row.type" />
|
||||
|
|
@ -111,7 +125,7 @@
|
|||
<el-table-column label="生产工单编码" align="center" prop="workOrderCode" width="160" />
|
||||
<el-table-column label="产品物料编码" align="center" prop="itemCode" width="120" />
|
||||
<el-table-column label="产品物料名称" align="center" prop="itemName" width="120" />
|
||||
<el-table-column label="规格型号" align="center" prop="itemSpec" width="120" />
|
||||
<el-table-column label="规格型号" align="center" prop="itemSpecification" width="120" />
|
||||
<el-table-column label="单位" align="center" prop="unitMeasureName" width="80" />
|
||||
<el-table-column label="报工数量" align="center" prop="feedbackQuantity" width="100" />
|
||||
<el-table-column label="报工人" align="center" prop="feedbackUserNickname" width="100" />
|
||||
|
|
@ -158,33 +172,18 @@
|
|||
</el-button>
|
||||
</template>
|
||||
<!-- 审批中状态:驳回、执行、取消 -->
|
||||
<!-- TODO @AI:把【审批】【驳回】融合,点击后,弹出一个界面,然后里面在通过,不通过; -->
|
||||
<!-- DONE @AI:把【审批】【驳回】融合,点击后弹出一个界面,里面通过/不通过 -->
|
||||
<!-- TODO @AI:弹出,继续是 Form 组件,参考 /Users/yunai/Java/yudao-all-in-one/yudao-ui-admin-vue3/src/views/mes/wm/returnvendor/ReturnVendorForm.vue -->
|
||||
<template v-if="scope.row.status === MesProFeedbackStatusEnum.APPROVING">
|
||||
<el-button
|
||||
link
|
||||
type="warning"
|
||||
@click="handleReject(scope.row.id)"
|
||||
v-hasPermi="['mes:pro-feedback:update']"
|
||||
>
|
||||
驳回
|
||||
</el-button>
|
||||
<el-button
|
||||
link
|
||||
type="success"
|
||||
@click="handleApprove(scope.row.id)"
|
||||
type="primary"
|
||||
@click="openApproveDialog(scope.row.id)"
|
||||
v-hasPermi="['mes:pro-feedback:approve']"
|
||||
>
|
||||
审批
|
||||
</el-button>
|
||||
</template>
|
||||
<!-- 所有状态:详情 -->
|
||||
<el-button
|
||||
link
|
||||
type="primary"
|
||||
@click="openForm('detail', scope.row.id)"
|
||||
v-hasPermi="['mes:pro-feedback:query']"
|
||||
>详情</el-button
|
||||
>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
|
@ -199,6 +198,17 @@
|
|||
|
||||
<!-- 表单弹窗:添加/修改 -->
|
||||
<FeedbackForm ref="formRef" @success="getList" />
|
||||
|
||||
<!-- 审批弹窗 -->
|
||||
<Dialog title="审批报工" v-model="approveDialogVisible" width="400px">
|
||||
<div style="text-align: center; padding: 20px 0">
|
||||
<p style="margin-bottom: 20px; font-size: 14px">请确认审批结果</p>
|
||||
<el-button type="success" size="large" @click="handleApprove">通过</el-button>
|
||||
<el-button type="danger" size="large" @click="handleReject" style="margin-left: 24px"
|
||||
>不通过</el-button
|
||||
>
|
||||
</div>
|
||||
</Dialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
|
|
@ -279,24 +289,36 @@ const handleSubmit = async (id: number) => {
|
|||
} catch {}
|
||||
}
|
||||
|
||||
const handleReject = async (id: number) => {
|
||||
// ==================== 审批弹窗 ====================
|
||||
|
||||
const approveDialogVisible = ref(false)
|
||||
const approveTargetId = ref<number>()
|
||||
|
||||
const openApproveDialog = (id: number) => {
|
||||
approveTargetId.value = id
|
||||
approveDialogVisible.value = true
|
||||
}
|
||||
|
||||
const handleApprove = async () => {
|
||||
try {
|
||||
await message.confirm('确认要驳回该报工单吗?')
|
||||
await ProFeedbackApi.rejectFeedback(id)
|
||||
message.success('报工单已驳回')
|
||||
const id = approveTargetId.value!
|
||||
approveDialogVisible.value = false
|
||||
const finished = await ProFeedbackApi.approveFeedback(id)
|
||||
if (finished) {
|
||||
message.success('报工单已审批完成')
|
||||
} else {
|
||||
message.success('报工成功,请等待质量检验完成!')
|
||||
}
|
||||
await getList()
|
||||
} catch {}
|
||||
}
|
||||
|
||||
const handleApprove = async (id: number) => {
|
||||
const handleReject = async () => {
|
||||
try {
|
||||
await message.confirm('确认要审批该报工单吗?')
|
||||
const status = await ProFeedbackApi.approveFeedback(id)
|
||||
if (status === MesProFeedbackStatusEnum.UNCHECK) {
|
||||
message.success('报工成功,请等待质量检验完成!')
|
||||
} else {
|
||||
message.success('报工单已审批完成')
|
||||
}
|
||||
const id = approveTargetId.value!
|
||||
approveDialogVisible.value = false
|
||||
await ProFeedbackApi.rejectFeedback(id)
|
||||
message.success('报工单已驳回')
|
||||
await getList()
|
||||
} catch {}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue