feat(biz): 更新用户机台管理功能为工序管理

This commit is contained in:
zxy 2026-06-01 10:38:33 +08:00
parent e0c5e1a4ef
commit 9835388514
8 changed files with 161 additions and 92 deletions

View File

@ -10,6 +10,7 @@ import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import static com.ningxia.yunxi.chemmes.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY;
import static com.ningxia.yunxi.chemmes.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@Schema(description = "管理后台 - 采购订单主分页 Request VO")
@ -26,7 +27,7 @@ public class PurOrderPageReqVO extends PageParam {
private String purOrdNo;
@Schema(description = "订单日期")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY)
private LocalDate[] purDate;
@Schema(description = "附件信息")

View File

@ -53,6 +53,8 @@ public class UserMachineDetailRespVO {
private Integer lineId;
private String proLineCd;
private String proLineName;
private String procName;
private String procCd;
private Integer procId;
}

View File

@ -30,4 +30,11 @@ public class UserMachineDetailSaveReqVO {
private Integer lineId;
private String proLineName;
private String proLineCd;
private String procName;
private String procCd;
private Integer procId;
}

View File

@ -55,4 +55,7 @@ public class UserMachineDetailDO extends BaseDO {
private String proLineCd;
private String proLineName;
private String procName;
private String procCd;
private Integer procId;
}

View File

@ -3,7 +3,6 @@ package com.ningxia.yunxi.chemmes.module.biz.service.usermachine;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import com.ningxia.yunxi.chemmes.module.biz.controller.admin.usermachine.vo.UserMachineDetailSaveReqVO;
import com.ningxia.yunxi.chemmes.module.biz.dal.dataobject.proline.ProLineDO;
import com.ningxia.yunxi.chemmes.module.biz.dal.dataobject.usermachine.UserMachineDetailDO;
import com.ningxia.yunxi.chemmes.module.biz.dal.dataobject.usermachine.UserMachineDetailMapper;
import com.ningxia.yunxi.chemmes.module.biz.service.proline.ProLineService;
@ -52,12 +51,12 @@ public class UserMachineDetailServiceImpl implements UserMachineDetailService {
detailEntity.setMachineName(form.getMachineName());
detailEntity.setEnabledStatus(0);
// 根据机台ID查询机台信息
ProLineDO machineEntity = proLineService.getProLine(form.getLineId());
if (machineEntity != null) {
detailEntity.setLineId(form.getLineId());
detailEntity.setProLineCd(machineEntity.getProLineCd());
detailEntity.setProLineName(machineEntity.getProLineName());
}
detailEntity.setProLineCd(form.getProLineCd());
detailEntity.setProLineName(form.getProLineName());
detailEntity.setProcCd(form.getProcCd());
detailEntity.setProcName(form.getProcName());
detailEntity.setProcId(form.getProcId());
return detailEntity;
})
.collect(Collectors.toList());

View File

