feat(mes): 添加生产报工相关的请求和响应 VO,重构报工控制器及服务实现
parent
f7d8682073
commit
170b9e0857
|
|
@ -0,0 +1,90 @@
|
|||
import request from '@/config/axios'
|
||||
|
||||
// MES 生产报工 VO
|
||||
export interface ProFeedbackVO {
|
||||
id: number // 编号
|
||||
code: string // 报工单编号
|
||||
type: number // 报工类型
|
||||
channel: string // 报工途径
|
||||
feedbackTime: Date // 报工时间
|
||||
workstationId: number // 工作站编号
|
||||
workstationCode: string // 工作站编码
|
||||
workstationName: string // 工作站名称
|
||||
routeId: number // 工艺路线编号
|
||||
routeCode: string // 工艺路线编码
|
||||
processId: number // 工序编号
|
||||
processCode: string // 工序编码
|
||||
processName: string // 工序名称
|
||||
checkFlag: boolean // 是否需要检验
|
||||
workOrderId: number // 生产工单编号
|
||||
workOrderCode: string // 工单编码
|
||||
workOrderName: string // 工单名称
|
||||
taskId: number // 生产任务编号
|
||||
taskCode: string // 任务编码
|
||||
itemId: number // 产品物料编号
|
||||
itemCode: string // 物料编码
|
||||
itemName: string // 物料名称
|
||||
itemSpec: string // 规格型号
|
||||
unitMeasureId: number // 单位编号
|
||||
unitMeasureName: string // 单位名称
|
||||
expireDate: Date // 过期日期
|
||||
batchCode: string // 批次号
|
||||
scheduledQuantity: number // 排产数量
|
||||
feedbackQuantity: number // 本次报工数量
|
||||
qualifiedQuantity: number // 合格品数量
|
||||
unqualifiedQuantity: number // 不良品数量
|
||||
uncheckQuantity: number // 待检测数量
|
||||
laborScrapQuantity: number // 工废数量
|
||||
materialScrapQuantity: number // 料废数量
|
||||
otherScrapQuantity: number // 其他废品数量
|
||||
feedbackUserId: number // 报工用户编号
|
||||
feedbackUserNickname: string // 报工人昵称
|
||||
approveUserId: number // 审核用户编号
|
||||
approveUserNickname: string // 审核人昵称
|
||||
status: number // 状态
|
||||
remark: string // 备注
|
||||
}
|
||||
|
||||
// MES 生产报工 API
|
||||
export const ProFeedbackApi = {
|
||||
// 查询生产报工分页
|
||||
getFeedbackPage: async (params: any) => {
|
||||
return await request.get({ url: `/mes/pro/feedback/page`, params })
|
||||
},
|
||||
// 查询生产报工详情
|
||||
getFeedback: async (id: number) => {
|
||||
return await request.get({ url: `/mes/pro/feedback/get?id=` + id })
|
||||
},
|
||||
// 新增生产报工
|
||||
createFeedback: async (data: ProFeedbackVO) => {
|
||||
return await request.post({ url: `/mes/pro/feedback/create`, data })
|
||||
},
|
||||
// 修改生产报工
|
||||
updateFeedback: async (data: ProFeedbackVO) => {
|
||||
return await request.put({ url: `/mes/pro/feedback/update`, data })
|
||||
},
|
||||
// 删除生产报工
|
||||
deleteFeedback: async (id: number) => {
|
||||
return await request.delete({ url: `/mes/pro/feedback/delete?id=` + id })
|
||||
},
|
||||
// 导出生产报工 Excel
|
||||
exportFeedback: async (params: any) => {
|
||||
return await request.download({ url: `/mes/pro/feedback/export-excel`, params })
|
||||
},
|
||||
// 提交报工
|
||||
submitFeedback: async (id: number) => {
|
||||
return await request.put({ url: `/mes/pro/feedback/submit?id=` + id })
|
||||
},
|
||||
// 驳回报工
|
||||
rejectFeedback: async (id: number) => {
|
||||
return await request.put({ url: `/mes/pro/feedback/reject?id=` + id })
|
||||
},
|
||||
// 执行报工
|
||||
executeFeedback: async (id: number) => {
|
||||
return await request.put({ url: `/mes/pro/feedback/execute?id=` + id })
|
||||
},
|
||||
// 取消报工
|
||||
cancelFeedback: async (id: number) => {
|
||||
return await request.put({ url: `/mes/pro/feedback/cancel?id=` + id })
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,493 @@
|
|||
<!-- MES 生产报工表单 -->
|
||||
<template>
|
||||
<!-- TODO @AI:一行 3 个 -->
|
||||
<Dialog :title="dialogTitle" v-model="dialogVisible" width="960px">
|
||||
<el-form
|
||||
ref="formRef"
|
||||
:model="formData"
|
||||
:rules="formRules"
|
||||
label-width="120px"
|
||||
v-loading="formLoading"
|
||||
>
|
||||
<el-row>
|
||||
<el-col :span="12">
|
||||
<!-- TODO @AI:生成,前端处理;参考别的模块 -->
|
||||
<el-form-item label="报工单号" prop="code">
|
||||
<el-input v-model="formData.code" disabled placeholder="自动生成" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="报工类型" prop="type">
|
||||
<el-select
|
||||
v-model="formData.type"
|
||||
placeholder="请选择报工类型"
|
||||
:disabled="isDetail"
|
||||
class="!w-1/1"
|
||||
>
|
||||
<el-option
|
||||
v-for="dict in getIntDictOptions(DICT_TYPE.MES_PRO_FEEDBACK_TYPE)"
|
||||
:key="dict.value"
|
||||
:label="dict.label"
|
||||
:value="dict.value"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row>
|
||||
<!-- TODO @芋艿:报告途径,是不是非必须? -->
|
||||
<el-col :span="12">
|
||||
<el-form-item label="报工途径" prop="channel">
|
||||
<el-select
|
||||
v-model="formData.channel"
|
||||
placeholder="请选择报工途径"
|
||||
:disabled="isDetail"
|
||||
class="!w-1/1"
|
||||
>
|
||||
<el-option
|
||||
v-for="dict in getStrDictOptions(DICT_TYPE.MES_PRO_FEEDBACK_CHANNEL)"
|
||||
:key="dict.value"
|
||||
:label="dict.label"
|
||||
:value="dict.value"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="批次号" prop="batchCode">
|
||||
<el-input
|
||||
v-model="formData.batchCode"
|
||||
placeholder="请输入批次号"
|
||||
:disabled="isDetail"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<!-- 工单选择 -->
|
||||
<!-- TODO @AI:生产工单 select; -->
|
||||
<el-row>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="生产工单" prop="workOrderId">
|
||||
<el-select
|
||||
v-model="formData.workOrderId"
|
||||
filterable
|
||||
remote
|
||||
reserve-keyword
|
||||
:remote-method="searchWorkOrder"
|
||||
placeholder="请搜索工单编码/名称"
|
||||
:disabled="isDetail"
|
||||
class="!w-1/1"
|
||||
@change="handleWorkOrderChange"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in workOrderOptions"
|
||||
:key="item.id"
|
||||
:label="item.code + ' - ' + item.name"
|
||||
:value="item.id"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="生产任务" prop="taskId">
|
||||
<el-select
|
||||
v-model="formData.taskId"
|
||||
filterable
|
||||
remote
|
||||
reserve-keyword
|
||||
:remote-method="searchTask"
|
||||
placeholder="请搜索任务编码"
|
||||
:disabled="isDetail || !formData.workOrderId"
|
||||
class="!w-1/1"
|
||||
@change="handleTaskChange"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in taskOptions"
|
||||
:key="item.id"
|
||||
:label="item.code + ' - ' + item.name"
|
||||
:value="item.id"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<!-- 工作站 / 工序(任务选中后自动填充,也支持手动选择) -->
|
||||
<!-- TODO @AI:工作站 select; -->
|
||||
<el-row>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="工作站" prop="workstationId">
|
||||
<el-select
|
||||
v-model="formData.workstationId"
|
||||
filterable
|
||||
remote
|
||||
reserve-keyword
|
||||
:remote-method="searchWorkstation"
|
||||
placeholder="请搜索工作站"
|
||||
:disabled="isDetail"
|
||||
class="!w-1/1"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in workstationOptions"
|
||||
:key="item.id"
|
||||
:label="item.code + ' - ' + item.name"
|
||||
:value="item.id"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<!-- TODO @AI:生产任务 select; -->
|
||||
<el-col :span="12">
|
||||
<el-form-item label="工序" prop="processId">
|
||||
<el-input v-model="processDisplay" disabled placeholder="由任务自动带入" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<!-- 物料 / 单位 / 工艺路线(自动填充,只读) -->
|
||||
<!-- TODO 下面的 itemDisplay、scheduledQuantity 不需要 -->
|
||||
<el-row>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="产品物料" prop="itemId">
|
||||
<el-input v-model="itemDisplay" disabled placeholder="由任务自动带入" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="排产数量" prop="scheduledQuantity">
|
||||
<el-input-number
|
||||
v-model="formData.scheduledQuantity"
|
||||
:min="0"
|
||||
:precision="2"
|
||||
disabled
|
||||
class="!w-1/1"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<!-- 数量区域 -->
|
||||
<el-divider content-position="left">报工数量</el-divider>
|
||||
<el-row>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="报工数量" prop="feedbackQuantity">
|
||||
<el-input-number
|
||||
v-model="formData.feedbackQuantity"
|
||||
: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="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 v-if="formData.unqualifiedQuantity > 0">
|
||||
<el-col :span="8">
|
||||
<el-form-item label="工废数量">
|
||||
<el-input-number
|
||||
v-model="formData.laborScrapQuantity"
|
||||
:min="0"
|
||||
:precision="2"
|
||||
:disabled="isDetail"
|
||||
class="!w-1/1"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="料废数量">
|
||||
<el-input-number
|
||||
v-model="formData.materialScrapQuantity"
|
||||
:min="0"
|
||||
:precision="2"
|
||||
:disabled="isDetail"
|
||||
class="!w-1/1"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="其他废品">
|
||||
<el-input-number
|
||||
v-model="formData.otherScrapQuantity"
|
||||
:min="0"
|
||||
:precision="2"
|
||||
:disabled="isDetail"
|
||||
class="!w-1/1"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<!-- TODO @AI:报工人、报工时间、审批人 -->
|
||||
<el-row>
|
||||
<el-col :span="24">
|
||||
<el-form-item label="备注" prop="remark">
|
||||
<el-input
|
||||
v-model="formData.remark"
|
||||
type="textarea"
|
||||
:rows="3"
|
||||
placeholder="请输入备注"
|
||||
:disabled="isDetail"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
<template #footer v-if="!isDetail">
|
||||
<el-button @click="submitForm" type="primary" :disabled="formLoading">确 定</el-button>
|
||||
<el-button @click="dialogVisible = false">取 消</el-button>
|
||||
</template>
|
||||
</Dialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { getIntDictOptions, getStrDictOptions, DICT_TYPE } from '@/utils/dict'
|
||||
import { ProFeedbackApi, ProFeedbackVO } from '@/api/mes/pro/feedback'
|
||||
import { ProWorkOrderApi } from '@/api/mes/pro/workorder'
|
||||
|
||||
// TODO @AI:方法注释、变量注释,参考别的模块;
|
||||
|
||||
defineOptions({ name: 'FeedbackForm' })
|
||||
|
||||
const { t } = useI18n()
|
||||
const message = useMessage()
|
||||
|
||||
const dialogVisible = ref(false)
|
||||
const dialogTitle = ref('')
|
||||
const formLoading = ref(false)
|
||||
const formType = ref('') // 'create' | 'update' | 'detail'
|
||||
|
||||
const formData = ref({
|
||||
id: undefined,
|
||||
type: undefined,
|
||||
channel: undefined,
|
||||
workstationId: undefined,
|
||||
routeId: undefined,
|
||||
processId: undefined,
|
||||
workOrderId: undefined,
|
||||
taskId: undefined,
|
||||
itemId: undefined,
|
||||
unitMeasureId: undefined,
|
||||
expireDate: undefined,
|
||||
batchCode: undefined,
|
||||
scheduledQuantity: 0,
|
||||
feedbackQuantity: 0,
|
||||
qualifiedQuantity: 0,
|
||||
unqualifiedQuantity: 0,
|
||||
uncheckQuantity: 0,
|
||||
laborScrapQuantity: 0,
|
||||
materialScrapQuantity: 0,
|
||||
otherScrapQuantity: 0,
|
||||
remark: undefined,
|
||||
code: undefined
|
||||
})
|
||||
|
||||
const formRules = reactive({
|
||||
type: [{ required: true, message: '报工类型不能为空', trigger: 'change' }],
|
||||
workOrderId: [{ required: true, message: '生产工单不能为空', trigger: 'change' }],
|
||||
taskId: [{ required: true, message: '生产任务不能为空', trigger: 'change' }],
|
||||
workstationId: [{ required: true, message: '工作站不能为空', trigger: 'change' }],
|
||||
feedbackQuantity: [{ required: true, message: '报工数量不能为空', trigger: 'blur' }]
|
||||
})
|
||||
const formRef = ref()
|
||||
|
||||
/** 是否为详情模式 */
|
||||
const isDetail = computed(() => formType.value === 'detail')
|
||||
|
||||
/** 是否需要检验(checkFlag) */
|
||||
const checkFlag = ref(false)
|
||||
|
||||
/** 显示字段(只读) */
|
||||
const processDisplay = ref('')
|
||||
const itemDisplay = ref('')
|
||||
|
||||
// ==================== 远程搜索选项 ====================
|
||||
|
||||
const workOrderOptions = ref<any[]>([])
|
||||
const taskOptions = ref<any[]>([])
|
||||
const workstationOptions = ref<any[]>([])
|
||||
|
||||
/** 搜索工单 */
|
||||
const searchWorkOrder = async (query: string) => {
|
||||
if (!query) return
|
||||
const data = await ProWorkOrderApi.getWorkOrderPage({
|
||||
pageNo: 1,
|
||||
pageSize: 20,
|
||||
code: query,
|
||||
status: 1
|
||||
})
|
||||
workOrderOptions.value = data.list
|
||||
}
|
||||
|
||||
/** 搜索任务(按工单过滤) */
|
||||
// TODO @芋艿:pro_task API 待迁移,暂用占位
|
||||
const searchTask = async (query: string) => {
|
||||
if (!query || !formData.value.workOrderId) return
|
||||
// TODO @芋艿:待 pro_task 前端 API 迁移后,替换为 ProTaskApi.getTaskPage({ workOrderId, code: query })
|
||||
taskOptions.value = []
|
||||
}
|
||||
|
||||
/** 搜索工作站 */
|
||||
const searchWorkstation = async (query: string) => {
|
||||
if (!query) return
|
||||
// 使用工作站 API 搜索(这里用简单查询)
|
||||
// TODO @芋艿:如果有工作站搜索 API,可替换
|
||||
workstationOptions.value = []
|
||||
}
|
||||
|
||||
/** 工单变更 */
|
||||
const handleWorkOrderChange = (workOrderId: number) => {
|
||||
// 清空任务相关字段
|
||||
formData.value.taskId = undefined
|
||||
formData.value.routeId = undefined
|
||||
formData.value.processId = undefined
|
||||
formData.value.itemId = undefined
|
||||
formData.value.unitMeasureId = undefined
|
||||
formData.value.workstationId = undefined
|
||||
formData.value.scheduledQuantity = 0
|
||||
processDisplay.value = ''
|
||||
itemDisplay.value = ''
|
||||
taskOptions.value = []
|
||||
checkFlag.value = false
|
||||
}
|
||||
|
||||
/** 任务变更:自动填充关联字段 */
|
||||
const handleTaskChange = (taskId: number) => {
|
||||
const task = taskOptions.value.find((t: any) => t.id === taskId)
|
||||
if (!task) return
|
||||
formData.value.routeId = task.routeId
|
||||
formData.value.processId = task.processId
|
||||
formData.value.itemId = task.itemId
|
||||
formData.value.unitMeasureId = task.unitMeasureId
|
||||
formData.value.workstationId = task.workstationId
|
||||
formData.value.scheduledQuantity = task.quantity
|
||||
processDisplay.value = task.processCode ? task.processCode + ' - ' + task.processName : ''
|
||||
itemDisplay.value = task.itemCode ? task.itemCode + ' - ' + task.itemName : ''
|
||||
// TODO @芋艿:加载 checkFlag(查询 routeProcess)
|
||||
}
|
||||
|
||||
/** 打开弹窗 */
|
||||
const open = async (type: string, id?: number) => {
|
||||
dialogVisible.value = true
|
||||
dialogTitle.value = type === 'detail' ? '报工详情' : t('action.' + type)
|
||||
formType.value = type
|
||||
resetForm()
|
||||
if (id) {
|
||||
formLoading.value = true
|
||||
try {
|
||||
const data = (await ProFeedbackApi.getFeedback(id)) as any
|
||||
formData.value = data
|
||||
// 填充显示字段
|
||||
processDisplay.value = data.processCode ? data.processCode + ' - ' + data.processName : ''
|
||||
itemDisplay.value = data.itemCode ? data.itemCode + ' - ' + data.itemName : ''
|
||||
checkFlag.value = data.checkFlag || false
|
||||
// 填充选项(让 select 能显示已选值)
|
||||
if (data.workOrderId) {
|
||||
workOrderOptions.value = [
|
||||
{ id: data.workOrderId, code: data.workOrderCode, name: data.workOrderName }
|
||||
]
|
||||
}
|
||||
if (data.taskId) {
|
||||
taskOptions.value = [{ id: data.taskId, code: data.taskCode, name: '' }]
|
||||
}
|
||||
if (data.workstationId) {
|
||||
workstationOptions.value = [
|
||||
{ id: data.workstationId, code: data.workstationCode, name: data.workstationName }
|
||||
]
|
||||
}
|
||||
} finally {
|
||||
formLoading.value = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
defineExpose({ open })
|
||||
|
||||
/** 提交表单 */
|
||||
const emit = defineEmits(['success'])
|
||||
const submitForm = async () => {
|
||||
await formRef.value.validate()
|
||||
formLoading.value = true
|
||||
try {
|
||||
const data = formData.value as unknown as ProFeedbackVO
|
||||
if (formType.value === 'create') {
|
||||
await ProFeedbackApi.createFeedback(data)
|
||||
message.success(t('common.createSuccess'))
|
||||
} else {
|
||||
await ProFeedbackApi.updateFeedback(data)
|
||||
message.success(t('common.updateSuccess'))
|
||||
}
|
||||
dialogVisible.value = false
|
||||
emit('success')
|
||||
} finally {
|
||||
formLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
/** 重置表单 */
|
||||
const resetForm = () => {
|
||||
formData.value = {
|
||||
id: undefined,
|
||||
type: undefined,
|
||||
channel: undefined,
|
||||
workstationId: undefined,
|
||||
routeId: undefined,
|
||||
processId: undefined,
|
||||
workOrderId: undefined,
|
||||
taskId: undefined,
|
||||
itemId: undefined,
|
||||
unitMeasureId: undefined,
|
||||
expireDate: undefined,
|
||||
batchCode: undefined,
|
||||
scheduledQuantity: 0,
|
||||
feedbackQuantity: 0,
|
||||
qualifiedQuantity: 0,
|
||||
unqualifiedQuantity: 0,
|
||||
uncheckQuantity: 0,
|
||||
laborScrapQuantity: 0,
|
||||
materialScrapQuantity: 0,
|
||||
otherScrapQuantity: 0,
|
||||
remark: undefined,
|
||||
code: undefined
|
||||
}
|
||||
workOrderOptions.value = []
|
||||
taskOptions.value = []
|
||||
workstationOptions.value = []
|
||||
processDisplay.value = ''
|
||||
itemDisplay.value = ''
|
||||
checkFlag.value = false
|
||||
formRef.value?.resetFields()
|
||||
}
|
||||
</script>
|
||||
|
|
@ -0,0 +1,320 @@
|
|||
<!-- MES 生产报工列表 -->
|
||||
<template>
|
||||
<ContentWrap>
|
||||
<!-- 搜索工作栏 -->
|
||||
<el-form
|
||||
class="-mb-15px"
|
||||
:model="queryParams"
|
||||
ref="queryFormRef"
|
||||
:inline="true"
|
||||
label-width="100px"
|
||||
>
|
||||
<el-form-item label="报工单号" prop="code">
|
||||
<el-input
|
||||
v-model="queryParams.code"
|
||||
placeholder="请输入报工单号"
|
||||
clearable
|
||||
@keyup.enter="handleQuery"
|
||||
class="!w-240px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="报工类型" prop="type">
|
||||
<el-select
|
||||
v-model="queryParams.type"
|
||||
placeholder="请选择报工类型"
|
||||
clearable
|
||||
class="!w-240px"
|
||||
>
|
||||
<el-option
|
||||
v-for="dict in getIntDictOptions(DICT_TYPE.MES_PRO_FEEDBACK_TYPE)"
|
||||
:key="dict.value"
|
||||
:label="dict.label"
|
||||
:value="dict.value"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<!-- TODO @AI:select; -->
|
||||
<el-form-item label="工单编号" prop="workOrderId">
|
||||
<el-input
|
||||
v-model="queryParams.workOrderId"
|
||||
placeholder="请输入工单编号"
|
||||
clearable
|
||||
@keyup.enter="handleQuery"
|
||||
class="!w-240px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<!-- TODO @AI:产品物料 select -->
|
||||
<!-- TODO @AI:报工人 select -->
|
||||
<!-- TODO @AI:记录人 select -->
|
||||
<el-form-item label="状态" prop="status">
|
||||
<el-select v-model="queryParams.status" placeholder="请选择状态" clearable class="!w-240px">
|
||||
<el-option
|
||||
v-for="dict in getIntDictOptions(DICT_TYPE.MES_PRO_FEEDBACK_STATUS)"
|
||||
:key="dict.value"
|
||||
:label="dict.label"
|
||||
:value="dict.value"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="报工时间" prop="feedbackTime">
|
||||
<el-date-picker
|
||||
v-model="queryParams.feedbackTime"
|
||||
value-format="YYYY-MM-DD HH:mm:ss"
|
||||
type="daterange"
|
||||
start-placeholder="开始日期"
|
||||
end-placeholder="结束日期"
|
||||
:default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]"
|
||||
class="!w-240px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button @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-button
|
||||
type="primary"
|
||||
plain
|
||||
@click="openForm('create')"
|
||||
v-hasPermi="['mes:pro-feedback:create']"
|
||||
>
|
||||
<Icon icon="ep:plus" class="mr-5px" /> 新增
|
||||
</el-button>
|
||||
<el-button
|
||||
type="success"
|
||||
plain
|
||||
@click="handleExport"
|
||||
:loading="exportLoading"
|
||||
v-hasPermi="['mes:pro-feedback:export']"
|
||||
>
|
||||
<Icon icon="ep:download" class="mr-5px" /> 导出
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</ContentWrap>
|
||||
|
||||
<!-- 列表 -->
|
||||
<ContentWrap>
|
||||
<el-table
|
||||
v-loading="loading"
|
||||
:data="list"
|
||||
:stripe="true"
|
||||
:show-overflow-tooltip="true"
|
||||
row-key="id"
|
||||
>
|
||||
<el-table-column label="报工单号" align="center" prop="code" width="160" />
|
||||
<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" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="工作站" align="center" prop="workstationName" width="120" />
|
||||
<el-table-column label="工序" align="center" prop="processName" width="100" />
|
||||
<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="unitMeasureName" width="80" />
|
||||
<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="feedbackTime"
|
||||
:formatter="dateFormatter"
|
||||
width="180"
|
||||
/>
|
||||
<el-table-column label="审核人" align="center" prop="approveUserNickname" width="100" />
|
||||
<el-table-column label="状态" align="center" prop="status" width="100">
|
||||
<template #default="scope">
|
||||
<dict-tag :type="DICT_TYPE.MES_PRO_FEEDBACK_STATUS" :value="scope.row.status" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" align="center" width="240" fixed="right">
|
||||
<template #default="scope">
|
||||
<!-- 草稿状态:编辑、提交、删除 -->
|
||||
<template v-if="scope.row.status === MesProFeedbackStatusEnum.PREPARE">
|
||||
<el-button
|
||||
link
|
||||
type="primary"
|
||||
@click="openForm('update', scope.row.id)"
|
||||
v-hasPermi="['mes:pro-feedback:update']">
|
||||
编辑
|
||||
</el-button>
|
||||
<el-button
|
||||
link
|
||||
type="success"
|
||||
@click="handleSubmit(scope.row.id)"
|
||||
v-hasPermi="['mes:pro-feedback:update']">
|
||||
提交
|
||||
</el-button>
|
||||
<el-button
|
||||
link
|
||||
type="danger"
|
||||
@click="handleDelete(scope.row.id)"
|
||||
v-hasPermi="['mes:pro-feedback:delete']">
|
||||
删除
|
||||
</el-button>
|
||||
</template>
|
||||
<!-- 审批中状态:驳回、执行、取消 -->
|
||||
<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="handleExecute(scope.row.id)"
|
||||
v-hasPermi="['mes:pro-feedback:update']">
|
||||
执行
|
||||
</el-button>
|
||||
<el-button
|
||||
link
|
||||
type="danger"
|
||||
@click="handleCancel(scope.row.id)"
|
||||
v-hasPermi="['mes:pro-feedback:update']"
|
||||
>取消</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>
|
||||
<!-- 分页 -->
|
||||
<Pagination
|
||||
:total="total"
|
||||
v-model:page="queryParams.pageNo"
|
||||
v-model:limit="queryParams.pageSize"
|
||||
@pagination="getList"
|
||||
/>
|
||||
</ContentWrap>
|
||||
|
||||
<!-- 表单弹窗:添加/修改 -->
|
||||
<FeedbackForm ref="formRef" @success="getList" />
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { dateFormatter } from '@/utils/formatTime'
|
||||
import download from '@/utils/download'
|
||||
import { ProFeedbackApi, ProFeedbackVO } from '@/api/mes/pro/feedback'
|
||||
import FeedbackForm from './FeedbackForm.vue'
|
||||
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
|
||||
import { MesProFeedbackStatusEnum } from '@/views/mes/utils/constants'
|
||||
|
||||
// TODO @AI:变量、方法注释,参考别的模块;
|
||||
|
||||
defineOptions({ name: 'MesProFeedback' })
|
||||
|
||||
const message = useMessage()
|
||||
const { t } = useI18n()
|
||||
|
||||
const loading = ref(true)
|
||||
const list = ref<ProFeedbackVO[]>([])
|
||||
const total = ref(0)
|
||||
const queryParams = reactive({
|
||||
pageNo: 1,
|
||||
pageSize: 10,
|
||||
code: undefined,
|
||||
type: undefined,
|
||||
workOrderId: undefined,
|
||||
status: undefined,
|
||||
feedbackTime: undefined
|
||||
})
|
||||
const queryFormRef = ref()
|
||||
const exportLoading = ref(false)
|
||||
|
||||
/** 查询列表 */
|
||||
const getList = async () => {
|
||||
loading.value = true
|
||||
try {
|
||||
const data = await ProFeedbackApi.getFeedbackPage(queryParams)
|
||||
list.value = data.list
|
||||
total.value = data.total
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
const handleQuery = () => {
|
||||
queryParams.pageNo = 1
|
||||
getList()
|
||||
}
|
||||
const resetQuery = () => {
|
||||
queryFormRef.value.resetFields()
|
||||
handleQuery()
|
||||
}
|
||||
|
||||
const formRef = ref()
|
||||
const openForm = (type: string, id?: number) => {
|
||||
formRef.value.open(type, id)
|
||||
}
|
||||
|
||||
const handleDelete = async (id: number) => {
|
||||
try {
|
||||
await message.delConfirm()
|
||||
await ProFeedbackApi.deleteFeedback(id)
|
||||
message.success(t('common.delSuccess'))
|
||||
await getList()
|
||||
} catch {}
|
||||
}
|
||||
|
||||
const handleSubmit = async (id: number) => {
|
||||
try {
|
||||
await message.confirm('确认要提交该报工单吗?')
|
||||
await ProFeedbackApi.submitFeedback(id)
|
||||
message.success('报工单已提交')
|
||||
await getList()
|
||||
} catch {}
|
||||
}
|
||||
|
||||
const handleReject = async (id: number) => {
|
||||
try {
|
||||
await message.confirm('确认要驳回该报工单吗?')
|
||||
await ProFeedbackApi.rejectFeedback(id)
|
||||
message.success('报工单已驳回')
|
||||
await getList()
|
||||
} catch {}
|
||||
}
|
||||
|
||||
const handleExecute = async (id: number) => {
|
||||
try {
|
||||
await message.confirm('确认要执行该报工单吗?')
|
||||
await ProFeedbackApi.executeFeedback(id)
|
||||
message.success('报工单已执行')
|
||||
await getList()
|
||||
} catch {}
|
||||
}
|
||||
|
||||
const handleCancel = async (id: number) => {
|
||||
try {
|
||||
await message.confirm('确认要取消该报工单吗?')
|
||||
await ProFeedbackApi.cancelFeedback(id)
|
||||
message.success('报工单已取消')
|
||||
await getList()
|
||||
} catch {}
|
||||
}
|
||||
|
||||
const handleExport = async () => {
|
||||
try {
|
||||
await message.exportConfirm()
|
||||
exportLoading.value = true
|
||||
const data = await ProFeedbackApi.exportFeedback(queryParams)
|
||||
download.excel(data, '生产报工.xls')
|
||||
} finally {
|
||||
exportLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
await getList()
|
||||
})
|
||||
</script>
|
||||
Loading…
Reference in New Issue