feat(mes): 添加报工相关字段和简化选择组件,优化数据处理逻辑

pull/871/MERGE
YunaiV 2026-02-21 12:29:49 +08:00
parent 1c4ae03e7d
commit e9e066cf25
4 changed files with 80 additions and 157 deletions

View File

@ -9,9 +9,12 @@
> >
<el-row> <el-row>
<el-col :span="12"> <el-col :span="12">
<!-- TODO @AI生成逻辑 -->
<el-form-item label="项目编码" prop="code"> <el-form-item label="项目编码" prop="code">
<el-input v-model="formData.code" placeholder="请输入项目编码" /> <el-input v-model="formData.code" placeholder="请输入项目编码">
<template #append>
<el-button @click="generateCode" :disabled="formType === 'update'">生成</el-button>
</template>
</el-input>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12"> <el-col :span="12">
@ -69,6 +72,7 @@
import { getIntDictOptions, DICT_TYPE } from '@/utils/dict' import { getIntDictOptions, DICT_TYPE } from '@/utils/dict'
import { DvSubjectApi, DvSubjectVO } from '@/api/mes/dv/subject' import { DvSubjectApi, DvSubjectVO } from '@/api/mes/dv/subject'
import { CommonStatusEnum } from '@/utils/constants' import { CommonStatusEnum } from '@/utils/constants'
import { generateRandomStr } from '@/utils'
defineOptions({ name: 'SubjectForm' }) defineOptions({ name: 'SubjectForm' })
@ -97,6 +101,11 @@ const formRules = reactive({
}) })
const formRef = ref() // Ref const formRef = ref() // Ref
/** 生成项目编码 */
const generateCode = () => {
formData.value.code = 'SUBJECT' + generateRandomStr(8)
}
/** 打开弹窗 */ /** 打开弹窗 */
const open = async (type: string, id?: number) => { const open = async (type: string, id?: number) => {
dialogVisible.value = true dialogVisible.value = true

View File

@ -1,5 +1,4 @@
<!-- 安灯呼叫记录 新增/详情弹窗 --> <!-- 安灯呼叫记录 新增/详情弹窗 -->
<!-- TODO @芋艿需要提供这样的新增么 -->
<template> <template>
<Dialog :title="dialogTitle" v-model="dialogVisible" width="600px"> <Dialog :title="dialogTitle" v-model="dialogVisible" width="600px">
<el-form <el-form
@ -16,17 +15,11 @@
<el-form-item label="发起人" prop="userId"> <el-form-item label="发起人" prop="userId">
<UserSelect v-model="formData.userId" /> <UserSelect v-model="formData.userId" />
</el-form-item> </el-form-item>
<!-- TODO @芋艿这里的 select 组件 -->
<el-form-item label="生产工单" prop="workOrderId"> <el-form-item label="生产工单" prop="workOrderId">
<el-input <ProWorkOrderSelect v-model="formData.workOrderId" placeholder="请选择工单(可选)" />
v-model="formData.workOrderId"
placeholder="请输入工单编号(可选)"
type="number"
/>
</el-form-item> </el-form-item>
<!-- TODO @芋艿这里的 select 组件 -->
<el-form-item label="工序" prop="processId"> <el-form-item label="工序" prop="processId">
<el-input v-model="formData.processId" placeholder="请输入工序编号(可选)" type="number" /> <ProProcessSelect v-model="formData.processId" placeholder="请选择工序(可选)" />
</el-form-item> </el-form-item>
<el-form-item label="呼叫原因" prop="configId"> <el-form-item label="呼叫原因" prop="configId">
<AndonConfigSelect v-model="formData.configId" @change="handleConfigChange" /> <AndonConfigSelect v-model="formData.configId" @change="handleConfigChange" />
@ -67,6 +60,8 @@ import { ProAndonRecordApi } from '@/api/mes/pro/andon/record'
import { ProAndonConfigVO } from '@/api/mes/pro/andon/config' import { ProAndonConfigVO } from '@/api/mes/pro/andon/config'
import { DICT_TYPE } from '@/utils/dict' import { DICT_TYPE } from '@/utils/dict'
import MdWorkstationSelect from '@/views/mes/md/workstation/components/MdWorkstationSelect.vue' import MdWorkstationSelect from '@/views/mes/md/workstation/components/MdWorkstationSelect.vue'
import ProWorkOrderSelect from '@/views/mes/pro/workorder/components/ProWorkOrderSelect.vue'
import ProProcessSelect from '@/views/mes/pro/process/components/ProProcessSelect.vue'
import UserSelect from '@/views/system/user/components/UserSelect.vue' import UserSelect from '@/views/system/user/components/UserSelect.vue'
import AndonConfigSelect from '../config/components/AndonConfigSelect.vue' import AndonConfigSelect from '../config/components/AndonConfigSelect.vue'
import { useUserStoreWithOut } from '@/store/modules/user' import { useUserStoreWithOut } from '@/store/modules/user'

View File

@ -52,75 +52,40 @@
</el-col> </el-col>
</el-row> </el-row>
<!-- 工单 / 任务 / 工作站 --> <!-- 工单 / 任务 / 工作站 -->
<!-- TODO @AI生产工单 select -->
<el-row :gutter="20"> <el-row :gutter="20">
<el-col :span="8"> <el-col :span="8">
<el-form-item label="生产工单" prop="workOrderId"> <el-form-item label="生产工单" prop="workOrderId">
<el-select <ProWorkOrderSelect
v-model="formData.workOrderId" v-model="formData.workOrderId"
filterable
remote
reserve-keyword
:remote-method="searchWorkOrder"
placeholder="请搜索工单编码"
:disabled="isDetail" :disabled="isDetail"
class="!w-1/1" placeholder="请选择工单"
@change="handleWorkOrderChange" @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-form-item>
</el-col> </el-col>
<el-col :span="8"> <el-col :span="8">
<el-form-item label="生产任务" prop="taskId"> <el-form-item label="生产任务" prop="taskId">
<el-select <ProTaskSelect
v-model="formData.taskId" v-model="formData.taskId"
filterable :workOrderId="formData.workOrderId"
remote
reserve-keyword
:remote-method="searchTask"
placeholder="请搜索任务编码"
:disabled="isDetail || !formData.workOrderId" :disabled="isDetail || !formData.workOrderId"
class="!w-1/1" placeholder="请选择任务"
@change="handleTaskChange" @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-form-item>
</el-col> </el-col>
<el-col :span="8"> <el-col :span="8">
<el-form-item label="工作站" prop="workstationId"> <el-form-item label="工作站" prop="workstationId">
<el-select <MdWorkstationSelect
v-model="formData.workstationId" v-model="formData.workstationId"
filterable
remote
reserve-keyword
:remote-method="searchWorkstation"
placeholder="请搜索工作站"
:disabled="isDetail" :disabled="isDetail"
class="!w-1/1" placeholder="请选择工作站"
> />
<el-option
v-for="item in workstationOptions"
:key="item.id"
:label="item.code + ' - ' + item.name"
:value="item.id"
/>
</el-select>
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> </el-row>
<!-- 工序 / 批次号 --> <!-- 工序 / 批次号 -->
<!-- TODO @芋艿是不是不用这个字段待定 -->
<el-row :gutter="20"> <el-row :gutter="20">
<el-col :span="8"> <el-col :span="8">
<el-form-item label="工序" prop="processId"> <el-form-item label="工序" prop="processId">
@ -225,22 +190,36 @@
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> </el-row>
<!-- TODO @AI报工人报工时间审批人select 模式 --> <!-- 报工人 / 报工时间 / 审核人 -->
<!-- 报工人 / 报工时间 / 审核人仅编辑/详情模式展示 --> <el-row :gutter="20">
<el-row :gutter="20" v-if="formData.id">
<el-col :span="8"> <el-col :span="8">
<el-form-item label="报工人"> <el-form-item label="报工人" prop="feedbackUserId">
<el-input :model-value="formData.feedbackUserNickname" disabled /> <UserSelect
v-model="formData.feedbackUserId"
:disabled="isDetail"
placeholder="请选择报工人"
/>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="8"> <el-col :span="8">
<el-form-item label="报工时间"> <el-form-item label="报工时间" prop="feedbackTime">
<el-input :model-value="formData.feedbackTime" disabled /> <el-date-picker
v-model="formData.feedbackTime"
type="datetime"
value-format="YYYY-MM-DD HH:mm:ss"
placeholder="请选择报工时间"
:disabled="isDetail"
class="!w-1/1"
/>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="8"> <el-col :span="8">
<el-form-item label="审核人"> <el-form-item label="审核人" prop="approveUserId">
<el-input :model-value="formData.approveUserNickname" disabled /> <UserSelect
v-model="formData.approveUserId"
:disabled="isDetail"
placeholder="请选择审核人"
/>
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> </el-row>
@ -269,7 +248,10 @@
<script setup lang="ts"> <script setup lang="ts">
import { getIntDictOptions, getStrDictOptions, DICT_TYPE } from '@/utils/dict' import { getIntDictOptions, getStrDictOptions, DICT_TYPE } from '@/utils/dict'
import { ProFeedbackApi, ProFeedbackVO } from '@/api/mes/pro/feedback' import { ProFeedbackApi, ProFeedbackVO } from '@/api/mes/pro/feedback'
import { ProWorkOrderApi } from '@/api/mes/pro/workorder' 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'
defineOptions({ name: 'FeedbackForm' }) defineOptions({ name: 'FeedbackForm' })
@ -302,11 +284,10 @@ const formData = ref<Record<string, any>>({
laborScrapQuantity: 0, laborScrapQuantity: 0,
materialScrapQuantity: 0, materialScrapQuantity: 0,
otherScrapQuantity: 0, otherScrapQuantity: 0,
remark: undefined, feedbackUserId: undefined,
// RespVO
feedbackUserNickname: undefined,
feedbackTime: undefined, feedbackTime: undefined,
approveUserNickname: undefined approveUserId: undefined,
remark: undefined
}) })
const formRules = reactive({ const formRules = reactive({
@ -327,38 +308,7 @@ const checkFlag = ref(false)
/** 工序显示(只读) */ /** 工序显示(只读) */
const processDisplay = ref('') const processDisplay = 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
// TODO @ API
workstationOptions.value = []
}
/** 工单变更:清空任务相关字段 */ /** 工单变更:清空任务相关字段 */
const handleWorkOrderChange = () => { const handleWorkOrderChange = () => {
@ -369,14 +319,14 @@ const handleWorkOrderChange = () => {
formData.value.unitMeasureId = undefined formData.value.unitMeasureId = undefined
formData.value.workstationId = undefined formData.value.workstationId = undefined
processDisplay.value = '' processDisplay.value = ''
taskOptions.value = []
checkFlag.value = false checkFlag.value = false
} }
/** 任务变更:自动填充关联字段 */ /** 任务变更:自动填充关联字段 */
const handleTaskChange = (taskId: number) => { const handleTaskChange = (task: any) => {
const task = taskOptions.value.find((t: any) => t.id === taskId) 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.itemId = task.itemId formData.value.itemId = task.itemId
@ -421,20 +371,6 @@ const open = async (type: string, id?: number) => {
// //
processDisplay.value = data.processCode ? data.processCode + ' - ' + data.processName : '' processDisplay.value = data.processCode ? data.processCode + ' - ' + data.processName : ''
checkFlag.value = (data as any).checkFlag || false checkFlag.value = (data as any).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 { } finally {
formLoading.value = false formLoading.value = false
} }
@ -490,14 +426,11 @@ const resetForm = () => {
laborScrapQuantity: 0, laborScrapQuantity: 0,
materialScrapQuantity: 0, materialScrapQuantity: 0,
otherScrapQuantity: 0, otherScrapQuantity: 0,
remark: undefined, feedbackUserId: undefined,
feedbackUserNickname: undefined,
feedbackTime: undefined, feedbackTime: undefined,
approveUserNickname: undefined approveUserId: undefined,
remark: undefined
} }
workOrderOptions.value = []
taskOptions.value = []
workstationOptions.value = []
processDisplay.value = '' processDisplay.value = ''
checkFlag.value = false checkFlag.value = false
formRef.value?.resetFields() formRef.value?.resetFields()

View File

@ -33,29 +33,18 @@
/> />
</el-select> </el-select>
</el-form-item> </el-form-item>
<!-- TODO @AIselect增加一个 workOrder select 组件 -->
<el-form-item label="生产工单" prop="workOrderId"> <el-form-item label="生产工单" prop="workOrderId">
<el-select <ProWorkOrderSelect v-model="queryParams.workOrderId" placeholder="请选择工单" class="!w-240px" />
v-model="queryParams.workOrderId" </el-form-item>
filterable <el-form-item label="产品物料" prop="itemId">
remote <MdItemSelect v-model="queryParams.itemId" placeholder="请选择产品物料" class="!w-240px" />
reserve-keyword </el-form-item>
:remote-method="searchWorkOrder" <el-form-item label="报工人" prop="feedbackUserId">
placeholder="请搜索工单编码" <UserSelect v-model="queryParams.feedbackUserId" placeholder="请选择报工人" class="!w-240px" />
clearable </el-form-item>
class="!w-240px" <el-form-item label="记录人" prop="creator">
> <UserSelect v-model="queryParams.creator" placeholder="请选择记录人" class="!w-240px" />
<el-option
v-for="item in workOrderOptions"
:key="item.id"
:label="item.code"
:value="item.id"
/>
</el-select>
</el-form-item> </el-form-item>
<!-- TODO @AI产品物料 select -->
<!-- TODO @AI报工人 select -->
<!-- TODO @AI记录人 select -->
<el-form-item label="状态" prop="status"> <el-form-item label="状态" prop="status">
<el-select v-model="queryParams.status" placeholder="请选择状态" clearable class="!w-240px"> <el-select v-model="queryParams.status" placeholder="请选择状态" clearable class="!w-240px">
<el-option <el-option
@ -221,7 +210,9 @@
import { dateFormatter } from '@/utils/formatTime' import { dateFormatter } from '@/utils/formatTime'
import download from '@/utils/download' import download from '@/utils/download'
import { ProFeedbackApi, ProFeedbackVO } from '@/api/mes/pro/feedback' import { ProFeedbackApi, ProFeedbackVO } from '@/api/mes/pro/feedback'
import { ProWorkOrderApi } from '@/api/mes/pro/workorder' import ProWorkOrderSelect from '@/views/mes/pro/workorder/components/ProWorkOrderSelect.vue'
import MdItemSelect from '@/views/mes/md/item/components/MdItemSelect.vue'
import UserSelect from '@/views/system/user/components/UserSelect.vue'
import FeedbackForm from './FeedbackForm.vue' import FeedbackForm from './FeedbackForm.vue'
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict' import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
import { MesProFeedbackStatusEnum } from '@/views/mes/utils/constants' import { MesProFeedbackStatusEnum } from '@/views/mes/utils/constants'
@ -240,20 +231,15 @@ const queryParams = reactive({
code: undefined, code: undefined,
type: undefined, type: undefined,
workOrderId: undefined, workOrderId: undefined,
itemId: undefined,
feedbackUserId: undefined,
creator: undefined,
status: undefined, status: undefined,
feedbackTime: undefined feedbackTime: undefined
}) })
const queryFormRef = ref() const queryFormRef = ref()
const exportLoading = ref(false) const exportLoading = ref(false)
/** 工单远程搜索选项 */
const workOrderOptions = ref<any[]>([])
const searchWorkOrder = async (query: string) => {
if (!query) return
const data = await ProWorkOrderApi.getWorkOrderPage({ pageNo: 1, pageSize: 20, code: query })
workOrderOptions.value = data.list
}
/** 查询列表 */ /** 查询列表 */
const getList = async () => { const getList = async () => {
loading.value = true loading.value = true