@ -31,28 +31,11 @@ declare module 'vue' {
DocAlert: typeof import('./../components/DocAlert/index.vue')['default']
Echart: typeof import('./../components/Echart/src/Echart.vue')['default']
Editor: typeof import('./../components/Editor/src/Editor.vue')['default']
ElAlert: typeof import('element-plus/es')['ElAlert']
ElAside: typeof import('element-plus/es')['ElAside']
ElAutoResizer: typeof import('element-plus/es')['ElAutoResizer']
ElAvatar: typeof import('element-plus/es')['ElAvatar']
ElBadge: typeof import('element-plus/es')['ElBadge']
ElButton: typeof import('element-plus/es')['ElButton']
ElButtonGroup: typeof import('element-plus/es')['ElButtonGroup']
ElCard: typeof import('element-plus/es')['ElCard']
ElCarousel: typeof import('element-plus/es')['ElCarousel']
ElCarouselItem: typeof import('element-plus/es')['ElCarouselItem']
ElCascader: typeof import('element-plus/es')['ElCascader']
ElCheckbox: typeof import('element-plus/es')['ElCheckbox']
ElCheckboxGroup: typeof import('element-plus/es')['ElCheckboxGroup']
ElCol: typeof import('element-plus/es')['ElCol']
ElCollapse: typeof import('element-plus/es')['ElCollapse']
ElCollapseItem: typeof import('element-plus/es')['ElCollapseItem']
ElCollapseTransition: typeof import('element-plus/es')['ElCollapseTransition']
ElColorPicker: typeof import('element-plus/es')['ElColorPicker']
ElContainer: typeof import('element-plus/es')['ElContainer']
ElDatePicker: typeof import('element-plus/es')['ElDatePicker']
ElDescriptions: typeof import('element-plus/es')['ElDescriptions']
ElDescriptionsItem: typeof import('element-plus/es')['ElDescriptionsItem']
ElDialog: typeof import('element-plus/es')['ElDialog']
ElDivider: typeof import('element-plus/es')['ElDivider']
ElDrawer: typeof import('element-plus/es')['ElDrawer']
@ -68,44 +51,23 @@ declare module 'vue' {
ElementTask: typeof import('./../components/bpmnProcessDesigner/package/penal/task/ElementTask.vue')['default']
ElForm: typeof import('element-plus/es')['ElForm']
ElFormItem: typeof import('element-plus/es')['ElFormItem']
ElHeader: typeof import('element-plus/es')['ElHeader']
ElIcon: typeof import('element-plus/es')['ElIcon']
ElImage: typeof import('element-plus/es')['ElImage']
ElImageViewer: typeof import('element-plus/es')['ElImageViewer']
ElInput: typeof import('element-plus/es')['ElInput']
ElInputNumber: typeof import('element-plus/es')['ElInputNumber']
ElLink: typeof import('element-plus/es')['ElLink']
ElMain: typeof import('element-plus/es')['ElMain']
ElOption: typeof import('element-plus/es')['ElOption']
ElPagination: typeof import('element-plus/es')['ElPagination']
ElPopover: typeof import('element-plus/es')['ElPopover']
ElRadio: typeof import('element-plus/es')['ElRadio']
ElRadioButton: typeof import('element-plus/es')['ElRadioButton']
ElRadioGroup: typeof import('element-plus/es')['ElRadioGroup']
ElRate: typeof import('element-plus/es')['ElRate']
ElRow: typeof import('element-plus/es')['ElRow']
ElScrollbar: typeof import('element-plus/es')['ElScrollbar']
ElSelect: typeof import('element-plus/es')['ElSelect']
ElSkeleton: typeof import('element-plus/es')['ElSkeleton']
ElSlider: typeof import('element-plus/es')['ElSlider']
ElSpace: typeof import('element-plus/es')['ElSpace']
ElSwitch: typeof import('element-plus/es')['ElSwitch']
ElTable: typeof import('element-plus/es')['ElTable']
ElTableColumn: typeof import('element-plus/es')['ElTableColumn']
ElTableV2: typeof import('element-plus/es')['ElTableV2']
ElTabPane: typeof import('element-plus/es')['ElTabPane']
ElTabs: typeof import('element-plus/es')['ElTabs']
ElTag: typeof import('element-plus/es')['ElTag']
ElText: typeof import('element-plus/es')['ElText']
ElTimeline: typeof import('element-plus/es')['ElTimeline']
ElTimelineItem: typeof import('element-plus/es')['ElTimelineItem']
ElTimePicker: typeof import('element-plus/es')['ElTimePicker']
ElTimeSelect: typeof import('element-plus/es')['ElTimeSelect']
ElTooltip: typeof import('element-plus/es')['ElTooltip']
ElTransfer: typeof import('element-plus/es')['ElTransfer']
ElTree: typeof import('element-plus/es')['ElTree']
ElTreeSelect: typeof import('element-plus/es')['ElTreeSelect']
ElUpload: typeof import('element-plus/es')['ElUpload']
Error: typeof import('./../components/Error/src/Error.vue')['default']
FlowCondition: typeof import('./../components/bpmnProcessDesigner/package/penal/flow-condition/FlowCondition.vue')['default']
Form: typeof import('./../components/Form/src/Form.vue')['default']
@ -122,6 +84,7 @@ declare module 'vue' {
ProcessDesigner: typeof import('./../components/bpmnProcessDesigner/package/designer/ProcessDesigner.vue')['default']
ProcessPalette: typeof import('./../components/bpmnProcessDesigner/package/palette/ProcessPalette.vue')['default']
ProcessViewer: typeof import('./../components/bpmnProcessDesigner/package/designer/ProcessViewer.vue')['default']
ProcSelect: typeof import('./../views/biz/proc/ProcSelect.vue')['default']
PropertiesPanel: typeof import('./../components/bpmnProcessDesigner/package/penal/PropertiesPanel.vue')['default']
Qrcode: typeof import('./../components/Qrcode/src/Qrcode.vue')['default']
ReceiveTask: typeof import('./../components/bpmnProcessDesigner/package/penal/task/task-components/ReceiveTask.vue')['default']

View File

@ -49,23 +49,56 @@
<el-input v-model="formData.remark" placeholder="请输入备注" type="textarea" :rows="2" />
</el-form-item>
<!-- 机台信息 -->
<!-- 工序信息 -->
<div class="mt-20px">
<div class="mb-15px flex items-center">
<span class="font-weight-600">机台信息</span>
<el-button type="primary" plain size="small" @click="addMachine" class="ml-10px">
<span class="font-weight-600">工序信息</span>
<el-button type="primary" plain size="small" @click="addProc" class="ml-10px">
<Icon icon="ep:plus" class="mr-5px" /> 新增
</el-button>
</div>
<el-table :data="machineList" :show-overflow-tooltip="true" border>
<el-table-column label="序号" align="center" type="index" width="60px" />
<el-table-column label="机台编码" align="center" prop="machineCd" />
<el-table-column label="机台名称" align="center" prop="machineName" />
<el-table-column label="产线编码" align="center" min-width="150px">
<template #default="scope">
<el-select
v-model="scope.row.proLineId"
placeholder="请选择产线"
class="!w-full"
@change="handleProLineChange(scope.row)"
>
<el-option
v-for="item in proLineOptions"
:key="item.id"
:label="item.proLineName + '(' + item.proLineCd + ')'"
:value="item.id"
/>
</el-select>
</template>
</el-table-column>
<el-table-column label="工序编码" align="center" min-width="150px">
<template #default="scope">
<el-select
v-model="scope.row.procId"
placeholder="请选择工序"
class="!w-full"
@change="handleProcChange(scope.row)"
>
<el-option
v-for="item in procOptions"
:key="item.id"
:label="item.procName + '(' + item.procCd + ')'"
:value="item.id"
/>
</el-select>
</template>
</el-table-column>
<el-table-column label="创建人" align="center" prop="creator" />
<el-table-column label="创建时间" align="center" prop="createTime" :formatter="dateFormatter" />
<el-table-column label="操作" align="center" width="80px">
<template #default="scope">
<el-button link type="danger" size="small" @click="removeMachine(scope.$index)">删除</el-button>
<el-button link type="danger" size="small" @click="removeProc(scope.$index)">删除</el-button>
</template>
</el-table-column>
</el-table>
@ -76,9 +109,6 @@
<el-button @click="dialogVisible = false"> </el-button>
</template>
</Dialog>
<!-- 机台选择弹窗 -->
<MachineSelect ref="machineSelectRef" @confirm="confirmMachine" />
</template>
<script setup lang="ts">
import { ref, reactive, watch } from 'vue'
@ -86,7 +116,8 @@ import { getIntDictOptions, getStrDictOptions, DICT_TYPE } from '@/utils/dict'
import { Icon } from '@/components/Icon'
import * as UserMachineApi from '@/api/biz/usermachine'
import * as SystemUserApi from '@/api/system/user'
import MachineSelect from '@/views/biz/machine/MachineSelect.vue'
import * as ProLineApi from '@/api/biz/proline'
import * as ProcApi from '@/api/biz/proc'
import { dateFormatter } from '@/utils/formatTime'
const { t } = useI18n()
@ -116,7 +147,8 @@ const formRef = ref()
const userOptions = ref([])
const userList = ref([])
const machineList = ref([])
const machineSelectRef = ref()
const proLineOptions = ref([]) // 线
const procOptions = ref([]) //
const open = async (type: string, id?: number) => {
dialogVisible.value = true
@ -124,16 +156,14 @@ const open = async (type: string, id?: number) => {
formType.value = type
resetForm()
await loadUsers()
await loadProLineOptions()
await loadProcOptions()
if (id) {
formLoading.value = true
try {
const data = await UserMachineApi.getUserMachine(id)
formData.value = data
// lineId
machineList.value = (data.machineList || []).map(item => ({
...item,
lineId: item.lineId || item.belgLineId,
}))
machineList.value = data.machineList || []
} finally {
formLoading.value = false
}
@ -152,6 +182,24 @@ const loadUsers = async () => {
} catch {}
}
const loadProLineOptions = async () => {
try {
const data = await ProLineApi.getProLineList()
proLineOptions.value = data || []
} catch (error) {
console.error('加载产线列表失败:', error)
}
}
const loadProcOptions = async () => {
try {
const data = await ProcApi.getProcList()
procOptions.value = data || []
} catch (error) {
console.error('加载工序列表失败:', error)
}
}
watch(() => formData.value.userNo, (userNo) => {
if (userNo) {
const user = userList.value.find((u: any) => u.username === userNo)
@ -162,28 +210,47 @@ watch(() => formData.value.userNo, (userNo) => {
}
})
const addMachine = () => {
const selectedIds = machineList.value.map(m => m.machineId)
machineSelectRef.value.open(selectedIds)
}
const confirmMachine = (machines: any[]) => {
machines.forEach((item: any) => {
const exists = machineList.value.some(m => m.machineId === item.id)
if (!exists) {
const addProc = () => {
machineList.value.push({
machineId: item.id,
machineCd: item.machineCd,
machineName: item.machineName,
creator: item.creator,
createTime: item.createTime,
lineId: item.belgLineId || item.lineId, //
})
}
lineId: undefined,
proLineId: undefined,
proLineCd: undefined,
proLineName: undefined,
procId: undefined,
procCd: undefined,
procName: undefined,
})
}
const removeMachine = (index: number) => {
const handleProLineChange = (row: any) => {
if (row.proLineId) {
const proLine = proLineOptions.value.find((p: any) => p.id === row.proLineId)
if (proLine) {
row.lineId = proLine.id
row.proLineCd = proLine.proLineCd
row.proLineName = proLine.proLineName
}
} else {
row.lineId = undefined
row.proLineCd = undefined
row.proLineName = undefined
}
}
const handleProcChange = (row: any) => {
if (row.procId) {
const proc = procOptions.value.find((p: any) => p.id === row.procId)
if (proc) {
row.procCd = proc.procCd
row.procName = proc.procName
}
} else {
row.procCd = undefined
row.procName = undefined
}
}
const removeProc = (index: number) => {
machineList.value.splice(index, 1)
}
@ -197,19 +264,48 @@ watch(dialogVisible, (val) => {
})
const submitForm = async () => {
if (machineList.value.length === 0) {
message.warning('请选择机台信息')
message.warning('请添加工序信息')
return
}
//
for (let i = 0; i < machineList.value.length; i++) {
const item = machineList.value[i]
if (!item.proLineId) {
message.warning(`${i + 1}行的产线编码不能为空`)
return
}
if (!item.procId) {
message.warning(`${i + 1}行的工序编码不能为空`)
return
}
}
// 线
for (let i = 0; i < machineList.value.length; i++) {
const currentItem = machineList.value[i]
for (let j = i + 1; j < machineList.value.length; j++) {
const compareItem = machineList.value[j]
if (currentItem.proLineId === compareItem.proLineId && currentItem.procId === compareItem.procId) {
message.warning(`'${currentItem.proLineName}'+'${currentItem.procName}'数据重复,请确认!`)
return
}
}
}
await formRef.value.validate()
formLoading.value = true
try {
const data = {
...formData.value,
machineList: machineList.value.map(m => ({
machineId: m.machineId,
machineCd: m.machineCd,
machineName: m.machineName,
lineId: m.lineId,
machineList: machineList.value.map(p => ({
lineId: p.lineId,
proLineId: p.proLineId,
proLineCd: p.proLineCd,
proLineName: p.proLineName,
procId: p.procId,
procCd: p.procCd,
procName: p.procName,
})),
} as unknown as UserMachineApi.UserMachineVO
if (formType.value === 'create') {

View File

@ -118,10 +118,8 @@
<div class="font-weight-600 mb-15px">机台信息</div>
<el-table v-loading="machineLoading" :data="machineList" :show-overflow-tooltip="true" :stripe="true" border>
<el-table-column label="序号" align="center" type="index" width="60px" />
<el-table-column label="机台编码" align="center" prop="machineCd" />
<el-table-column label="机台名称" align="center" prop="machineName" />
<el-table-column label="生产编码" align="center" prop="proLineCd" />
<el-table-column label="生产线名称" align="center" prop="proLineName" />
<el-table-column label="产线编码" align="center" prop="proLineCd" />
<el-table-column label="工序编码" align="center" prop="procCd" />
<el-table-column label="创建人" align="center" prop="creator" />
<el-table-column label="创建时间" align="center" prop="createTime" :formatter="dateFormatter2" />
</el-table>