feat(mes): 添加报工人和审核人字段,优化审批逻辑

pull/871/MERGE
YunaiV 2026-03-19 08:40:56 +08:00
parent 6553ab1875
commit 424f3d04c1
5 changed files with 198 additions and 322 deletions

View File

@ -24,7 +24,7 @@ export interface ProFeedbackVO {
itemId: number // 产品物料编号 itemId: number // 产品物料编号
itemCode: string // 物料编码 itemCode: string // 物料编码
itemName: string // 物料名称 itemName: string // 物料名称
itemSpec: string // 规格型号 itemSpecification: string // 规格型号
unitMeasureId: number // 单位编号 unitMeasureId: number // 单位编号
unitMeasureName: string // 单位名称 unitMeasureName: string // 单位名称
expireDate: Date // 过期日期 expireDate: Date // 过期日期

View File

@ -15,7 +15,7 @@ export interface ProRouteProcessVO {
waitTime?: number // 等待时间(分钟) waitTime?: number // 等待时间(分钟)
colorCode?: string // 甘特图显示颜色 colorCode?: string // 甘特图显示颜色
keyFlag?: number // 是否关键工序 keyFlag?: number // 是否关键工序
checkFlag?: number // 是否质检工序 checkFlag?: boolean // 是否质检工序
remark?: string // 备注 remark?: string // 备注
createTime?: Date // 创建时间 createTime?: Date // 创建时间
} }
@ -37,6 +37,14 @@ export const ProRouteProcessApi = {
return await request.get({ url: `/mes/pro/route-process/get?id=` + id }) 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) => { createRouteProcess: async (data: ProRouteProcessVO) => {
return await request.post({ url: `/mes/pro/route-process/create`, data }) return await request.post({ url: `/mes/pro/route-process/create`, data })

View File

@ -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>

View File

@ -66,17 +66,48 @@
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> </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-col :span="8">
<el-form-item label="工序" prop="processId"> <el-form-item label="报工数量" prop="feedbackQuantity">
<el-input v-model="processDisplay" disabled placeholder="由任务自动带入" /> <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-form-item>
</el-col> </el-col>
</el-row> </el-row>
<!-- 数量区域 --> <!-- 质检工序只填报工数量 -->
<el-divider content-position="left">报工数量</el-divider> <el-row :gutter="20" v-else>
<el-row :gutter="20">
<el-col :span="8"> <el-col :span="8">
<el-form-item label="报工数量" prop="feedbackQuantity"> <el-form-item label="报工数量" prop="feedbackQuantity">
<el-input-number <el-input-number
@ -88,46 +119,9 @@
/> />
</el-form-item> </el-form-item>
</el-col> </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> </el-row>
<!-- 废品分类不良品>0 时展开 --> <!-- 废品分类非质检工序 不良品>0 时展开 -->
<!-- TODO @芋艿在评审下 --> <el-row :gutter="20" v-if="!checkFlag && formData.unqualifiedQuantity > 0">
<el-row :gutter="20" v-if="formData.unqualifiedQuantity > 0">
<el-col :span="8"> <el-col :span="8">
<el-form-item label="工废数量"> <el-form-item label="工废数量">
<el-input-number <el-input-number
@ -136,6 +130,7 @@
:precision="2" :precision="2"
:disabled="isDetail" :disabled="isDetail"
class="!w-1/1" class="!w-1/1"
@change="handleScrapChanged"
/> />
</el-form-item> </el-form-item>
</el-col> </el-col>
@ -147,6 +142,7 @@
:precision="2" :precision="2"
:disabled="isDetail" :disabled="isDetail"
class="!w-1/1" class="!w-1/1"
@change="handleScrapChanged"
/> />
</el-form-item> </el-form-item>
</el-col> </el-col>
@ -158,6 +154,7 @@
:precision="2" :precision="2"
:disabled="isDetail" :disabled="isDetail"
class="!w-1/1" class="!w-1/1"
@change="handleScrapChanged"
/> />
</el-form-item> </el-form-item>
</el-col> </el-col>
@ -178,7 +175,7 @@
<el-date-picker <el-date-picker
v-model="formData.feedbackTime" v-model="formData.feedbackTime"
type="datetime" type="datetime"
value-format="YYYY-MM-DD HH:mm:ss" value-format="x"
placeholder="请选择报工时间" placeholder="请选择报工时间"
:disabled="isDetail" :disabled="isDetail"
class="!w-1/1" class="!w-1/1"
@ -218,22 +215,32 @@
</template> </template>
<script setup lang="ts"> <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 { 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 ProWorkOrderSelect from '@/views/mes/pro/workorder/components/ProWorkOrderSelect.vue'
import ProTaskSelect from '@/views/mes/pro/task/components/ProTaskSelect.vue' import ProTaskSelect from '@/views/mes/pro/task/components/ProTaskSelect.vue'
import MdWorkstationSelect from '@/views/mes/md/workstation/components/MdWorkstationSelect.vue' import MdWorkstationSelect from '@/views/mes/md/workstation/components/MdWorkstationSelect.vue'
import UserSelect from '@/views/system/user/components/UserSelect.vue' import UserSelect from '@/views/system/user/components/UserSelect.vue'
import { useUserStore } from '@/store/modules/user'
defineOptions({ name: 'FeedbackForm' }) defineOptions({ name: 'FeedbackForm' })
const { t } = useI18n() const { t } = useI18n() //
const message = useMessage() const message = useMessage() //
const dialogVisible = ref(false) const dialogVisible = ref(false) //
const dialogTitle = ref('') const formLoading = ref(false) //
const formLoading = ref(false) const formType = ref('') // create - update - detail -
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>>({ const formData = ref<Record<string, any>>({
id: undefined, id: undefined,
code: undefined, code: undefined,
@ -243,6 +250,7 @@ const formData = ref<Record<string, any>>({
processId: undefined, processId: undefined,
workOrderId: undefined, workOrderId: undefined,
taskId: undefined, taskId: undefined,
itemId: undefined,
expireDate: undefined, expireDate: undefined,
feedbackQuantity: 0, feedbackQuantity: 0,
qualifiedQuantity: 0, qualifiedQuantity: 0,
@ -261,46 +269,72 @@ const formRules = reactive({
workOrderId: [{ required: true, message: '生产工单不能为空', trigger: 'change' }], workOrderId: [{ required: true, message: '生产工单不能为空', trigger: 'change' }],
taskId: [{ required: true, message: '生产任务不能为空', trigger: 'change' }], taskId: [{ required: true, message: '生产任务不能为空', trigger: 'change' }],
workstationId: [{ 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 formRef = ref() // Ref
const isDetail = computed(() => formType.value === 'detail') //
/** 是否为详情模式 */ const checkFlag = ref(true) // true
const isDetail = computed(() => formType.value === 'detail')
/** 是否需要检验checkFlag */
const checkFlag = ref(false)
/** 工序显示(只读) */
const processDisplay = ref('')
// ==================== ==================== // ==================== ====================
/** 加载工序的 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 = () => { const handleWorkOrderChange = () => {
formData.value.taskId = undefined formData.value.taskId = undefined
formData.value.routeId = undefined formData.value.routeId = undefined
formData.value.processId = undefined formData.value.processId = undefined
formData.value.workstationId = undefined formData.value.workstationId = undefined
processDisplay.value = '' formData.value.itemId = undefined
checkFlag.value = false checkFlag.value = true
} }
/** 任务变更:自动填充关联字段 */ /** 任务变更:自动填充关联字段 */
const handleTaskChange = (task: any) => { const handleTaskChange = async (task: any) => {
if (!task) { if (!task) {
return return
} }
formData.value.routeId = task.routeId formData.value.routeId = task.routeId
formData.value.processId = task.processId formData.value.processId = task.processId
formData.value.workstationId = task.workstationId formData.value.workstationId = task.workstationId
processDisplay.value = task.processCode ? task.processCode + ' - ' + task.processName : '' formData.value.itemId = task.itemId
// TODO @ checkFlag routeProcess await loadCheckFlag(task.routeId, task.processId)
} }
// ==================== ==================== /** 生成报工单编号 */
/** 生成报工单编号(前端生成) */
// TODO @ // TODO @
const generateCode = () => { const generateCode = () => {
const now = new Date() const now = new Date()
@ -323,33 +357,26 @@ const generateCode = () => {
/** 打开弹窗 */ /** 打开弹窗 */
const open = async (type: string, id?: number) => { const open = async (type: string, id?: number) => {
dialogVisible.value = true dialogVisible.value = true
// TODO @AI computed
dialogTitle.value =
type === 'detail'
? '查看生产报工记录'
: type === 'create'
? '添加生产报工记录'
: '修改生产报工记录'
formType.value = type formType.value = type
resetForm() resetForm()
// /
if (id) { if (id) {
formLoading.value = true formLoading.value = true
try { try {
const data = await ProFeedbackApi.getFeedback(id) const data = await ProFeedbackApi.getFeedback(id)
formData.value = data as any formData.value = data as any
// await loadCheckFlag(data.routeId, data.processId)
processDisplay.value = data.processCode ? data.processCode + ' - ' + data.processName : ''
checkFlag.value = (data as any).checkFlag || false
} finally { } finally {
formLoading.value = false formLoading.value = false
} }
} else { } else {
// // +
formData.value.code = generateCode() formData.value.code = generateCode()
formData.value.feedbackUserId = useUserStore().getUser.id
} }
} }
defineExpose({ open }) defineExpose({ open }) // open
/** 提交表单 */ /** 提交表单 */
const emit = defineEmits(['success']) const emit = defineEmits(['success'])
@ -358,6 +385,21 @@ const submitForm = async () => {
formLoading.value = true formLoading.value = true
try { try {
const data = formData.value as unknown as ProFeedbackVO 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') { if (formType.value === 'create') {
await ProFeedbackApi.createFeedback(data) await ProFeedbackApi.createFeedback(data)
message.success(t('common.createSuccess')) message.success(t('common.createSuccess'))
@ -366,6 +408,7 @@ const submitForm = async () => {
message.success(t('common.updateSuccess')) message.success(t('common.updateSuccess'))
} }
dialogVisible.value = false dialogVisible.value = false
//
emit('success') emit('success')
} finally { } finally {
formLoading.value = false formLoading.value = false
@ -383,6 +426,7 @@ const resetForm = () => {
processId: undefined, processId: undefined,
workOrderId: undefined, workOrderId: undefined,
taskId: undefined, taskId: undefined,
itemId: undefined,
expireDate: undefined, expireDate: undefined,
feedbackQuantity: 0, feedbackQuantity: 0,
qualifiedQuantity: 0, qualifiedQuantity: 0,
@ -396,8 +440,7 @@ const resetForm = () => {
approveUserId: undefined, approveUserId: undefined,
remark: undefined remark: undefined
} }
processDisplay.value = '' checkFlag.value = true
checkFlag.value = false
formRef.value?.resetFields() formRef.value?.resetFields()
} }
</script> </script>

View File

@ -34,13 +34,21 @@
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="生产工单" prop="workOrderId"> <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>
<el-form-item label="产品物料" prop="itemId"> <el-form-item label="产品物料" prop="itemId">
<MdItemSelect v-model="queryParams.itemId" placeholder="请选择产品物料" class="!w-240px" /> <MdItemSelect v-model="queryParams.itemId" placeholder="请选择产品物料" class="!w-240px" />
</el-form-item> </el-form-item>
<el-form-item label="报工人" prop="feedbackUserId"> <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>
<el-form-item label="记录人" prop="creator"> <el-form-item label="记录人" prop="creator">
<UserSelect v-model="queryParams.creator" placeholder="请选择记录人" class="!w-240px" /> <UserSelect v-model="queryParams.creator" placeholder="请选择记录人" class="!w-240px" />
@ -99,8 +107,14 @@
:show-overflow-tooltip="true" :show-overflow-tooltip="true"
row-key="id" row-key="id"
> >
<!-- TODO @AI这里点击后跳转详情然后去掉下面的详情按钮 --> <!-- DONE @AI这里点击后跳转详情然后去掉下面的详情按钮 -->
<el-table-column label="报工单号" align="center" prop="code" width="160" /> <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"> <el-table-column label="报工类型" align="center" prop="type" width="100">
<template #default="scope"> <template #default="scope">
<dict-tag :type="DICT_TYPE.MES_PRO_FEEDBACK_TYPE" :value="scope.row.type" /> <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="workOrderCode" width="160" />
<el-table-column label="产品物料编码" align="center" prop="itemCode" width="120" /> <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="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="unitMeasureName" width="80" />
<el-table-column label="报工数量" align="center" prop="feedbackQuantity" width="100" /> <el-table-column label="报工数量" align="center" prop="feedbackQuantity" width="100" />
<el-table-column label="报工人" align="center" prop="feedbackUserNickname" width="100" /> <el-table-column label="报工人" align="center" prop="feedbackUserNickname" width="100" />
@ -158,33 +172,18 @@
</el-button> </el-button>
</template> </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"> <template v-if="scope.row.status === MesProFeedbackStatusEnum.APPROVING">
<el-button <el-button
link link
type="warning" type="primary"
@click="handleReject(scope.row.id)" @click="openApproveDialog(scope.row.id)"
v-hasPermi="['mes:pro-feedback:update']"
>
驳回
</el-button>
<el-button
link
type="success"
@click="handleApprove(scope.row.id)"
v-hasPermi="['mes:pro-feedback:approve']" v-hasPermi="['mes:pro-feedback:approve']"
> >
审批 审批
</el-button> </el-button>
</template> </template>
<!-- 所有状态详情 -->
<el-button
link
type="primary"
@click="openForm('detail', scope.row.id)"
v-hasPermi="['mes:pro-feedback:query']"
>详情</el-button
>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
@ -199,6 +198,17 @@
<!-- 表单弹窗添加/修改 --> <!-- 表单弹窗添加/修改 -->
<FeedbackForm ref="formRef" @success="getList" /> <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> </template>
<script setup lang="ts"> <script setup lang="ts">
@ -279,24 +289,36 @@ const handleSubmit = async (id: number) => {
} catch {} } 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 { try {
await message.confirm('确认要驳回该报工单吗?') const id = approveTargetId.value!
await ProFeedbackApi.rejectFeedback(id) approveDialogVisible.value = false
message.success('报工单已驳回') const finished = await ProFeedbackApi.approveFeedback(id)
if (finished) {
message.success('报工单已审批完成')
} else {
message.success('报工成功,请等待质量检验完成!')
}
await getList() await getList()
} catch {} } catch {}
} }
const handleApprove = async (id: number) => { const handleReject = async () => {
try { try {
await message.confirm('确认要审批该报工单吗?') const id = approveTargetId.value!
const status = await ProFeedbackApi.approveFeedback(id) approveDialogVisible.value = false
if (status === MesProFeedbackStatusEnum.UNCHECK) { await ProFeedbackApi.rejectFeedback(id)
message.success('报工成功,请等待质量检验完成!') message.success('报工单已驳回')
} else {
message.success('报工单已审批完成')
}
await getList() await getList()
} catch {} } catch {}
} }