1058 lines
51 KiB
Java
1058 lines
51 KiB
Java
package com.ruoyi.system.controller;
|
||
|
||
import cn.dev33.satoken.annotation.SaCheckPermission;
|
||
import cn.hutool.json.JSONUtil;
|
||
import com.alibaba.excel.EasyExcel;
|
||
import com.alibaba.excel.ExcelWriter;
|
||
import com.alibaba.excel.support.ExcelTypeEnum;
|
||
import com.alibaba.excel.write.metadata.WriteSheet;
|
||
import com.ruoyi.common.annotation.Log;
|
||
import com.ruoyi.common.annotation.RepeatSubmit;
|
||
import com.ruoyi.common.config.DingTalkProperties;
|
||
import com.ruoyi.common.core.controller.BaseController;
|
||
import com.ruoyi.common.core.domain.PageQuery;
|
||
import com.ruoyi.common.core.domain.R;
|
||
import com.ruoyi.common.core.domain.entity.SysUser;
|
||
import com.ruoyi.common.core.page.TableDataInfo;
|
||
import com.ruoyi.common.core.validate.AddGroup;
|
||
import com.ruoyi.common.core.validate.EditGroup;
|
||
import com.ruoyi.common.dingding.util.DingUtil;
|
||
import com.ruoyi.common.enums.BusinessType;
|
||
import com.ruoyi.common.excel.DefaultExcelListener;
|
||
import com.ruoyi.common.excel.ExcelResult;
|
||
import com.ruoyi.common.exception.ServiceException;
|
||
import com.ruoyi.common.helper.LoginHelper;
|
||
import com.ruoyi.common.utils.FtpUtil;
|
||
import com.ruoyi.common.utils.StringUtils;
|
||
import com.ruoyi.common.utils.file.SmbUtil;
|
||
import com.ruoyi.common.utils.poi.ExcelUtil;
|
||
import com.ruoyi.system.domain.*;
|
||
import com.ruoyi.system.domain.bo.ProcessRouteBo;
|
||
import com.ruoyi.system.domain.dto.*;
|
||
import com.ruoyi.system.domain.vo.PcRigidChainVo;
|
||
import com.ruoyi.system.domain.vo.PlannedProcessVo;
|
||
import com.ruoyi.system.domain.vo.ProcessRouteVo;
|
||
import com.ruoyi.system.domain.vo.ProductionOrderVo;
|
||
import com.ruoyi.system.jdmain.rouplan.Model;
|
||
import com.ruoyi.system.mapper.BomDetailsMapper;
|
||
import com.ruoyi.system.mapper.MaterialBomMapper;
|
||
import com.ruoyi.system.mapper.ProcessOrderProMapper;
|
||
import com.ruoyi.system.mapper.ProcessRouteMapper;
|
||
import com.ruoyi.system.runner.JdUtil;
|
||
import com.ruoyi.system.service.*;
|
||
import lombok.RequiredArgsConstructor;
|
||
import lombok.extern.slf4j.Slf4j;
|
||
import org.springframework.beans.factory.annotation.Autowired;
|
||
import org.springframework.http.HttpStatus;
|
||
import org.springframework.http.MediaType;
|
||
import org.springframework.http.ResponseEntity;
|
||
import org.springframework.validation.annotation.Validated;
|
||
import org.springframework.web.bind.annotation.*;
|
||
import org.springframework.web.multipart.MultipartFile;
|
||
|
||
import javax.servlet.ServletOutputStream;
|
||
import javax.servlet.http.HttpServletResponse;
|
||
import javax.validation.constraints.NotEmpty;
|
||
import javax.validation.constraints.NotNull;
|
||
import java.io.*;
|
||
import java.math.BigDecimal;
|
||
import java.math.RoundingMode;
|
||
import java.net.URLEncoder;
|
||
import java.text.SimpleDateFormat;
|
||
import java.util.*;
|
||
import java.util.concurrent.CompletableFuture;
|
||
import java.util.stream.Collectors;
|
||
|
||
/**
|
||
* 工艺路线
|
||
*
|
||
* @date 2024-10-09
|
||
*/
|
||
@Validated
|
||
@RequiredArgsConstructor
|
||
@RestController
|
||
@RequestMapping("/system/route")
|
||
@Slf4j
|
||
public class ProcessRouteController extends BaseController {
|
||
private final ProcessRouteMapper baseMapper;
|
||
private final IProcessRouteService iProcessRouteService;
|
||
private final IBomDetailsService iBomDetailsService;
|
||
private final ProcessOrderProMapper proMapper;
|
||
private final IImMaterialService materialService;
|
||
@Autowired
|
||
BomDetailsMapper bomDetailsMapper;
|
||
@Autowired
|
||
MaterialBomMapper materialBomMapper;
|
||
@Autowired
|
||
private DingTalkProperties dingTalkProperties;
|
||
@Autowired
|
||
private ISysOssService iSysOssService;
|
||
@Autowired
|
||
private IProcessOrderProService processOrderProService;
|
||
@Autowired
|
||
private ISysUserService userService;
|
||
|
||
@Autowired
|
||
private com.ruoyi.common.dingding.robot.RobotGroupService robotGroupService;
|
||
|
||
@Autowired
|
||
private com.ruoyi.common.dingding.media.MediaService mediaService;
|
||
|
||
private Long generateUniqueParentId(Long originalId) {
|
||
return originalId + 1000;
|
||
}
|
||
|
||
@Log(title = "查看BOM上传状态")
|
||
@SaCheckPermission("system:route:viewGetBomUploadStatus")
|
||
@PostMapping("/viewGetBomUploadStatus")
|
||
public R<String> viewGetBomUploadStatus(@RequestParam String rooteProdet) {
|
||
return iProcessRouteService.viewGetBomUploadStatus(rooteProdet);
|
||
}
|
||
|
||
/**
|
||
* 主动更新可用库存
|
||
*/
|
||
@SaCheckPermission("system:route:list")
|
||
@GetMapping("/list2")
|
||
public TableDataInfo<ProcessRouteVo> list2(ProcessRouteBo bo, PageQuery pageQuery) {
|
||
try {
|
||
// 查询工艺路线数据
|
||
TableDataInfo<ProcessRouteVo> processRouteVoTableDataInfo = iProcessRouteService.queryPageList2(bo, pageQuery);
|
||
// 用于存储父子关系的Map,key为"物料编码_物料名称",值为父级ProcessRouteVo
|
||
Map<String, ProcessRouteVo> routeMap = new HashMap<>();
|
||
// 存储顶级列表
|
||
List<ProcessRouteVo> topLevelList = new ArrayList<>();
|
||
// 获取查询返回的行数据
|
||
List<ProcessRouteVo> rows = processRouteVoTableDataInfo.getRows();
|
||
// 遍历所有工艺路线记录
|
||
for (ProcessRouteVo processRouteVo : rows) {
|
||
// 组合父级键值,物料编码 + 物料名称
|
||
String parentCodeAndName = String.format("%s_%s", processRouteVo.getMaterialCode(), processRouteVo.getMaterialName());
|
||
// 查找是否已存在父节点
|
||
ProcessRouteVo parent = routeMap.get(parentCodeAndName);
|
||
if (parent == null) {
|
||
// 如果父节点不存在,创建并初始化
|
||
parent = new ProcessRouteVo();
|
||
parent.setId(generateUniqueParentId(processRouteVo.getId()));
|
||
parent.setRouteDescription(processRouteVo.getRouteDescription());
|
||
// parent.setParentId((Long.valueOf(generateUniqueParentId(processRouteVo.getId()))));
|
||
parent.setMaterialCode(processRouteVo.getMaterialCode());
|
||
parent.setMaterialName(processRouteVo.getMaterialName());
|
||
parent.setMaterial(processRouteVo.getMaterial());
|
||
parent.setDiscWeight(processRouteVo.getDiscWeight());
|
||
parent.setFirstBatchQuantity(processRouteVo.getFirstBatchQuantity());
|
||
|
||
// 初始化子节点列表
|
||
parent.setChildren(new ArrayList<>());
|
||
// 将父节点放入Map中
|
||
routeMap.put(parentCodeAndName, parent);
|
||
// 将父节点加入顶级列表
|
||
topLevelList.add(parent);
|
||
}
|
||
// 创建子节点,并将其添加到父节点的子集
|
||
ProcessRouteVo child = createChildVo(processRouteVo, parent.getId(), parent.getMaterialCode(), parent.getMaterialName());
|
||
parent.getChildren().add(child);
|
||
}
|
||
// 设置返回的rows为顶级节点列表
|
||
processRouteVoTableDataInfo.setRows(topLevelList);
|
||
// 返回构建后的数据
|
||
return processRouteVoTableDataInfo;
|
||
} catch (Exception e) {
|
||
e.printStackTrace();
|
||
return new TableDataInfo<>();
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 查询工艺路线列表
|
||
*/
|
||
@SaCheckPermission("system:route:list")
|
||
@GetMapping("/list")
|
||
public TableDataInfo<ProcessRouteVo> list(ProcessRouteBo bo, PageQuery pageQuery) {
|
||
try {
|
||
// 查询工艺路线数据
|
||
TableDataInfo<ProcessRouteVo> processRouteVoTableDataInfo = iProcessRouteService.queryPageList(bo, pageQuery);
|
||
// 用于存储父子关系的Map,key为"物料编码_物料名称",值为父级ProcessRouteVo
|
||
Map<String, ProcessRouteVo> routeMap = new HashMap<>();
|
||
// 存储顶级列表
|
||
List<ProcessRouteVo> topLevelList = new ArrayList<>();
|
||
// 获取查询返回的行数据
|
||
List<ProcessRouteVo> rows = processRouteVoTableDataInfo.getRows();
|
||
// 遍历所有工艺路线记录
|
||
for (ProcessRouteVo processRouteVo : rows) {
|
||
// 组合父级键值,物料编码 + 物料名称
|
||
String parentCodeAndName = String.format("%s_%s", processRouteVo.getMaterialCode(), processRouteVo.getMaterialName());
|
||
// 查找是否已存在父节点
|
||
ProcessRouteVo parent = routeMap.get(parentCodeAndName);
|
||
if (parent == null) {
|
||
// 如果父节点不存在,创建并初始化
|
||
parent = new ProcessRouteVo();
|
||
parent.setId(generateUniqueParentId(processRouteVo.getId()));
|
||
parent.setRouteDescription(processRouteVo.getRouteDescription());
|
||
// parent.setParentId((Long.valueOf(generateUniqueParentId(processRouteVo.getId()))));
|
||
parent.setMaterialCode(processRouteVo.getMaterialCode());
|
||
parent.setMaterialName(processRouteVo.getMaterialName());
|
||
parent.setMaterial(processRouteVo.getMaterial());
|
||
parent.setDiscWeight(processRouteVo.getDiscWeight());
|
||
parent.setBatchQuantity(processRouteVo.getBatchQuantity());
|
||
parent.setFirstBatchQuantity(processRouteVo.getFirstBatchQuantity());
|
||
|
||
// 初始化子节点列表
|
||
parent.setChildren(new ArrayList<>());
|
||
// 将父节点放入Map中
|
||
routeMap.put(parentCodeAndName, parent);
|
||
// 将父节点加入顶级列表
|
||
topLevelList.add(parent);
|
||
}
|
||
// 创建子节点,并将其添加到父节点的子集
|
||
ProcessRouteVo child = createChildVo(processRouteVo, parent.getId(), parent.getMaterialCode(), parent.getMaterialName());
|
||
parent.getChildren().add(child);
|
||
}
|
||
|
||
// 设置返回的rows为顶级节点列表
|
||
processRouteVoTableDataInfo.setRows(topLevelList);
|
||
|
||
// 返回构建后的数据
|
||
return processRouteVoTableDataInfo;
|
||
} catch (Exception e) {
|
||
e.printStackTrace();
|
||
return new TableDataInfo<>();
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 创建子节点的辅助方法
|
||
*
|
||
* @param processRouteVo 原始数据
|
||
* @return ProcessRouteVo 子节点
|
||
*/
|
||
private ProcessRouteVo createChildVo(ProcessRouteVo processRouteVo, Long parentId, String materialCode, String materialName) {
|
||
ProcessRouteVo child = new ProcessRouteVo();
|
||
child.setId(processRouteVo.getId());
|
||
child.setParentId(parentId);
|
||
child.setProcessNo(processRouteVo.getProcessNo());
|
||
child.setWorkCenter(processRouteVo.getWorkCenter());
|
||
child.setProcessName(processRouteVo.getProcessName());
|
||
child.setProcessDescription(processRouteVo.getProcessDescription());
|
||
child.setProcessControl(processRouteVo.getProcessControl());
|
||
child.setActivityDuration(processRouteVo.getActivityDuration());
|
||
child.setActivityUnit(processRouteVo.getActivityUnit());
|
||
child.setUnitQuantity(processRouteVo.getUnitQuantity());
|
||
child.setPlanStartTime(processRouteVo.getPlanStartTime());
|
||
child.setPlanEndTime(processRouteVo.getPlanEndTime());
|
||
child.setXuStartTime(processRouteVo.getXuStartTime());
|
||
child.setXuEndTime(processRouteVo.getXuEndTime());
|
||
return child;
|
||
}
|
||
|
||
/**
|
||
* 导出工艺路线列表
|
||
*/
|
||
@SaCheckPermission("system:route:export2")
|
||
@Log(title = "工艺路线", businessType = BusinessType.EXPORT)
|
||
@PostMapping("/export2")
|
||
public void export2(ProcessRouteBo bo, HttpServletResponse response) {
|
||
log.info("获取项目生产数据表:{}", bo);
|
||
List<ProcessRoute> list = iProcessRouteService.queryList(bo);
|
||
List<MaterialUsageDTO2> bomlist = JdUtil.getPRD_PPBOM(bo.getRouteDescription());
|
||
//过滤bomlist 只要009开头的标准件
|
||
bomlist = bomlist.stream().filter(bom -> bom.getMaterialCode().startsWith("009")).collect(Collectors.toList());
|
||
if (list.isEmpty() && bomlist.isEmpty()) {
|
||
throw new ServiceException("没有数据");
|
||
}
|
||
try {
|
||
// 设置响应头
|
||
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
|
||
response.setCharacterEncoding("utf-8");
|
||
String fileName = URLEncoder.encode("工艺路线", "UTF-8").replaceAll("\\+", "%20");
|
||
response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
|
||
ServletOutputStream os = response.getOutputStream();
|
||
|
||
// 创建ExcelWriter
|
||
try (com.alibaba.excel.ExcelWriter excelWriter = EasyExcel.write(os).autoCloseStream(false) // 防止自动关闭流
|
||
.build()) {
|
||
// 写入工艺路线sheet
|
||
if (!list.isEmpty()) {
|
||
WriteSheet writeSheet1 = EasyExcel.writerSheet(0, "工艺路线").head(ProcessRoute.class).build();
|
||
excelWriter.write(list, writeSheet1);
|
||
}
|
||
|
||
// 写入标准件清单sheet
|
||
if (!bomlist.isEmpty()) {
|
||
WriteSheet writeSheet2 = EasyExcel.writerSheet(1, "标准件清单").head(MaterialUsageDTO2.class).build();
|
||
excelWriter.write(bomlist, writeSheet2);
|
||
}
|
||
}
|
||
} catch (Exception e) {
|
||
throw new RuntimeException("导出Excel异常: " + e.getMessage(), e);
|
||
}
|
||
}
|
||
|
||
@SaCheckPermission("system:route:export")
|
||
@Log(title = "工艺路线", businessType = BusinessType.EXPORT)
|
||
@PostMapping("/export")
|
||
public void export(ProcessRouteBo bo, HttpServletResponse response) {
|
||
log.info("获取项目生产数据表:{}", bo);
|
||
// 下载Excel模板
|
||
SmbUtil.downloadExcelFiles(bo.getRouteDescription());
|
||
// 构建Excel文件路径
|
||
String ExcelName = "D:\\file\\" + bo.getRouteDescription() + "汇总表.xlsx";
|
||
File file = new File(ExcelName);
|
||
if (!file.exists()) {
|
||
throw new ServiceException("文件不存在,请确认路径是否正确");
|
||
}
|
||
//读取file的所有的物料编码
|
||
try {
|
||
|
||
if (file.exists()) {
|
||
// 读取Excel的sheet6 从第三行开始 读取到第4列 无数据的跳过
|
||
DefaultExcelListener<ProcessRoute> listener = new DefaultExcelListener<>(true);
|
||
EasyExcel.read(ExcelName, ProcessRoute.class, listener).sheet(6).headRowNumber(3).doRead();
|
||
}
|
||
} catch (Exception e) {
|
||
throw new RuntimeException(e);
|
||
}
|
||
// 查询要写入的数据是否
|
||
List<ProcessRoute> list = iProcessRouteService.queryList(bo);
|
||
|
||
try {
|
||
// 设置响应头
|
||
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
|
||
response.setCharacterEncoding("utf-8");
|
||
String fileName = URLEncoder.encode("工艺路线", "UTF-8").replaceAll("\\+", "%20");
|
||
response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
|
||
|
||
ServletOutputStream os = response.getOutputStream();
|
||
|
||
// 使用 EasyExcel 写入已有Excel的第七个sheet(index=6)
|
||
try (ExcelWriter excelWriter = EasyExcel.write(os).withTemplate(file) // 指定模板文件
|
||
.autoCloseStream(true).build()) {
|
||
|
||
// 写入到第七个 sheet(index=6),并命名为“工艺路线”
|
||
WriteSheet writeSheet = EasyExcel.writerSheet("已有工艺路线").head(ProcessRoute.class).needHead(true).build();
|
||
excelWriter.write(list, writeSheet);
|
||
}
|
||
|
||
os.flush();
|
||
} catch (Exception e) {
|
||
log.error("导出Excel异常", e);
|
||
throw new RuntimeException("导出Excel异常: " + e.getMessage(), e);
|
||
}
|
||
}
|
||
|
||
|
||
/**
|
||
* 获取工艺路线详细信息
|
||
*
|
||
* @param id 主键
|
||
*/
|
||
@SaCheckPermission("system:route:query")
|
||
@GetMapping("/{id}")
|
||
public R<ProcessRouteVo> getInfo(@NotNull(message = "主键不能为空") @PathVariable Long id) {
|
||
return R.ok(iProcessRouteService.queryById(id));
|
||
}
|
||
|
||
/**
|
||
* 新增工艺路线
|
||
*/
|
||
@SaCheckPermission("system:route:add")
|
||
@Log(title = "工艺路线", businessType = BusinessType.INSERT)
|
||
@RepeatSubmit()
|
||
@PostMapping()
|
||
public R<Void> add(@Validated(AddGroup.class) @RequestBody ProcessRouteBo bo) {
|
||
return toAjax(iProcessRouteService.insertByBo(bo));
|
||
}
|
||
|
||
/**
|
||
* 导出
|
||
* 修改工艺路线
|
||
*/
|
||
@SaCheckPermission("system:route:edit")
|
||
@Log(title = "工艺路线", businessType = BusinessType.UPDATE)
|
||
@RepeatSubmit()
|
||
@PutMapping()
|
||
public R<Void> edit(@Validated(EditGroup.class) @RequestBody ProcessRouteBo bo) {
|
||
return toAjax(iProcessRouteService.updateByBo(bo));
|
||
}
|
||
|
||
/**
|
||
* 删除工艺路线
|
||
*
|
||
* @param ids 主键串
|
||
*/
|
||
@SaCheckPermission("system:route:remove")
|
||
@Log(title = "工艺路线", businessType = BusinessType.DELETE)
|
||
@DeleteMapping("/{ids}")
|
||
public R<Void> remove(@NotEmpty(message = "主键不能为空") @PathVariable Long[] ids) {
|
||
return toAjax(iProcessRouteService.deleteWithValidByIds(Arrays.asList(ids), true));
|
||
}
|
||
|
||
@Log(title = "生产工艺计划表导入", businessType = BusinessType.IMPORT)
|
||
@SaCheckPermission("system:route:importRoute")
|
||
@PostMapping(value = "/importData", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
|
||
public R importData(@RequestParam("file") MultipartFile file) throws Exception {
|
||
String originalFilename = file.getOriginalFilename();
|
||
|
||
log.info("读取文件名: " + originalFilename);
|
||
// 读取工艺部分sheet
|
||
ExcelResult<ProcessRouteVo> result = ExcelUtil.importExcelSheet6(file.getInputStream(), ProcessRouteVo.class, true);
|
||
List<ProcessRouteVo> list1 = result.getList();
|
||
// 读取总装部分sheet
|
||
ExcelResult<ProductionOrderVo> result1 = ExcelUtil.importExcelSheet1(file.getInputStream(), ProductionOrderVo.class, true);
|
||
List<ProductionOrderVo> list = result1.getList();
|
||
String productionOrderNo = list1.get(0).getRouteDescription();
|
||
List<BomDetails> bomDetails = iBomDetailsService.selectByProjectNumber(list1.get(0).getRouteDescription());
|
||
List<ProcessRoute> route = iProcessRouteService.selectByProjectNumber(list1.get(0).getRouteDescription());
|
||
if (list1.isEmpty()) {
|
||
return R.fail("项目 " + productionOrderNo + "工艺生产计划表为空,请检查此表或将sheet移动至第七个!");
|
||
}
|
||
if (!bomDetails.isEmpty()) {
|
||
return R.fail("项目 " + productionOrderNo + "已导入过BOM,请先清空再上传");
|
||
}
|
||
if (!route.isEmpty()) {
|
||
return R.fail("项目 " + productionOrderNo + "已导入过工艺 ,请先清空再上传");
|
||
}
|
||
if (iProcessRouteService.saveData(list1, list)) {
|
||
// 保存临时文件用于发送给指定用户
|
||
File tempFile = null;
|
||
try {
|
||
String tempDirPath = "D:/file/";
|
||
File tempDir = new File(tempDirPath);
|
||
if (!tempDir.exists()) {
|
||
tempDir.mkdirs();
|
||
}
|
||
tempFile = new File(tempDirPath + System.currentTimeMillis() + "_" + originalFilename);
|
||
file.transferTo(tempFile);
|
||
} catch (Exception e) {
|
||
log.error("保存上传临时文件失败", e);
|
||
}
|
||
final File uploadFile = tempFile;
|
||
|
||
// 获取当前登录用户昵称(需要在异步线程前获取)
|
||
String currentUserNickName = "未知用户";
|
||
try {
|
||
Long userId = LoginHelper.getUserId();
|
||
if (userId != null) {
|
||
SysUser user = userService.selectUserById(userId);
|
||
if (user != null && StringUtils.isNotEmpty(user.getNickName())) {
|
||
currentUserNickName = user.getNickName();
|
||
}
|
||
}
|
||
} catch (Exception e) {
|
||
log.warn("获取当前登录用户昵称失败", e);
|
||
}
|
||
|
||
// 异步发送钉钉卡片和文件
|
||
String finalNickName = currentUserNickName;
|
||
CompletableFuture.runAsync(() -> {
|
||
try {
|
||
if (uploadFile != null && uploadFile.exists()) {
|
||
String planUserIds = dingTalkProperties.getPlanUserId();
|
||
if (StringUtils.isNotBlank(planUserIds)) {
|
||
String mediaId = mediaService.uploadMedia("file", uploadFile.getAbsolutePath());
|
||
// 支持多人推送,假设多个 userId 以逗号分隔
|
||
String[] userIds = planUserIds.split(",");
|
||
for (String userId : userIds) {
|
||
String cleanUserId = userId.trim();
|
||
if (StringUtils.isNotBlank(cleanUserId)) {
|
||
try {
|
||
robotGroupService.sendFileToUser(cleanUserId, mediaId, originalFilename);
|
||
log.info("上传的工艺计划表已成功发送给用户: {}", cleanUserId);
|
||
} catch (Exception e) {
|
||
log.error("发送文件给用户 {} 异常", cleanUserId, e);
|
||
}
|
||
}
|
||
}
|
||
} else {
|
||
log.warn("未配置钉钉工艺计划接收人(planUserId),跳过发送文件");
|
||
}
|
||
}
|
||
} catch (Exception e) {
|
||
log.error("发送文件给工艺计划接收人异常", e);
|
||
} finally {
|
||
if (uploadFile != null && uploadFile.exists()) {
|
||
uploadFile.delete();
|
||
}
|
||
}
|
||
|
||
try {
|
||
ProcessOrderPro order = processOrderProService.selectByProjectNumber(productionOrderNo);
|
||
if (order != null) {
|
||
// 获取 AccessToken
|
||
String accessToken = DingUtil.getAccessToken(dingTalkProperties.getAppKey(), dingTalkProperties.getAppSecret());
|
||
// 构造卡片数据
|
||
Map<String, String> cardDataMap = new HashMap<>();
|
||
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
|
||
cardDataMap.put("pro_number", StringUtils.defaultIfEmpty(order.getProductionOrderNo(), ""));
|
||
cardDataMap.put("createTime", order.getRouteUptime() != null ? sdf.format(new Date()) : "");
|
||
cardDataMap.put("title", finalNickName + "提交工艺审核");
|
||
cardDataMap.put("lastMessage", "请尽快处理");
|
||
cardDataMap.put("status", StringUtils.defaultIfEmpty("待审批", "待审批"));
|
||
|
||
String outTrackId = "audit-card-" + System.currentTimeMillis();
|
||
// 调用发送给工艺负责人的方法 createAndDeliverCardToUser
|
||
DingUtil.createAndDeliverCardToUser(
|
||
accessToken,
|
||
dingTalkProperties.getRouteCardTemplateId(),
|
||
Collections.singletonList(dingTalkProperties.getRouteApprovalId()),
|
||
outTrackId,
|
||
cardDataMap,
|
||
dingTalkProperties.getCallbackRouteKey()
|
||
);
|
||
// 统一存入带 userId 后缀的完整 outTrackId,以便和钉钉回调保持一致
|
||
String fullOutTrackId = outTrackId + "_" + dingTalkProperties.getRouteApprovalId();
|
||
// 更新数据库中的AuditCardId
|
||
ProcessOrderPro update = new ProcessOrderPro();
|
||
update.setId(order.getId());
|
||
update.setUpdateBy("Dingding");
|
||
update.setAuditCardId(fullOutTrackId);
|
||
update.setBomStatus(2L);
|
||
// 更新审核状态为1(已审核/提交审核)
|
||
update.setRouteStatus(0L);
|
||
proMapper.updateById(update);
|
||
}
|
||
} catch (Exception e) {
|
||
log.error("发送钉钉卡片异常", e);
|
||
}
|
||
});
|
||
return R.ok("上传物料成功");
|
||
} else {
|
||
return R.fail("导入失败");
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 查询组焊件集合
|
||
*/
|
||
@Log(title = "查询组焊件集合")
|
||
@SaCheckPermission("system:route:pushGroupWeldments")
|
||
@PostMapping("/pushGroupWeldments")
|
||
public List<ProcessRoute> pushGroupWeldments(@RequestBody ProcessRoute processRoute) {
|
||
return iProcessRouteService.pushGroupWeldments(processRoute);
|
||
}
|
||
|
||
/**
|
||
* 查询需要单独生成BOm 的原材料集合
|
||
*/
|
||
@Log(title = "查询需要单独生成BOM的原材料集合")
|
||
@SaCheckPermission("system:route:getRawBom")
|
||
@PostMapping("/getRawBom")
|
||
public List<ProcessRoute> getRawBom(@RequestParam String rooteProdet) {
|
||
return iProcessRouteService.getRawBom(rooteProdet);
|
||
}
|
||
|
||
/**
|
||
* 查询工艺表中所有的需要做工艺的物料
|
||
*
|
||
* @return RequestBody List<ProcessRouteVo> routeVoList
|
||
*/
|
||
public List<ProcessRoute> getProcessRouteList(@RequestParam String rooteProdet) {
|
||
List<ProcessRoute> list = iProcessRouteService.pushRawMater(rooteProdet);
|
||
return list;
|
||
}
|
||
|
||
@Log(title = "查询工艺工序集合")
|
||
@SaCheckPermission("system:route:getProcessRoute")
|
||
@PostMapping("/getProcessRoute")
|
||
public List<ProcessRouteXuDTO> getProcessRoute(@RequestParam String rooteProdet) {
|
||
return iProcessRouteService.getProcessRoute(rooteProdet);
|
||
}
|
||
|
||
@Log(title = "推送工艺工序")
|
||
@SaCheckPermission("system:route:pushRouteBom")
|
||
@PostMapping("/pushRouteBom")
|
||
public R<ProcessRoutePushResultDTO> pushRouteBom(@RequestParam String rooteProdet, @RequestParam String groupName) {
|
||
return iProcessRouteService.pushRouteBom(rooteProdet, groupName);
|
||
}
|
||
|
||
/**
|
||
* 查询项目列表
|
||
*/
|
||
@Log(title = "获取所有的项目令号")
|
||
@SaCheckPermission("system:route:getDistinctProjectCodes")
|
||
@GetMapping("/getDistinctProjectCodes")
|
||
public ResponseEntity<List<String>> getDistinctProjectCodes(String query) {
|
||
return ResponseEntity.ok(iProcessRouteService.getDistinctProjectCodes(query));
|
||
}
|
||
|
||
@Log(title = "获取工序列表")
|
||
@SaCheckPermission("system:route:getProcessInfoList")
|
||
@GetMapping("/getProcessInfoList")
|
||
public ResponseEntity<List<String>> getProcessInfoList(String query) {
|
||
return ResponseEntity.ok(iProcessRouteService.getProcessInfoList(query));
|
||
}
|
||
|
||
@Log(title = "根据生产令号获取生产编号==》获取计划编号")
|
||
@SaCheckPermission("system:route:getSelecPlanRouteList")
|
||
@PostMapping("/getSelecPlanRouteList")
|
||
public List<CombinedDTO> getSelecPlanRouteList(@RequestParam String rooteProdet) {
|
||
return iProcessRouteService.getSelecPlanRouteList(rooteProdet);
|
||
}
|
||
|
||
@Log(title = "生成项目图纸PDF")
|
||
@SaCheckPermission("system:route:generatePDFs")
|
||
@GetMapping("/generatePDFs")
|
||
public void generatePDFs(String rooteProdet, HttpServletResponse response) throws IOException {
|
||
// 调用服务层方法生成 ZIP 文件并获取其路径
|
||
String zipFilePath = iProcessRouteService.generatePDFs(rooteProdet);
|
||
ProcessOrderPro processOrderPro = proMapper.selectByProjectNumber(rooteProdet);
|
||
processOrderPro.setBomStatus(5L);
|
||
proMapper.updateById(processOrderPro);
|
||
// 读取文件为字节数组
|
||
File zipFile = new File(zipFilePath);
|
||
if (!zipFile.exists()) {
|
||
throw new FileNotFoundException("ZIP 文件未找到: " + zipFilePath);
|
||
}
|
||
FileInputStream fis = new FileInputStream(zipFile);
|
||
OutputStream outputStreams = response.getOutputStream();
|
||
response.setContentType("application/zip");
|
||
byte[] buffer = new byte[1024];
|
||
int len;
|
||
while ((len = fis.read(buffer)) != -1) {
|
||
outputStreams.write(buffer, 0, len);
|
||
}
|
||
outputStreams.flush();
|
||
|
||
fis.close();
|
||
outputStreams.close();
|
||
}
|
||
|
||
@Log(title = "更新计划时间")
|
||
@SaCheckPermission("system:route:updateProcessPlan")
|
||
@PostMapping("/updateProcessPlan")
|
||
public List<Model> updateProcessPlan(@RequestParam String rooteProdet) throws Exception {
|
||
return iProcessRouteService.updateProcessPlan(rooteProdet);
|
||
}
|
||
|
||
/**
|
||
* 更新生产订单的时间
|
||
*/
|
||
@Log(title = "更新生产订单时间")
|
||
@SaCheckPermission("system:route:updateProcesTime")
|
||
@PostMapping("/updateProcesTime")
|
||
public List<Model> updateProcesTime(@RequestParam String rooteProdet) throws Exception {
|
||
return iProcessRouteService.updateProcesTime(rooteProdet);
|
||
}
|
||
|
||
/**
|
||
* 保存工艺路线
|
||
*/
|
||
@SaCheckPermission("system:route:addRoute")
|
||
@Log(title = "保存工艺路线", businessType = BusinessType.INSERT)
|
||
@RepeatSubmit()
|
||
@PostMapping("/addRoute")
|
||
public R<Void> addRoute(@RequestBody List<ProcessRouteVo> list) {
|
||
|
||
return iProcessRouteService.addRoute(list);
|
||
}
|
||
|
||
@SaCheckPermission("system:route:deleteRoute")
|
||
@Log(title = "删除工艺路线", businessType = BusinessType.INSERT)
|
||
@RepeatSubmit()
|
||
@PostMapping("/deleteRoute")
|
||
public List<ProcessRoute> deleteRoute(@RequestBody ProcessRoute processRoute) {
|
||
return iProcessRouteService.deleteRoute(processRoute);
|
||
}
|
||
|
||
@Log(title = "获取材料bom列表")
|
||
@SaCheckPermission("system:route:getBomInfo")
|
||
@PostMapping("/getBomInfo")
|
||
public ResponseEntity<List<MaterialBom>> getProcessMaterialList(@RequestParam(value = "materialCode") String materialCode, @RequestParam(value = "materialName") String materialName, @RequestParam(value = "productionOrderNo") String productionOrderNo) {
|
||
return ResponseEntity.ok(iProcessRouteService.getProcessMaterialList(materialCode, materialName, productionOrderNo));
|
||
}
|
||
|
||
@Log(title = "获取金蝶列表")
|
||
@SaCheckPermission("system:route:getProcessRouteList")
|
||
@GetMapping("/getProcessRouteList")
|
||
public ResponseEntity<List<ProcessRouteJdDTO>> getProcessRouteList(@RequestParam(value = "materialCode") String materialCode, @RequestParam(value = "materialName") String materialName, @RequestParam(value = "productionOrderNo") String productionOrderNo) {
|
||
return ResponseEntity.ok(iProcessRouteService.getProcessRouteList(materialCode, materialName, productionOrderNo));
|
||
}
|
||
|
||
@Log(title = "导入时间", businessType = BusinessType.IMPORT)
|
||
@SaCheckPermission("system:route:importDataTime")
|
||
@PostMapping(value = "/importDataTime", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
|
||
public R<Void> importDataTime(@RequestParam("file") MultipartFile file) throws Exception {
|
||
String originalFilename = file.getOriginalFilename();
|
||
log.info("读取文件名: " + originalFilename);
|
||
ExcelResult<ProcessRouteVo> result = ExcelUtil.importExcelSheet6(file.getInputStream(), ProcessRouteVo.class, true);
|
||
List<ProcessRouteVo> list = result.getList();
|
||
List<ProcessRoute> list1 = iProcessRouteService.importDataTime(list);
|
||
return R.ok("更新成功");
|
||
}
|
||
|
||
|
||
@Log(title = "导入时间", businessType = BusinessType.IMPORT)
|
||
@SaCheckPermission("system:route:importDataTime123")
|
||
@PostMapping(value = "/importDataTime123", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
|
||
public R<Void> importDataTime123(@RequestParam("file") MultipartFile file) throws Exception {
|
||
DefaultExcelListener<PcRigidChainVo> listener = new DefaultExcelListener<>(true);
|
||
EasyExcel.read(file.getInputStream(), PcRigidChainVo.class, listener).excelType(ExcelTypeEnum.XLS).sheet(1).headRowNumber(4).doRead();
|
||
List<PcRigidChainVo> list1 = listener.getExcelResult().getList();
|
||
for (PcRigidChainVo pcRigidChainVO : list1) {
|
||
log.info("数据 ===============>: " + JSONUtil.toJsonStr(pcRigidChainVO));
|
||
}
|
||
return R.ok("更新成功");
|
||
}
|
||
|
||
|
||
@Log(title = "获取金蝶工艺路线")
|
||
@SaCheckPermission("system:route:getSelectProcessRout1e")
|
||
@PostMapping("/getSelectProcessRout1e")
|
||
public List<ProcessRouteSelectDTO> getSelectProcessRoute1(@RequestParam String materilCode) {
|
||
return iProcessRouteService.getSelectProcessRoute(materilCode);
|
||
}
|
||
|
||
private void processCombinedDTO(CombinedDTO combinedDTO, List<BomDetails> bomDetailsList, List<ProcessRoute> routeList, List<MaterialBom> materialBoms, String productionOrderNo) {
|
||
// 处理工序列表
|
||
combinedDTO.getProcesses().forEach(process -> {
|
||
ProcessRoute processRoute = createProcessRoute(process, combinedDTO, productionOrderNo);
|
||
routeList.add(processRoute);
|
||
});
|
||
// 处理物料清单
|
||
combinedDTO.getMaterialUsageDTOList().forEach(materialUsageDTO -> {
|
||
BomDetails bomDetails = createBomDetails(materialUsageDTO, combinedDTO, productionOrderNo);
|
||
bomDetailsList.add(bomDetails);
|
||
});
|
||
// 处理材料BOM
|
||
combinedDTO.getMaterialUsageDTOList().forEach(materialUsageDTO -> {
|
||
MaterialBom materialBom = creatBomMaterial(materialUsageDTO, combinedDTO, productionOrderNo);
|
||
materialBoms.add(materialBom);
|
||
});
|
||
|
||
}
|
||
|
||
private void processMaterAndRoute(JDMaterialAndRoute materialAndRoute, List<BomDetails> bomDetailsList, List<ProcessRoute> routeList, List<MaterialBom> materialBoms, String productionOrderNo) {
|
||
// 处理工序列表
|
||
materialAndRoute.getPlannedProcessVos().forEach(processRouteDTO -> {
|
||
ProcessRoute processRoute = createProcessRoute1(processRouteDTO, materialAndRoute, productionOrderNo);
|
||
routeList.add(processRoute);
|
||
});
|
||
// 处理物料清单
|
||
materialAndRoute.getMaterialUseDTOS().forEach(materialUsageDTO -> {
|
||
BomDetails bomDetails = createBomDetails1(materialUsageDTO, materialAndRoute, productionOrderNo);
|
||
bomDetailsList.add(bomDetails);
|
||
});
|
||
// 处理材料BOM
|
||
materialAndRoute.getMaterialUseDTOS().forEach(materialUsageDTO -> {
|
||
MaterialBom materialBom = creatBomMaterial1(materialUsageDTO, materialAndRoute, productionOrderNo);
|
||
materialBoms.add(materialBom);
|
||
});
|
||
|
||
}
|
||
|
||
private MaterialBom creatBomMaterial1(MaterialUseDTO materialUsageDTO, JDMaterialAndRoute materialAndRoute, String productionOrderNo) {
|
||
MaterialBom materialBom = new MaterialBom();
|
||
materialBom.setProjectNumber(productionOrderNo);
|
||
materialBom.setParentMaterialCode(materialAndRoute.getMaterialCode());
|
||
materialBom.setParentMaterialName(materialAndRoute.getMaterialName());
|
||
materialBom.setMaterialCode(materialUsageDTO.getMaterialCode());
|
||
materialBom.setMaterialName(materialUsageDTO.getMaterialName());
|
||
materialBom.setUnit(materialUsageDTO.getChildUnit());
|
||
materialBom.setMaterialType(materialUsageDTO.getCaizhi());
|
||
//保留四位小数
|
||
materialBom.setQuantity(String.valueOf(BigDecimal.valueOf(materialUsageDTO.getFenzi()).divide(new BigDecimal(materialUsageDTO.getFenmu()), 4, RoundingMode.HALF_UP)));
|
||
return materialBom;
|
||
}
|
||
|
||
private BomDetails createBomDetails1(MaterialUseDTO materialUsageDTO, JDMaterialAndRoute materialAndRoute, String productionOrderNo) {
|
||
BomDetails bomDetails = new BomDetails();
|
||
bomDetails.setTotalWeight(productionOrderNo);
|
||
bomDetails.setFNumber(materialAndRoute.getMaterialCode());
|
||
bomDetails.setFName(materialAndRoute.getMaterialName());
|
||
bomDetails.setPartNumber(materialUsageDTO.getMaterialCode());
|
||
bomDetails.setUnitWeight("是");
|
||
bomDetails.setWareHouse(materialUsageDTO.getChildUnit());
|
||
//子项分子
|
||
bomDetails.setQuantity(String.valueOf(materialUsageDTO.getFenzi()));
|
||
//子项分母
|
||
bomDetails.setDenominator(Double.valueOf(materialUsageDTO.getFenmu()));
|
||
bomDetails.setName(materialUsageDTO.getMaterialName());
|
||
bomDetails.setMaterial(materialUsageDTO.getCaizhi());
|
||
return bomDetails;
|
||
}
|
||
|
||
private ProcessRoute createProcessRoute1(ProcessRouteDTO processRouteDTO, JDMaterialAndRoute materialAndRoute, String productionOrderNo) {
|
||
|
||
ProcessRoute processRoute = new ProcessRoute();
|
||
// 设置路线描述为生产订单号
|
||
processRoute.setRouteDescription(productionOrderNo);
|
||
// 设置工序号
|
||
processRoute.setProcessNo(processRouteDTO != null ? processRouteDTO.getProcessNo() : null);
|
||
// 设置工序名称
|
||
processRoute.setProcessName(processRouteDTO != null ? processRouteDTO.getProcessName() : null);
|
||
|
||
if (materialAndRoute != null && StringUtils.isNotEmpty(materialAndRoute.getMaterialCode())) {
|
||
ImMaterial materialByCode = materialService.getMaterialByCode(materialAndRoute.getMaterialCode());
|
||
if (materialByCode != null && materialByCode.getSingleWeight() != null) {
|
||
processRoute.setDiscWeight(Double.valueOf(String.valueOf(materialByCode.getSingleWeight())));
|
||
} else {
|
||
processRoute.setDiscWeight(null);
|
||
}
|
||
} else {
|
||
processRoute.setDiscWeight(null);
|
||
}
|
||
|
||
processRoute.setMaterial(materialAndRoute != null ? materialAndRoute.getCaizhi() : null);
|
||
// 设置物料代码
|
||
processRoute.setMaterialCode(materialAndRoute != null ? materialAndRoute.getMaterialCode() : null);
|
||
processRoute.setMaterialName(materialAndRoute != null ? materialAndRoute.getMaterialName() : null);
|
||
|
||
processRoute.setWorkCenter(processRouteDTO != null ? processRouteDTO.getWorkCenter() : null);
|
||
// 基本时长
|
||
processRoute.setActivityDuration(processRouteDTO != null ? processRouteDTO.getActivityDuration() : null);
|
||
processRoute.setProcessDescription(processRouteDTO != null ? processRouteDTO.getProcessDescription() : null);
|
||
processRoute.setProcessControl(processRouteDTO != null ? processRouteDTO.getProcessControl() : null);
|
||
|
||
processRoute.setXuStartTime(null);
|
||
processRoute.setXuEndTime(null);
|
||
processRoute.setActivityUnit("分");
|
||
|
||
// 本批数量对应
|
||
processRoute.setBatchQuantity(materialAndRoute != null ? materialAndRoute.getBenpi() : null);
|
||
if (materialAndRoute != null && materialAndRoute.getDantai() != null) {
|
||
processRoute.setFirstBatchQuantity(Double.valueOf(materialAndRoute.getDantai()));
|
||
} else {
|
||
processRoute.setFirstBatchQuantity(null);
|
||
}
|
||
|
||
List<MaterialUseDTO> materialUsageDTOList = materialAndRoute != null ? materialAndRoute.getMaterialUseDTOS() : null;
|
||
if (materialUsageDTOList != null) {
|
||
for (MaterialUseDTO materialUsageDTO : materialUsageDTOList) {
|
||
if (materialUsageDTO != null) {
|
||
processRoute.setUnitQuantity(materialUsageDTO.getFenzi());
|
||
processRoute.setBomMaterial(materialUsageDTO.getCaizhi());
|
||
processRoute.setRawMaterialCode(materialUsageDTO.getMaterialCode());
|
||
processRoute.setRawMaterialName(materialUsageDTO.getMaterialName());
|
||
processRoute.setBomUnit(materialUsageDTO.getChildUnit());
|
||
if ("根".equals(materialUsageDTO.getChildUnit())) {
|
||
if (materialUsageDTO.getFenmu() != null) {
|
||
processRoute.setDiscUsage(String.valueOf(Double.valueOf(materialUsageDTO.getFenmu())));
|
||
} else {
|
||
processRoute.setDiscUsage(null);
|
||
}
|
||
} else {
|
||
if (materialUsageDTO.getFenzi() != null && materialUsageDTO.getFenmu() != null && materialUsageDTO.getFenmu() != 0) {
|
||
processRoute.setDiscUsage(String.valueOf(materialUsageDTO.getFenzi() / materialUsageDTO.getFenmu()));
|
||
} else {
|
||
processRoute.setDiscUsage(null);
|
||
}
|
||
}
|
||
processRoute.setMaterial(materialUsageDTO.getCaizhi());
|
||
} else {
|
||
processRoute.setUnitQuantity(null);
|
||
processRoute.setBomMaterial(null);
|
||
processRoute.setRawMaterialCode(null);
|
||
processRoute.setRawMaterialName(null);
|
||
processRoute.setBomUnit(null);
|
||
processRoute.setDiscUsage(null);
|
||
processRoute.setMaterial(null);
|
||
}
|
||
}
|
||
}
|
||
return processRoute;
|
||
}
|
||
|
||
@Log(title = "生成金蝶标准工艺")
|
||
@SaCheckPermission("system:route:getKindeeExcel")
|
||
@GetMapping("/getKindeeExcel")
|
||
public ResponseEntity<String> getKindeeExcel(String rooteProdet) throws IOException {
|
||
|
||
List<CombinedDTO> planRouteList = iProcessRouteService.getSelecPlanRouteList(rooteProdet);
|
||
List<BomDetails> bomDetailsList = new ArrayList<>();
|
||
List<ProcessRoute> routeList = new ArrayList<>();
|
||
List<MaterialBom> materialBoms = new ArrayList<>();
|
||
|
||
// 将数据写入excel 中
|
||
for (CombinedDTO combinedDTO : planRouteList) {
|
||
processCombinedDTO(combinedDTO, bomDetailsList, routeList, materialBoms, rooteProdet);
|
||
}
|
||
|
||
// 批量插入数据库
|
||
try {
|
||
bomDetailsMapper.insertBatch(bomDetailsList);
|
||
baseMapper.insertBatch(routeList);
|
||
materialBomMapper.insertBatch(materialBoms);
|
||
return ResponseEntity.ok("保存成功");
|
||
} catch (Exception e) {
|
||
// 处理异常并返回失败信息
|
||
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("保存失败: " + e.getMessage());
|
||
}
|
||
}
|
||
|
||
private ProcessRoute createProcessRoute(PlannedProcessVo process, CombinedDTO combinedDTO, String productionOrderNo) {
|
||
ProcessRoute processRoute = new ProcessRoute();
|
||
// 设置路线描述为生产订单号
|
||
processRoute.setRouteDescription(productionOrderNo);
|
||
// 设置工序号
|
||
processRoute.setProcessNo(process.getFOperNumber());
|
||
// 设置工序名称
|
||
processRoute.setProcessName(process.getFProcessName());
|
||
String materialCode = combinedDTO.getMaterialCode();
|
||
try {
|
||
List<ProcessRoute> singleWeightList = iProcessRouteService.getSingleWeght(materialCode);
|
||
if (singleWeightList != null && !singleWeightList.isEmpty()) {
|
||
processRoute.setDiscWeight(singleWeightList.get(0).getDiscWeight());
|
||
}
|
||
} catch (Exception e) {
|
||
// 记录日志或采取其他措施
|
||
log.error("Error fetching single weight for material code: " + materialCode, e);
|
||
}
|
||
|
||
// 设置物料代码
|
||
processRoute.setMaterialCode(combinedDTO.getMaterialCode());
|
||
processRoute.setMaterialName(combinedDTO.getMaterialName());
|
||
Double fOperQty = process.getFOperQty();
|
||
long l = fOperQty.longValue();
|
||
processRoute.setWorkCenter(process.getFWorkCenterName());
|
||
// 基本时长
|
||
processRoute.setActivityDuration(process.getFActivity1BaseQty());
|
||
processRoute.setProcessDescription(process.getFOperDescription());
|
||
processRoute.setProcessControl(process.getFOptCtrlCodeIFName());
|
||
processRoute.setXuStartTime(process.getFSeqPlanStartTime());
|
||
processRoute.setXuEndTime(process.getFSeqPlanFinishTime());
|
||
processRoute.setActivityUnit("分");
|
||
// 本批数量对应
|
||
processRoute.setBatchQuantity(process.getFMOQty());
|
||
List<MaterialUsageDTO> materialUsageDTOList = combinedDTO.getMaterialUsageDTOList();
|
||
for (MaterialUsageDTO materialUsageDTO : materialUsageDTOList) {
|
||
processRoute.setUnitQuantity(materialUsageDTO.getFNumerator());
|
||
processRoute.setBomMaterial(materialUsageDTO.getChildMaterial());
|
||
processRoute.setRawMaterialCode(materialUsageDTO.getMaterialCode());
|
||
processRoute.setRawMaterialName(materialUsageDTO.getMaterialName());
|
||
processRoute.setBomUnit(materialUsageDTO.getUnit());
|
||
if (materialUsageDTO.getUnit().equals("根")) {
|
||
processRoute.setDiscUsage(String.valueOf(materialUsageDTO.getFDenominator()));
|
||
} else {
|
||
processRoute.setDiscUsage(String.valueOf(materialUsageDTO.getFNumerator() / materialUsageDTO.getFDenominator()));
|
||
}
|
||
|
||
processRoute.setMaterial(materialUsageDTO.getChildMaterial());
|
||
|
||
}
|
||
return processRoute;
|
||
}
|
||
|
||
private BomDetails createBomDetails(MaterialUsageDTO materialUsageDTO, CombinedDTO combinedDTO, String productionOrderNo) {
|
||
BomDetails bomDetails = new BomDetails();
|
||
bomDetails.setTotalWeight(productionOrderNo);
|
||
bomDetails.setFNumber(combinedDTO.getMaterialCode());
|
||
bomDetails.setFName(combinedDTO.getMaterialName());
|
||
bomDetails.setPartNumber(materialUsageDTO.getMaterialCode());
|
||
bomDetails.setUnitWeight("是");
|
||
bomDetails.setWareHouse(materialUsageDTO.getUnit());
|
||
//子项分子
|
||
bomDetails.setQuantity(String.valueOf(materialUsageDTO.getFNumerator()));
|
||
//子项分母
|
||
bomDetails.setDenominator(materialUsageDTO.getFDenominator());
|
||
bomDetails.setName(materialUsageDTO.getMaterialName());
|
||
if (materialUsageDTO.getItemType().equals("1")) {
|
||
bomDetails.setStats("外购");
|
||
} else {
|
||
bomDetails.setStats("自制");
|
||
}
|
||
|
||
bomDetails.setMaterial(materialUsageDTO.getChildMaterial());
|
||
return bomDetails;
|
||
}
|
||
|
||
private MaterialBom creatBomMaterial(MaterialUsageDTO materialUsageDTO, CombinedDTO combinedDTO, String productionOrderNo) {
|
||
MaterialBom materialBom = new MaterialBom();
|
||
materialBom.setProjectNumber(productionOrderNo);
|
||
materialBom.setParentMaterialCode(combinedDTO.getMaterialCode());
|
||
materialBom.setParentMaterialName(combinedDTO.getMaterialName());
|
||
materialBom.setMaterialCode(materialUsageDTO.getMaterialCode());
|
||
materialBom.setMaterialName(materialUsageDTO.getMaterialName());
|
||
materialBom.setUnit(materialUsageDTO.getUnit());
|
||
materialBom.setMaterialType(materialUsageDTO.getItemType());
|
||
materialBom.setQuantity(String.valueOf(BigDecimal.valueOf(materialUsageDTO.getFNumerator())));
|
||
|
||
return materialBom;
|
||
}
|
||
|
||
|
||
/**
|
||
* 导出工艺路线列表
|
||
*/
|
||
@SaCheckPermission("system:route:getAllRouteAndUse")
|
||
@Log(title = "获取全部工艺路线和物料清单", businessType = BusinessType.OTHER)
|
||
@PostMapping("/getAllRouteAndUse")
|
||
public void getAllRouteAndUse(@RequestParam("rooteProdet") String rooteProdet) {
|
||
log.info("获取项目生产数据表:{}", rooteProdet);
|
||
// 下载Excel模板 (切换为FTP方式)
|
||
// SmbUtil.downloadExcelFiles(rooteProdet);
|
||
|
||
String ftpHost = "192.168.5.18";
|
||
String ftpUser = "admin";
|
||
String ftpPass = "hbyt2025";
|
||
int ftpPort = 21;
|
||
String localDir = "D:\\file";
|
||
// 假设远程目录结构与SMB一致,为 /2026/{rooteProdet}
|
||
String remoteDir = "/2026/" + rooteProdet;
|
||
|
||
R<String> ftpResult = FtpUtil.downloadFtpDirectoryFiles(ftpHost, ftpUser, ftpPass, ftpPort, remoteDir, localDir);
|
||
if (R.isError(ftpResult)) {
|
||
log.error("FTP下载失败: {}", ftpResult.getMsg());
|
||
} else {
|
||
log.info("FTP下载结果: {}", ftpResult.getMsg());
|
||
}
|
||
|
||
// 构建Excel文件路径
|
||
String ExcelName = "D:\\file\\" + rooteProdet + "汇总表.xlsx";
|
||
File file = new File(ExcelName);
|
||
|
||
if (!file.exists()) {
|
||
throw new ServiceException("文件不存在,请确认路径是否正确");
|
||
}
|
||
//读取file的所有的物料编码
|
||
try {
|
||
|
||
if (file.exists()) {
|
||
// 读取Excel的sheet6 从第三行开始 读取到第4列 无数据的跳过
|
||
DefaultExcelListener<ProcessRouteGetDTO> listener = new DefaultExcelListener<>(true);
|
||
EasyExcel.read(ExcelName, ProcessRouteGetDTO.class, listener).sheet(6).headRowNumber(3).doRead();
|
||
List<ProcessRouteGetDTO> list = listener.getExcelResult().getList();
|
||
List<JDMaterialAndRoute> list1 = iProcessRouteService.getProcessRouteGD(list, rooteProdet);
|
||
|
||
List<BomDetails> bomDetailsList = new ArrayList<>();
|
||
List<ProcessRoute> routeList = new ArrayList<>();
|
||
List<MaterialBom> materialBoms = new ArrayList<>();
|
||
|
||
for (JDMaterialAndRoute materialAndRoute : list1) {
|
||
processMaterAndRoute(materialAndRoute, bomDetailsList, routeList, materialBoms, rooteProdet);
|
||
}
|
||
|
||
bomDetailsMapper.insertBatch(bomDetailsList);
|
||
baseMapper.insertBatch(routeList);
|
||
materialBomMapper.insertBatch(materialBoms);
|
||
}
|
||
} catch (Exception e) {
|
||
throw new RuntimeException(e);
|
||
}
|
||
}
|
||
|
||
|
||
/**
|
||
* 更新生产订单仓库字段
|
||
*/
|
||
@SaCheckPermission("system:route:updateProductionOrders")
|
||
@Log(title = "更新生产订单仓库", businessType = BusinessType.OTHER)
|
||
@PostMapping("/updateProductionOrders")
|
||
public R updateProductionOrders(@RequestParam("rooteProdet") String rooteProdet, @RequestParam("cangKuNum") String cangKuNum) throws Exception {
|
||
//判断此项目是否有
|
||
List<String> list = iProcessRouteService.updateProductionOrders(rooteProdet, cangKuNum);
|
||
return R.ok(list);
|
||
}
|
||
|
||
/**
|
||
* 更新采购申请入库仓库仓库
|
||
*/
|
||
@SaCheckPermission("system:route:updateProductionOrders")
|
||
@Log(title = "更新采购申请单仓库", businessType = BusinessType.OTHER)
|
||
@PostMapping("/updateCgOrders")
|
||
public R updateCgOrders(@RequestParam("rooteProdet") String rooteProdet, @RequestParam("cangKuNum") String cangKuNum) throws Exception {
|
||
//判断此项目是否有
|
||
List<String> list = iProcessRouteService.updateCgOrders(rooteProdet, cangKuNum);
|
||
return R.ok(list);
|
||
}
|
||
}
|