UI-Project/src/router/index.js
@@ -273,6 +273,20 @@ }, ] }, /*----------- 工程排产 ----------------*/ { path: 'engineerScheduling', name: 'engineerScheduling', component: () => import('../views/EngineerScheduling/engineerScheduling.vue'), children: [ { path: '/EngineerScheduling/engineerScheduling', name: 'engineerScheduling', component: () => import('../views/EngineerScheduling/engineerScheduling.vue') }, ] }, /*----------- 中空 ----------------*/ { path: 'hollow', UI-Project/src/views/EngineerScheduling/engineerScheduling.vue
New file @@ -0,0 +1,248 @@ <script lang="ts" setup> import { ref, computed, watch, onMounted } from 'vue' import { useI18n } from 'vue-i18n' import { ElMessage, ElTransfer, ElTabs, ElTabPane, ElButton } from 'element-plus' import request from '@/utils/request' const { t } = useI18n() const activeTab = ref('cutting1') // Transfer组件所需的数据格式 interface TransferDataItem { key: string label: string projectNo: string projectName: string } // 所有可选数据(左侧) const dataSource = ref<TransferDataItem[]>([]) // 已选数据的keys(右侧) const targetKeys = ref<string[]>([]) // 根据当前标签页获取右侧列表标题 const getRightListTitle = computed(() => { switch (activeTab.value) { case 'cutting1': return t('large.countOutOne') case 'cutting2': return t('large.countOutTwo') case 'tempered': return t('large.temp') default: return '已排产' } }) // 获取左侧数据源 const fetchDataSource = async () => { try { // 根据当前标签页选择不同的接口 const apiUrl = activeTab.value === 'tempered' ? '/cacheVerticalGlass/bigStorageCageDetails/queryEngineer' : '/loadGlass/optimizeProject/queryEngineer'; const response = await request.post(apiUrl) if (response.code === 200) { dataSource.value = response.data.map((item: any) => { const projectNo = activeTab.value === 'tempered' ? item.engineerId : item.projectNo const name = activeTab.value === 'tempered' ? item.engineerId : (item.projectNo + "-" + item.projectName) return { key: projectNo, label: name, projectNo: projectNo, projectName: activeTab.value === 'tempered' ? '' : item.projectName } }) } else { ElMessage.error(`获取数据失败: ${response.message || '未知错误'}`) } } catch (error) { console.error('获取左侧数据失败:', error) ElMessage.error('请稍后重试') } } // 获取右侧已选数据 const fetchTargetKeys = async () => { try { // 根据当前标签页确定type参数 let type = 1; // 默认切割一线 if (activeTab.value === 'cutting2') { type = 2; // 切割二线 } else if (activeTab.value === 'tempered') { type = 3; // 钢化 } const response = await request.post('/loadGlass/optimizeProject/engineerScheduling', { type: type }) if (response.code === 200) { // 对于所有标签页,使用projectNo作为key targetKeys.value = response.data.map((item: any) => item.projectNo) // 重要:将右侧数据添加到dataSource中,确保Transfer组件能找到对应的项 response.data.forEach((item: any) => { // 检查dataSource中是否已存在该项 const exists = dataSource.value.some(dataItem => dataItem.key === item.projectNo) if (!exists) { // 如果不存在,添加到dataSource中 const newItem: TransferDataItem = { key: item.projectNo, label: `${item.projectNo}-${item.projectName || 'null'}`, projectNo: item.projectNo, projectName: item.projectName || '' } dataSource.value.push(newItem) } }) } else { ElMessage.error(`获取数据失败: ${response.message || '未知错误'}`) } } catch (error) { console.error('获取右侧数据失败:', error) ElMessage.error('请稍后重试') } } // 保存排产信息 const saveScheduling = async () => { try { // 根据当前标签页确定type参数 let type = 1; // 默认切割一线 if (activeTab.value === 'cutting2') { type = 2; // 切割二线 } else if (activeTab.value === 'tempered') { type = 3; // 钢化 } const engineerList = targetKeys.value.map(projectNo => { const dataItem = dataSource.value.find(item => item.key === projectNo) return { projectNo: projectNo, projectName: dataItem ? dataItem.projectName : '' } }) const response = await request.post(`/loadGlass/optimizeProject/updateEngineerScheduling?type=${type}`, engineerList) if (response.code === 200) { ElMessage.success('保存成功') // 重新加载数据 await fetchDataSource() await fetchTargetKeys() } else { ElMessage.error(`保存失败: ${response.message || '未知错误'}`) } } catch (error) { console.error('保存排产信息失败:', error) ElMessage.error('请稍后重试') } } // 重置排产信息 const resetScheduling = async () => { await fetchDataSource() await fetchTargetKeys() ElMessage.info(t('已取消')) } // 监听标签页切换,根据不同标签页加载对应的数据 watch(activeTab, async (newTab) => { // 重新获取数据 await fetchDataSource() await fetchTargetKeys() }) // 移除formatFunc,使用默认配置,Element Plus Transfer组件默认就会显示数量统计 // 如果需要自定义标题显示,可以通过titles属性处理 // 组件挂载时获取数据 onMounted(async () => { await fetchDataSource() await fetchTargetKeys() }) </script> <template> <div class="engineer-scheduling-container"> <el-tabs v-model="activeTab" class="custom-tabs"> <el-tab-pane :label="t('large.countOutOne')" name="cutting1" /> <el-tab-pane :label="t('large.countOutTwo')" name="cutting2" /> <el-tab-pane :label="t('large.temp')" name="tempered" /> </el-tabs> <div class="transfer-wrapper"> <el-transfer v-model="targetKeys" filterable :data="dataSource" :titles="['待排产', getRightListTitle]" :button-texts="['', '']" /> <div class="transfer-save"> <el-button type="primary" @click="saveScheduling"> {{ t('searchOrder.makesure') }} </el-button> <el-button type="primary" @click="resetScheduling"> {{ t('delivery.cancel') }} </el-button> </div> </div> </div> </template> <style scoped> .engineer-scheduling-container { padding: 20px; border: 1px solid #dcdfe6; border-radius: 4px; background-color: #fff; } .custom-tabs { margin-bottom: 20px; } ::v-deep(.custom-tabs .el-tabs__item) { font-size: 20px; } .transfer-wrapper { display: flex; flex-direction: column; align-items: center; gap: 20px; } .transfer-save { display: flex; gap: 10px; } /* 自定义Transfer组件的样式 */ ::v-deep(.el-transfer-panel) { font-size: 16px; width: 350px; height: 440px; } ::v-deep(.el-transfer-panel-body-height) { height: 470px; } ::v-deep(.el-transfer-panel__header) { font-weight: bold; font-size: 18px; } ::v-deep(.el-checkbox__label) { font-size: 16px; } </style> hangzhoumesParent/common/servicebase/src/main/java/com/mes/pp/controller/OptimizeProjectController.java
@@ -1,12 +1,14 @@ package com.mes.pp.controller; import com.baomidou.mybatisplus.extension.api.R; import com.mes.pp.entity.OptimizeProject; import com.mes.pp.entity.request.OptimizeRequest; import com.mes.pp.service.OptimizeProjectService; import com.mes.utils.Result; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import liquibase.pro.packaged.O; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; @@ -41,6 +43,30 @@ return Result.build(200, "", glass); } @ApiOperation("查询工程信息") @PostMapping("/queryEngineer") //显示工程信息 pp表 @ResponseBody public Result<List<OptimizeProject>> queryEngineer() { List<OptimizeProject> resultList = optimizeProjectService.queryEngineer(); return Result.build(200, "", resultList); } @ApiOperation("查询工程排产信息") @PostMapping("/engineerScheduling") //显示工程排产信息 engineerScheduling表 @ResponseBody public Result<List<OptimizeProject>> engineerScheduling(@RequestBody OptimizeProject optimizeProject) { List<OptimizeProject> engineerScheduling = optimizeProjectService.engineerScheduling(optimizeProject); return Result.build(200, "", engineerScheduling); } @ApiOperation("更新工程信息") @PostMapping("/updateEngineerScheduling") //更新工程排产信息 engineerScheduling表 @ResponseBody public Result<List<OptimizeProject>> updateEngineerScheduling(@RequestParam Integer type, @RequestBody List<OptimizeProject> engineerList) { List<OptimizeProject> resultList = optimizeProjectService.updateEngineerScheduling(type, engineerList); return Result.build(200, "更新成功", resultList); } // @ApiOperation("保存工程信息") // @PostMapping("/saveProject") //显示工程选择信息 // public Result<List<OptimizeProject>> saveProject(@RequestBody OptimizeRequest optimizeRequest) { hangzhoumesParent/common/servicebase/src/main/java/com/mes/pp/mapper/OptimizeProjectMapper.java
@@ -4,6 +4,8 @@ import com.github.yulichang.base.MPJBaseMapper; import com.mes.pp.entity.OptimizeProject; import com.mes.pp.entity.request.OptimizeRequest; import liquibase.pro.packaged.L; import org.apache.ibatis.annotations.Param; import java.util.List; @@ -18,4 +20,34 @@ @DS("pp") public interface OptimizeProjectMapper extends MPJBaseMapper<OptimizeProject> { List<OptimizeProject> saveProject(OptimizeRequest optimizeRequest); /** * 查询工程信息 * * @return */ List<OptimizeProject> queryEngineer(); /** * 查询工程排产信息 * * @param optimizeProject * @return */ List<OptimizeProject> engineerScheduling(OptimizeProject optimizeProject); /** * 删除工程信息 * * @param type */ void deleteByType(@Param("type") Integer type); /** * 更新工程信息 * * @param projectList */ void batchInsert(@Param("list") List<OptimizeProject> projectList); } hangzhoumesParent/common/servicebase/src/main/java/com/mes/pp/service/OptimizeProjectService.java
@@ -40,4 +40,22 @@ */ List<OptimizeProject> getDoingTask(); /** * 查询工程信息 * @return */ List<OptimizeProject> queryEngineer(); /** * 查询工程排序信息 * @return */ List<OptimizeProject> engineerScheduling(OptimizeProject optimizeProject); /** * 更新工程排产信息 * @return */ List<OptimizeProject> updateEngineerScheduling(Integer type , List<OptimizeProject> engineerList); } hangzhoumesParent/common/servicebase/src/main/java/com/mes/pp/service/impl/OptimizeProjectServiceImpl.java
@@ -15,8 +15,10 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.time.LocalDateTime; import java.util.Date; import java.util.List; /** @@ -90,5 +92,32 @@ return this.list(wrapper); } @Override public List<OptimizeProject> queryEngineer() { return this.baseMapper.queryEngineer(); } @Override public List<OptimizeProject> engineerScheduling(OptimizeProject optimizeProject) { return this.baseMapper.engineerScheduling(optimizeProject); } @Override @Transactional(rollbackFor = Exception.class) public List<OptimizeProject> updateEngineerScheduling(Integer type , List<OptimizeProject> projectList) { // 1. 删除对应类型的数据 baseMapper.deleteByType(type); // 2. 设置值 projectList.forEach(project -> { project.setType(type); project.setState(100); project.setId(null); // 清除ID }); // 3. 批量插入新数据 baseMapper.batchInsert(projectList); return projectList; } } hangzhoumesParent/common/servicebase/src/main/resources/mapper/OptimizeProjectMapper.xml
@@ -13,6 +13,14 @@ </resultMap> <resultMap id="resultMap" type="com.mes.pp.entity.OptimizeProject"> <result property="id" column="id"/> <result property="projectNo" column="project_no"/> <result property="projectName" column="project_name"/> <result property="state" column="state"/> <result property="type" column="type"/> </resultMap> <select id="saveProject" parameterType="com.mes.pp.entity.request.OptimizeRequest" resultMap="sequenceMap"> select a.project_no, 1 as glass_type, a.width, a.height, REGEXP_REPLACE(b.glass_thickness, '\\D', '')as glass_thickness, a.heat_layout_sort, 0 as state from optimize_detail a @@ -20,5 +28,53 @@ where a.project_no = #{projectNo} </select> <select id="queryEngineer" parameterType="com.mes.pp.entity.OptimizeProject" resultMap="resultMap"> select p.project_no, p.project_name from pp.optimize_project p where p.state = 100 and p.project_no not in ( select es.project_no from north_glass_mes.engineer_scheduling es where es.project_no is not null ) order by p.id </select> <select id="engineerScheduling" parameterType="com.mes.pp.entity.request.OptimizeRequest" resultMap="resultMap"> select es.project_no, es.project_name, es.type from north_glass_mes.engineer_scheduling es where es.state = 100 <if test="type != null and type != ''"> and es.type = #{type} </if> order by es.id </select> <!-- 根据类型删除engineer_scheduling表中的数据 --> <delete id="deleteByType"> DELETE FROM north_glass_mes.engineer_scheduling WHERE type = #{type} </delete> <!-- 批量插入数据到engineer_scheduling表 --> <insert id="batchInsert"> INSERT INTO north_glass_mes.engineer_scheduling ( project_no, project_name, state, type ) VALUES <foreach collection="list" item="item" separator=","> ( #{item.projectNo}, #{item.projectName}, #{item.state}, #{item.type} ) </foreach> </insert> </mapper> hangzhoumesParent/moduleService/CacheVerticalGlassModule/src/main/java/com/mes/bigstorage/controller/BigStorageCageDetailsController.java
@@ -10,15 +10,13 @@ import com.mes.bigstorage.service.BigStorageCageDetailsService; import com.mes.bigstorage.service.BigStorageCageService; import com.mes.common.config.Const; import com.mes.pp.entity.OptimizeProject; import com.mes.utils.RedisUtil; import com.mes.utils.Result; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; import java.util.List; @@ -197,5 +195,13 @@ String glassId = map.get("glassId"); return Result.build(200, "报破损成功", bigStorageCageDetailsService.bigStorageGlassDamageByGlassId(glassId)); } @ApiOperation("查询工程待排产信息") @PostMapping("/queryEngineer") //显示工程排产信息 @ResponseBody public Result<List<BigStorageCageDetails>> queryEngineer() { List<BigStorageCageDetails> result = bigStorageCageDetailsService.queryEngineer(); return Result.build(200, "", result); } } hangzhoumesParent/moduleService/CacheVerticalGlassModule/src/main/java/com/mes/bigstorage/service/BigStorageCageDetailsService.java
@@ -7,6 +7,7 @@ import com.mes.bigstorage.entity.vo.BigStorageQueryVO; import com.mes.bigstoragetask.entity.UpdateBigStorageCageDTO; import com.mes.glassinfo.entity.GlassInfo; import com.mes.pp.entity.OptimizeProject; import java.util.List; import java.util.Map; @@ -134,4 +135,11 @@ * @return */ boolean cancelTemperingTask(); /** * 查询工程待排序信息 * @return */ List<BigStorageCageDetails> queryEngineer(); } hangzhoumesParent/moduleService/CacheVerticalGlassModule/src/main/java/com/mes/bigstorage/service/impl/BigStorageCageDetailsServiceImpl.java
@@ -2,6 +2,7 @@ import cn.hutool.core.lang.Assert; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.github.yulichang.base.MPJBaseServiceImpl; import com.github.yulichang.toolkit.JoinWrappers; @@ -28,6 +29,7 @@ import com.mes.glassinfo.entity.GlassInfo; import com.mes.glassinfo.mapper.GlassInfoMapper; import com.mes.glassinfo.service.GlassInfoService; import com.mes.pp.entity.OptimizeProject; import com.mes.sysconfig.entity.SysConfig; import com.mes.sysconfig.service.SysConfigService; import com.mes.temperingglass.entity.TemperingGlassInfo; @@ -568,4 +570,12 @@ public void updateDeviceIdBySlot(List<Integer> slotList) { baseMapper.updateDeviceIdBySlot(slotList); } @Override public List<BigStorageCageDetails> queryEngineer() { QueryWrapper<BigStorageCageDetails> wrapper = new QueryWrapper<>(); wrapper.select("distinct engineer_id") .eq("state", 100); return this.list(wrapper); } }